;***********************************************************************
;
;		       MBYE (Modular 'BYE')
;			8250 UART routines
;		   v1.0 (02/07/84) by Kim Levitt
;
;	This is adapted from the WD8250 routines in BYE3.
;
;	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 Western Digital 8250 chip that is hooked up to
; an external modem.  If your modem cannot detect a ring, then set
; NORING true.
;
;=======================================================================
;
; 02/07/84  Altered and renamed to work with MBYE	- Kim Levitt
; 11/27/83  Altered and renamed to work with BYE3	- Irv Hoff
; 08/04/83  Added MDQUIT routine			- Paul Traina
; 07/18/83  Fixed several bugs that I put in 		- Paul Traina
; 10/04/82  Initial re-write of old 8250 routines	- Paul Traina
;
;=======================================================================
;
; The following define the port address to use.
;
BASEP:	EQU	0D8H		;Base port modem port
DATPORT:EQU	BASEP		;Data port
LPORT:	EQU	BASEP+3		;Line control
CPORT:	EQU	BASEP+4		;Modem control
SPORT:	EQU	BASEP+5		;Line status port
MSPORT:	EQU	BASEP+6		;Modem status port
RPORT:	EQU	BASEP+6		;Ring indicator port
;
; Line status bits
;
DAV:	EQU	00000001B	;Data available
ORUN:	EQU	00000010B	;Overrun error
PERR:	EQU	00000100B	;Parity error
FERR:	EQU	00001000B	;Framing error
ERR:	EQU	ORUN+PERR+FERR	;Error bits
TBMT:	EQU	00100000B	;Transmitt buffer empty
;
; Modem status bits
;
DSR:	EQU	00100000B	;Data set ready
RDET:	EQU	01000000B	;Ring detect
DCD:	EQU	10000000B	;Carrier detect
;
; Baud rate divisors
;
BR300LS: EQU	080H		;300 baud
BR300MS: EQU	001H
BR450LS: EQU	000H		;450 baud
BR450MS: EQU	001H
BR600LS: EQU	0C0H		;600 baud
BR600MS: EQU	000H
BR120LS: EQU	060H		;1200 baud
BR120MS: EQU	000H
;
;	Modem control bits
;
DTR:	EQU	00000001B	;Data terminal ready
RTS:	EQU	00000010B	;Request to send
OUT1:	EQU	00000100B	;Aux output #1
OUT2:	EQU	00001000B	;Aux output #2
;
;	Line control bits
;
WLS0:	EQU	00000001B	;Word length select 0
WLS1:	EQU	00000010B	;Word length select 1
STB:	EQU	00000100B	;Stop bit select
PEN:	EQU	00001000B	;Parity enable
PES:	EQU	00010000B	;Even parity select
SPS:	EQU	00100000B
BRKS:	EQU	01000000B	;Break
DLAB:	EQU	10000000B
;
;
;***********************************************************************
;
; 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)
;
MDINIT:
	XRA	A		;Shut off DTR & RTS
	OUT	CPORT		;..which turns off modem.
	RET
;
; The following routine will make the modem answer the phone.
;
MDANSW:
	MVI	A,DTR+RTS	;Turn on DTR and let modem answer phone
	OUT	CPORT
	CALL	SET300		;Set 300 baud (for init only)
	MVI	A,WLS0+WLS1	;8 data bits, 1 stop bit, no parity
	OUT	LPORT
	RET
;
; The following is a routine to determine if there is a character wait-
; ing to be received, if none, Zero flag will be set, otherwise, 0FFH
; will be returned in register A.  Remember that the system will like
; you a little more if you also mask out framing, parity, and overrun
; errors.
;
MDINST:
	PUSH	B		;Save BC
	IN	SPORT		;Get status
	MOV	B,A		;Save it in B (status cleared by read)
	ANI	DAV		;Data available?
	JZ	NDAV		;Return if not ready
	MOV	A,B		;else, check error bits
	ANI	ERR		;for parity/overrun/framing errors
	JZ	DAVA		;if none, ok...
	IN	DPORT		;else clear garbage
;
NDAV:
	XRA	A		;say no data
	POP	B		;restore BC
	RET			;and return
;
DAVA:
	ORI	0FFH		;We have a character
	POP	B		;restore BC
	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	SPORT
	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	MSPORT			;Get modem status
	ANI	DCD			;Got a carrier?
	RET
;
; The following routine will check to see if the phone is ringing, if it
; isn't, it will return with Zero set, otherwise Zero will be cleared.
;
MDRING:
	IN	RPORT		;Ringing?
	ANI	RDET		;1=yes, 0=no
	RET
;
; 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 remove that routine
; and put the pointer in front of SETINV.
;
; If the baud rate change was successful, make SURE the Zero flag is set.
;
; 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.
;
SET110:				;110 baud is seldom used
SET600:				;600 bause is only for PMMI
SET710:				;710 baud is only for PMMI
;
SETINV:
	ORI	0FFH
	RET
;
; Set up for 300 baud
;
SET300:
	PUSH	D		;Set 300
	MVI	D,BR300MS
 	MVI	E,BR300LS
	JMP	SETALL
;
; Set up for 450 baud
;
SET450:
	PUSH	D		;Set 450
	MVI	D,BR450MS
	MVI	E,BR450LS
	JMP	SETALL
;
; Set up for 1200 baud
;
SET1200:
	PUSH	D		;Set 1200
	MVI	D,BR120MS
	MVI	E,BR120LS
;
SETALL:
	CALL	SETBAUD
	POP	D
	XRA	A
	RET
;
; This routine takes the baud rate divisors passed in the DE register
; and sets the modem port accordingly.
;
SETBAUD:
	MVI	A,83H		;Set DLAB
	OUT	LPORT
	MOV	A,E		;Get LSB
	OUT	DATPORT
	MOV	A,D		;Get MSB
	OUT	DATPORT+1
	MVI	A,WLS0+WLS1	;8 data bits, no parity, 1 stop bit
	OUT 	LPORT
	PUSH	B
	MVI	B,2		;wait about .2 seconds
	CALL	DELAY
	POP	B
	IN	DATPORT		;Clear out any inpuyt chars.
	IN	DATPORT
	RET
;
; Ok, that's all of the modem dependant routines that MBYE uses, so if
; you patch this file into your copy of MBYE, then it should work out
; well.
;
;**********************************************************************
;
