; B3OV-1.INS - Osborne Vixen insert for BYE3 - 07/17/85
;
;	     8251A with BIOS routines setting baud rate
;
;
; This version is for an 8251A I/O with extended BIOS jump for setting
; baudrate.  Note:  This is an insert, not an overlay.
;
; This version is for the Osborne Vixen which uses an extended BIOS
; function call to set the baudrate.  The normal serial input interrupt
; driver in BIOS is disabled while BYE3 is used.
;
;
; *  *	*  *  *  *  *  *  *  *	*  *  *  *  *  *  *  *	*  *  *  *  *  *
;
;  07/30/85  Restored to original format	- pst
;  06/15/85  Written for use with BYE3		- Roy Robinson
;
; *  *	*  *  *  *  *  *  *  *	*  *  *  *  *  *  *  *	*  *  *  *  *  *
;
;-----------------------------------------------------------------------
; PATCH #1 -------------------------------------------------------------
;-----------------------------------------------------------------------
;
; Listed below is a patch for disabling the serial input interrupt
; driver in the Vixen BIOS.  This patch goes AFTER the label
; "START1" and immediately AFTER the line of code, CALL MDCARCK
; This patch is in the BYE source code.
;
; ---->  beginning of patch:
;
;	JNZ	BYPASS
;  INITMOD:
;	PUSH	PSW
;	MVI	C,7	; Use BDOS to obrain current IOBYTE
;	CALL	BDOS	;
;	STA	OLDIOB	; Save old IOBYTE
;	ANI	3fH	;
;	ORI	80H	; Make CEN: PORT new LST: DEVICE
;	MOV	E,A
;	MVI	C,8
;	CALL	BDOS	; Use BDOS to place new IOBYTE in first page of memory
;	DI		;
;	LHLD	INTVEC	; Get serial port interrupt processor address
;	SHLD	OLDVEC	; Save serial port interrupt processor address
;	DCX	H
;	DCX	H
;	DCX	H	; HL has next interrupt processor address
;	SHLD	INTVEC	; This is now first interrupt processor rather
;			;   than second
;
;INITSIO:
;	LHLD	BIOS	; Find start ofF BIOS
;	MVI	L,3CH	; Displacement of baudrate byte from start of BIOS
;	MOV	A,M
;	STA	OLDBAUD ; Save original baudrate byte
;	MVI	L,3BH	; Displacement of 8251 mode byte from start of BIOS
;	MOV	A,M	; Old mode byte set by ROM is 2SB, NP, 8DB, X16 clock
;	STA	OLDMODE ; Save original 8251 mode byte
;	MOV	B,L
;	MVI	A,6EH	; 1 SB, NP, 8 DB, X16 clock modem byte
;	CALL	IORESET ; Use extended BIOS jump to reset 8251
;	MVI	A,37H	; 8251 command byte RTS/DTR active, TXD and RXD active
;	OUT	31H	; Send it to 8251 control port
;	MVI	A,3	; Select 8155 port C
;	OUT	21h	;
;	IN	28h	; Get miscellaneous byte
;	STA	OLDMSC	; Save misdellaneous info byte
;	ORI	00001111B
;			; Disable ring detect interrupt, RXD interrupt, XMIT
;			;   interrupt, emab;e omterma; clock
;	MOV	E,A
;	MVI	A,3
;	OUT	21h	; Select 8155 port C
;	MOV	A,E
;	OUT	28h	; Send new control byte to 8155 port C
;	EI
;	POP	PSW
;	ORA	A
;
;BYPASS:
;	JNZ	GOODBY
;	original code continues here
;
;=======================================================================
;
;-----------------------------------------------------------------------
; PATCH #2 -------------------------------------------------------------
;-----------------------------------------------------------------------
;
;
; Listed below is a patch for re-enabling the serial input interrupt
; driver in the Vixen.	Place this patch before the instruction line
; "JMP	0000H" in the EXCPM routine in the BYE source code.
;
;--> Patch starts here
;
;RSTINT:
;	LDA	OLDIOB	; Get original IOBYTE
;	MVI	C,8
;	MOV	E,A	; Use BDOS to restore original IOBYTE
;	CALL	BDOS
;	DI
;	XRA	A
;	OUT	STPORT	; Disable 8251 DTR/RTS lines
;	LHLD	OLDVEC	; Get original interrupt service address
;	SHLD	INTVEC	; Restore original interrupt service address
;	MVI	A,3	; Select 8155 port C
;	OUT	21H
;	IN	28H	; Get misc. info byte for controlling interrupt lines
;	ANI	030H	; Zero the least significant four bits, keep the
;			;   remainining two most significant bits
;	MOV	E,A
;	LDA	OLDMSC	; Get original misc. 8155 control byte
;	ANI	0FH	; Keep least significant four bits
;	ORA	E	; Combine everything
;	MOV	E,A
;	MVI	A,3
;	OUT	21H	; Select 8155 port C
;	MOV	A,E
;	OUT	28H	; Restore original 8155 control byte
;	EI
;	MVI	B,3CH
;	LDA	OLDBAUD ; Restore original baudrate byte
;	CALL	IORESET ; Do an 8251 reset
;	MVI	B,3BH
;	LDA	OLDMODE ; Restore original mode byte
;	CALL	IORESET ; Do an 8251 reset
;
;--> Original code starts again with the following instruction:
;
;	JMP	0000H
;
;-----------------------------------------------------------------------
;
;
; E Q U A T E S
;
;
INTVEC	EQU	0EFFEH		; Address of interrupt vector to first
				; interrupt service routine
BDOS	EQU	0005H		; Address of bdos in first page of RAM
BIOS	EQU	0001H		; Address of warm boot jump in BIOS
AJUMP	EQU	0C3H		; JUMP instruction opcode
;
;
PORT:	EQU	030H
DATPORT:EQU	PORT		; Modem data port
STPORT:	EQU	PORT+1		; Modem status port
;
; Modem status port equates
;
; The following are STPORT AND TSTPORT commands
;
OFFINS	EQU	00010000B	; Drop DTR and disable RCV/XMT
ONINS	EQU	00010111B	; Reset flags, send DTR, enable RX and TX
RSTINS	EQU	00010111B	; Reset USART and send DTR


;
; The following are STPORT status masks
;
DAV:	EQU	00000010B	; Data available - rda
TRDY:	EQU	00000100B	; Transmit buffer empty - tbe
DSR:	EQU	10000000B	; Data carrier detect - use DSR
PE:	EQU	00001000B	; Parity error - register 1
OE:	EQU	00010000B	; Overrun error - register 1
FE:	EQU	00100000B	; Framing error - register 1
ERR:	EQU	PE+OE+FE	; Parity, overrun and framing errors
;
;-----------------------------------------------------------------------
;
; 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:MVI	A,ONINS		; Reset status
	OUT	STPORT
	IN	STPORT		; Get status
	ANI	DSR		; Check for carrier detect
	RET
;
; This routine should turn off everything on the modem, and get it ready
; to wait for a ring.  (Also hang it up.)
;
MDINIT:	MVI	A,OFFINS	; Clear DTR
	OUT	STPORT		; Causing modem to hangup
	PUSH	B		; Preserve in case we need it
	MVI	B,20		; 2 seconds to drop DTR

OFFTI:	CALL	DELAY		; 0.1 second delay
	DCR	B
	JNZ	OFFTI		; Keep waiting until carrier drops
	POP	B		; Restore BC
	MVI	A,ONINS		; Raise DTR so that modem can answer the phone
	OUT	STPORT
;
	 IF	IMODEM
	CALL	IMINIT		; Initialize smartmodem
	 ENDIF			; IMODEM
;
	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
	RET
;
; The following is a routine to determine if there is a character wait-
; ing to be received.  If there are none, the 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:	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			; 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		; Read port
	ANI	TRDY		; Mask crap
	RZ
	ORI	0FFH
	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
;
; Re-initialize modem and hang up phone by dropping DTR and leaving
; modem inactive
;
MDQUIT:	 IF	IMODEM
	CALL	IMQUIT
	 ENDIF			; IMODEM
;
; Called by main BYE program after caller types BYE
;
MDSTOP:	XRA	A		; Turn off rts/dtr, rx/tx
	OUT	STPORT		; Command byte to 8251 control port
	RET
;
; These next routines set the proper baud rates for the modem.	If you
; do not support the particular rate, then simply put in a JMP to 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
; not handle it.
;
SETINV:	MVI	A,0FFH
	ORI	A		; Make sure the Zero flag is not set
	RET
;
SET300:	MVI	A,06H		; Store baud rate parameter (300 baud)
	MVI	B,3CH
	JMP	SETBAUD
;
SET1200:MVI	A,08H		; Store baud rate parameter (1200 baud)
	MVI	B,3CH
	JMP	SETBAUD
;
SET2400:MVI	A,0BH		; Store baud rate parameter (2400 baud)
	MVI	B,3CH

SETBAUD:CALL	IORESET		; Use extended BIOS function to reset baudrate
	XRA	A		; Say baudrate change was satisfactory
	RET
;
IORESET:
;
; Subroutine which executes a master reset for 8251.  8251 reset is a
; BIOS function in VIXEN extended BIOS
;
;	ENTRY:
;	A	=	byte value to be replaced in BIOS
;			(mode byte or baudrate byte)
;
;	B	=	hex displacement from base of BIOS
;			for mode byte or baudrate byte
;			(mode byte = 3BH)
;			(baudrate byte = 3CH)
;
;	EXIT:
;	NONE
;
	LHLD	BIOS		; Find base of BIOS
	MOV	L,B
	MOV	M,A
	MVI	L,36H		; Displacement in BIOS for 8251 reset function
	SHLD	EXTFUN
	CALL	BIOSFUNC	; Subroutine call of BIOS 8251 reset function
	RET
;
OLDIOB:	DS	1		; Original  IOBYTE
OLDMSC:	DS	1		; Original misc. control byte for 8155 port C
OLDVEC:	DS	2		; Original interrupt service vector
OLDMODE:DB	1		; Original 8251 mode byte from BIOS
OLDBAUD:DB	1		; Original baudrate byte for 8251 from BIOS
BIOSFUNC: DB	AJUMP		; Absolute jump to the following memory address
EXTFUN:	DS	2		; BIOS extended function address
;			       end
;-----------------------------------------------------------------------
~~~
;  06/15/85  Written for use with BYE3		- Roy Robinson
;						  FOG RCPM #4
;						  (415) 591-6259
