	TITLE M5b Z-80 MONITOR CHARACTER I/O ROM
	LIST	NOCOND
;****************************************************************************
;
;	SYSTEM MONITOR FOR M5b
;	(c) 1982,1983  GRH ELECTRONICS, CUPERTINO, CA
;
;****************************************************************************
;
;	This code module contains the system character I/O drivers and 
; resides in the same address space as the resident Monitor ROM. The ROMs
; communicate with each other through a ROM transfer function.
;
*INCLUDE B:ZBMH122.HDR
;****************************************************************************
;
;	Revision status:
;
; 1.0 - Release
; 1.22	11-22-90   GRH
;	Split off from Monitor code to separate ROM in order to gain space
;	 for I/O drivers and interrupt code.
;	Add rom xover function as include file.
;	Add function dispatcher for execution and breakpoint entries.
;	Add CON: selection based on Naked Terminal presence.
;
VERSN	EQU	122
;****************************************************************************
	FORM
FALSE	EQU	0
TRUE	EQU	NOT FALSE

;
;   INCLUDE SYSTEM DEFINITION FILES
;
;*MACLIB    ASMBTOOL.MLB
;*INCLUDE   MONBOARD.DEF
;*INCLUDE   NAKEDT.DEF
;*INCLUDE   PRI.DEF
;*INCLUDE   PSIO.DEF
;*INCLUDE B:ZBMF101.DEF
;*INCLUDE B:ZBMG101.DEF
;
	LIST	OFF
*MACLIB	   ASMBTOOL.MLB
*INCLUDE   MONBOARD.DEF
*INCLUDE   NAKEDT.DEF
*INCLUDE   PRI.DEF
*INCLUDE   PSIO.DEF
*INCLUDE B:ZBMF101.DEF
*INCLUDE B:ZBMG101.DEF
	LIST	ON


THIS_ROM EQU	CHR_RNUM

	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
;
	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	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 MONITOR ROM VERSION
;
	DW	MFUNERR		;1: RETURN CHAR DEVICE PARAMETERS
	DW	MFUNERR		;2: EXECUTE SELF TEST
	DW	MFUNERR		;3: SET STANDARD CONSOLE DEVICE
	DW	MFUNERR		;4: SET STANDARD LIST DEVICE
	DW	MFUNERR		;5: INITIALIZE CHAR DEVICE
	DW	MFUNERR		;6: SET DEVICE BAUD RATE
	DW	MFUNERR		;7: SPARE
	DW	CIS		;8: RETURN STANDARD CONSOLE INPUT STATUS
	DW	CI		;9: RETURN STANDARD CONSOLE CHAR
	DW	COS		;10: RETURN STANDARD CONSOLE OUTPUT STATUS
	DW	CO		;11: SEND CHAR TO STANDARD CONSOLE
	DW	LOS		;12: RETURN STANDARD LIST DEVICE OUTPUT STATUS
	DW	LO		;13: SEND CHAR TO STANDARD LIST DEVICE
;
MAXFUNS	EQU	($ - FUNTABL) / 2

	SUBTTL	DEBUGGER FUNCTIONS
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
;	RETURN VERSION FUNCTION
;	EXIT -	HL= VERSION # (123D = 1.23)
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
RETVERS:
	LD	HL,VERSN
	RET


;****************************************************************************
;
;	INITIALIZE I/O
;
;****************************************************************************
;
ROM_INIT:
;
;   IF NAKED TERMINAL INSTALLED THEN SET IOBYTE TO IT
;   ELSE SET IOBYTE TO SIO
;
	IN	A,(NT_STAT)
	AND	A,[1 SHL NT_PRSNT]
	RRCA
	LD	(IOBYTE),A
;
;   INIT SIO ANYWAY
;
	LD	HL,IOIDTA	;SET TABLE PTR
;
IOILP:	LD	C,(HL)		;FETCH PORT
	INC	HL
;
	LD	A,C		;IF PORT == -1 THEN DONE
	INC	A
	JR	Z,IOIDN
;
	LD	B,(HL)		;FETCH COUNT
	INC	HL
	OTIR
	JR	IOILP
;
;   SIO DONE
;
IOIDN:
;
;   DISPLAY SIGN-ON
;
	LD	HL,LOGMSG
	CALL	PRTS
;
;   DONE
;
	RET


;############################################################################
;
;	SIO INITIALIZATION DATA TABLE
;
;############################################################################
;
IOIDTA:
;
;   PSIO SIO #0A
;
	DB	PS_SER0S	;PORT
	DB	8		;BYTE COUNT
	DB	18H		;CHANNEL RESET
	DB	4,44H		;WRITE REG #4: 16x CLOCK, 1 STOP BIT
	DB	3,0C1H		;WRITE REG #3: Rx 8-BIT CHAR, Rx ENABLE
	DB	5,0EAH		;WRITE REG #5: DTR, Tx 8-BIT CHAR, Tx ENABLE, RTS
	DB	0		;READ REG #0
;
;   PSIO SIO #0B
;
	DB	PS_SER1S	;PORT
	DB	8		;BYTE COUNT
	DB	18H		;CHANNEL RESET
	DB	4,44H		;WRITE REG #4: 16x CLOCK, 1 STOP BIT
	DB	3,0C1H		;WRITE REG #3: Rx 8-BIT CHAR, Rx ENABLE
	DB	5,0EAH		;WRITE REG #5: DTR, Tx 8-BIT CHAR, Tx ENABLE, RTS
	DB	0		;READ REG #0
;
;   PSIO SIO #1A
;
	DB	PS_SER2S	;PORT
	DB	8		;BYTE COUNT
	DB	18H		;CHANNEL RESET
	DB	4,44H		;WRITE REG #4: 16x CLOCK, 1 STOP BIT
	DB	3,0C1H		;WRITE REG #3: Rx 8-BIT CHAR, Rx ENABLE
	DB	5,0EAH		;WRITE REG #5: DTR, Tx 8-BIT CHAR, Tx ENABLE, RTS
	DB	0		;READ REG #0
;
;   PSIO SIO #1B
;
	DB	PS_SER3S	;PORT
	DB	8		;BYTE COUNT
	DB	18H		;CHANNEL RESET
	DB	4,44H		;WRITE REG #4: 16x CLOCK, 1 STOP BIT
	DB	3,0C1H		;WRITE REG #3: Rx 8-BIT CHAR, Rx ENABLE
	DB	5,0EAH		;WRITE REG #5: DTR, Tx 8-BIT CHAR, Tx ENABLE, RTS
	DB	0		;READ REG #0
;
;   CTC TIMER 0: SIO 0A&B BAUD RATE
;
	DB	PS_CTC0		;PORT
	DB	2		;COUNT
	DB	01000101B	;CONTROL WORD
	DB	8		;9600 BAUD
;
;   CTC TIMER 1: SIO 1A BAUD RATE
;
	DB	PS_CTC1		;PORT
	DB	2		;COUNT
	DB	01000101B	;CONTROL WORD
	DB	8		;9600 BAUD
;
;   CTC TIMER 2: SIO 1B BAUD RATE
;
	DB	PS_CTC2		;PORT
	DB	2		;COUNT
	DB	01000101B	;CONTROL WORD
	DB	8		;9600 BAUD
;
	DB	-1	;END-OF-TABLE


	SUBTTL	FUNCTIONS AND PROCEDURES
;****************************************************************************
;
;	DISPLAY TEXT ON CONSOLE PROCEDURE
;	ENTRY-	HL= PTR TO BIT-7 TERMINATED ASCII TEXT
;
;****************************************************************************
;
PRTS:
;
;   DISPLAY CHAR
;
	LD	C,(HL)
	RES	7,C
	PUSH	HL
	CALL	CO
	POP	HL
;
;   IF CHAR < 128 THEN DO NEXT CHAR
;
	BIT	7,(HL)
	INC	HL
	JR	Z,PRTS
;
	RET


	SUBTTL	IOBYTE HANDLERS
;****************************************************************************
;
;	SYSTEM CONSOLE OUTPUT STATUS SELECTOR
;	ENTRY-	(IOBYTE BIT 0..1)= 0: CON0, 1: CON1, 2: CON2, 3: CON3
;	EXIT -	A= 0: BUSY, FFH: READY
;
;****************************************************************************
;
COS:	LD	A,(IOBYTE)
	AND	A,3
	JP	Z,COS0		;CONSOLE 0
	CP	A,2
	JP	M,COS1		;CONSOLE 1
	JP	Z,COS2		;CONSOLE 2
	JP	COS3		;CONSOLE 3


;****************************************************************************
;
;	SYSTEM CONSOLE OUTPUT SELECTOR
;	ENTRY-	(IOBYTE BIT 0..1): 0: CON0, 1: CON1, 2: CON2, 3: CON3
;		C= CHAR
;
;****************************************************************************
;
CO:	LD	A,(IOBYTE)
	AND	A,3
	JP	Z,CO0		;CONSOLE 0
	CP	A,2
	JP	M,CO1		;CONSOLE 1
	JP	Z,CO2		;CONSOLE 2
	JP	CO3		;CONSOLE 3


;****************************************************************************
;
;	SYSTEM CONSOLE INPUT STATUS SELECTOR
;	ENTRY-	(IOBYTE BIT 0..1)= 0: CON0, 1: CON1, 2: CON2, 3: CON3
;	EXIT -	A= 0: NOT READY, FFH: CHAR READY
;
;****************************************************************************
;
CIS:	LD	A,(IOBYTE)
	AND	A,3
	JP	Z,CIS0		;CONSOLE 0
	CP	A,2
	JP	M,CIS1		;CONSOLE 1
	JP	Z,CIS2		;CONSOLE 2
	JP	CIS3		;CONSOLE 3


;****************************************************************************
;
;	SYSTEM CONSOLE INPUT SELECTOR
;	ENTRY-	(IOBYTE BIT 0..1)= 0: CON0, 1: CON1, 2: CON2, 3: CON3
;	EXIT -	A= CHAR (CTRL-Z: EOF)
;
;****************************************************************************
;
CI:	LD	A,(IOBYTE)
	AND	A,3
	JP	Z,CI0		;CONSOLE 0
	CP	A,2
	JP	M,CI1		;CONSOLE 1
	JP	Z,CI2		;CONSOLE 2
	JP	CI3		;CONSOLE 3


;****************************************************************************
;
;	LIST DEVICE OUTPUT SELECTOR
;	ENTRY-	(IOBYTE BIT 6..7)= 0: LST0, 40H: LST1, 80H: LST2, C0H: CON
;		C= CHAR
;
;****************************************************************************
;
LO:	LD	A,(IOBYTE)
	AND	A,0C0H
	JP	Z,LO0		;PRINTER 0
	CP	A,80H
	JP	M,LO1		;PRINTER 1
	JP	Z,LO2		;PRINTER 2
	JP	CO		;CONSOLE


;****************************************************************************
;
;	LIST DEVICE STATUS INPUT SELECTOR
;	ENTRY-	(IOBYTE BIT 6..7)= 0: LST0, 40H: LST1, 80H: LST2, C0H: CON
;	EXIT -	A= 0: BUSY, FFH: READY
;
;****************************************************************************
;
LOS:	LD	A,(IOBYTE)
	AND	A,0C0H
	JP	Z,LOS0	;PRINTER 0
	CP	A,80H
	JP	M,LOS1	;PRINTER 1
	JP	Z,LOS2	;PRINTER 2
	JP	COS	;CONSOLE

	SUBTTL	PRIMITIVE I/O DRIVERS
;****************************************************************************
;
;	PRIMARY CONSOLE DEVICE (CON0) : NAKED TERMINAL
;
;****************************************************************************
;
;   RETURN INPUT STATUS
;
CIS0:	IN	A,(NT_STAT)	;IF NOT CHAR NOT READY THEN RETURN 0
	AND	A,1 SHL NT_READY
	RET	Z
	LD	A,-1		;ELSE RETURN -1
	RET
;
;
;   RETURN INPUT CHAR
;
CI0:	CALL	CIS0		;IF CHAR NOT READY THEN WAIT
	JR	Z,CI0
;
	IN	A,(NT_DATA)	;ELSE RETURN CHAR
	RET
;
;
;   RETURN OUTPUT STATUS
;
COS0:	IN	A,(NT_STAT)	;IF NOT READY TO ACCEPT CHAR THEN WAIT
	CPL
	AND	A,1 SHL NT_BUSY
	RET	Z
	LD	A,-1
	RET
;
;
;   OUTPUT CHAR
;
CO0:	CALL	COS0		;IF BUSY THEN WAIT
	JR	Z,CO0
;
	LD	A,C		;OUTPUT CHAR & RETURN
	OUT	(NT_DATA),A
	RET


;****************************************************************************
;
;	ALTERNATE CONSOLE DEVICE (CON1) : SIO #0
;
;****************************************************************************
;
CIS1:
	IN 	A,(PS_SER0S)	;FETCH STATUS
	AND	A,00000001B	;TEST RXRDY
	RET	Z
;
	LD	A,-1
	RET
;
;
CI1:
	CALL	CIS1		;WAIT FOR CHAR READY
	JR	Z,CI1
;
	IN	A,(PS_SER0D)	;FETCH CHAR
	RET
;
;
COS1:
	IN	A,(PS_SER0S)	;FETCH STATUS
	AND	A,00000100B	;TEST TX BUFFER EMPTY
	RET	Z
;
	LD	A,-1
	RET
;
;
CO1:
	CALL	COS1		;WAIT IF BUSY
	JR	Z,CO1
;
	LD	A,C		;SEND CHAR
	OUT	(PS_SER0D),A
	RET


;****************************************************************************
;
;	ALTERNATE CONSOLE DEVICE (CON2)
;
;****************************************************************************
;
CIS2:	EQU	CIS0
CI2:	EQU	CI0
COS2:	EQU	COS0
CO2:	EQU	CO0


;****************************************************************************
;
;	ALTERNATE CONSOLE DEVICE (CON3)
;
;****************************************************************************
;
CIS3:	EQU	CIS0
CI3:	EQU	CI0
COS3:	EQU	COS0
CO3:	EQU	CO0


;****************************************************************************
;
;	LIST DEVICE 1 (LST1) : PRI CENTRONICS
;	
;****************************************************************************
;
;   RETURN OUTPUT STATUS
;
LOS0:
	LD	A,0BFH			;THIS PRINTER NEEDS STB=F FOR BUSY
	OUT	(PRI_2CNT),A		; TO WORK PROPERLY
;
	IN	A,(PRI_1ST)		;FETCH STATUS
	CPL
	AND	A,[1 SHL PRI_1BSB]	;TEST BUSY
	RET	Z
;
	LD	A,-1
	RET
;
;
;   OUTPUT CHAR
;
LO0:
	CALL	LOS0			;WAIT FOR BUSY=FALSE
	JR	Z,LO0
;
	LD	A,C			;OUTPUT CHARACTER
	OUT	(PRI_1DO),A
	LD	A,NOT [1 SHL PRI_1CSB]	;OUTPUT STROBE
	OUT	(PRI_2CNT),A
	LD	A,0BFH
	OUT	(PRI_2CNT),A		;CLEAR STROBE
	RET


;****************************************************************************
;
;	LIST DEVICE 1 (LST1)
;
;****************************************************************************
;
LOS1:	EQU	LOS0
LO1:	EQU	LO0


;****************************************************************************
;
;	LIST DEVICE 2 (LST2)
;
;****************************************************************************
;
LOS2:	EQU	LOS0
LO2:	EQU	LO0



LOGMSG	DB	' M5b Character I/O V. '
	PVERS	VERSN
	DM	CR,LF

	END
