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.
 
 
 
 
 
 

264 lines
6.4 KiB

;
;==================================================================================================
; DALLAS SEMICONDUCTOR DS1302 RTC DRIVER
;==================================================================================================
;
; CONSTANTS
;
DSRTC_BASE .EQU RTC ; RTC PORT ON ALL N8VEM SERIES Z80 PLATFORMS
;
DSRTC_DATA .EQU %10000000 ; BIT 7 CONTROLS RTC DATA (I/O) LINE
DSRTC_CLK .EQU %01000000 ; BIT 6 CONTROLS RTC CLOCK LINE, 1 = HIGH
DSRTC_RD .EQU %00100000 ; BIT 5 CONTROLS DATA DIRECTION, 1 = READ
DSRTC_CE .EQU %00010000 ; BIT 4 CONTROLS RTC CE LINE, 1 = HIGH (ENABLED)
;
DSRTC_BUFSIZ .EQU 7 ; 7 BYTE BUFFER (YYMMDDHHMMSSWW)
;
; RTC DEVICE INITIALIZATION ENTRY
;
DSRTC_INIT:
PRTS("DSRTC: $")
;
; CHECK FOR CLOCK HALTED
CALL DSRTC_TSTCLK
JR Z,DSRTC_INIT1
PRTS("INIT CLOCK $")
LD HL,DSRTC_TIMDEF
CALL DSRTC_SETTIM
;
DSRTC_INIT1:
; DISPLAY CURRENT TIME
LD HL,DSRTC_TIMBUF
PUSH HL
CALL DSRTC_GETTIM
POP HL
CALL PRTDT
;
XOR A ; SIGNAL SUCCESS
RET
;
; RTC DEVICE FUNCTION DISPATCH ENTRY
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
; B: FUNCTION (IN)
;
DSRTC_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,DSRTC_GETTIM ; GET TIME
DEC A
JP Z,DSRTC_SETTIM ; SET TIME
DEC A
JP Z,DSRTC_GETBYT ; GET NVRAM BYTE VALUE
DEC A
JP Z,DSRTC_SETBYT ; SET NVRAM BYTE VALUE
DEC A
JP Z,DSRTC_GETBLK ; GET NVRAM DATA BLOCK VALUES
DEC A
JP Z,DSRTC_SETBLK ; SET NVRAM DATA BLOCK VALUES
CALL PANIC
;
; NVRAM FUNCTIONS ARE NOT AVAILABLE IN SIMULATOR
;
DSRTC_GETBYT:
DSRTC_SETBYT:
DSRTC_GETBLK:
DSRTC_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
;
DSRTC_GETTIM:
;
; READ THE CLOCK
PUSH HL ; SAVE ADR OF OUTPUT BUF
LD HL,DSRTC_BUF ; USE WORK BUF TO READ CLOCK
CALL DSRTC_RDCLK ; READ THE CLOCK
;
; TRANSLATE FROM TEMP BUF TO OUTPUT BUF
POP HL ; RESTORE THE OUTPUT BUF ADR
LD A,(DSRTC_YR)
LD (HL),A
INC HL
LD A,(DSRTC_MON)
LD (HL),A
INC HL
LD A,(DSRTC_DT)
LD (HL),A
INC HL
LD A,(DSRTC_HR)
LD (HL),A
INC HL
LD A,(DSRTC_MIN)
LD (HL),A
INC HL
LD A,(DSRTC_SEC)
LD (HL),A
;
; CLEAN UP AND RETURN
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; RTC SET TIME
; A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
; HL: DATE/TIME BUFFER (IN)
; BUFFER FORMAT IS BCD: YYMMDDHHMMSS
; 24 HOUR TIME FORMAT IS ASSUMED
;
DSRTC_SETTIM:
;
; TRANSLATE FROM INPUT BUF TO WORK BUF
LD A,(HL)
LD (DSRTC_YR),A
INC HL
LD A,(HL)
LD (DSRTC_MON),A
INC HL
LD A,(HL)
LD (DSRTC_DT),A
INC HL
LD A,(HL)
LD (DSRTC_HR),A
INC HL
LD A,(HL)
LD (DSRTC_MIN),A
INC HL
LD A,(HL)
LD (DSRTC_SEC),A
XOR A ; FIX: DERIVE DAY OF WEEK!!!
LD (DSRTC_DAY),A
;
; WRITE TO CLOCK
LD HL,DSRTC_BUF ; POINT TO WORK BUF
CALL DSRTC_WRCLK ; SEND IT TO RTC
;
; CLEAN UP AND RETURN
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; TEST CLOCK FOR VALID DATA
; READ CLOCK HALT BIT AND RETURN ZF BASED ON BIT VALUE
; 0 = RUNNING
; 1 = HALTED
;
DSRTC_TSTCLK:
LD C,$81 ; SECONDS REGISTER HAS CLOCK HALT FLAG
CALL DSRTC_CMD ; SEND THE COMMAND
CALL DSRTC_GET ; READ THE REGISTER
AND %10000000 ; HIGH ORDER BIT IS CLOCK HALT
RET
;
; BURST READ CLOCK DATA INTO BUFFER AT HL
;
DSRTC_RDCLK:
LD C,$BF ; COMMAND = $BF TO BURST READ CLOCK
CALL DSRTC_CMD ; SEND COMMAND TO RTC
LD B,DSRTC_BUFSIZ ; B IS LOOP COUNTER
DSRTC_RDCLK1:
PUSH BC ; PRESERVE BC
CALL DSRTC_GET ; GET NEXT BYTE
LD (HL),A ; SAVE IN BUFFER
INC HL ; INC BUF POINTER
POP BC ; RESTORE BC
DJNZ DSRTC_RDCLK1 ; LOOP IF NOT DONE
XOR A ; ALL LINES OFF TO CLEAN UP
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
RET
;
; BURST WRITE CLOCK DATA FROM BUFFER AT HL
;
DSRTC_WRCLK:
LD C,$8E ; COMMAND = $8E TO WRITE CONTROL REGISTER
CALL DSRTC_CMD ; SEND COMMAND
XOR A ; $00 = UNPROTECT
CALL DSRTC_PUT ; SEND VALUE TO CONTROL REGISTER
;
LD C,$BE ; COMMAND = $BE TO BURST WRITE CLOCK
CALL DSRTC_CMD ; SEND COMMAND TO RTC
LD B,DSRTC_BUFSIZ ; B IS LOOP COUNTER
DSRTC_WRCLK1:
PUSH BC ; PRESERVE BC
LD A,(HL) ; GET NEXT BYTE TO WRITE
CALL DSRTC_PUT ; PUT NEXT BYTE
INC HL ; INC BUF POINTER
POP BC ; RESTORE BC
DJNZ DSRTC_WRCLK1 ; LOOP IF NOT DONE
LD A,$80 ; ADD CONTROL REG BYTE, $80 = PROTECT ON
CALL DSRTC_PUT ; WRITE REQUIRED 8TH BYTE
XOR A ; ALL LINES OFF TO CLEAN UP
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
RET
;
; SEND COMMAND IN C TO RTC
;
DSRTC_CMD:
LD A,DSRTC_RD ; CE LOW TO RESET RTC
OUT (DSRTC_BASE),A ; WRITE IT
LD A,C ; LOAD COMMAND
CALL DSRTC_PUT ; WRITE IT
RET
;
; WRITE BYTE IN A TO THE RTC
;
DSRTC_PUT:
LD B,8 ; LOOP FOR 8 BITS
DSRTC_PUT1:
RRCA ; ROTATE NEXT BIT TO SEND INTO BIT 7
LD C,A ; SAVE WORKING VALUE
AND %10000000 ; ISOLATE THE DATA BIT
OR DSRTC_CE ; ADD CHIP ENABLE, CLOCK HIGH
OUT (DSRTC_BASE),A ; WRITE TO PORT WITH CLOCK LOW
XOR DSRTC_CLK ; TURN CLOCK BACK ON
OUT (DSRTC_BASE),A ; WRITE TO PORT WITH CLOCK HIGH
LD A,C ; RECOVER WORKING VALUE
DJNZ DSRTC_PUT1 ; LOOP IF NOT DONE
RET
;
; READ BYTE FROM RTC, RETURN VALUE IN A
;
DSRTC_GET:
LD C,0 ; INITIALIZE WORKING VALUE TO 0
LD B,8 ; LOOP FOR 8 BITS
DSRTC_GET1:
LD A,DSRTC_RD+DSRTC_CE ; LOWER CLOCK, CE STAYS HI, READ IS ON
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
NOP ; SETTLE
IN A,(DSRTC_BASE) ; READ THE RTC PORT
AND %00000001 ; ISOLATE THE DATA BIT
OR C ; COMBINE WITH WORKING VALUE
RRCA ; ROTATE FOR NEXT BIT
LD C,A ; SAVE WORKING VALUE
LD A,DSRTC_CLK+DSRTC_RD+DSRTC_CE ; CLOCK BACK TO HIGH NOW
OUT (DSRTC_BASE),A ; WRITE TO RTC PORT
DJNZ DSRTC_GET1 ; LOOP IF NOT DONE
LD A,C ; GET RESULT INTO A
RET
;
; WORKING VARIABLES
;
; DSRTC_BUF IS USED FOR BURST READ/WRITE OF CLOCK DATA TO DS-1302
; FIELDS BELOW MATCH ORDER OF DS-1302 FIELDS (BCD)
;
DSRTC_BUF:
DSRTC_SEC: .DB 0 ; SECOND
DSRTC_MIN: .DB 0 ; MINUTE
DSRTC_HR: .DB 0 ; HOUR
DSRTC_DT: .DB 0 ; DATE
DSRTC_MON: .DB 0 ; MONTH
DSRTC_DAY: .DB 0 ; DAY OF WEEK
DSRTC_YR: .DB 0 ; YEAR
;
; DSRTC_TIMBUF IS TEMP BUF USED TO STORE TIME TEMPORARILY TO DISPLAY
; IT.
;
DSRTC_TIMBUF .FILL 6,0 ; 6 BYTES FOR GETTIM
;
; DSRTC_TIMDEF IS DEFAULT TIME VALUE TO INITIALIZE CLOCK IF IT IS
; NOT RUNNING.
;
DSRTC_TIMDEF: ; DEFAULT TIME VALUE TO INIT CLOCK
.DB $00,$01,$01 ; 2000-01-01
.DB $00,$00,$00 ; 00:00:00