;
;**********************************************************************
;
; B5C-KPRO.INS	A TIME insert for BYE500 and up
;  07/15/85	Note:  This is an insert--not an overlay
;			Wayne Masters
;			Potpourri, 408-378-7474
;
; Adapted from:
; MBC-KPRO.ASM -- Version 1.0 -- 03/01/84 -- by Kim Levitt
;
;	TIME routine for BYE5 running on Kaypro 2 with Pro-Clock
;	(adapted from Kaypro Pro-Clock driver written by Greg Haerr)
;
;	This overlay is designed to work on a Kaypro II running BYE5
;	and equipped with a Business Computer Systems Pro-Clock RTC.
;	(Use the DATE program to initialize the clock outside of BYE.)
;	(BCS address: 5350 South 3600 West; Salt Lake City, UT 84118)
;
;	When called this routine will check the RTCBUF. If a '99H'
;	is in the first byte, the clock is initialized. Next the
;	seconds are checked, and if changed since last update of
;	RTC buffer, the clock is stopped, data copied to RTCBUF and
;	the clock is restarted. (If no change in seconds, the
;	routine returns immediately.)
;
;**********************************************************************
;
TIME:
	LDA	RTCBUF		; Get first BCD byte
	CPI	099H		; 99 ?
	CZ	CLKINIT		; If so, init clock...
	CALL	HOLDON		; Put clock on hold
	MVI	C,0		; Check low seconds
	CALL	RDPIO		; To see if change...
	LXI	H,RTCBUF+2	; Compared to old secs
	XRA	M		; Value stored in
	ANI	0FH		; RTC buffer (low nibble)
	JZ	CLKEXIT		; If no change, skip update
	MVI	C,5		; Start with hi hours
	LXI	H,RTCBUF	; And copy to RTCBUF
	CALL	GETCLK		; (get time)
	MVI	C,12		; Start with hi year
	LXI	H,RTCBUF+4	; And copy to RTCBUF
	CALL	GETCLK		; (and date)
	LDA	RTCBUF		; Get hours
	ANI	03FH		; Mask out PM/24 hour bits
	STA	RTCBUF
	LDA	RTCBUF+6	; Get day
	ANI	03FH		; Mask out leap year bit
	STA	RTCBUF+6
CLKEXIT:
	MVI	C,13		; Set clock addr. to
	CALL	WRADDR		; Junk location so no data cleared
	CALL	HOLDOFF		; When we take clock off hold..
	LDA	RTCBUF		; Get BCD HH
	CALL	BCDBIN		; Convert to binary
	STA	CCHOUR		; For BYE5
	LDA	RTCBUF+1	; Get BCD MM
	CALL	BCDBIN		; Convert to binary
	STA	CCMIN		; For BYE5
	RET			; And return (for now..)
;
GETCLK:
	MVI	B,3		; Repeat 3 times for 3 BCD bytes
CLKLP:
	CALL	RDPIO		; Get data at address C
	RLC ! RLC ! RLC	! RLC	; Move to high nibble for BCD
	MOV	M,A		; Save at location temporarily
	DCR	C		; Decrement clock addr
	CALL	RDPIO		; Get data at next address
	ORA	M		; OR with previously saved data
	MOV	M,A		; And save it
	DCR	C		; Decrement clock addr
	INX	H		; Increment to next BCD byte
	DCR	B		; Decrement BCD counter
	JNZ	CLKLP		; If 3rd BCD byte, done..
	RET			; Return
;
; PIO STUFF
;
MODE3	EQU	0CFH		; Bit control mode
;
DATA	EQU	0AH		; Port B data
CMD	EQU	0BH		; Port B cmd
;
; mask values for clock chip
;
LATCH	EQU	80H		; Set address latch (active high)
WR	EQU	40H		; Write (active high)
RD	EQU	20H		; Read (active high)
HOLD	EQU	10H		; Time hold (active high)
;
CLKINIT:
	MVI	A,7		; Disable interrupts
	OUT	CMD
;
; fall into set output
;
; set output mode
;
SETOUT:
	LDA	FLAG		; Get current state
	OUT	DATA		; Preset data register
	MVI	A,MODE3		; Set bit control mode
	OUT	CMD
	XRA	A		; Set all outputs mask
	OUT	CMD
	LDA	FLAG
	OUT	DATA
	RET
;
; set input mode
;
SETIN:
	LDA	FLAG		; Get current state
	ORI	RD		; Set read line
	OUT	DATA
	MVI	A,MODE3
	OUT	CMD
	MVI	A,0FH		; D7-d4 are still output, mask em'
	OUT	CMD
	LDA	FLAG
	ORI	RD
	OUT	DATA
	XCHG ! XCHG		; Delay for 6 uS min.
	RET
;
; send data in A to address in C
;
WRPIO:
	MOV	B,A		; Save data in B
	CALL	WRADDR		; Set address
	MOV	A,B		; Fall into write data
;
; write data in A
;
WRDATA:
	MOV	C,A		; Save in C
	LDA	FLAG		; Get current flag
	ORA	C		; Or in data
	OUT	DATA
	ORI	WR		; And write it
	OUT	DATA
	NOP			; Delay for 1 uS min
	NOP
	ANI	(NOT WR) AND 0FFH ; Reset write
	OUT	DATA
	RET
;
; read data into A from address in C
;
RDPIO:
	PUSH	B
	CALL	WRADDR		; Set address
;
; fall into read data
;
; read data into A
;
RDDATA:
	CALL	SETIN		; Set input mode
	IN	DATA		; Input data
	ANI	0FH		; Just in case
	MOV	C,A		; Save in C
	CALL	SETOUT		; Set to output mode
	MOV	A,C		; Get saved data
	POP	B		; Restore BC
	RET
;
; latch address in C
;
WRADDR:
	LDA	FLAG		; Get current flag
	ORA	C		; Or in address
	OUT	DATA		; Send address
	ORI	LATCH		; Set latch
	OUT	DATA		; And latch it
	ANI	(NOT LATCH) AND	0FFH
	OUT	DATA
	RET
;
HOLDON:
	MVI	A,HOLD		; Set hold flag
	STA	FLAG
	CALL	WRDATA
HOLD0:
	MVI	B,20		; Wait 150 uS
HOLD1:
	XCHG ! XCHG
	DCR	B
	JNZ	HOLD1
	RET
;
HOLDOFF:
	XRA	A		; Reset hold flag
	STA	FLAG
	JMP	WRDATA
;
FLAG:	DB	0		; Current hold/nohold status flag
;
;**********************************************************************
;
; This is the end of the TIME insert for BYE500 and up. If you
; replace the existing TIME insert with this, and have a Kaypro 2 equipped
; with a Pro-Clock, it SHOULD work fine...
;
;**********************************************************************
;
