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.
 
 
 
 
 
 

228 lines
5.4 KiB

.Z80
VERS EQU 03
;
;RTC_BASE EQU 70H ; RTC PORT ON N8VEM/ZETA
RTC_BASE EQU 88H ; RTC PORT ON N8
;
RTC_DATA EQU 10000000B ; BIT 7 CONTROLS RTC DATA (I/O) LINE
RTC_CLK EQU 01000000B ; BIT 6 CONTROLS RTC CLOCK LINE, 1 = HIGH
RTC_RD EQU 00100000B ; BIT 5 CONTROLS DATA DIRECTION, 1 = READ
RTC_CE EQU 00010000B ; BIT 4 CONTROLS RTC CE LINE, 1 = HIGH (ENABLED)
;
COMMON /_CLKID/
DESCST: DEFW 0000 ; Add label here if a static year byte
; is used by your clock driver. The
; label should point to the year byte
; 123456789012345678901234
CLKNAM: DEFB 'N8 DS1302 Clock ' ; Exactly 24 chars in name
DEFB VERS/10+'0','.',VERS MOD 10 +'0',0
;
DESCR: DEFB 'DS1302 Real-time Clock Driver for N8 Z180',0
;
COMMON /_PARM_/
;
PARBAS: DEFW 0 ; # of parameters (Set to 00 if none)
DEFW 0 ; Pointer to STRS (Set to 00 if none)
;
CSEG
;
;-------------------------------------------------------------
; Z S D O S C L O C K H E A D E R
;-------------------------------------------------------------
; Enter: HL = Address to Put Date/Time string
; Exit : Time moved and counter incremented
; A=1 for OK status on exit
;
; Enter: HL points to a 6-byte buffer to Get/Set time
; Exit : A=1 on Success, A=FFH if error
; HL points to last char in buffer
; E contains original seconds (HL+5)
JP GETTIM ; Get time
JP WRCLK ; Set time
;
BUFSIZE EQU 7
BUFRTC:
BUFSEC: DEFB 0 ; Second
BUFMIN: DEFB 0 ; Minute
BUFHR: DEFB 0 ; Hour
BUFDT: DEFB 0 ; Date
BUFMON: DEFB 0 ; Month
BUFDAY: DEFB 0 ; Day
BUFYR: DEFB 0 ; Year
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; R e a d T h e C l o c k
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;
GETTIM: PUSH HL
LD HL,BUFRTC
CALL CLK_RD
; COPY DATE/TIME INTO OUTPUT BUFFER
POP HL
LD A,(BUFYR)
LD (HL),A
INC HL
LD A,(BUFMON)
LD (HL),A
INC HL
LD A,(BUFDT)
LD (HL),A
INC HL
LD A,(BUFHR)
LD (HL),A
INC HL
LD A,(BUFMIN)
LD (HL),A
INC HL
LD A,(BUFSEC)
LD (HL),A
LD E,(HL)
; RETURN WITH SUCCESS
XOR A
INC A
RET
;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; S e t T h e C l o c k
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;
WRCLK: LD A,(HL)
LD (BUFYR),A
INC HL
LD A,(HL)
LD (BUFMON),A
INC HL
LD A,(HL)
LD (BUFDT),A
INC HL
LD A,(HL)
LD (BUFHR),A
INC HL
LD A,(HL)
LD (BUFMIN),A
INC HL
LD A,(HL)
LD (BUFSEC),A
PUSH HL
LD HL,BUFRTC
CALL CLK_WR
POP HL
; RETURN WITH SUCCESS
XOR A
INC A
RET
;
; BURST READ CLOCK DATA INTO BUFFER AT HL
;
CLK_RD:
LD C,0BFH ; COMMAND = $BF TO BURST READ CLOCK
CALL RTC_CMD ; SEND COMMAND TO RTC
LD B,BUFSIZE ; B IS LOOP COUNTER
CLK_RD1:
PUSH BC ; PRESERVE BC
CALL RTC_GET ; GET NEXT BYTE
LD (HL),A ; SAVE IN BUFFER
INC HL ; INC BUF POINTER
POP BC ; RESTORE BC
DJNZ CLK_RD1 ; LOOP IF NOT DONE
XOR A ; ALL LINES OFF TO CLEAN UP
OUT (RTC_BASE),A ; WRITE TO RTC PORT
RET
;
; BURST WRITE CLOCK DATA FROM BUFFER AT HL
;
CLK_WR:
LD C,08EH ; COMMAND = $8E TO WRITE CONTROL REGISTER
CALL RTC_CMD ; SEND COMMAND
XOR A ; $00 = UNPROTECT
CALL RTC_PUT ; SEND VALUE TO CONTROL REGISTER
;
LD C,0BEH ; COMMAND = $BE TO BURST WRITE CLOCK
CALL RTC_CMD ; SEND COMMAND TO RTC
LD B,BUFSIZE ; B IS LOOP COUNTER
CLK_WR1:
PUSH BC ; PRESERVE BC
LD A,(HL) ; GET NEXT BYTE TO WRITE
CALL RTC_PUT ; PUT NEXT BYTE
INC HL ; INC BUF POINTER
POP BC ; RESTORE BC
DJNZ CLK_WR1 ; LOOP IF NOT DONE
LD A,80H ; ADD CONTROL REG BYTE, $80 = PROTECT ON
CALL RTC_PUT ; WRITE REQUIRED 8TH BYTE
XOR A ; ALL LINES OFF TO CLEAN UP
OUT (RTC_BASE),A ; WRITE TO RTC PORT
RET
;
; SEND COMMAND IN C TO RTC
;
RTC_CMD:
LD A,RTC_RD ; CE LOW TO RESET RTC
OUT (RTC_BASE),A ; WRITE IT
LD A,C ; LOAD COMMAND
CALL RTC_PUT ; WRITE IT
RET
;
; WRITE BYTE IN A TO THE RTC
;
RTC_PUT:
LD B,8 ; LOOP FOR 8 BITS
RTC_PUT1:
RRCA ; ROTATE NEXT BIT TO SEND INTO BIT 7
LD C,A ; SAVE WORKING VALUE
AND 10000000B ; ISOLATE THE DATA BIT
OR RTC_CE ; ADD CHIP ENABLE, CLOCK HIGH
OUT (RTC_BASE),A ; WRITE TO PORT WITH CLOCK LOW
XOR RTC_CLK ; TURN CLOCK BACK ON
OUT (RTC_BASE),A ; WRITE TO PORT WITH CLOCK HIGH
LD A,C ; RECOVER WORKING VALUE
DJNZ RTC_PUT1 ; LOOP IF NOT DONE
RET
;
; READ BYTE FROM RTC, RETURN VALUE IN A
;
RTC_GET:
LD C,0 ; INITIALIZE WORKING VALUE TO 0
LD B,8 ; LOOP FOR 8 BITS
RTC_GET1:
LD A,RTC_RD+RTC_CE ; LOWER CLOCK, CE STAYS HI, READ IS ON
OUT (RTC_BASE),A ; WRITE TO RTC PORT
NOP ; SETTLE
IN A,(RTC_BASE) ; READ THE RTC PORT
AND 00000001B ; ISOLATE THE DATA BIT
OR C ; COMBINE WITH WORKING VALUE
RRCA ; ROTATE FOR NEXT BIT
LD C,A ; SAVE WORKING VALUE
LD A,RTC_CLK+RTC_RD+RTC_CE ; CLOCK BACK TO HIGH NOW
OUT (RTC_BASE),A ; WRITE TO RTC PORT
DJNZ RTC_GET1 ; LOOP IF NOT DONE
LD A,C ; GET RESULT INTO A
RET
;
;
;
COMMON /_POST_/
RET ; This RETURN MUST be present even if no other
; code is included in this section
COMMON /_PRE_/
;
;---------------------------------------------------------------
; Read clock and wait for seconds to roll - watchdog protected
; Enter with: DE pointing to relocated clock read routine
; HL pointing to base of high module
TSTRD: JR TSTRD0 ; Jump around address store
DEFW TSTRD ; Org location of the code
TSTRD0: SCF
LD A,1
RET
END