.TITLE CDATDI .IDENT /V01/ .ENABLE LC ; ; This module forms part of the suite of Date Routines returning the ; current date in one of the following forms, or converting one form to ; another. ; Form I - Day, Month & Year since 1950 as 3 byte values ; Form A - ASCII DD-MMM-YY ; Form D - Integer*2 days since 1st January 1950 ; Form E - Integer*2 encoded date ; Form W - Weekday Number (0 = Sunday) ; ; Author: V01 30-Jun-80 Phil Stephensen-Payne ; ; Calling Sequence: ; ; This subroutine is called via the standard FORTRAN calling sequence as: ; ; CALL CDATDI (DAYNO,DAY,MONTH,YEAR [,STATUS]) ; or ; STATUS = CDATDI (DAYNO,DAY,MONTH,YEAR) ; ; or ; CALL CDATDI from MACRO-11 with ; R5 = 0 ; R1 = DAYNO ; R0 = STATUS on output ; R1 = DAY on output ; R2 = MONTH on output ; R3 = YEAR on output ; ; Where: ; DAYNO = Number of days since 1/1/50 (1/1/50 = 1) ; DAY = Number of day (1-31) ; MONTH = Number of month (1-12) ; YEAR = Year since 1950 (1950=0) ; STATUS = Optional error return ; ; Errors returned: ; ; STATUS = 0 if the operation was successful ; = -1 if a parameter error was detected ; = -2 if an invalid input date was specified ; ; External references: ; ; This module calls the subroutines PRMCHK ; ; DAY2: .WORD 0,31.,59.,90.,120.,151.,181.,212.,243.,273.,304.,334. ; ; CDATDI:: TST R5 ; Called directly from MACRO-11? BEQ 20$ ; If eq yes - omit PRMCHK ; ; Specify number of parameters including error return. R5 not affected. ; MOV #5,R0 ; Check Number of Parameters CALL PRMCHK ; BCC 10$ ; If CC parameters OK - carry on JMP END ; Else error - exit immediately ; 10$: TST (R5)+ ; Ignore Number of parameters MOV #-1,R0 ; Assume a parameter error BIT #1,(R5) ; Parameter word-aligned? BNE END ; If NE no - error MOV @(R5)+,R1 ; Get the parameter ; 20$: TST R1 ; Zero day number? BEQ ERR ; If EQ yes - error CMP R1,#36525. ; Valid date? BHI ERR ; If HI no - error MOV R1,R2 ; Save the date CLR R0 ; Clear high word for division DIV #365.,R0 ; Get number of years (first guess) MOV R0,R3 ; Save the answer ; 30$: MUL #365.,R0 ; Get number of days to 31st Dec previous year MOV R3,R0 ; INC R0 ; ASR R0 ; (allow for leap days) ASR R0 ; ADD R0,R1 ; CMP R1,R2 ; Are we in the right year? BLO 40$ ; If LO yes - carry on DEC R3 ; No - back a year MOV R3,R0 ; BR 30$ ; ; 40$: ADD #50.,R3 ; Adjust it to 0-100 the other way MOV R3,-(SP) ; Yes - save the year number CMP (SP),#100. ; BLO 50$ ; SUB #100.,(SP) ; ; 50$: SUB R1,R2 ; Discount what we've just accounted for BIC #177774,R3 ; Get Leap Year Value BNE 70$ ; If NE not leap year CMP R2,#60. ; The magic February 29th? BNE 60$ ; If NE no - carry on MOV #29.,R1 ; Yes - set it by hand MOV #2,R2 ; BR 100$ ; and exit ; 60$: BLO 70$ ; If LO OK as it is - carry on DEC R2 ; Else - discount 29th Feb ; 70$: MOV R2,R1 ; Stuff day number in right place CLR R2 ; Initialise month number ; 80$: CMP R1,DAY2(R2) ; This month? BLOS 90$ ; Yes - carry on ADD #2,R2 ; No - try next one CMP R2,#24. ; Run off the end? BLO 80$ ; If LO no - check the next one ; 90$: SUB DAY2-2(R2),R1 ; Adjust day number ASR R2 ; And month number ; 100$: MOV (SP)+,R3 ; And retrieve year number TST R5 ; MACRO-11 call? BEQ 110$ ; If eq yes - just end MOVB R1,@(R5)+ ; No - return parameters MOVB R2,@(R5)+ ; MOVB R3,@(R5)+ ; ; 110$: CLR R0 ; END: RETURN ; ERR: MOV #-2,R0 ; Invalid date RETURN ; .END