.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