; ;================================================================================================== ; SYSTEM TIMER BASED CLOCK DRIVER ;================================================================================================== ; TIMRTC_BUFSIZ .EQU 6 ; SIX BYTE BUFFER (YYMMDDHHMMSS) ; ; RTC DEVICE INITIALIZATION ENTRY ; TIMRTC_INIT: CALL NEWLINE ; FORMATTING PRTS("TIMRTC: $") ; ; HOOK THE HBIOS SECONDS VECTOR LD HL,(VEC_SECOND+1) ; GET CUR SECONDS VECTOR LD (TIMRTC_VEC),HL ; SAVE IT INTERNALLY LD HL,TIMRTC_INT ; OUR SECONDS INT ENTRY LD (VEC_SECOND+1),HL ; REPLACE IT ; ; DISPLAY CURRENT TIME CALL TIMRTC_GETTIM0 LD HL,TIMRTC_BCDBUF ; POINT TO BCD BUF CALL PRTDT ; XOR A ; SIGNAL SUCCESS RET ; ; RTC DEVICE FUNCTION DISPATCH ENTRY ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR ; B: FUNCTION (IN) ; TIMRTC_DISPATCH: LD A,B ; GET REQUESTED FUNCTION AND $0F ; ISOLATE SUB-FUNCTION JP Z,TIMRTC_GETTIM ; GET TIME DEC A JP Z,TIMRTC_SETTIM ; SET TIME DEC A JP Z,TIMRTC_GETBYT ; GET NVRAM BYTE VALUE DEC A JP Z,TIMRTC_SETBYT ; SET NVRAM BYTE VALUE DEC A JP Z,TIMRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES DEC A JP Z,TIMRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES CALL PANIC ; ; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR ; TIMRTC_GETBYT: TIMRTC_SETBYT: TIMRTC_GETBLK: TIMRTC_SETBLK: CALL PANIC ; ; RTC GET TIME ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR ; HL: DATE/TIME BUFFER (OUT) ; BUFFER FORMAT IS BCD: YYMMDDHHMMSS ; 24 HOUR TIME FORMAT IS ASSUMED ; TIMRTC_GETTIM: ; GET THE TIME INTO TEMP BUF PUSH HL ; SAVE PTR TO CALLERS BUFFER CALL TIMRTC_GETTIM0 ; GET TIME TO WORK BUFFER ; ; NOW COPY TO REAL DESTINATION (INTERBANK SAFE) LD A,BID_BIOS ; COPY FROM BIOS BANK LD (HB_SRCBNK),A ; SET IT LD A,(HB_INVBNK) ; COPY TO CURRENT USER BANK LD (HB_DSTBNK),A ; SET IT LD HL,TIMRTC_BCDBUF ; SOURCE ADR POP DE ; DEST ADR LD BC,TIMRTC_BUFSIZ ; LENGTH CALL HB_BNKCPY ; COPY THE CLOCK DATA ; LD DE,60 ; DELAY 60 * 16US = ~1MS CALL VDELAY ; SLOW DOWN SIMH FOR CLOCK TICKING TEST XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; TIMRTC_GETTIM0: LD HL,TIMRTC_BINBUF ; FROM BINARY BUFFER LD DE,TIMRTC_BCDBUF ; TO BCD BUFFER HB_DI CALL TIMRTC_BIN2BCD ; COPY AND CONVERT HB_EI RET ; ; RTC SET TIME ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR ; HL: DATE/TIME BUFFER (IN) ; BUFFER FORMAT IS BCD: YYMMDDHHMMSSWW ; 24 HOUR TIME FORMAT IS ASSUMED ; TIMRTC_SETTIM: ; COPY TO BCD BUF LD A,(HB_INVBNK) ; COPY FROM CURRENT USER BANK LD (HB_SRCBNK),A ; SET IT LD A,BID_BIOS ; COPY TO BIOS BANK LD (HB_DSTBNK),A ; SET IT LD DE,TIMRTC_BCDBUF ; DEST ADR LD BC,TIMRTC_BUFSIZ ; LENGTH CALL HB_BNKCPY ; COPY THE CLOCK DATA ; LD HL,TIMRTC_BCDBUF ; FROM BCD BUF LD DE,TIMRTC_BINBUF ; TO BIN BUF HB_DI CALL TIMRTC_BCD2BIN ; COPY AND CONVERT HB_EI ; XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ; HANDLER FOR TIMER SECONDS INTERRUPT ; TIMRTC_INT: LD HL,TIMRTC_BINBUF + TIMRTC_BUFSIZ - 1 INC (HL) ; INC SECONDS LD A,59 ; MAX VALUE CP (HL) ; OVERFLOW? JR NC,TIMRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO ZERO DEC HL ; POINT TO MINUTES INC (HL) ; INCREMENT MINUTE CP (HL) ; OVERFLOW? JR NC,TIMRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO ZERO DEC HL ; POINT TO HOURS INC (HL) ; INCREMENT HOURS LD A,23 ; MAX VALUE CP (HL) ; OVERFLOW? JR NC,TIMRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO ZERO DEC HL ; POINT TO DATE LD A,(TIMRTC_MO) ; GET CURRENT MONTH DEC A ; ZERO OFFSET LD DE,TIMRTC_MONTBL ; POINT TO DAYS IN MON TBL ADD A,E ; ADD OFFSET LD E,A ; BACK TO E JR NC,TIMRTC_INT1 ; NO CARRY, SKIP INC D ; HANDLE CARRY TIMRTC_INT1: LD A,(DE) ; A := DAYS IN MONTH LD C,A ; COPY TO C FOR LATER LD A,(TIMRTC_MO) ; GET CURRENT MONTH CP 2 ; FEBRUARY? JR NZ,TIMRTC_INT2 ; IF NOT, NOT LEAY, SKIP LD A,(TIMRTC_YR) ; GET CURRENT YEAR AND $03 ; CHECK FOR LEAP JR NZ,TIMRTC_INT2 ; IF NOT LEAP, SKIP AHEAD INC C ; BUMP DAYS IN FEB FOR LEAP TIMRTC_INT2: INC (HL) ; INCREMENT DATE LD A,C ; A := TRUE DAYS IN MONTH + 1 CP (HL) ; OVERFLOW? JR NZ,TIMRTC_INTX ; NOPE, DONE LD (HL),1 ; BACK TO DAY ONE DEC HL ; POINT TO MONTH INC (HL) ; INCREMENT MONTH LD A,13 ; PAST MAX? CP (HL) ; OVERFLOW? JR NZ,TIMRTC_INTX ; NOPE, DONE LD (HL),1 ; BACK TO MONTH ONE DEC HL ; POINT TO YEAR INC (HL) ; INCREMENT YEAR LD A,100 ; PAST MAX? CP (HL) ; OVERFLOW? JR NZ,TIMRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO YEAR ZERO TIMRTC_INTX: JP PANIC TIMRTC_VEC .EQU $-2 ; ; CONVERT FROM BINARY BUF (HL) TO BCD BUF (DE) ; TIMRTC_BIN2BCD: LD B,TIMRTC_BUFSIZ TIMRTC_BIN2BCD1: LD A,(HL) CALL BYTE2BCD LD (DE),A INC HL INC DE DJNZ TIMRTC_BIN2BCD1 RET ; ; CONVERT FROM BCD BUF (HL) TO BINARY BUF (DE) ; TIMRTC_BCD2BIN LD B,TIMRTC_BUFSIZ TIMRTC_BCD2BIN1: LD A,(HL) CALL BCD2BYTE LD (DE),A INC HL INC DE DJNZ TIMRTC_BCD2BIN1 RET ; ; WORKING VARIABLES ; TIMRTC_BINBUF: ; ALL IN BINARY TIMRTC_YR .DB 20 TIMRTC_MO .DB 01 TIMRTC_DT .DB 01 TIMRTC_HH .DB 00 TIMRTC_MM .DB 00 TIMRTC_SS .DB 00 ; TIMRTC_BCDBUF .FILL TIMRTC_BUFSIZ ; TIMRTC_MONTBL: ; DAYS IN MONTH + 1 .DB 32 ; JANUARY .DB 29 ; FEBRUARY (NON-LEAP) .DB 32 ; MARCH .DB 31 ; APRIL .DB 32 ; MAY .DB 31 ; JUNE .DB 32 ; JULY .DB 32 ; AUGUST .DB 31 ; SEPTEMBER .DB 32 ; OCTOBER .DB 31 ; NOVEMBER .DB 32 ; DECEMBER