; ;================================================================================================== ; SYSTEM TIMER BASED CLOCK DRIVER ;================================================================================================== ; INTRTC_BUFSIZ .EQU 6 ; SIX BYTE BUFFER (YYMMDDHHMMSS) ; ; RTC DEVICE INITIALIZATION ENTRY ; INTRTC_INIT: LD A,(RTC_DISPACT) ; RTC DISPATCHER ALREADY SET? OR A ; SET FLAGS RET NZ ; IF ALREADY ACTIVE, ABORT ; CALL NEWLINE ; FORMATTING PRTS("INTRTC: $") ; ; HOOK THE HBIOS SECONDS VECTOR LD HL,(VEC_SECOND+1) ; GET CUR SECONDS VECTOR LD (INTRTC_VEC),HL ; SAVE IT INTERNALLY LD HL,INTRTC_INT ; OUR SECONDS INT ENTRY LD (VEC_SECOND+1),HL ; REPLACE IT ; ; DISPLAY CURRENT TIME CALL INTRTC_GETTIM0 LD HL,INTRTC_BCDBUF ; POINT TO BCD BUF CALL PRTDT ; LD BC,INTRTC_DISPATCH CALL RTC_SETDISP ; XOR A ; SIGNAL SUCCESS RET ; ; RTC DEVICE FUNCTION DISPATCH ENTRY ; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR ; B: FUNCTION (IN) ; INTRTC_DISPATCH: LD A,B ; GET REQUESTED FUNCTION AND $0F ; ISOLATE SUB-FUNCTION JP Z,INTRTC_GETTIM ; GET TIME DEC A JP Z,INTRTC_SETTIM ; SET TIME DEC A JP Z,INTRTC_GETBYT ; GET NVRAM BYTE VALUE DEC A JP Z,INTRTC_SETBYT ; SET NVRAM BYTE VALUE DEC A JP Z,INTRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES DEC A JP Z,INTRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES DEC A JP Z,INTRTC_GETALM ; GET ALARM DEC A JP Z,INTRTC_SETALM ; SET ALARM DEC A JP Z,INTRTC_DEVICE ; REPORT RTC DEVICE INFO SYSCHKERR(ERR_NOFUNC) RET ; ; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR ; INTRTC_GETBYT: INTRTC_SETBYT: INTRTC_GETBLK: INTRTC_SETBLK: INTRTC_GETALM: INTRTC_SETALM: SYSCHKERR(ERR_NOTIMPL) RET ; ; 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 ; INTRTC_GETTIM: ; GET THE TIME INTO TEMP BUF PUSH HL ; SAVE PTR TO CALLERS BUFFER CALL INTRTC_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,INTRTC_BCDBUF ; SOURCE ADR POP DE ; DEST ADR LD BC,INTRTC_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 ; INTRTC_GETTIM0: LD HL,INTRTC_BINBUF ; FROM BINARY BUFFER LD DE,INTRTC_BCDBUF ; TO BCD BUFFER HB_DI CALL INTRTC_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 ; INTRTC_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,INTRTC_BCDBUF ; DEST ADR LD BC,INTRTC_BUFSIZ ; LENGTH CALL HB_BNKCPY ; COPY THE CLOCK DATA ; LD HL,INTRTC_BCDBUF ; FROM BCD BUF LD DE,INTRTC_BINBUF ; TO BIN BUF HB_DI CALL INTRTC_BCD2BIN ; COPY AND CONVERT HB_EI ; XOR A ; SIGNAL SUCCESS RET ; AND RETURN ; ; REPORT RTC DEVICE INFO ; INTRTC_DEVICE: LD D,RTCDEV_INT ; D := DEVICE TYPE LD E,0 ; E := PHYSICAL DEVICE NUMBER LD H,0 ; H := 0, DRIVER HAS NO MODES LD L,0 ; L := 0, NO I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; ; HANDLER FOR TIMER SECONDS INTERRUPT ; INTRTC_INT: LD HL,INTRTC_BINBUF + INTRTC_BUFSIZ - 1 INC (HL) ; INC SECONDS LD A,59 ; MAX VALUE CP (HL) ; OVERFLOW? JR NC,INTRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO ZERO DEC HL ; POINT TO MINUTES INC (HL) ; INCREMENT MINUTE CP (HL) ; OVERFLOW? JR NC,INTRTC_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,INTRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO ZERO DEC HL ; POINT TO DATE LD A,(INTRTC_MO) ; GET CURRENT MONTH DEC A ; ZERO OFFSET LD DE,INTRTC_MONTBL ; POINT TO DAYS IN MON TBL ADD A,E ; ADD OFFSET LD E,A ; BACK TO E JR NC,INTRTC_INT1 ; NO CARRY, SKIP INC D ; HANDLE CARRY INTRTC_INT1: LD A,(DE) ; A := DAYS IN MONTH LD C,A ; COPY TO C FOR LATER LD A,(INTRTC_MO) ; GET CURRENT MONTH CP 2 ; FEBRUARY? JR NZ,INTRTC_INT2 ; IF NOT, NOT LEAY, SKIP LD A,(INTRTC_YR) ; GET CURRENT YEAR AND $03 ; CHECK FOR LEAP JR NZ,INTRTC_INT2 ; IF NOT LEAP, SKIP AHEAD INC C ; BUMP DAYS IN FEB FOR LEAP INTRTC_INT2: INC (HL) ; INCREMENT DATE LD A,C ; A := TRUE DAYS IN MONTH + 1 CP (HL) ; OVERFLOW? JR NZ,INTRTC_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,INTRTC_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,INTRTC_INTX ; NOPE, DONE LD (HL),0 ; BACK TO YEAR ZERO INTRTC_INTX: JP PANIC INTRTC_VEC .EQU $-2 ; ; CONVERT FROM BINARY BUF (HL) TO BCD BUF (DE) ; INTRTC_BIN2BCD: LD B,INTRTC_BUFSIZ INTRTC_BIN2BCD1: LD A,(HL) CALL BYTE2BCD LD (DE),A INC HL INC DE DJNZ INTRTC_BIN2BCD1 RET ; ; CONVERT FROM BCD BUF (HL) TO BINARY BUF (DE) ; INTRTC_BCD2BIN LD B,INTRTC_BUFSIZ INTRTC_BCD2BIN1: LD A,(HL) CALL BCD2BYTE LD (DE),A INC HL INC DE DJNZ INTRTC_BCD2BIN1 RET ; ; WORKING VARIABLES ; INTRTC_BINBUF: ; ALL IN BINARY INTRTC_YR .DB 20 INTRTC_MO .DB 01 INTRTC_DT .DB 01 INTRTC_HH .DB 00 INTRTC_MM .DB 00 INTRTC_SS .DB 00 ; INTRTC_BCDBUF .FILL INTRTC_BUFSIZ ; INTRTC_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