; B3RS2-3.ASM  -  BYE3 Insert for TRS-80 2/12/16/16B  -  04/15/85
;
;		    Zilog Z80-SIO and CTC routines
;		      by Steve Fox & Paul Traina
;
; This version is for the Zilog SIO chip that is hooked up to an extern-
; al modem.  It works with the TRS-80 Model II & 12 with versions of
; CP/M 2.2 except P&T 2.2m.  Will work on P&T 2.2m ONLY when running
; ZCPR3.  A CTC timer is used as the baud rate generator.
;
; This version adapted for use with TRS-80 Models 2/12/16 & 16B.
;
; NOTE:  This is an insert, not an overlay.
;
;-----------------------------------------------------------------------
;
; 04/15/85  Rewrote to work with current BYE3 versions,
;	    added 2400 bps, other changes		- Irv Hoff
; 12/23/84  Altered and renamed to work with BYE3 for
;	    TRS-80 Models 2/12/16 & 16B 		- Ken Brown
; 12/15/83  Altered and renamed to work with BYE3	- Irv Hoff
; 08/04/83  Updated for use with ByeII version 1.6	- Paul Traina
; 07/19/83  Improved operation of modem initialization. - Paul Traina
; 04/18/83  Added option to use 300/1200 Smartmodem.	- Don Brown
; 04/14/83  Added option for alt. CTC baud set format.	- Paul Traina
; 02/21/83  Initial version.				- Steve Fox
;
;-----------------------------------------------------------------------
;
; Set base port for SIO & CTC chips for TRS-80 Models 2/12/16/16B
;
BASEP	EQU	0F4H		; Base port for SIO
BASEC	EQU	0F0H		; Base port for CTC baud rate generator
;
;
; The following define the port addresses to use.
;
DATPORT	EQU	BASEP		; Data port
STPORT	EQU	BASEP+2		; Status/control port
BPORT	EQU	BASEC		; Baud rate port
BPORT1	EQU	BASEC+1		; Port for TRS-80 Models 2/12/16/16B
;
;
; The following are STPORT commands (output these to STPORT)
;
RESCHN	EQU	00011000B	; Reset channel
RESSTA	EQU	00010000B	; Reset ext/status
WRREG1	EQU	00000000B	; Value to write to register 1
WRREG3	EQU	11000001B	; 8 bits/character, enable RX
WRREG4	EQU	01000100B	; 16x, 1 stop bit, no parity
DTROFF	EQU	00000000B	; DTR off, RTS off
DTRON	EQU	11101010B	; DTR, RTS, 8 bits/char, TX, RX enable
ONINS	EQU	00110000B	; Error reset
;
;
; The following are STPORT status masks
;
DAV	EQU	00000001B	; Data available
TRDY	EQU	00000100B	; Transmit buffer empty
DCD	EQU	00001000B	; Data carrier detect
PE	EQU	00010000B	; Parity error
OE	EQU	00100000B	; Overrun error
FE	EQU	01000000B	; Framing error
ERR	EQU	PE+OE+FE	; Parity, overrun and framing error
;
;
; Changed BDCMD1 & BDCMD2 EQU'S for TRS-80 Models 2/12/16/16B
;
BDCMD1	EQU	07H		; 110,300,600 & 1200 baud
BDCMD2	EQU	47H		; 2400 4800 9600 baud
;
;
;-----------------------------------------------------------------------
;
;
; The following routine will reset the CTC to 300 baud and allow the
; modem to answer the phone.
;
MDANSW:	CALL	SET300		; Set 300 baud
;
	 IF	IMODEM
	CALL	IMANSW
	 ENDIF			; Imodem
;
	IN	DATPORT		; Clear out garbage
	IN	DATPORT		; Make sure we're clear
	RET			; Return
;.....
;
;
; The following routine checks to make sure we still have carrier.  If
; there is no carrier, it will return with the Zero flag set.
;
MDCARCK:MVI	A,RESSTA	; Reset status
	OUT	STPORT
	IN	STPORT		; Get status
	ANI	DCD		; Check for data carrier
	RET
;.....
;
;
; This routine should turn off everything on the modem, hang it up, and
; get it ready to wait for a ring.
;
MDINIT:	MVI	A,RESCHN	; Reset channel
	OUT	STPORT
	MVI	A,4		; Setup to write register 4
	OUT	STPORT
	MVI	A,WRREG4
	OUT	STPORT
	MVI	A,1		; Setup to write register 1
	OUT	STPORT
	MVI	A,WRREG1
	OUT	STPORT
	MVI	A,5		; Setup to write register 5
	OUT	STPORT
	MVI	A,DTROFF	; Clear DTR causing hangup
	OUT	STPORT
	PUSH	B
	MVI	B,20		; 2 second delay
;
OFFTI:	CALL	DELAY		; 0.1 second delay
	DCR	B
	JNZ	OFFTI		; Keep looping until finished
	POP	B		; Restore BC
	MVI	A,3		; Setup to write register 3
	OUT	STPORT
	MVI	A,WRREG3	; Initialize receive register
	OUT	STPORT
	MVI	A,5		; Setup to write register 5
	OUT	STPORT
	MVI	A,DTRON		; Turn on DTR so modem can answer phone
	OUT	STPORT
;
	 IF	IMODEM		; If using hayes 300/1200 smartmodem
	CALL	IMINIT		; Go initialize smartmodem now
	 ENDIF			; Smodem
;
	RET			; Return
;.....
;
;
; The following routine will input one character from the modem port.
; If there is nothing there, it will return garbage... so use the MDINST
; routine first.
;
MDINP:	IN	DATPORT		; Get character
	ANI	7FH		; Strip parity
	RET			; Return
;.....
;
;
; The following routine determines if there is a character waiting to
; be received.	If no not, the Zero flag will be set,  If yes, 0FFH will
; be returned in 'A'.
;
MDINST:	IN	STPORT		; Get status
	ANI	DAV		; Got a character?
	RZ			; Return if none
	ORI	0FFH		; Otherwise, set the proper flag
	RET			; And return
;.....
;
;
; The following is a routine to determine if the transmit buffer is
; empty.  If it is empty, it will return with the Zero flag clear.  If
; the transmitter is busy, then it will return with the Zero flag set.
;
MDOUTST:IN	STPORT
	ANI	TRDY		; Mask it
	RET
;.....
;
;
; The following is a routine that will output one character in register
; 'A' to the modem.
;
; **** Use MDOUTST first to see if buffer is empty ****
;
MDOUTP:	OUT	DATPORT		; Send it
	RET
;.....
;
;
; The following routine will turn off DTR and disconnect the modem.  It
; will also  prevent the modem from accepting any more calls.
;
MDQUIT:	 IF	IMODEM		; If using a smartmodem
	CALL	IMQUIT		; Tell it to shut down
	 ENDIF			; IMODEM
;
	MVI	A,5		; Setup to write register 5
	OUT	STPORT
	MVI	A,DTROFF	; Clear DTR causing shutdown
	OUT	STPORT
	XCHG			; Give it time to react
	XCHG
	RET
;.....
;
;
MDRING:	RET
;.....
;
;
; These next routines set the proper baud rates for the modem.	If you
; do not support the particular rate, then simply put the label in front
; of the SETINV routine.  If the baud rate change was successful, make
; SURE the Zero flag is set.
;
SET300:	MVI	A,BD300		; Load rate
	PUSH	PSW		; Store it
	MVI	A,BDCMD1	; Get first byte of command
	JMP	SETBAUD
;
SET1200:MVI	A,BD1200
	PUSH	PSW
	MVI	A,BDCMD1
	JMP	SETBAUD
;
SET2400:MVI	A,BD2400
	PUSH	PSW
	MVI	A,BDCMD2
;.....
;
;
SETBAUD:OUT	BPORT		; Send first byte of command
	OUT	BPORT1
	POP	PSW		; Restore the rate
	OUT	BPORT		; Send rate
	OUT	BPORT1
	XRA	A		; Say rate is ok
	RET
;.....
;
;
; The following routine returns a 255 because we were not able to set to
; the proper baud rate because either the serial port or the modem can't
; handle it.
;
;
SETINV:	ORI	0FFH		; Make sure zero flag is not set
	RET
;.....
;
;
; CTC baud rate divisors
;
BD300	EQU	34H		; 300 baud
BD600	EQU	1AH		; 600 bps  (not supported by smartmodem)
BD1200	EQU	0DH		; 1200 bps
BD2400	EQU	34H		; 2400 bps

;.....
;
;
;			       end
------------------------------------------------------------------------:
