;SERHANA.68K	SEP-01-88	(Also see INFOSTR)
;RS-232 handler.
; by Loren Blaney
;
;REVISION HISTORY:
;MAR-03-88, Based on MAR-09-87 version of XMODEMA.68K
;JUL-07-88, Changed memory location
;SEP-01-88, Changed memory location and whittled off a few bytes.

	NOLIST
	INCLUDE	SYSPAG		;Get the system page difinitions
	LIST

DEVNUM	EQU	4		;Install this handler as device # 4

	ORG	$F26
START	EQU	@		;Address where this handler starts

;=======================================================================
;ENTRY POINTS:
;
SERHANA	DC.L	OPENI		;$00 = OPENI
	DC.L	OPENO		;$04 = OPENO
	DC.L	CHIN		;$08 = CHIN
	DC.L	CHOUT		;$0C = CHOUT
	DC.L	CLOSE		;$10 = CLOSE
	DC.L	GETINFO		;$14 = GETINFO

;-----------------------------------------------------------------------
;OPEN (INITIALIZE) THE RS-232 PORT AND SET THE INPUT BUFFER TO EMPTY
;
OPENI	BSR.S	OPEN		;Init RS-232 port for I/O, set baud rate
	BRA.S	FLUSH		;(PBRA) Flush out bytes in receive FIFO

;-----------------------------------------------------------------------
;Open (initialize) the RS-232 port.
;
OPENO	BSR.S	OPEN		;Init RS-232 port for I/O, set baud rate
	BRA.S	FLUSH		;(PBRA) Flush out bytes in receive FIFO

;-----------------------------------------------------------------------
;Get a character from the serial port and return it in D0.
;
CHIN	BRA.S	BYTEIN		;(PBRA)

;-----------------------------------------------------------------------
;Output the byte in D0 to the buffered RS-232 port.
;
CHOUT	BRA	BYTEOUT		;(PBRA)

;-----------------------------------------------------------------------
;Close the serial port.
;
CLOSE	RTS

;-----------------------------------------------------------------------
;RETURN THE ADDRESS OF THE INFORMATION ARRAY IN D0
;
GETINFO	MOVE.L	#INFO,D0
DUMMY	RTS

INFO	DC.L	START		;START AND END ADDRESSES OF THIS HANDLER
	DC.L	END
	DC.L	INFOSTR		;DESCRIPTION
INFOSTR	ASCII	'SERHANA   SEP-01-88  RS-232 handler, 1200 baud'
	DC.B	0

;======================================================================
;LOWEST LEVEL I/O ROUTINES:
;
SERDATR	EQU	$DFF018		;Serial port data and status register
SERDAT	EQU	$DFF030		;Serial port data register (write)
SERPER	EQU	$DFF032		;Serial port period and control register
INTREQ	EQU	$DFF09C		;Interrupt request (status) bits

;----------------------------------------------------------------------
;Routine to initialize RS-232 I/O.
; N = 1E9 /(baud rate * 279.4) -1
; (Max N = 16383, Min baud = 109)
; 1E9 /(300 * 279.4) -1 = 11929
; 1E9 /(19200 * 279.4) -1 = 185 
; 1E9 /(1200 * 279.4) -1 = 2982
;
N	EQU	2982
OPEN	MOVE.W	#N,SERPER.L	;Set 8 bits (bit 15 is clear)
	MOVE.W	#$0800,INTREQ.L	;Clear "receive buffer full" status bit
	RTS

;-----------------------------------------------------------------------
;Flush out any characters in the receive FIFO.
;
FLUSH	MOVE.L	D0,-(SP)	;Save D0

FL10	MOVE.W	SERDATR.L,D0	;Read status and data
	BTST	#14,D0		;Receive buffer full
	BEQ.S	FL90		;Branch if not -- exit

	MOVE.W	#$0800,INTREQ.L	;Clear "receive buffer full" status bit
	BRA.S	FL10		;Loop until all bytes flushed

FL90	MOVE.L	(SP)+,D0	;Restore D0
	RTS

;-----------------------------------------------------------------------
;Get a byte from the RS-232 port and return it in D0.
;
BYTEIN
BYIN10	MOVE.W	SERDATR.L,D0	;Read status and data
	BTST	#14,D0		;Receive buffer full?
	BEQ.S	BYIN10		;Branch if not -- loop

	MOVE.W	#$0800,INTREQ.L	;Clear "receive buffer full" status bit
	ANDI.L	#$000000FF,D0	;Return byte in D0
	RTS

;----------------------------------------------------------------------
;Routine to output the byte in D0 to an RS-232 port.
;
BYTEOUT	MOVEM.W	D0-D1,-(SP)	;Save low word of registers

BYO10	MOVE.W	SERDATR.L,D1	;Get serial port status
	BTST	#13,D1		;Test transmitter buffer empty
	BEQ.S	BYO10		;Branch if it is not empty

	ANDI.W	#$00FF,D0	;Add start and stop bits to the
	ORI.W	#$0100,D0	; data byte
	MOVE.W	D0,SERDAT.L	;Output data

	MOVEM.W	(SP)+,D0-D1	;Restore registers
	RTS


END	EQU	@ -1		;ADDRESS WHERE THIS HANDLER ENDS
	IF	END > $1000
	ERROR -- FILE IS TOO LONG
	ENDIF

;-----------------------------------------------------------------------
;HOOK THIS HANDLER INTO THE DEVICE HANDLER TABLE
;
	ORG	4 *DEVNUM +DEVTBL
	DC.L	SERHANA

	END
-----