You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

261 lines
6.1 KiB

;
;==================================================================================================
; 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
CALL SYSCHK
LD A,ERR_NOFUNC
OR A
RET
;
; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR
;
INTRTC_GETBYT:
INTRTC_SETBYT:
INTRTC_GETBLK:
INTRTC_SETBLK:
INTRTC_GETALM:
INTRTC_SETALM:
CALL SYSCHK
LD A,ERR_NOTIMPL
OR A
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 SYSCHK
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