;****************************************************************
;								*
;			B5C-ZCLK.INS				*
;								*
;	Clock insert for BYE5xx with the following hardware	*
;	configuration:						*
;								*
;		Heath/Zenith Z-100 series computer		*
;		ZCLK clock card from FBE Research		*
;								*
;		Hampton Childress				*
;		Sysop, BHEC RCPM/RBBS	10/27/85		*
;		(301) 661-2175					*
;								*
;	Be sure to set the BCDBIN equate to TRUE		*
;								*
;								*
;****************************************************************

;  Access to the ZCLK is via the 6821 Parallel Printer PIA
;  (U114) as follows:
;
;      PIA Bit	Name	Function
;     ------------------------------------------------
;	PB1	/ERROR	Enable access to ZCLK *
;
;	PA0	PD1	RD Strobe
;	PA1	PD2	WR Strobe
;
;	PB2	PD3	Address Counter Clock
;
;	PB4	PD5	Data Bus Bit D0 (LSB)
;	PB5	PD6	Data Bus Bit D1
;	PB6	PD7	Data Bus Bit D2
;	PB7	PD8	Data Bus Bit D3
;
;  * Installing the ZCLK disconnects PB1 from the /ERROR
;    signal from the printer.  PB1 is programmed as an input
;    by CP/M-86 but is used here as an output.
;
;************************************************************
; MSM5832 REGISTER DEFINITIONS
;************************************************************
;
;	       Data Bus
;  ADDR  NAME  D3 D2 D1 D0  RANGE  NOTES
; ----------------------------------------------------------
;    0	 S1	*  *  *  *   0-9   S1 and S10 are reset to
;    1	 S10	   *  *  *   0-5   zero on write to address
;
;    2	 MI1	*  *  *  *   0-9
;    3	 MI10	   *  *  *   0-5
;
;    4	 H1	*  *  *  *   0-9
;    5	 H10	A  B  *  *   0-2   A=1 for 24 hour format
;				   A=0 for 12 hour format
;				   B=1 for PM  B=0 for AM
;    6	 W	  *  *	*   0-6
;
;    7	 D1    *  *  *	*   0-9
;    8	 D10	  C  *	*   0-3    C=0 for 28 day February
;				   C=1 for 29 day February
;    9	 MO1   *  *  *	*   0-9
;   10	 MO10		*   0-1
;
;   11	 Y1    *  *  *	*   0-9
;   12	 Y10   *  *  *	*
;
; All registers are read/write.  * means data valid as "1"
; or "0" bit.  Blank means bit does not exist ("0" during
; read and ignored on write).
;
;************************************************************
;

ZPIA	EQU	0E0H			; PIA base port
ADATA	EQU	ZPIA+0
ACTL	EQU	ZPIA+1
BDATA	EQU	ZPIA+2
BCTL	EQU	ZPIA+3
CENTURY	EQU	019H

;
;
TIME:	DI				; No interrupts
	CALL	ACCESS			; Enable the ZCLK
	CALL	SPBDIR			; Select direction register
	MVI	A,00001110B		; Make DB4-DB7 inputs
	OUT	BDATA
	CALL	SPBDAT			; Select data register
	IN	ADATA			; Set RD low
	ANI	11111110B
	OUT	ADATA
	LXI	D,BUFFER
	MVI	B,13
INLOOP:	CALL	RDZCLK			; Read ZCLK byte
	STAX	D			; Byte to buffer
	INX	D			; Advance pointer
	CALL	CLKADR			; Advance address counter
	DCR	B			; Done all?
	JNZ	INLOOP			; Loop if not
	IN	ADATA			; Set RD high
	ORI	00000001B
	OUT	ADATA

;
;
	CALL	SPBDIR			; Select direction register
	MVI	A,11111100B		; Make PB1 an input
	OUT	BDATA
	CALL	SPBDAT			; Select data register
	EI				; Interrupts ok now
;
	LDA	BUFFER+5		; Still there seem to remain some
	ANI	03H			; annoying bits which must be
	STA	BUFFER+5		; removed
	LDA	BUFFER+6
	ANI	07H
	STA	BUFFER+6
	LDA	BUFFER+8
	ANI	03H
	STA	BUFFER+8
;
;
	LXI	D,RTCBUF		; Point to start of RTC buffer (hours)
	LXI	H,BUFFER+5		; Point to our buffer (hours)
	CALL	GTSTOR
	CALL	BCDBIN
	STA	CCHOUR
	LXI	H,BUFFER+3		; Minutes
	CALL	GTSTOR
	CALL	BCDBIN
	STA	CCMIN
	LXI	H,BUFFER+1		; Seconds
	CALL	GTSTOR
	MVI	A,CENTURY		; Century equate
	STAX	D			; Century
	INX	D
	MVI	B,3			; Set counter
	LXI	H,BUFFER+12
DTLOOP:	CALL	GTSTOR			; Simple date moving loop
	DCX	H			; Point to next byte
	DCR	B			; Test counter to see if we're done
	JNZ	DTLOOP			; Day, month, year

	RET				; To BYE

GTSTOR:	MOV	A,M			; Get a character from the buffer
	RLC ! RLC ! RLC	! RLC		; Position data in high nibble
	ANI	0F0H			; Just for good measure
	DCX	H
	ADD	M			; Add the low nibble to form bcd
	STAX	D			; Store it
	INX	D			; Increment RTCBUF pointer
	RET

;
;
RDZCLK:
	PUSH	B			; Wait for access (6 usec)
	MVI	B,6
	CALL	WAITSOME
	POP	B
	IN	BDATA			; Read ZCLK
	RRC ! RRC ! RRC	! RRC		; Position the data
	ANI	00001111B		; Mask off unwanted bits
	RET
;
;
CLKADR:	IN	BDATA
	ORI	00000100B		; Set counter clock high
	OUT	BDATA
	ANI	11111011B		; Set counter clock low
	OUT	BDATA
	RET
;
;
SPBDIR:	IN	BCTL			; Select B port direction reg
	ANI	11111011B
	OUT	BCTL
	RET
;
;
SPBDAT:	IN	BCTL			; Select B port data register
	ORI	00000100B
	OUT	BCTL
	RET
;
;
ACCESS:	IN	ADATA			; Set RD and WR high
	ORI	00000011B
	OUT	ADATA
	CALL	SPBDIR			; Select direction register
	MVI	A,11111110B		; Make PB1 and output
	OUT	BDATA
	CALL	SPBDAT			; Select data register
	XRA	A			; Make PB1 low to enable ZCLK
	OUT	BDATA
;
	MVI	B,150			; Wait for access (150 usec)
WAITSOME:
	NOP ! NOP ! NOP	! NOP !	NOP	; Waste 1 usec. at 5 mhz
	DCR	B
	JNZ	WAITSOME
	RET
;
BUFFER	DB	'xxxxxxxxxxxxx'		; 13 byte buffer for the ZCLK
;
; *** End of ZCLK clock card routine for the Z-100 ***
;
