;COM2/DVR - LDOS 6.2 - 01/03/84 - Mod II
;
	TITLE	'<RS-232 driver for SETCOM>'
;*=*=*
;       Change Log
;
; 02/23/83 - Changed wakeup vectoring to return:
;               C = character, if available
;               A = STATUS port image
;               Z = character received
; 05/20/83 - relocate to HIGH$ if no room in driver area
; 05/25/83 - fixed SFLAG calculation to pt to SFLAG
;
;*=*=*
INTVC$	EQU	03EH		;interrupt table
RSSERVA	EQU	INTVC$+4	;receive serviceA address
RSSERVB	EQU	INTVC$+6	;receive serviceB address
$CTC0	EQU	0F0H		;counter-timer-controller
$CTC1	EQU	0F1H
$CTC2	EQU	0F2H
$CTCX	EQU	000H		;dummy for channel B
$SIOA	EQU	0F6H		;SIOA base port
$SIOB	EQU	0F7H		;SIOB base port
;
ETX	EQU	03
LF	EQU	10
CR	EQU	13
*GET	COPYCOM:3
*GET	SVCMAC:3
;
	SUBTTL	'<Driver Initialization Routines>'
;
	ORG	2400H
BEGIN	PUSH	DE		;Save DCT address
	POP	IX		;  in index reg
	LD	(CLDCB),DE	;Stuff prologue
;
;	check if user specified port address
;
CKSTR	LD	A,(HL)		;get input
	INC	HL		;bump pointer
	CP	' '		;nil?
	JR	Z,CKSTR		;yes, ignore them
	CP	0DH		;carriage return?
	JR	Z,USENAME	;port from name
	CP	'('		;param start?
	JP	NZ,PRMERR	;param error if not!
	DEC	HL		;correct pointer
	LD	DE,PRMTBL	;parameter table
	@@PARAM			;evaluate params
	JP	NZ,PRMERR	;go if error!
	LD	A,(PRESP)	;get response byte
	OR	A		;anything?
	JR	Z,USENAME	;nope, use name for port
	LD	DE,(PDATA)	;get input
	INC	D		;check msb
	DEC	D		;D<>0?
	JP	NZ,PRMERR	;go if >256!
	LD	A,E		;get lsb
	OR	A		;0?
	JP	Z,PRMERR	;port=0?
	CP	3		;1/2?
	JP	NC,PRMERR	;go if wrong
	JR	BEG0		;continue
;
;	use device name to specify port
;
USENAME	LD	A,(IX+7)	;get last char name
	CP	' '		;last char blank?
	JR	NZ,BEG0		;go if not
	LD	A,(IX+6)	;else fetch first char
BEG0	AND	1		;use char as address
;
;	fetch hardware address' for SIO ports
;
	LD	BC,RSSERVA	;interrupt vector address
	LD	DE,$CTC0<8+$CTC1	;CTC ports
	LD	HL,'L'<8+$SIOA	;ID + base port
	JR	NZ,BEG1		;go if one
;
	LD	BC,RSSERVB	;interrupt vector
	LD	DE,$CTC2<8+$CTCX	;CTC ports
	LD	HL,'M'<8+$SIOB	;ID + base port
;
BEG1	LD	(INTVC),BC	;save vector
	LD	A,H		;get ascii ID
	LD	(MODNAME),A	;save module name postfix
	LD	(MODNAM2),A	;save into prefix
	LD	A,L		;get base port
	LD	(BASPORT),A	;save into data table
	LD	(CTCPORT),DE	;save CTC ports
;
	@@DSPLY	HELLO$		;Welcome the user
;*=*=*
;       Check if entry from SET command
;*=*=*
	@@FLAGS
	BIT	3,(IY+'C'-'A')	;System request?
	JP	Z,VIASET	;nope, abort
;*=*=*
;       Grab system dependent vectors
;*=*=*
	PUSH	IY		;pass @FLAGS to DE
	POP	DE		;DE => @FLAGS
	LD	HL,'K'-'A'	;Kflag$ offset
	ADD	HL,DE		;HL => KFLAG$
	LD	(KFLAG),HL	;save for quick test
	LD	HL,'S'-'A'	;SFLAG$ offset
	ADD	HL,DE		;HL => SFLAG$
	LD	(SFLAG),HL	;save for quick test
;*=*=*
;       Move @ICNFG vector into driver
;*=*=*
	LD	A,(IY+28)	;Get opcode prefix
	LD	(LINK),A	;save link prefix
	LD	L,(IY+29)	;Get address
	LD	H,(IY+30)
	LD	(LINK+1),HL	;save link address
;*=*=*
;       Check if driver alread resident
;*=*=*
	LD	DE,CL$		;Check if filter is
	@@GTMOD			;  already resident
	EX	DE,HL		;Put DCB ptr to HL
	JR	NZ,NOTRES	;GM if not
;*=*=*
;       Make sure that the new DCB is same as the old
;*=*=*
	LD	C,(HL)		;P/u DCB pointer LSB
	INC	HL
	LD	B,(HL)		;P/u DCB pointer MSB
	LD	HL,6		;Get old DCB name &
	ADD	HL,BC		;  stuff into error
	LD	A,(HL)		;  message in case
	INC	HL		;  a different DCB
	LD	H,(HL)		;  is referenced
	LD	L,A
	LD	(DCBNAM$),HL	;Stuff message with spec
	LD	HL,(CLDCB)	;P/u DCB existing DCB
	OR	A		;  pointer
	SBC	HL,BC		;Same DCB pointer?
	JP	NZ,DCBERR	;Can't install if diff
	JP	ISRES		;else driver resident
;
;	install new driver, attempt to place low
;
NOTRES	LD	DE,'IK'		;*KI device
	@@GTDCB			;Locate low memory ptr
	JP	NZ,IOERR	;go if not found
;
;	locate current pointer to low modules
;
	DEC	HL		;right before keyboard
	LD	D,(HL)		;load MSB
	DEC	HL		;dec pointer
	LD	E,(HL)		;load LSB
	LD	(LCPTR+1),HL	;Save ptr for later
	LD	HL,CLEND-CLDVR-1 ;driver length
	ADD	HL,DE		;Start + driver length
	LD	(SVEND+1),HL	;save new low pointer
	LD	BC,1300H	;Max addr + 1
	XOR	A		;clear carry
	SBC	HL,BC		;test if room to add low
	JR	C,PUTLOW	;yes, go!
;*=*=*
;       check if high memory available
;*=*=*
	BIT	0,(IY+'C'-'A')	;Memory frozen?
	JP	NZ,NOROOM	;Can't fit in low core!
	LD	HL,0		;init for fetch
	LD	B,L		;Get HIGH$
	@@HIGH$
	LD	(SVEND+1),HL	;Top of driver
	OR	A		;clear carry
	LD	BC,CLEND-CLDVR	;Minus length
	SBC	HL,BC		;new high memory
	LD	B,0		;init high$
	PUSH	HL		;save
	@@HIGH$			;Is new HIGH$
	POP	HL		;restore new location
	INC	HL		;Plus one is start
	LD	(HCPTR),HL	;Save it
	LD	HL,HCPTR	;And point to it
	LD	(LCPTR+1),HL
	LD	A,0FFH		;flag himem used
	LD	(HGHFLG),A	;save flag
;*=*=*
;       Relocate internal references in driver
;*=*=*
PUTLOW	PUSH	IX		;save driver pointer
	LD	IX,RELTAB	;Point to relocation tbl
SVEND	LD	HL,$-$		;Find distance to move
	LD	(CLDVR+2),HL	;Set last byte used
	LD	DE,CLEND-1	;end -1
	OR	A		;Clear carry flag
	SBC	HL,DE		;adjust address
	LD	B,H		;Move to BC
	LD	C,L
;
RLOOP	LD	L,(IX)		;Get address to change
	LD	H,(IX+1)
	LD	A,H		;check for term
	OR	L		;=0000?
	JR	Z,RELEND	;yes, go!
	LD	A,(HL)		;get LSB address
	ADD	A,C		;add lsb offset
	LD	(HL),A		;update
	INC	HL		;bump table
	LD	A,(HL)		;get MSB address
	ADC	A,B		;add msb offset
	LD	(HL),A		;update
	INC	IX		;bump relo table
	INC	IX		;2 bytes each
	JR	RLOOP		;go next value
;
RELEND	POP	IX		;Restore DCB
;*=*=*
;       Set up @ICNFG
;*=*=*
	LD	HL,INIT		;Get (relocated)
RX01	EQU	$-2
	LD	(IY+29),L	;  init address
	LD	(IY+30),H
	LD	A,0C3H		;Get JP instruction
	LD	(IY+28),A
;*=*=*
;       Move driver
;*=*=*
LCPTR	LD	HL,$-$		;Low core pointer
	LD	E,(HL)
	INC	HL
	LD	D,(HL)
	PUSH	DE		;Save start
	LD	HL,CLDVR
	LD	BC,CLEND-CLDVR	;Calc driver length
	LDIR			;move to new address
	LD	HL,(LCPTR+1)
	LD	(HL),E
	INC	HL
	LD	(HL),D
;*=*=*
;       Initialize the driver
;*=*=*
	PUSH	IX		;save
	CALL	INIT		;init device
RX02	EQU	$-2
	POP	IX		;restore
;
	POP	DE		;Pop filter start
;
ISRES	LD	HL,CLACT$	;Advise COM/DVR installed
	LD	(IX),7		;Init DCB type to "C/P/G"
	LD	(IX+1),E	;  & stuff the driver
	LD	(IX+2),D	;  address
	@@LOGOT			;display message
	LD	A,$-$		;did it use high memory?
HGHFLG	EQU	$-1
	OR	A		;nz if high
	JR	Z,NTHGH		;go if went low
	LD	HL,HMEM$	;message
	@@LOGOT			;display
NTHGH	LD	HL,0		;clear error code
	RET			;exit
;*=*=*
;       Error exits
;*=*=*
PRMERR	LD	HL,PRMERR$	;'parameter error'
	DB	0DDH
VIASET	LD	HL,VIASET$	;'must install via SET'
	DB	0DDH
DCBERR	LD	HL,DCBERR$	;'driver already attached
	DB	0DDH
NOROOM	LD	HL,NOROOM$	;'no memory available'
	@@LOGOT
	LD	HL,-1		;set error exit
	RET			;terminate
IOERR	LD	L,A		;pass error code
	LD	H,0		;init to system error
	OR	0C0H		;set return + short
	LD	C,A		;pass error code
	@@ERROR			;display and return
	RET			;now exit
;*=*=*
;       Messages & Data tables
;*=*=*
HCPTR	DW	0		;Save start if to HIGH$
CL$	DB	'$C'		;device name
MODNAME	DB	'L',ETX		;device modifier
;
HELLO$	DB	'COM'
*GET	CLIENT:3
;
NOROOM$	DB	'No memory space available',CR
DCBERR$	DB	'Driver already attached to *xx',CR
DCBNAM$	EQU	$-3
CLACT$	DB	'COM driver is now resident',CR
PRMERR$	DB	'Parameter error',CR
VIASET$	DB	'Must install via SET',CR
HMEM$	DB	LF,'Note: '
	DB	'driver installed in high memory',CR
;
;	parameter table
;
PRMTBL	DB	80H		;extended params
	DB	4+90H		;length + numeric
	DM	'PORT'
PRESP	DB	0		;response byte
	DW	PDATA		;data address
PDATA	DW	0		;response data here
;
;	relocation table
;
RELTAB	DW	RX01,RX02,RX03,RX04,RX05,RX06,RX07
	DW	RX08,RX09,RX10,RX11,RX12,RX13,RX14
	DW	RX15,RX16,RX17,RX18,RX19,RX20,RX21
	DW	RX22,RX23,RX24,RX25,0
;*=*=*
;       Actual driver
;*=*=*
CLDVR	EQU	$
	JR	CLBGN		;Branch around linkage
	DW	CLEND		;Last byte used
	DB	3,'$CL'
MODNAM2	EQU	$-1
CLDCB	DW	$-$
	DW	0
CLDATA$	EQU	$
MSMASK	EQU	$-CLDATA$
	DB	0
;*=*=*
;       UART control port image
;*=*=*
;       bit 7: 1 = even parity, 0 = odd parity
;       bits 6,5: word length <00=5, 10=6, 01=7, 11=8>
;       bit 4: 1 = 2 stop bits, 0 = 1 stop bit
;       bit 3: 1 = disable parity, 0 = enable parity
;       bit 2: 1 = enable transmit data, 0 = break
;       bit 1: 0 = Data Terminal Ready
;       bit 0: 0 = Request to Send
;*=*=*
UCIMAGE	EQU	$-CLDATA$
	DB	10100100B
BAUD	EQU	$-CLDATA$
	DB	55H		;Init 300 baud
LOGBRK	EQU	$-CLDATA$
	DB	3		;Default is Control-C
CLFLG	EQU	$-CLDATA$
	DB	0		;Init nG char in buf
BPORT	EQU	$-CLDATA$
	DB	0		;base I/O port
BASPORT	EQU	$-1
CTC2	EQU	$-CLDATA$	;CTC 1
	DB	0
CTC1	EQU	$-CLDATA$	;CTC 2
	DB	0
CTCPORT	EQU	$-2
CLBUF	EQU	$-CLDATA$
	DB	0		;One-char buffer
R5MASK	EQU	$-CLDATA$	;register 5 mask
	DB	0
WORD	EQU	$-CLDATA$	;word length mask
	DB	-1		;8 bits
;*=*=*
;       CL initialization routine. Set up DR interrupt
;       vector & initialize the hardware
;*=*=*
INIT	LD	HL,RECVINT	;receive address
RX03	EQU	$-2
	LD	($-$),HL	;pass to interrupt vector
INTVC	EQU	$-2
	LD	A,(INTVC$)	;LSB SIOA interrupt
	LD	(ITABLE+11),A	;save address
RX04	EQU	$-2
	ADD	A,16		;offset to SIOB interrupt
	LD	(ITABLE+18),A	;save address
RX05	EQU	$-2
	CALL	CTL2
RX06	EQU	$-2
LINK	RET			;Link back
	DB	0,0
;
CLBGN	LD	IX,CLDATA$	;Point tM data area
RX07	EQU	$-2
	JP	C,RECV		;Go if @GET request
RX08	EQU	$-2
	JP	Z,SEND		;Go if @PUT request
RX09	EQU	$-2
	LD	A,C		;P/U @CTL byte
	OR	A		;@CTL 00 ?
	JP	Z,CANISND	;Go if so
RX10	EQU	$-2
	DEC	A		;@CTL 01 ?
	JP	Z,CTL1		;Go if so
RX11	EQU	$-2
	DEC	A		;Was it CTL-2 "INIT UART"
	JR	Z,CTL2		;Go if so
	CP	4-2		;Wakeup feature?
	JP	Z,CTL4		;Go if wakeup feature
RX12	EQU	$-2
	XOR	A
	RET
;*=*=*
;       Initialize the UART & BRG
;*=*=*
CTL2	PUSH	IY		;save
	LD	IY,ITABLE	;init table
RX13	EQU	$-2
	LD	IX,CLDATA$	;start data table
RX14	EQU	$-2
;
;	init SIO/CTC port addresses
;
	LD	A,(IX+BPORT)	;get base port
	LD	(IY+2),A	;save into table
	LD	A,(IX+CTC1)	;get CTC 1 port
	LD	(IY+15),A	;save into table
	LD	A,(IX+CTC2)	;get CTC 2 port
	LD	(IY+20),A	;save into table
;
;	init baud rate configuration
;
	LD	A,(IX+BAUD)	;get baud rate
	AND	0FH		;low 4 bits
	ADD	A,A		;2 byte table
	LD	HL,BAUDTBL	;baud rate table
RX15	EQU	$-2
	ADD	A,L		;add to lsb
	LD	L,A		;update lsb
	JR	NC,$+3		;go if no overflow
	INC	H		;bump msb
	LD	A,(HL)		;get counter select
	LD	(IY+16),A	;RX baud
	LD	(IY+21),A	;TX baud
	INC	HL		;bump pointer
	LD	A,(HL)		;get count
	LD	(IY+17),A	;RX count
	LD	(IY+22),A	;TX count
;
;	init word length
;
	LD	A,(IX+UCIMAGE)	;get image
	RLCA			;align bits 6,5 => 1,0
	RLCA
	RLCA
	AND	3		;low 2 bits
	JP	PE,$+5		;go if 5 or 8
RX16	EQU	$-2
	XOR	3		;change 6/7 => 7/6
	ADD	A,5		;add offset
	LD	B,A		;init loop
	XOR	A		;init word byte
SIO1	SCF			;set bit
	RLA			;move into accum
	DJNZ	SIO1		;go for word length
	LD	(IX+WORD),A	;save word length mask
	LD	A,(IX+UCIMAGE)	;get config byte
	AND	60H		;bits 6/5 only
	OR	8		;TX enable
	BIT	1,(IX+UCIMAGE)	;DTR?
	JR	NZ,$+4		;go if not
	OR	80H		;enable DTR
	BIT	0,(IX+UCIMAGE)	;RTS?
	JR	NZ,$+4		;go if not
	OR	02H		;enable RTS
	LD	(IY+9),A	;DTR,TX enable,RTS,length
	LD	(IX+R5MASK),A	;save for CTL calls
	RLCA			;align for RX
	OR	01H		;RX enable
	LD	(IY+7),A	;save into RX table
;
;	init parity
;
	LD	A,40H		;parity mask
	BIT	3,(IX+UCIMAGE)	;enabled?
	JR	NZ,SIO2		;go if not
	SET	0,A		;set ODD
	BIT	7,(IX+UCIMAGE)	;odd?
	JR	Z,SIO2		;go if yes
	SET	1,A		;set EVEN
SIO2	SET	2,A		;set 1 stop bit
	BIT	4,(IX+UCIMAGE)	;1/2?
	JR	Z,$+4		;go if one
	SET	3,A		;set 2 stop bits
	LD	(IY+5),A	;update table
;
;	send compiled init data to SIO
;
	LD	HL,ITABLE	;get init table
RX17	EQU	$-2
	CALL	SNDDAT		;send data to chip
RX18	EQU	$-2
	POP	IY		;restore
	XOR	A		;set no error
	RET
;
;	init wake up feature
;
CTL4	PUSH	IY		;Transfer pointer to HL
	POP	HL
	LD	A,H		;Test if set or reset
	OR	L
	LD	A,0C9H		;Init disable wakeup
	EX	DE,HL		;Switch new value to DE
	LD	HL,(WAKEADR+1)	;  & p/u old in HL
RX19	EQU	$-2
	JR	Z,SETWAK
	LD	A,0C3H
SETWAK	LD	(WAKEADR),A
RX20	EQU	$-2
	LD	(WAKEADR+1),DE
RX21	EQU	$-2
	PUSH	HL		;Transfer pointer to IY
	POP	IY
	RET
;*=*=*
;       Check if ready to send
;*=*=*
CANISND	LD	C,(IX+BPORT)	;get SIO base port
	LD	A,10H		;reset
	OUT	(C),A		;reset ext
	IN	A,(C)		;RR0 status
	CPL			;reverse status
	ADD	A,A		;move bits 3/5 to 5/7
	ADD	A,A
	AND	10110000B	;keep DCD/CTS only
	BIT	4,A		;TX buffer empty?
	RET	NZ		;go if not
	LD	C,A		;save status
	XOR	(IX+MSMASK)	;mask for flip
	RRA			;align to low
	RRA
	RRA
	RRA
	AND	(IX+MSMASK)	;mask for which to check
	AND	0FH		;keep low 4 only
	LD	A,C		;get back original status
	RET			;done
;*=*=*
;       Send character
;*=*=*
SEND	PUSH	BC		;save char
	LD	A,C		;get char
	AND	(IX+WORD)	;strip bits
	LD	B,A		;save it
SNDWT	CALL	CANISND		;Poll
RX22	EQU	$-2
	JR	NZ,SNDWT	; until ready
	CALL	RESBRK		;reset break
RX25	EQU	$-2
	LD	C,(IX+BPORT)	;get base port
	DEC	C		;point to data port
	DEC	C
	OUT	(C),B		;send data byte
	POP	BC		;restore
	LD	A,C		;restore char
	CP	A		;set Z for OK
	RET			;  unchanged for return
;*=*=*
;       Receive character - Get from buffer if available
;*=*=*
RECV	BIT	7,(IX+CLFLG)	;char avail?
	JR	NZ,HRECV	;have a char, go!
	OR	-1		;set NZ
	CPL			;but return 0
	RET			;return NO char
HRECV	LD	A,(IX+CLBUF)	;Get the char
	RES	7,(IX+CLFLG)	;set char fetched
	CP	A		;Set Z-flag & exit
	RET
;*=*=*
;       Break request
;*=*=*
CTL1	LD	C,(IX+BPORT)	;get base port
	LD	A,5		;R5
	DI			;disable for send
	OUT	(C),A		;select register
	LD	A,(IX+R5MASK)	;get mask
	OR	10H		;set break bit
	OUT	(C),A		;send break
	EI
	SET	6,(IX+CLFLG)	;show break sent
	RET			;With Z-flag
;
;	reset break
;
RESBRK	BIT	6,(IX+CLFLG)	;break send prior?
	RET	Z		;nope, go!
;
	LD	C,(IX+BPORT)	;get base port
	LD	A,5		;R5
	DI			;disable for select
	OUT	(C),A		;select R5
	LD	A,(IX+R5MASK)	;get mask
	OUT	(C),A		;terminate break
	EI			;done
	RES	6,(IX+CLFLG)	;reset break cleared
	RET			;return
;*=*=*
;       Data received interrupt handler
;*=*=*
RECVINT	LD	IX,CLDATA$
RX23	EQU	$-2
	LD	C,(IX+BPORT)	;get base port
	IN	B,(C)		;read R0
	LD	A,10H		;channel reset
	OUT	(C),A		;reset
	BIT	7,B		;break here?
	JR	Z,RECVI1	;go if not
	BIT	5,(IX+CLFLG)	;was break sent?
	JR	NZ,RECVI2	;go if yes
	SET	5,(IX+CLFLG)	;else show as sent
	LD	A,(IX+LOGBRK)	;convert for break detect
	JR	RECVI3		;else show break
RECVI1	RES	5,(IX+CLFLG)	;terminate break bit
RECVI2	BIT	0,B		;RX char available?
	RET	Z		;nope, go!
	DEC	C		;point to data port
	DEC	C
	IN	A,(C)		;fetch char
	AND	(IX+WORD)	;strip bits
RECVI3	LD	B,A		;pass to B
	CALL	CKINP		;check input
RX24	EQU	$-2
WAKEADR	RET			;Wakeup if enabled
	DW	0		;Space for address
;*=*=*
;       Routine to check on a received character
;*=*=*
CKINP	LD	C,A		;Save tempy in reg-C
;*=*=*
;       BREAK & PAUSE & ENTER handler routine
;*=*=*
	LD	HL,$-$		;KFLAG$
KFLAG	EQU	$-2
	CP	CR		;ENTER char received?
	JR	NZ,PAWSCK	;Go if not
	SET	2,(HL)		;Set ENTER bit
	JR	RECVEX
;
PAWSCK	CP	60H		;Pause char received?
	JR	NZ,BRKCHK	;Go if not
	SET	1,(HL)		;Set pause bit
	JR	RECVEX
;
BRKCHK	LD	A,(IX+LOGBRK)	;P/u BREAK character
	OR	A		; check if NO break
	JR	Z,RECVEX	; go if so
;
	CP	C		;Break char received?
	JR	NZ,RECVEX	;go if not
;*=*=*
;       A BREAK was received, ck system's BREAK disable
;*=*=*
BRKRECD	LD	A,($-$)		;Check if break key
SFLAG	EQU	$-2
	AND	10H		;  is disabled
	LD	A,0		;Return NZ & A=0 if
	RET	NZ		;  the BREAK is disabled
	SET	0,(HL)		;Else set break bit
	LD	C,80H		;  & reset BREAK code
RECVEX	LD	(IX+CLBUF),C	;Put char into 1-char buf
	SET	7,(IX+CLFLG)	;show char avail
	XOR	A		;Set Z flag
	RET
;
;	issue init data to SIO/CTC chips
;
SNDDAT	LD	E,(HL)		;get table count
	INC	HL		;point to data
;
SNDDAT1	LD	B,(HL)		;get data count
	INC	HL		;bump
	LD	C,(HL)		;get port#
	INC	C		;check if nil
	DEC	C
	RET	Z		;yes, ignore CTC2!
	INC	HL		;else point to config dat
	OTIR			;send to port
	DEC	E		;less table count
	JR	NZ,SNDDAT1	;go for count
	RET			;else done!
;
;	init data for SIO ports
;
ITABLE	DB	3		;# tables
;
	DB	11		;# entries this table
	DB	$SIOA		;SIO base port address
	DB	018H		;channel reset
	DB	004H		;R4
	DB	044H		;X16, stop=1
	DB	003H		;R3
	DB	0E1H		;word=8, RX
	DB	005H		;R5
	DB	0EAH		;DTR,W=8,TX,RTS
	DB	002H		;R2
	DB	0		;offset interrupt
	DB	1+10H		;reset int, R1
	DB	01DH		;int on all RX chars
;
;	CTC #1 setup
;
	DB	3		;# entries this table
	DB	$CTC0		;CTC0 base port address
	DB	007H		;count, reset
	DB	034H		;default 300 baud
	DB	0		;offset interrupt vector
;
;	CTC #2 setup
;
	DB	2		;# entries
	DB	$CTC1		;CTC1 base port
	DB	007H		;count, reset
	DB	034H		;default 300 baud
;
;	baud rate lookup table
;
BAUDTBL	DW	0FE07H		;50
	DW	0D007H		;75
	DW	08E07H		;110
	DW	07407H		;135
	DW	06807H		;150
	DW	03407H		;300
	DW	01A07H		;600
	DW	00D07H		;1200
	DW	04547H		;1800
	DW	03E47H		;2000
	DW	03447H		;2400
	DW	02347H		;3600
	DW	01A47H		;4800
	DW	01147H		;7200
	DW	00D47H		;9600
	DW	00647H		;19200
CLEND	EQU	$
;
	END	BEGIN
