	TITLE	M5b MISCELLANEOUS I/O DRIVER ROM
	LIST	NOCOND
;****************************************************************************
;
;	MISC. I/O DRIVER ROUTINES FOR M5b
;
*INCLUDE B:ZBMH122.HDR
;****************************************************************************
;
; REVISION HISTORY:
;
; 1.0 -	23 SEP 83   GRH
;	Initial version transferred from CBIOS routines.
;
; 1.22	11-25-90   GRH
;	Modify slightly for Shared ROM ZMON V. 1.22.
;
;	1-7-91   GRH
;	Change read clock buffer function (1) to set clock calendar, and
;	 write clock buffer function (2) to set clock time.
;	1-21-91   GRH
;	Fix bug in clock time set function which set chip to 12 Hr format.
;
VERSN	EQU	122
;
;****************************************************************************

	SUBTTL	DECLARATIONS
;============================================================================
;
;*MACLIB    ASMBTOOL.MLB
;*INCLUDE   MONBOARD.DEF
;*INCLUDE   CLOCK.DEF
;*INCLUDE B:ZBMF101.DEF
;*INCLUDE B:ZBMG101.DEF
;
;============================================================================
	LIST	OFF
*MACLIB	   ASMBTOOL.MLB
*INCLUDE   MONBOARD.DEF
*INCLUDE   CLOCK.DEF
*INCLUDE B:ZBMF101.DEF
*INCLUDE B:ZBMG101.DEF
	LIST	ON

THIS_ROM EQU	CLK_RNUM	;ROM # OF THIS ROM


	SUBTTL	EXTERNAL ENTRY POINTS
	ORG	MONROM
;
	JP	CINIT		;COLD START
;
;   EXTERNAL FUNCTION ENTRY DURING INTERRUPT
;
	DS	(MONROM + 6) - $
	JP	I_STUB


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	EXTERNAL FUNCTION STUB FOR USE DURING AN INTERRUPT WITHOUT THE
; RESIDENT ROM ENABLED. USE IN ALL NON-RESIDENT ROMS.
;	ENTRY-	A= FUNCTION #
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
I_STUB:
	ADD	A,2		;BIAS UP
	PUSH	HL
	LD	H,MR_RNUM	;USE RESIDENT ROM
	LD	L,A
	EX	(SP),HL
	CALL	XROMF		;GO EXECUTE THE FUNCTION
	INC	SP		;BALANCE STACK
	INC	SP
	RET


;****************************************************************************
;
;	COLD INIT ONLY SWITCHES TO RESIDENT ROM
;
;****************************************************************************
;
CINIT:
;
;   SET STACK
;
	LD	SP,MONSTK
;
;   RESET ROM FUNCTION SHOULD NOT RETURN HERE
;
	LD	HL,[MR_RNUM SHL 8] + 1	;RESET
	PUSH	HL
	CALL	XROMF
;
;   IF RETURNED THEN HALT
;
	HALT


	SUBTTL	MONITOR BOARD SHADOW ROM SELECTION PROCEDURE
*INCLUDE	XROM.Z80

	SUBTTL	INITIALIZATION CODE
;----------------------------------------------------------------------------
;
;	THIS IS THE COLD START INIT CODE
;
;----------------------------------------------------------------------------
;
ROM_INIT:
;
;   OUTPUT SIGN-ON MESSAGE
;
	LD	HL,LOGMSG	;OUTPUT SIGN-ON
	CALL	PRTS
;
	RET

LOGMSG:	DB	' Misc. Drivers V. '
	PVERS	VERSN
	DM	CR,LF

	SUBTTL	MONITOR FUNCTION CALL DISPATCHER
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	ENTRY-	A= FUNCTION #
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
FUNCH:
	CP	A,MAXFUNS
	JR	NC,MFUNERR
;
;   FUNCTION SEEMS LEGAL, FETCH EXECUTION ADDRESS FROM TABLE
;
	PUSH	HL		;SAVE POSSIBLE ARGUMENT
;
	LD	HL,FUNTABL
	ADD	A,A
	ADD	A,L
	LD	L,A
	LD	A,0
	ADC	A,H
	LD	H,A
	LD	A,(HL)
	INC	HL
	LD	H,(HL)
	LD	L,A
;
;   RESTORE ARGUMENT & PUT EXECUTION ADDRESS ON STACK
	EX	(SP),HL
;
;   RETURN TO EXECUTION ADDRESS
;
	RET
;
;
;   FUNCTION ERROR
;
MFUNERR:
	LD	A,-1
	OR	A,A
	RET


;############################################################################
;
;	MONITOR FUNCTION TABLE
;
;############################################################################
;
FUNTABL:
	DW	RETVERS		;0: RETURN ROM VERSION #
	DW	CLKSCAL		;1: SET CLOCK CALENDAR
	DW	CLKSTIM		;2: SET CLOCK TIME
	DW	CLKCAL		;3: RETURN CLOCK CALENDAR DATA
	DW	CLKTIM		;4: RETURN CLOCK TIME DATA
	DW	CLKRETR		;5: RETURN CLOCK REGISTER DATA
	DW	CLKWAIT		;6: WAIT FOR CLOCK TO CHANGE
	DW	ISTHERE		;7: RETURN BOARD PRESENT STATUS
	DW	CLKSTOP		;8: STOP CLOCK
	DW	CLKSTRT		;9: START CLOCK
;
MAXFUNS	EQU	($ - FUNTABL) / 2

	SUBTTL	ROM FUNCTIONS
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN VERSION FUNCTION #0
;	EXIT -	HL= VERSION # (123D = 1.23)
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
RETVERS:
	LD	HL,VERSN
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	SET CLOCK CALENDAR FUNCTION #1
;	ENTRY-	B= DATE
;		D= MONTH
;		E= YEAR
;		L= DAY OF WEEK
;	EXIT -	A= 0
;		BC, DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKSCAL:
;
;   STOP CLOCK
;
	PUSH	BC
	CALL	CLKSTOP
;
;   SET UP PTR TO REGS
;
	LD	C,CLK_WEEK
;
;   PROCESS DAY OF WEEK
;
	LD	A,L
	CALL	H2BCD		;A= LSD, L= MSD
;
	CALL	CLK_SET
;
;   PROCESS DATE
;
	INC	C
	POP	HL		;WAS BC (DATE)
	LD	A,H
	CALL	H2BCD
;
	CALL	CLK_SET
;
	LD	A,L
	INC	C
	CALL	CLK_SET
;
;   PROCESS MONTH
;
	INC	C
	LD	A,D
	CALL	H2BCD
;
	CALL	CLK_SET
;
	LD	A,L
	INC	C
	CALL	CLK_SET
;
;   PROCESS YEAR
;
	INC	C
	LD	A,E
	CALL	H2BCD
;
	CALL	CLK_SET
;
	LD	A,L
	INC	C
	CALL	CLK_SET
;
;   DONE, TURN ON CLOCK
;
	JP	CLKSTRT


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	SET CLOCK TIME FUNCTION #2
;	ENTRY-	B= SECONDS
;		D= MINUTES
;		E= HOURS
;	EXIT -	A= 0
;		BC, DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKSTIM:
;
;   STOP CLOCK
;
	CALL	CLKSTOP
;
;   SET UP TO SET EACH REGISTER
;
	LD	C,CLK_SECL	;SET REGISTER #
;
;   PROCESS SECONDS
;
	LD	A,B
	CALL	H2BCD
;
	CALL	CLK_SET
;
	LD	A,L
	INC	C
	CALL	CLK_SET
;
;   PROCESS MINUTES
;
	INC	C
	LD	A,D
	CALL	H2BCD
;
	CALL	CLK_SET
;
	LD	A,L
	INC	C
	CALL	CLK_SET
;
;   PROCESS HOURS
;
	INC	C
	LD	A,E
	CALL	H2BCD
;
	CALL	CLK_SET
;
	LD	A,L
	SET	3,A		;SET 24 HR FORMAT BIT (HOURS MSD)
	INC	C
	CALL	CLK_SET
;
;   START CLOCK
;
	JP	CLKSTRT


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN CALENDAR FUNCTION #3
;	EXIT -	A= DAY
;		B= MONTH
;		C= YEAR
;		L= DAY OF WEEK
;		DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKCAL:
;
;   WAIT FOR CLOCK DATA TO BE STABLE FOR AWHILE
;
	CALL	CLKWAIT
;
;   FETCH DAY OF WEEK & SAVE
;
	LD	C,CLK_WEEK
	CALL	GETD
	AND	A,7		;MASK OFF GARBAGE {0..7}
	LD	L,A
;
;   PROCESS DAY
;
	INC	C
	CALL	GET2D
	LD	H,3		;MASK {0..39}
	CALL	GETN
	PUSH	AF
;
;   PROCESS MONTH
;
	CALL	GET2D
	LD	H,1		;MASK {0..19}
	CALL	GETN
	LD	B,A
;
;   PROCESS YEAR
;
	CALL	GET2D
	LD	H,0FH		;MASK {0..99}
	CALL	GETN
;
;   RETURN VALUES
;
	LD	C,A	;RETURN YEAR IN C
	POP	AF	;RETURN DAY IN A
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN TIME FUNCTION #4
;	EXIT -	A= SECONDS
;		B= MINUTES
;		C= HOURS
;		DE= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKTIM:
;
;   WAIT FOR CLOCK TO STABILIZE
;
	CALL	CLKWAIT
;
;   PROCESS SECONDS
;
	LD	C,CLK_SECL
	CALL	GET2D
	LD	H,7		;MASK {0..79}
	CALL	GETN
	PUSH	AF		;SAVE
;
;   PROCESS MINUTES
;
	CALL	GET2D
	CALL	GETN		;USE SAME MASK AS ABOVE {0..79}
	LD	B,A
;
;   PROCESS HOURS
;
	CALL	GET2D
	LD	H,3		;MASK {0..39}
	CALL	GETN
	LD	C,A
;
;   RETURN MINUTES IN A
;
	POP	AF
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN CLOCK DATA FUNCTION #5
;	ENTRY-	C= CLOCK REGISTER #
;	EXIT -	A= REGISTER DATA
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKRETR:
GETD:
;
;   TELL CLOCK WHICH REGISTER TO READ
;
	LD	A,C
	SET	CLK_RD,A	;SET READ BIT
	OUT	(CLK_CMD),A
;
;   DELAY >= 5us PER DATA SHEET
;
	EX	(SP),HL
	EX	(SP),HL
;
;   RETURN WITH DATA
;
	IN	A,(CLK_DATA)	;RETURN DATA
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	WAIT FOR CLOCK TO CHANGE FUNCTION #6
;	EXIT -	A= 0: OK, /0: BOARD NOT PRESENT
;		C= CLK_SECL
;		B= LO SECONDS DATA
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKWAIT:
;
;   IF BOARD NOT THERE THEN RETURN ERROR
;
	CALL	ISTHERE
	RET	NZ
;
;   FETCH CURRENT SECONDS
;
	LD	C,CLK_SECL
	CALL	GETD
	AND	A,CLK_DMSK		;MASK OFF UNWANTED BITS
	LD	B,A
;
;   WAIT UNTIL SECONDS CHANGE
;
CLKRWT:	CALL	GETD
	AND	A,CLK_DMSK
	CP	A,B
	JR	Z,CLKRWT
;
;   DONE, RETURN 0
;
	LD	B,A
	XOR	A,A
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	TEST IF BOARD PRESENT FUNCTION #7
;	EXIT -	A,L= 0: THERE, /0: NOT THERE
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
ISTHERE:
;
;   FETCH CLOCK DATA
;
	IN	A,(CLK_DATA)
;
;   IF UPPER BITS NOT DRIVEN THEN BOARD IS NOT THERE
;
	AND	A,11000000B
;
;   ADJUST SENSE
;
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	STOP CLOCK FUNCTION #8
;	EXIT -	A, B= ?
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKSTOP:
;
;   PUT HOLD ON CLOCK
;
	LD	A,[1 SHL CLK_HOLD]
	OUT	(CLK_DATA),A
;
;   DELAY >= 150us FROM HOLD
;
	LD	B,20		;DELAY >= 150us FROM HOLD
;
CLKSDL:	EX	(SP),HL
	EX	(SP),HL
	DJNZ	CLKSDL
;
;   DONE
;
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	START CLOCK FUNCTION #9
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLKSTRT:
;
;   CLEAR HOLD
;
	XOR	A,A
	OUT	(CLK_DATA),A
;
;   CLEAR COMMAND
;
	OUT	(CLK_CMD),A
;
;   DONE
;
	RET


	SUBTTL	FUNCTIONS & PROCEDURES
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN 2 BCD DIGITS FROM CLOCK FUNCTION
;	ENTRY-	C= CLOCK REGISTER #
;	EXIT-	DE= DIGITS
;		A= HIGH DIGIT
;		C= C + 2
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
GET2D:
;
;   FETCH LOW DIGIT
;
	CALL	GETD
	LD	E,A
;
;   FETCH HIGH DIGIT
;
	INC	C
	CALL	GETD
	LD	D,A
;
;   PRESETUP FOR NEXT TIME
;
	INC	C
;
;   DONE
;
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	CONVERT BCD NUMBER TO BINARY FUNCTION
;	ENTRY-	E= LO BCD #
;		D= HI BCD #
;		H= MASK FOR HI BYTE
;	EXIT -	A= NUMBER
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
GETN:
;
;   SAVE REGS
;
	PUSH	BC
;
;   FETCH LOW BYTE
;
	LD	A,E
	AND	A,CLK_DMSK
	LD	C,A
;
;   FETCH HIGH BYTE
;
	LD	A,D
;
;   MASK OFF NON-NUMERICAL BITS
;
	AND	A,H
;
;   MULTIPLY TENS DIGIT BY 10 & ADD TO UNITS
;
	LD	B,A		;SET CNT
	LD	A,C		;GET UNITS DIGIT
	JR	Z,NOTENS	;IF (TENS & MASK) == 0 THEN RETURN UNITS
;
	LD	C,10		;ELSE ADD TENS DIGIT
;
TENSLP:	ADD	A,C
	DJNZ	TENSLP
;
;   DONE CONVERTING, RESTORE & RETURN
;
NOTENS:	POP	BC
;
	RET


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	CONVERT BINARY NUMBER TO BCD DIGITS FUNCTION
;	ENTRY-	A= BINARY DATA
;	EXIT -	A= UNITS DIGIT
;		L= TENS DIGIT
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
H2BCD:
;
;   TENS = 0
;
	LD	L,0
;
;   IF UNITS < 10 THEN DONE
;
H2BCDL:
	CP	A,10
	RET	C
;
;   ELSE UNITS -= 10
;
	SUB	A,10
	INC	L
	JR	H2BCDL


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	SET CLOCK DIGIT PROCEDURE
;	ENTRY-	A= BCD DATA
;		C= COMMAND
;	EXIT -	A= COMMAND
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
CLK_SET:
;
;   OUTPUT DATA
;
	SET	CLK_HOLD,A	;KEEP CLOCK STOPPED
	OUT	(CLK_DATA),A
;
;   OUTPUT REGISTER #
;
	LD	A,C
	OUT	(CLK_CMD),A
;
;   STROBE DATA INTO REGISTER
;
	SET	CLK_WRT,A
	OUT	(CLK_CMD),A
;
	LD	A,C
	OUT	(CLK_CMD),A
;
;   DONE
;
	RET


;****************************************************************************
;
;	PRTS ROUTINE OUTPUTS AN ASCII STRING ONTO THE CONSOLE.
;  THE STRING MUST BE TERMINATED BY BIT 7 SET IN THE LAST CHAR OF THE STRING.
;	ENTRY-	HL= TEXT PTR
;
;****************************************************************************
;
PRTS:
;
;   TOP OF PRINTING LOOP
;
	LD	C,(HL)		;FETCH CHAR
;
	RES	7,C		;MAKE SURE BIT 7 = 0
	PUSH	HL
	CALL	CO
	POP	HL
;
	BIT	7,(HL)		;IF BIT 7 = 1 THEN STOP
	INC	HL
	JR	Z,PRTS
;
;   DONE
;
	RET


;****************************************************************************
;
;	SEND CHAR TO SYSTEM CONSOLE PROCEDURE
;	ENTRY-	C= CHAR
;
;****************************************************************************
;
CO:
	XCROM	MF_CO
;
;   DONE
;
	RET


	END