;***********************************************************************
;
;			  MBYE  (Modular BYE)
;			 8251A USART routines
;		Version 2.0 - by Kim Levitt - 02/20/84
;
;	This version is for a 8251A I/O with CTC timer to set speed,
; or for a Morrow Micro Decision using the 8251A baud rate multiplier
; to change baud rates. (Set your printer port baud rate switches to
; 1200 baud and connect your modem to this port.)
;
;	These routines will allow the easy patching of MBYE for any 
; type of modem/serial port combination.  Certain routines must return
; status flags, so please be careful to set the flags as directed.
;
; This version is for the Intel 8251A chip that is hooked up to an ex-
; ternal modem. Since the 8251A cannot detect rings (RI), set NORING EQU
; YES in the main program. Also, since the 8251A cannot detect carrier,
; you should wire pin 8 (DCD) from your modem to pin 6 (DSR) on your
; port, which the 8251 reads to determine if carrier is present.
;
;=======================================================================
;
; 02/20/84  Added equates and code for MicroDecisions   - Kim Levitt
; 02/07/84  Fixed and renamed to work with MBYE		- Kim Levitt
; 11/27/83  Altered and renamed to work with BYE3	- Irv Hoff
; 10/04/83  Modified for use with 8251A I/O with
;	    CTC timer to set speed.			- Irv Hoff
; 10/04/82  Routines added, no fuss, mess, or frills.	- Paul Traina
;
;=======================================================================
;
; Set this equate to YES if you are running on a Morrow MicroDecision
;
MICROD:	EQU	YES		;Yes, if Morrow MicroDecision
;
	 IF	MICROD
BASEP:	EQU	0FEH		;MicroDecision base port address
	 ENDIF
;
	 IF	NOT MICROD
BASEP:	EQU	28H		;Set to your modem's UART base port
RCVPORT:EQU	20H		;Set to recv speed CTC port
XMTPORT:EQU	1AH		;Set to xmit speed CTC port
	 ENDIF
;
; The following define the port address to use.
;
DATPORT:EQU	BASEP		;Data port
STPORT:	EQU	BASEP+1		;Status/Control port
;
; The following are STPORT commands (output these to STPORT)
;
MODINS:	EQU	01001110B	;8 bits, no parity, 1 stop bit, 16x
OFFINS:	EQU	00010000B	;drop DTR and disable RCV/XMT
ONINS:	EQU	00010111B	;reset flags, send DTR, enable rx & tx
RSTINS:	EQU	01000010B	;reset USART and send DTR
;
; The following are STPORT status masks
;
DAV:	EQU	00000010B	;data available
TBMT:	EQU	00000001B	;transmit buffer empty
DSR:	EQU	10000000B	;data set ready (no DCD avail)
FE:	EQU	00100000B	;framing error
OE:	EQU	00010000B	;overrun error
ERR:	EQU	OE+FE		;overrun and framing error
;
	 IF	NOT MICROD
;
; The following are CTC timer baud rates divisors.
;
BD300:	EQU	32		;9600/300  =  300 bps
BD450:	EQU	21		;9600/450  =  450 bps
BD1200:	EQU	8		;9600/1200 = 1200 bps
;
	 ENDIF
;
;=======================================================================
;
; If any of your routines zaps anything other than the Accumulator, then
; you must preserve all other registers.
;
;=======================================================================
;
; This routine should turn off everything on the modem, and get it ready
; to wait for a ring.  (Also hang it up) (lowers DTR)
;
MDINIT:
	MVI	A,RSTINS	;reset UART
	OUT	STPORT
	CALL	UDELAY
;
	 IF	NOT MICROD
	MVI	A,MODINS	;x16 clk, 1 stop bit, etc.
	 ENDIF
;
	 IF	MICROD AND SPDBYTE
	LDA	MSPEED		;if multi speed, check speed byte
	CPI	5		;if not 1200 baud now, set to 300
	JNZ	INIT300
	MVI	A,MODINS	;else set to 1200
	JMP	INITSET
	 ENDIF
;
	 IF	MICROD
INIT300:
	MVI	A,MODINS+1	;x64 clk for 300 initially
	 ENDIF
;
INITSET:
	OUT	STPORT
	CALL	UDELAY
	MVI	A,OFFINS	;Clear DTR
	OUT	STPORT		;causing hangup
	RET			;return
;
; The following routine will make the modem answer the phone. (raise DTR)
;
MDANSW:
	MVI	A,ONINS		;turn on DTR, etc.
	OUT	STPORT
	RET			;return
;
; The following is a routine to determine if there is a character wait-
; ing to be received,  if none, the Zero flag will be set, otherwise it
; returns with FF in register A.  Remember that the system will like you
; a little more if you also mask out framing, parity, and overrun errors.
;
MDINST:
	IN	STPORT		;get status
	ANI	DAV		;got a character?
	RZ			;return if none
	IN	STPORT		;get status again
	ANI	ERR		;check for framing and overrun
	JZ	MDINST1		;no errors
	MVI	A,ONINS		;reset error flags
	OUT	STPORT
	XRA	A		;return false
	RET
;
MDINST1:
	ORI	0FFH		;We have a character
	RET
;
; The following is a routine to determine if the transmit buffer is
; empty.  If it is, 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	TBMT
	RET
;
; The following is a routine that will check to make sure we still have
; carrier.  If there is no carrier, it will return with the Zero flag
; set.
;
MDCARCK:
	IN	STPORT	;get status
	ANI	DSR	;check if Data Set Ready is on (no DCD)
	RET		;(wire modem pin 8 to port pin 6 for carrier read)
;
; The following is a routine that 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 and other garbage
	RET
;
; The following is a routine that will output one character in register
; A to the modem.  REMEMBER, that is register A, not register C.
;  
; ** Use MDOUTST first to see if buffer is empty **
;
MDOUTP:
	OUT	DATPORT		;send it
	RET
;
; These next routines set the proper baud rates for the modem.  If you
; do not support the particular rate, then simply set the appropriate
; S110 - S1200 equates in the main program. If the baud rate change
; is successful, make SURE the Zero flag is set.
;
	 IF	NOT MICROD	;if non-MicroDecision (CTC)
;
; Set up for 300 bps
;
SET300:
	MVI	B,BD300		;load 300 bps
	JMP	SETSPD
;
; Set up for 450 bps
;
SET450:
	MVI	B,BD450		;load 450 bps
	JMP	SETSPD
;
; Set up for 1200 bps
;
SET1200:
	MVI	B,BD1200	;poke in 1200 bps
;
SETSPD:
	MVI	A,47H
	OUT	RCVPORT
	OUT	XMTPORT
	MOV	A,B		;get the speed value back
	OUT	RCVPORT
	OUT	XMTPORT
	XRA	A		;say it is ok
	RET
;
	 ENDIF	;NOT MICROD
;
	 IF	MICROD
;
; On MicroDecisions, there is no software controllable baud rate chip,
; (at least not on the MD1 and MD2, anyway), so only two baud rates
; can be selected, either 300 or 1200 baud, by using the baud rate
; factor variable of the 8251A to change baud rates instead of an
; external baud rate chip. Be sure to set up your dip switches so that
; 1200 is the baud rate for your printer port and attach your modem
; there. Set the switches to 1200 even if it is a 300 only modem, as
; the software will switch to 300 only if switches are set up right.
;
;
SET300:
	MVI	B,MODINS+1	;x64 clk for 300 baud
	JMP	SETBAUD		;change baud rate
;
SET1200:
	MVI	B,MODINS	;x16 clk for 1200 baud
SETBAUD:
	MVI	A,RSTINS	;return to mode instruction reg
	OUT	STPORT
	CALL	UDELAY
	MOV	A,B		;get clk multiplier
	OUT	STPORT
	JMP	UDELAY		;pause and return
;
SET450:
;
	 ENDIF	;MICROD
;
; The following routines returns a 255 because we were not able to set to
; the proper baud rate because the serial port can't handle it.
; (Use S110-S1200 equates and SINGLE equate to select from valid baud
; rates you wish to support. (in main pgm))
;
SET110:
SET600:
SET710:
;
SETINV:
	MVI	A,0FFH
	ORA	A		;make sure the Zero flag isn't set
	RET
;
; 8251 specific USART delay
;
UDELAY:
	NOP
	NOP
	NOP
	RET
;
; Ok, that's all of the modem dependent routines that MBYE uses, so if
; you patch this file into your copy of MBYE, it should work out well.
;
;***********************************************************************
;