;
;==================================================================================================
; MAXIM DS1305 RTC DRIVER
;==================================================================================================
;
; THE DS1305 USES AN SPI INTERFACE.  THIS DRIVER CURRENTLY ASSUMES THE
; FPGA-BASED SPI INTERFACE IMPLEMENTED IN THE S100 FPGA Z80.
;
; TRICKLE CHARGING IS NOT CURRENTLY IMPLEMENTED SINCE THE S100 FPGA Z80
; DOES NOT SUPPORT THE USER OF A SUPER CAPACITOR.
;
;  REGISTER ADDRESSES (HEX / BCD):
;
;  +---+-----+---------------+-------------------+------------------+----------------+
;  |ADR|  D7 | D6  | D5 | D4 | D3 | D2 | D1 | D0 | RANGE            | REGISTER       |
;  +---+-----+---------------+-------------------+------------------+----------------+
;  | 0 |  0  |     10-SECOND |          1-SECOND |            00-59 | SECONDS        |
;  +---+-----+-----+---------+-------------------+------------------+----------------+
;  | 1 |  0  |     10-MINUTE |          1-MINUTE |            00-59 | MINUTES        |
;  +---+-----+-----+---------+-------------------+------------------+----------------+
;  | 2 |  0  |  0  | 10-HOUR |            1-HOUR |            00-23 | HOURS          |
;  +---+-----+-----+----+----+-------------------+------------------+----------------+
;  | 3 |  0  |  0  |  0 |  0 |       DAY OF WEEK |            01-07 | DAY OF WEEK    |
;  +---+-----+-----+----+----+----+--------------+------------------+----------------+
;  | 4 |  0  |  0  | 10-DATE |            1-DATE |            01-31 | DATE           |
;  +---+-----+-----+----+----+-------------------+------------------+----------------+
;  | 5 |  0  |  0  |10-MONTH |           1-MONTH |            01-12 | MONTH          |
;  +---+-----+-----+----+----+-------------------+------------------+----------------+
;  | 6 |             10-YEAR |            1-YEAR |            00-99 | YEAR           |
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;                        --- ALARM 0 ---
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;  | 7 |  M  |     10-SECOND |          1-SECOND |            00-59 | SECONDS ALARM  |
;  +---+-----+---------------+-------------------+------------------+----------------+
;  | 8 |  M  |     10-MINUTE |          1-MINUTE |            00-59 | MINUTES ALARM  |
;  +---+-----+-----+---------+-------------------+------------------+----------------+
;  | 9 |  M  |  0  | 10-HOUR |            1-HOUR |            00-23 | HOURS ALARM    |
;  +---+-----+-----+----+----+-------------------+------------------+----------------+
;  | A |  M  |  0  | 0  | 0  |               DAY |              1-7 | DAY ALARM      |
;  +---+-----+-----+----+----+----+--------------+------------------+----------------+
;                        --- ALARM 1 ---
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;  | B |  M  |     10-SECOND |          1-SECOND |            00-59 | SECONDS ALARM  |
;  +---+-----+---------------+-------------------+------------------+----------------+
;  | C |  M  |     10-MINUTE |          1-MINUTE |            00-59 | MINUTES ALARM  |
;  +---+-----+-----+---------+-------------------+------------------+----------------+
;  | D |  M  |  0  | 10-HOUR |            1-HOUR |            00-23 | HOURS ALARM    |
;  +---+-----+-----+----+----+-------------------+------------------+----------------+
;  | E |  M  |  0  | 0  | 0  |               DAY |              1-7 | DAY ALARM      |
;  +---+-----+-----+----+----+----+--------------+------------------+----------------+
;
;  +---+-----+-----+---------+-------------------+------------------+----------------+
;  | F |/EOSC| WP  | 0  | 0  | 0  |INTC|AIE1|AIE0|                  | CONTROL REG    |
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;  |10 |  0  |  0  | 0  | 0  | 0  | 0  |IRQ1|IRQ0|                  | STATUS REG     |
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;  |11 | TRICKLE CHG ENABLE  |  DIODE  |RESISTOR |                  | TRICKLE CHG REG|
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;  |12-1F |              RESERVED                |                  |                |
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;  |20-7F |              USER NVRAM              |            00-FF |                |
;  +---+-----+-----+----+----+----+----+----+----+------------------+----------------+
;
;  0 = SHOULD BE SET TO 0 FOR VALID TIME/CALENDAR RANGE.
;  CLOCK CALENDAR DATA IS BCD. AUTOMATIC LEAP YEAR ADJUSTMENT.
;  DAY-OF-WEEK CODED AS SUNDAY = 1 THROUGH SATURDAY = 7.
;
; CONSTANTS
;
DS5RTC_BASE	.EQU	$68
DS5RTC_DATA	.EQU	DS5RTC_BASE + 0
DS5RTC_SELECT	.EQU	DS5RTC_BASE + 2	; WRITE
DS5RTC_STATUS	.EQU	DS5RTC_BASE + 2	; READ
DS5RTC_RUN	.EQU	DS5RTC_BASE + 3	; START READ/WRITE USING IN/OUT OPCODE
;
; IO PORTS
;
DS5NVM_BASE		.EQU	DS5RTC_BASE + $20

DS5RTC_REG_SEC		.EQU	$00
DS5RTC_REG_MIN		.EQU	$01
DS5RTC_REG_HOUR		.EQU	$02
DS5RTC_REG_WEEKDAY	.EQU	$03
DS5RTC_REG_DATE		.EQU	$04
DS5RTC_REG_MONTH	.EQU	$05
DS5RTC_REG_YEAR		.EQU	$06
DS5RTC_REG_ALM0_SEC	.EQU	$07
DS5RTC_REG_ALM0_MIN	.EQU	$08
DS5RTC_REG_ALM0_HOUR	.EQU	$09
DS5RTC_REG_ALM0_DAY	.EQU	$0A
DS5RTC_REG_ALM1_SEC	.EQU	$0B
DS5RTC_REG_ALM1_MIN	.EQU	$0C
DS5RTC_REG_ALM1_HOUR	.EQU	$0D
DS5RTC_REG_ALM1_DAY	.EQU	$0E
DS5RTC_REG_CONTROL	.EQU	$0F
DS5RTC_REG_STATUS	.EQU	$10
DS5RTC_REG_TCHG		.EQU	$11
DS5RTC_REG_NVM_BASE	.EQU	$20
;
; VALUES FOR DIFFERENT BATTERY OR SUPERCAPACITOR CHARGE RATES
;
DS5RTC_TC1D2K	.EQU	%10100101	; 1 DIODE 2K RESISTOR (DEFAULT)
DS5RTC_TC1D4K	.EQU	%10100110	; 1 DIODE 4K RESISTOR
DS5RTC_TC1D8K	.EQU	%10100111	; 1 DOIDE 8K RESISTOR
DS5RTC_TC2D2K	.EQU	%10101001	; 2 DIODES 2K RESISTOR
DS5RTC_TC2D4K	.EQU	%10101010	; 2 DIODES 4K RESISTOR
DS5RTC_TC2D8K	.EQU	%10101011	; 2 DIODES 8K RESISTOR
;
;
;
DS5RTC_BUFSIZE	.EQU	6		; 6 BYTE BUFFER (YYMMDDHHMMSS)
;
	DEVECHO	"DS5RTC: RTCIO="
	DEVECHO	DS5RTC_BASE
	DEVECHO	", IO="
	DEVECHO	DS5RTC_BASE
	DEVECHO	"\n"
;
; RTC DEVICE INITIALIZATION ENTRY
;
DS5RTC_INIT:
	LD	A,(RTC_DISPACT)		; RTC DISPATCHER ALREADY SET?
	OR	A			; SET FLAGS
	RET	NZ			; IF ALREADY ACTIVE, ABORT
;
	CALL	NEWLINE			; FORMATTING
	PRTS("DS5RTC: IO=0x$")
	LD	A, DS5RTC_BASE
	CALL	PRTHEXBYTE
;
	CALL	DS5RTC_DETECT		; HARDWARE DETECTION
	JR	Z,DS5RTC_INIT1		; IF ZERO, ALL GOOD
	PRTS(" NOT PRESENT$")		; NOT ZERO, H/W NOT PRESENT
	OR	$FF			; SIGNAL FAILURE
	RET				; BAIL OUT
;
DS5RTC_INIT1:
	; DISPLAY CURRENT TIME
	CALL	PC_SPACE		; FORMATTING
	LD	HL,DS5RTC_BUF		; USE INTERNAL BUFFER
	CALL	DS5RTC_RDCLK		; GET RAW RTC DATE/TIME
	LD	HL,DS5RTC_TIMBUF	; POINT TO HBIOS TIME BUF
	CALL	DS5RTC_CLK2TIM		; CONVERT TO HBIOS FMT
	LD	HL,DS5RTC_TIMBUF	; POINT TO HBIOS TIME BUF
	CALL	PRTDT			; PRINT FORMATTED DATE/TIME
;
	; ADD OURSELVES TO RTC DISPATCHER
	LD	BC,DS5RTC_DISPATCH
	CALL	RTC_SETDISP
;
	XOR	A
	RET
;
; RTC DEVICE FUNCTION DISPATCH ENTRY
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
;   B: FUNCTION (IN)
;
DS5RTC_DISPATCH:
	LD	A, B				; Get requested function
	AND	$0F				; Isolate Sub-Function
	JP	Z, DS5RTC_GETTIM		; Get Time
	DEC	A
	JP	Z, DS5RTC_SETTIM		; Set Time
	DEC	A
	JP	Z, DS5RTC_GETBYT		; Get NVRAM Byte Value
	DEC	A
	JP	Z, DS5RTC_SETBYT		; Set NVRAM Byte Value
	DEC	A
	JP	Z, DS5RTC_GETBLK		; Get NVRAM Data Block Value
	DEC	A
	JP	Z, DS5RTC_SETBLK		; Set NVRAM Data Block Value
	DEC	A
	JP	Z, DS5RTC_GETALM		; Get Alarm
	DEC	A
	JP	Z, DS5RTC_SETALM		; Set Alarm
;
; 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
;
DS5RTC_GETTIM:
	PUSH	HL			; SAVE ADR OF OUTPUT BUF
;
	; READ THE CLOCK
	LD	HL,DS5RTC_BUF		; POINT TO CLOCK BUFFER
	CALL	DS5RTC_RDCLK		; READ THE CLOCK
	LD	HL,DS5RTC_TIMBUF	; POINT TO TIME BUFFER
	CALL	DS5RTC_CLK2TIM		; CONVERT CLOCK TO TIME
;
	; 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,DS5RTC_TIMBUF	; SOURCE ADR
	POP	DE			; DEST ADR
	LD	BC,6			; LENGTH IS 6 BYTES
#IF (INTMODE == 1)
	DI
#ENDIF
	CALL	HB_BNKCPY		; COPY THE CLOCK DATA
#IF (INTMODE == 1)
	EI
#ENDIF
;
	; 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
;
DS5RTC_SETTIM:
	; COPY INCOMING TIME DATA TO OUR TIME BUFFER
	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,DS5RTC_TIMBUF	; DEST ADR
	LD	BC,6			; LENGTH IS 6 BYTES
#IF (INTMODE == 1)
	DI
#ENDIF
	CALL	HB_BNKCPY		; COPY THE CLOCK DATA
#IF (INTMODE == 1)
	EI
#ENDIF
;
	; WRITE TO CLOCK
	LD	HL,DS5RTC_TIMBUF	; POINT TO TIME BUFFER
	CALL	DS5RTC_TIM2CLK		; CONVERT TO CLOCK FORMAT
	LD	HL,DS5RTC_BUF		; POINT TO CLOCK BUFFER
	CALL	DS5RTC_WRCLK		; WRITE TO THE CLOCK
;
	; CLEAN UP AND RETURN
	XOR	A			; SIGNAL SUCCESS
	RET				; AND RETURN
;
; RTC GET NVRAM BYTE
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
;   C: INDEX (IN)
;   E: VALUE (OUT)
;
DS5RTC_GETBYT:
	LD	A,C			; INDEX TO A
	ADD	A,$20			; NVRAM STARTS AT REG $20
	LD	C,A			; BACK TO REG C
	CALL	DS5RTC_GET		; DO IT
	LD	E,A			; MOVE RESULT TO E
	XOR	A			; SIGNAL SUCCESS
	RET				; DONE
;
; RTC SET NVRAM BYTE
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
;   C: INDEX (IN)
;   E: VALUE (IN)
;
DS5RTC_SETBYT:
	LD	A,C			; INDEX TO A
	ADD	A,$20			; NVRAM STARTS AT REG $20
	LD	C,A			; BACK TO REG C
	CALL	DS5RTC_WPOFF		; DISABLE WRITE PROTECT
	CALL	DS5RTC_PUT		; DO IT
	CALL	DS5RTC_WPOFF		; ENABLE WRITE PROTECT
	LD	E,A			; MOVE RESULT TO E
	XOR	A			; SIGNAL SUCCESS
	RET				; DONE
;
; RTC GET BLOCK
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
;   HL: BUFFER ADDRESS (IN)
;
DS5RTC_GETBLK:
	SYSCHKERR(ERR_NOTIMPL)
	RET
;
; RTC GET BLOCK
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERR
;   HL: BUFFER ADDRESS (IN)
;
DS5RTC_SETBLK:
	SYSCHKERR(ERR_NOTIMPL)
	RET
;
; RTC GET ALARM
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERROR
;   HL: DATE/TIME BUFFER ADDRESS (IN)
; BUFFER FORMAT IS BCD: YYMMDDHHMMSS
; 24 HOUR TIME FORMAT IS ASSUMED
;
DS5RTC_GETALM:
	SYSCHKERR(ERR_NOTIMPL)
	RET
;
; RTC SET ALARM
;   A: RESULT (OUT), 0=OK, Z=OK, NZ=ERROR
;   HL: DATE/TIME BUFFER ADDRESS (IN)
; BUFFER FORMAT IS BCD: YYMMDDHHMMSS
; 24 HOUR TIME FORMAT IS ASSUMED
;
DS5RTC_SETALM:
	SYSCHKERR(ERR_NOTIMPL)
	RET
;
;==================================================================================================
; INTERNAL PROCEDURES
;==================================================================================================
;
; TURN ON WRITE PROTECT
;
DS5RTC_WPON:
	PUSH	AF
	PUSH	BC
	LD	A,%01000000		; CONTROL REGISTER W/P ON VALUE
	LD	C,DS5RTC_REG_CONTROL	; CONTROL REGISTER ADR
	CALL	DS5RTC_PUT		; SET CONTROL REGISTER
	POP	BC
	POP	AF
	RET
;
; TURN OFF WRITE PROTECT
;
DS5RTC_WPOFF:
	PUSH	AF
	PUSH	BC
	XOR	A			; CONTROL REGISTER W/P OFF VALUE
	LD	C,DS5RTC_REG_CONTROL	; CONTROL REGISTER ADR
	CALL	DS5RTC_PUT		; SET CONTROL REGISTER
	POP	BC
	POP	AF
	RET
;
; DETECT RTC HARDWARE PRESENCE
;
DS5RTC_DETECT:
	CALL	DS5RTC_WPOFF		; DISABLE WRITE PROTECT
;
	; TEST AN NVRAM BYTE (NON-DESTRUCTIVE)
	LD	C,$7F			; LAST NVRAM BYTE
	CALL	DS5RTC_GET		; GET CURRENT VALUE
	LD	B,A			; SAVE IN B
	XOR	$FF			; FLIP ALL BITS
	CALL	DS5RTC_PUT		; SAVE TO RTC NVRAM
	CALL	DS5RTC_GET		; GET UPDATED VALUE
	XOR	$FF			; FLIP ALL BITS
	CP	B			; COMPARE W/ ORIGINAL READ
	PUSH	AF			; SAVE FLAGS
	CALL	DS5RTC_PUT		; RESAVE ORIGINAL VALUE
;
	CALL	DS5RTC_WPON		; RESTORE WRITE PROTECT
	POP	AF			; RESTORE FLAGS
	RET				; ZF INDICATES PRESENCE
;
; READ RTC DATE/TIME INTO INTERNAL BUFFER
;
DS5RTC_RDCLK:
	LD	B,7			; 7 BYTE DATE/TIME BUFFER
	LD	C,DS5RTC_REG_SEC	; START W/ SECONDS REGISTER
	LD	HL,DS5RTC_BUF		; USE INTERNAL BUFFER
	CALL	DS5RTC_GETBUF		; FILL THE BUFFER
	XOR	A			; SIGNAL SUCCESS
	RET				; RETURN
;
; WRITE RTC DATE/TIME FROM INTERNAL BUFFER
;
DS5RTC_WRCLK:
	CALL	DS5RTC_WPOFF		; DISABLE WRITE PROTECT
	LD	B,7			; 7 BYTE DATE/TIME BUFFER
	LD	C,DS5RTC_REG_SEC	; START W/ SECONDS REGISTER
	LD	HL,DS5RTC_BUF		; USE INTERNAL BUFFER
	CALL	DS5RTC_PUTBUF		; FILL THE BUFFER
	CALL	DS5RTC_WPON		; RESTORE WRITE PROTECT
	XOR	A			; SIGNAL SUCCESS
	RET				; RETURN
;
; CONVERT DATA IN CLOCK BUFFER TO TIME BUFFER AT HL
;
DS5RTC_CLK2TIM:
	LD	A,(DS5RTC_YR)
	LD	(HL),A
	INC	HL
	LD	A,(DS5RTC_MON)
	LD	(HL),A
	INC	HL
	LD	A,(DS5RTC_DT)
	LD	(HL),A
	INC	HL
	LD	A,(DS5RTC_HR)
	LD	(HL),A
	INC	HL
	LD	A,(DS5RTC_MIN)
	LD	(HL),A
	INC	HL
	LD	A,(DS5RTC_SEC)
	LD	(HL),A
	RET
;
; CONVERT DATA IN TIME BUFFER AT HL TO CLOCK BUFFER
;
DS5RTC_TIM2CLK:
	PUSH	HL
	LD	A,(HL)
	LD	(DS5RTC_YR),A
	INC	HL
	LD	A,(HL)
	LD	(DS5RTC_MON),A
	INC	HL
	LD	A,(HL)
	LD	(DS5RTC_DT),A
	INC	HL
	LD	A,(HL)
	LD	(DS5RTC_HR),A
	INC	HL
	LD	A,(HL)
	LD	(DS5RTC_MIN),A
	INC	HL
	LD	A,(HL)
	LD	(DS5RTC_SEC),A
	POP	HL
	CALL	TIMDOW
	INC	A			; CONVERT FROM 0-6 TO 1-7
	LD	(DS5RTC_DAY),A
	RET
;
; READ A BUFFER OF BYTES FROM THE RTC
; START RTC ADR IN C, COUNT IN B, BUF PTR IN HL
;
DS5RTC_GETBUF:
	LD	A,1
	OUT	(DS5RTC_SELECT),A	; SELECT RTC
	LD	A,C			; ADDRESS TO A
	OUT	(DS5RTC_DATA),A		; SEND TO INTERFACE
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO WRITE ADR
	CALL	DS5RTC_WAITBSY		; WAIT FOR COMPLETION
DS5RTC_GETBUF1:
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO READ DATA
	CALL	DS5RTC_WAITBSY		; WAIT FOR DATA
	IN	A,(DS5RTC_DATA)		; GET VALUE
	LD	(HL),A			; SAVE BYTE IN BUFFER
	INC	HL			; BUMP BUF PTR
	DJNZ	DS5RTC_GETBUF1		; LOOP FOR REQUESTED BYTES
	LD	A,0
	OUT	(DS5RTC_SELECT),A	; DESELECT DEVICE
	RET
;
; WRITE A BUFFER OF BYTES TO THE RTC
; START RTC ADR IN C, COUNT IN B, BUF PTR IN HL
;
DS5RTC_PUTBUF:
	LD	A,1
	OUT	(DS5RTC_SELECT),A	; SELECT RTC
	LD	A,C			; ADDRESS TO A
	SET	7,A			; SET WRITE BIT
	OUT	(DS5RTC_DATA),A		; SEND TO INTERFACE
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO WRITE ADR
	CALL	DS5RTC_WAITBSY		; WAIT FOR COMPLETION
DS5RTC_PUTBUF1:
	LD	A,(HL)			; NEXT BYTE TO WRITE
	INC	HL			; BUMP BUF PTR
	OUT	(DS5RTC_DATA),A		; SEND TO INTERFACE
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO WRITE BYTE
	CALL	DS5RTC_WAITBSY		; WAIT FOR COMPLETION
	DJNZ	DS5RTC_PUTBUF1		; LOOP FOR REQUESTED BYTES
	LD	A,0
	OUT	(DS5RTC_SELECT),A	; DESELECT DEVICE
	RET
;
; GET A BYTE FROM THE RTC
; ADDRESS IN C, RETURN VALLUE IN A
;
DS5RTC_GET:
	LD	A,1
	OUT	(DS5RTC_SELECT),A	; SELECT RTC
	LD	A,C			; ADDRESS TO A
	OUT	(DS5RTC_DATA),A		; SEND TO INTERFACE
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO WRITE ADR
	CALL	DS5RTC_WAITBSY		; WAIT FOR COMPLETION
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO READ DATA
	CALL	DS5RTC_WAITBSY		; WAIT FOR DATA
	IN	A,(DS5RTC_DATA)		; GET VALUE
	PUSH	AF			; SAVE VALUE
	LD	A,0
	OUT	(DS5RTC_SELECT),A	; DESELECT DEVICE
	POP	AF			; RESTORE VALUE
	RET
;
; PUT A BYTE TO THE RTC
; ADDRESS IN C, VALUE IN A
;
DS5RTC_PUT:
	PUSH	AF			; SAVE VALUE TO PUT
	LD	A,1
	OUT	(DS5RTC_SELECT),A	; SELECT RTC
	LD	A,C			; ADDRESS TO A
	SET	7,A			; SET WRITE BIT
	OUT	(DS5RTC_DATA),A		; SEND TO INTERFACE
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTION TO WRITE ADR
	CALL	DS5RTC_WAITBSY		; WAIT FOR COMPLETION
	POP	AF			; RECOVER VALUE TO PUT
	OUT	(DS5RTC_DATA),A		; VALUE TO OUTPUT
	OUT	(DS5RTC_RUN),A		; SPI TRANSACTOIN TO WRITE VALUE
	CALL	DS5RTC_WAITBSY		; WAIT FOR WRITE TO COMPLETE
	LD	A,0
	OUT	(DS5RTC_SELECT),A	; DESELECT DEVICE
	RET
;
; WAIT UNTIL SPI INTERFACE IS NO LONGER BUSY
;
DS5RTC_WAITBSY:
	PUSH	AF			; PRESERVE AF
	PUSH	BC			; PRESERVE BC
;
	; AFTER INITIATING A SPI TRANSACTION, IT MAY TAKE A WHILE
	; FOR THE BUSY STATUS TO BE REFLECTED.  THE DELAYS BELOW
	; ENSURE ENOUGH TIME HAS ELAPSED.
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
;
	; SINCE THIS ROUTINE MAY BE USED TO DETECT AN RTC THAT DOES
	; NOT EXIST, WE PROTECT THE WAIT WITH A TIMEOUT LOOP TO
	; PREVENT A SYSTEM STALL.
	LD	B,0
DS5RTC_WAITBSY1:
	IN	A,(DS5RTC_STATUS)	; GET STATUS BYTE
	OR	A			; SET FLAGS
	JR	Z,DS5RTC_WAITBSY2	; IF ZERO, WE ARE DONE
	DJNZ	DS5RTC_WAITBSY1		; TRY TILL COUNTER EXHAUSTED
DS5RTC_WAITBSY2:
	POP	BC			; RECOVER BC
	POP	AF			; RECOVER AF
	RET
;
; DS5RTC_BUF IS USED FOR BURST READ/WRITE OF CLOCK DATA TO DS1305
; FIELDS BELOW MATCH ORDER OF DS1305 FIELDS (BCD)
;
DS5RTC_BUF:
DS5RTC_SEC	.DB	0		; SECOND
DS5RTC_MIN	.DB	0		; MINUTE
DS5RTC_HR	.DB	0		; HOUR
DS5RTC_DAY	.DB	0		; DAY OF WEEK
DS5RTC_DT	.DB	0		; DATE
DS5RTC_MON	.DB	0		; MONTH
DS5RTC_YR	.DB	0		; YEAR
;
; DS5RTC_TIMBUF IS TEMP BUF USED TO STORE TIME TEMPORARILY TO DISPLAY
; IT.
;
DS5RTC_TIMBUF	.FILL	6,0		; 6 BYTES FOR GETTIM
;
; DS5RTC_TIMDEF IS DEFAULT TIME VALUE TO INITIALIZE CLOCK IF IT IS
; NOT RUNNING.
;
DS5RTC_TIMDEF:	; DEFAULT TIME VALUE TO INIT CLOCK
		.DB	$00,$01,$01	; 2000-01-01
		.DB	$00,$00,$00	; 00:00:00
