; B5C-CPM3.INS - Clock routine for CP/M Plus ; ; (8/28/85) Added option to use standard BDOS calls for non-interrupt ; driven CP/M Plus systems. Unless the BIOS uses an ; interrupt driven clock, the SCB doesn't get updated. ; Also removed surrounding IF CLOCK OR RSPEED. ; -- Paul Bartholomew ; ; (8/17/85) Initial release for BYE501 and above. This INSert uses ; time/date routines originally written by Sigi Kluger. ; -- George Peace ;---------------------------------------------------------------- ; ; This clock insert uses BCDBIN and BINBCD subroutines. It requires that ; configuration tags BCD2BIN and BIN2BCD as well as CLOCK be set to YES. ; ; Note- This is an insert--not an overlay ; CLKINT EQU YES ; YES if SCB time is updated by interrupts ; as on Osborne Executive (OX) ; NO if BDOS access required to update SCB ; as on Morrow hard disk (MH) series ; CENTURY EQU 19H ; Current century (19xx) in BCD ; TIME: IF CLKINT DI ; Disable interrupts while checking time (SCB) LHLD SCBBASE ; Get SCB base address MVI L,SCBTIM ; Build SCB time field address MOV A,M ; Get hours (BCD) ENDIF ; CLKINT IF NOT CLKINT MVI C,105 ; CP/M Plus Get date/time call LXI D,DTDAT ; Address of DAT buffer DI ; Disable interrupts while checking time CALL BDOS ; Get info through BDOS EI ; Re-enable interrupts STA RTCBUF+2 ; Seconds returned in A (BCD) LDA DTHR ; Get Hour ENDIF ; NOT CLKINT STA RTCBUF ; Store BCD hours in RTCBUF CALL BCDBIN ; Convert to binary STA CCHOUR ; And save as current hour IF CLKINT INX H ; Point to minute byte MOV A,M ; Get minutes (BCD) ENDIF ; CLKINT IF NOT CLKINT LDA DTMN ; Get minutes ENDIF ; NOT CLKINT STA RTCBUF+1 ; Store BCD minutes in RTCBUF CALL BCDBIN ; Convert to binary STA CCMIN ; And save as current minute IF CLKINT INX H ; Point to seconds byte MOV A,M ; Get seconds (BCD) STA RTCBUF+2 ; Store BCD seconds in RTCBUF ENDIF ; CLKINT ; MVI A,CENTURY ; Get current century STA RTCBUF+3 ; And store in RTC buffer ; ; Get the date ; IF CLKINT LHLD SCBBASE ; Get SCB base address MVI L,SCBDAT ; Build SCB date field address MOV E,M INX H MOV D,M EI ; Enable interrupts after SCB access is done XCHG ; Transfer date to HL ENDIF ; CLKINT IF NOT CLKINT LHLD DTDAT ; Date in HL ENDIF ; NOT CLKINT ; MVI B,78 ; Set years counter ; LOOP: CALL CKLEAP LXI D,-365 ; Set up for subtract JNZ NOLPY ; Skip if no leap year DCX D ; Set for leap year ; NOLPY: DAD D ; Subtract JNC YDONE ; Continue if years done MOV A,H ORA L JZ YDONE SHLD DTDAT ; Else save days count INR B ; Increment years count JMP LOOP ; And do again ; ; ; The years are now finished, the years count is in 'B' and DTDAT holds ; the days (HL is invalid) ; YDONE: MOV A,B CALL BINBCD STA RTCBUF+4 CALL CKLEAP ; Check if leap year MVI A,-28 JNZ FEBNO ; February not 29 days MVI A,-29 ; Leap year ; FEBNO: STA FEB ; Set february LHLD DTDAT ; Get days count LXI D,MTABLE ; Point to months table MVI B,0FFH ; Set up 'B' for subtract MVI A,0 ; Set a for # of months ; MLOOP: PUSH PSW LDAX D ; Get month MOV C,A ; Put in 'C' for subtract POP PSW SHLD DTDAT ; Save days count DAD B ; Subtract INX D ; Increment months counter INR A JC MLOOP ; Loop for next month ; ; ; The months are finished, days count is on stack. First, calculate ; month. ; MDONE: MOV B,A ; Save months LHLD DTDAT MOV A,H ORA L JNZ NZD DCX D DCX D LDAX D CMA INR A MOV L,A DCR B ; NZD: MOV A,B ; Retrieve the binary month CALL BINBCD ; Convert binary month to BCD STA RTCBUF+5 ; Store BCD month in RTCBUF MOV A,L ; Retrieve binary day of month CALL BINBCD ; Convert to BCD STA RTCBUF+6 ; Store BCD day of month in RTCBUF ; RET ;..... ; ; ; This routine checks for leap years. ; CKLEAP: MOV A,B ANI 0FCH CMP B RET ;..... ; ; ; This is the month's table ; MTABLE: DB -31 ;January FEB: DB -28 ;February DB -31,-30,-31,-30 ;Mar-Jun DB -31,-31,-30 ;Jul-Sep DB -31,-30,-31 ;Oct-Dec ; DTDAT: DW 0 ; Storage for DATE IF NOT CLKINT DTHR: DB 0 ; Hour in BCD DTMN: DB 0 ; Minute in BCD ENDIF ; NOT CLKINT