
	.Z80		;This source is for M80.COM!
	ORG	00100H

;
;	Equates for ASCII control chars
;

NUL	EQU	000H
SOH	EQU	001H
STX	EQU	002H
ETX	EQU	003H
EOT	EQU	004H
ENQ	EQU	005H
ACK	EQU	006H
BEL	EQU	007H
BS	EQU	008H
TAB	EQU	009H
LF	EQU	00AH
VT	EQU	00BH
FF	EQU	00CH
CR	EQU	00DH
SO	EQU	00EH
SI	EQU	00FH
DLE	EQU	010H
XON	EQU	011H
DC2	EQU	012H
XOFF	EQU	013H
DC4	EQU	014H
NAK	EQU	015H
SYN	EQU	016H
ETB	EQU	017H
CAN	EQU	018H
EM	EQU	019H
SUB	EQU	01AH
ESC	EQU	01BH
FS	EQU	01CH
GS	EQU	01DH
RS	EQU	01EH
US	EQU	01FH

;
;	External ref equates
;

IOPORT00H	EQU	00000H
BDOS	EQU	00005H
IOPORT06H	EQU	00006H

;
;	End of external equates
;


STARTUP:
	LD	DE,INIT_MSG	;Give intro screen
	CALL	PRINT_STRING

GET_BAUD_RATE:
	LD	DE,BAUD_PROMPT	;Ask for baudrate value
	CALL	PRINT_STRING
	CALL	GET_BDOS_KEYPRESS
	CP	CR		;RETURN only?
	JP	NZ,EDIT_BAUD_RATE ;No, look at keypress
	LD	A,'6'		;Yes, use default value

EDIT_BAUD_RATE:
	SUB	'0'		;Make into binary 0-9
	CP	NUL		;Legal choice?
	JP	C,GET_BAUD_RATE	;No, try again
	CP	LF
	JP	NC,GET_BAUD_RATE ;Likewise no, try again
	LD	(BAUD_RATE),A	;Yes, save it as binary value

GET_PARITY_CHOICE:
	LD	DE,PARITY_PROMPT ;Give him parity choices
	CALL	PRINT_STRING
	CALL	GET_BDOS_KEYPRESS ;Get his response
	CP	CR		;RETURN only?
	JP	NZ,EDIT_PARITY_VALUE ;No, edit it
	LD	A,'N'		;Yes, use default

EDIT_PARITY_VALUE:
	CP	'E'		;Even parity?
	JP	Z,PARITY_IS_LEGAL ;Yes, legal
	CP	'O'		;Odd parity?
	JP	Z,PARITY_IS_LEGAL ;Yes, legal
	CP	'N'		;No parity?
	JP	Z,PARITY_IS_LEGAL ;Yes, legal
	JP	GET_PARITY_CHOICE ;Not legal, so ask again

PARITY_IS_LEGAL:
	LD	(PARITY_CHOICE),A ;Save parity selection as ASCII

GET_DATABITS_CHOICE:
	LD	DE,DATABITS_PROMPT ;Give Databits prompt
	CALL	PRINT_STRING
	CALL	GET_BDOS_KEYPRESS ;Get response
	CP	CR		;RETURN only?
	JP	NZ,EDIT_DATABITS_VALUE ;No, use it
	LD	A,'8'		;Yes, use default

EDIT_DATABITS_VALUE:
	SUB	'0'		;Make into binary 0 thru 8
	CP	BEL		;Legal choice?
	JP	Z,DATABITS_ARE_LEGAL ;Yes, use it
	CP	BS
	JP	Z,DATABITS_ARE_LEGAL ;Yes, use it
	JP	GET_DATABITS_CHOICE ;No, try again

DATABITS_ARE_LEGAL:
	LD	(DATABITS),A	;Save binary databits value

; 
; Now convert baudrate choice to binary timer value
; 
	LD	A,(BAUD_RATE)
	CP	NUL		;19.2 Kbaud?
	JP	NZ,TRY_9600_BAUD ;No
	LD	A,SI		;Yes, use timer value for 19.2 Kbaud
	JP	DONE_EDITING_BAUD

TRY_9600_BAUD:
	CP	SOH		;9600 baud?
	JP	NZ,TRY_4800_BAUD ;No
	LD	A,SO		;Yes, use timer value for 9600 baud
	JP	DONE_EDITING_BAUD

TRY_4800_BAUD:
	CP	STX		;4800 baud?
	JP	NZ,TRY_2400_BAUD ;No
	LD	A,FF		;Yes, use timer value for 4800 baud
	JP	DONE_EDITING_BAUD

TRY_2400_BAUD:
	CP	ETX		;2400 baud?
	JP	NZ,TRY_1200_BAUD ;No
	LD	A,LF		;Yes, use timer value for 2400 baud
	JP	DONE_EDITING_BAUD

TRY_1200_BAUD:
	CP	EOT		;1200 baud?
	JP	NZ,TRY_600_BAUD	;No
	LD	A,BEL		;Yes, use value for 1200 baud
	JP	DONE_EDITING_BAUD

TRY_600_BAUD:
	CP	ENQ		;600 baud?
	JP	NZ,TRY_300_BAUD	;No
	LD	A,ACK		;Yes, use timer value for 600 baud
	JP	DONE_EDITING_BAUD

TRY_300_BAUD:
	CP	ACK		;300 baud?
	JP	NZ,ASSUME_110_BAUD
	LD	A,ENQ		;Yes, use timer value for 300 baud
	JP	DONE_EDITING_BAUD

ASSUME_110_BAUD:
	LD	A,STX		;Use timer value for 110 baud

DONE_EDITING_BAUD:
	LD	(BAUD_RATE),A	;Save final timer value for baudrate

; 
; Now convert parity selection to proper control bits
; 
	LD	A,(PARITY_CHOICE)
	CP	'E'		;Even parity?
	JP	NZ,TRY_ODD_PARITY ;No
	LD	A,ETX		;Yes, use bit pattern for Even parity
	JP	HAVE_GOOD_PARITY_BITMAP

TRY_ODD_PARITY:
	CP	'O'		;Odd parity?
	JP	NZ,ASSUME_NO_PARITY ;No
	LD	A,SOH		;Yes, use bit pattern for Odd parity
	JP	HAVE_GOOD_PARITY_BITMAP

ASSUME_NO_PARITY:
	LD	A,NUL		;Use bit pattern for No parity

HAVE_GOOD_PARITY_BITMAP:
	LD	(PARITY_CHOICE),A ;Save final SIO parity bitmap

; 
; Edit databits (binary 7 or 8) 
; to create proper SIO bit pattern
; 
	LD	A,(DATABITS)
	CP	BEL		;7 data bits?
	JP	Z,SET_7_DATABIT_PATTERN ;Yes
	LD	A,'`'		;No, use SIO WR5 pattern for 8 TX databits
	LD	(SIO_WR5_TX_BITS),A ;Save to be passed to SIO Write Reg 5
	LD	A,'@'+80H	;Format 8 Rx databits for SIO Write Reg 3
	LD	(SIO_WR3_RX_BITS),A
	JP	SEND_ALL_TO_SIO

SET_7_DATABIT_PATTERN:
	LD	A,' '		;Set bit pattern for 7 Tx bits
	LD	(SIO_WR5_TX_BITS),A
	LD	A,'@'		;Ditto for 7 Rx data bits
	LD	(SIO_WR3_RX_BITS),A

SEND_ALL_TO_SIO:

; 
; OK, so send everything to SIO
; 
	DI
	LD	A,CAN		;Reset SIO
	OUT	(IOPORT06H),A
	OUT	(IOPORT06H),A
	LD	A,SOH		;Select SIO Write Reg 1
	OUT	(IOPORT06H),A
	XOR	A		;No SIO interrupts
	OUT	(IOPORT06H),A
	LD	A,EOT		;Select SIO Write Reg 4
	OUT	(IOPORT06H),A
	LD	A,(PARITY_CHOICE) ;Get parity bit pattern
	ADD	A,'D'		;Add 'Clock x 16' and '1 stop bit' pattern
	OUT	(IOPORT06H),A
	LD	A,ETX		;Select SIO Write Reg 3
	OUT	(IOPORT06H),A
	LD	A,(SIO_WR3_RX_BITS)
	ADD	A,SOH		;Enable Receiver
	OUT	(IOPORT06H),A
	LD	A,ENQ		;Select SIO Write Reg 5
	OUT	(IOPORT06H),A
	LD	A,(SIO_WR5_TX_BITS)
	ADD	A,LF+80H	;Add 'DTR' and 'Tx Enable' and 'RTS'
	OUT	(IOPORT06H),A
	LD	A,'G'		;Reset Baud Rate generator
	OUT	(IOPORT00H),A
	LD	A,(BAUD_RATE)	;Set our Baud Rate timer value
	OUT	(IOPORT00H),A
	EI
	LD	DE,WRAPUP_MSG	;Tell him that we're done
	CALL	PRINT_STRING
	RET			;Back to CP/M

GET_BDOS_KEYPRESS:

; 
; Return next keypress as Uppercase char in A-reg
; 
	LD	C,SOH
	CALL	BDOS		;Use BDOS to get next keypress
	CP	'`'		;Is it lowercase char?
	RET	C		;No, return it as-is
	SUB	' '		;Yes, convert to uppercase
	RET

PRINT_STRING:

; 
; Print $-terminated string at (DE)
; 
	LD	C,TAB
	JP	BDOS

INIT_MSG:
	DB	SUB,"INIT 1.0 for Xerox 820",CR,LF,LF,LF,CR,LF

	DB	"Baud Rates:",CR,LF,"19200 = 0",CR,LF,"9600  ="

	DB	" 1",CR,LF,"4800  = 2",CR,LF,"2400  = 3",CR,LF

	DB	"1200  = 4",CR,LF," 600  = 5",CR,LF," 300  = 6"

	DB	CR,LF," 110  = 7",CR,LF,"$"


BAUD_PROMPT:
	DB	CR,LF,"Select baud rate           (1-9): 6",BS

	DB	"$"


PARITY_PROMPT:
	DB	CR,LF,"Select parity  (Odd, Even, None): N",BS

	DB	"$"


DATABITS_PROMPT:
	DB	CR,LF,"Select word length      (7 or 8): 8",BS

	DB	"$"


WRAPUP_MSG:
	DB	CR,LF,"Communications port set.$"


BAUD_RATE:
	DB	NUL


DATABITS:
	DB	NUL


PARITY_CHOICE:
	DB	NUL


SIO_WR5_TX_BITS:
	DB	NUL


SIO_WR3_RX_BITS:
	DB	NUL,NUL,NUL,NUL,NUL
