.TITLE NBS NBS date/time routines .NLIST BEX .ENABL LC ; ; Pdp11/dcn - NBS date/time routines ; ; Entry symbols ; .GLOBL NBSDAT ;convert NBS date to internal format .GLOBL NBSTIM ;convert NBS time to internal format ; ; System definitions ; .ASECT .MCALL .COM,.GDAT ;dcnlib macros .COM ;define common data ; ; Procedure segment ; .PSECT $SUPI,RO,I ; ; NBSDAT (nbs) convert date in ddd (r0 = 0) or mm/dd (r0 = 1) format ; r0 = date format switch, r1 = field pointer, ; returns r0 = date, cc = c if error ; ; date formats ; 0 ddd spectracom format 0, truetime format ; 1 mm/dd heath format ; 2 yy ddd spectracom format 2 ; NBSDAT: MOV R2,-(SP) ;save MOV R3,-(SP) MOV R0,-(SP) ;save switch CMP @SP,#2 ;is this yy ddd format BEQ 20$ ;branch if yes .GDAT ;no. determine days to 1 jan this year BIC #140000,R0 MOV R0,R3 CLR R2 DIV #1461.,R2 ;(4*365+1) MOV R3,R0 MUL #1461.,R2 MOV #YEAR,R2 ;(days/year table pointer) 1$: SUB @R2,R0 ;fiddle the leaps BLT 2$ ADD (R2)+,R3 BR 1$ ; 20$: JSR PC,NBSDIG ;convert year field SUB #72.,R0 ;determine days 1 jan this year BMI 7$ ;branch if too low MOV R0,R2 ;(days/year table pointer) BIC #^C3,R2 ASL R2 ADD #YEAR,R2 MOV R0,R3 ;(leap days) MUL #365.,R3 ADD #3,R0 ASH #-2,R0 ADD R0,R3 CMPB (R1)+,#<' > BNE 7$ ;branch if syntax error 2$: JSR PC,NBSDIG ;convert first subfield BCS 7$ ;branch if error DEC R0 BMI 7$ ;branch if too low CMP R0,@R2 BHIS 7$ ;branch if too high CMP @SP,#1 ;is this mm/dd format BNE 6$ ;branch if no CMP R0,#12. ;yes. is month in range BHIS 7$ ;branch if no CMP @R2,#366. ;yes. is this leap year BEQ 3$ ;branch if no MOV #STDYER,R2 ;yes. use standard year table BR 4$ ; 3$: MOV #LEPYER,R2 ;use leap year table 4$: DEC R0 ;is this right month BLT 5$ ;branch if yes ADD (R2)+,R3 ;no. add month days BR 4$ ; 5$: JSR PC,NBSDIG ;get day of month BCS 7$ ;branch if error DEC R0 BMI 7$ ;branch if too low CMP R0,@R2 BHIS 7$ ;branch if too high 6$: ADD R3,R0 ;add current day CLC ;normal return BR 8$ ; 7$: SEC ;error return 8$: MOV (SP)+,R3 ;discard switch MOV (SP)+,R3 ;evas MOV (SP)+,R2 RTS PC ; ; NBSTIM (nbs) convert time in hh:mm:ss.f format (.f is optional) ; R1 = field pointer, returns r0-r1 = time (milliseconds), cc = c if error ; NBSTIM: MOV R2,-(SP) ;save MOV R3,-(SP) MOV R4,-(SP) CLR R2 ;initialize accumulator CLR R3 MOV #24.,R0 ;get hours JSR PC,CLK71 BCS 2$ ;branch if error CMPB (R1)+,#<':> BNE 2$ ;branch if syntax error MOV #60.,R0 ;get minutes JSR PC,CLK71 BCS 2$ ;branch if error CMPB (R1)+,#<':> BNE 2$ ;branch if syntax error MOV #60.,R0 ;get seconds JSR PC,CLK71 BCS 2$ ;branch if error CLR R4 ;assume no fraction CMPB (R1)+,#<'.> ;is fraction present BNE 1$ ;branch if no MOV R1,-(SP) ;yes. scan for terminator JSR PC,NBSDIG MOV R1,R4 MOV (SP)+,R1 SUB R1,R4 ;compute fraction size CMP R4,#3 BHI 2$ ;branch if too high ASL R4 MOV RADIX(R4),R0 ;get fraction JSR PC,CLK71 BCS 2$ ;branch if error 1$: NEG R4 ;scale to milliseconds MOV RADIX+6(R4),R0 JSR PC,DMUL MOV R2,R0 ;get result MOV R3,R1 CLC ;normal return BR 3$ ; 2$: SEC ;error return 3$: MOV (SP)+,R4 ;evas MOV (SP)+,R3 MOV (SP)+,R2 RTS PC ; ; Subroutine to perform double-precision multiplication ; R0 = multiplier, r2-r3 = multiplicand, returns r2-r3 = product (lsb) ; DMUL: MOV R1,-(SP) ;save MOV R4,-(SP) CLR R1 ;initialize MOV #33.,R4 1$: ASR R1 ;shift partial product right ROR R2 ROR R3 BCC 2$ ;branch if lsb = 0 ADD R0,R1 ;lsb <> 0. add multiplier 2$: SOB R4,1$ MOV (SP)+,R4 ;evas MOV (SP)+,R1 RTS PC ; ; Subroutine to accumulate next decimal field ; R0 = radix, r1 = field pointer, updates accumulator r2-r3, cc = c if error ; CLK71: MOV R0,-(SP) ;multiply by radix JSR PC,DMUL JSR PC,NBSDIG ;convert next field BCS 1$ ;branch if error CMP R0,(SP)+ BHIS 2$ ;branch if radix exceeded ADD R0,R3 ;add to product ADC R2 RTS PC ;normal return ; 1$: TST (SP)+ ;error return 2$: SEC RTS PC ; ; Subroutine to convert next decimal field to integer ; R1 = field pointer, returns r0 = integer, cc = c if error ; NBSDIG: MOV R3,-(SP) ;save CLR R3 ;initialize MOVB (R1)+,R0 ;get next digit CMPB R0,#'0 BLO 3$ ;branch if not CMPB R0,#'9 BHI 3$ ;branch if not 1$: MUL #10.,R3 ;convert to binary BIC #^C17,R0 ADD R0,R3 MOVB (R1)+,R0 ;get next digit CMPB R0,#'0 BLO 2$ ;branch if not CMPB R0,#'9 BHI 2$ ;branch if not BR 1$ ; 2$: CLC ;normal return BR 4$ ; 3$: SEC ;error return 4$: DEC R1 ;restore terminator MOV R3,R0 MOV (SP)+,R3 ;evas RTS PC ; ; Data segment ; .PSECT $SUPD,RO,D ; ; xx0 xx1 xx2 xx3 YEAR: .WORD 366.,365.,365.,365. ; jan feb mar apr may jun jul aug sep oct nov dec STDYER: .WORD 031.,028.,031.,030.,031.,030.,031.,031.,030.,031.,030.,031. LEPYER: .WORD 031.,029.,031.,030.,031.,030.,031.,031.,030.,031.,030.,031. RADIX: .WORD 1.,10.,100.,1000. ; .END