version	=	1
revision=	0
	.pabs
	.phex	
	.loc	100h
;		Program: SETBAUD 
;  SETBAUD is a program used for setting baud rates
; on any of the four RS232 ports on the DSC 3/4.
; All commands are sent from the file command line.
;
;   Output from SETBAUD takes three forms.
;1.  If a user types "SETBAUD P n" where P is a port
; number from 0 to 3, and n is an acceptable baud 
; rate that the port is to be set to, only a carriage
; return is made followed by a warm boot.
;2.  If an error is made, the first bad command line
; character is pointed out (by an arrow), and a 
; summary of instructions is then displayed followed
; by a warm boot.
;3.  If only "SETBAUD" is typed in, a summary of 
; instructions (identical to those in the error 
; message) is displayed.  A warm boot follows.
;
;  Data is entered through the file command line.
; Length of file command line is expected at 80h.
; The command line itself begins at 81h. DSC 3/4
; baud-rate-change addresses are 30h,31h,32h.
; 32h is the address for both port 2 and port 3.
; To change a port to a specific baud rate the 
; following bytes must be successively sent to the
; ports baud-rate-change address.
;
; BAUD RATE		  BYTES
; ---------		---------
;   9600		 45h,13
;   4800		 45h,26
;   2400		 45h,52
;   1800		 45h,69
;   1200		 45h,104
;    600	         45h,208
;    300		 05h,52
;    110		 05h,142
;
; SETBAUD consists  basically of four sub-parts.
; (1) Data definitions and variable initialization.
; (2) Checking the command line length.
;      If the command line length is 0 or 1, ERROR
;      (a procedure that points out the error and
;      prints a help summary)
; (3) The first 5 non-blank command line characters
;     are read and interpreted one at a time.
;     Port then baud rate is searched for.
;     (A space is expected between the 1st & 2nd char-
;     acters. If at any point, an unacceptable entry 
;     is found, or an unexpected end of line encount
;     -ered, an immediate jump to ERROR is made. 
;     This lists out a summary of acceptable entries,
;     then warm boots.
; (4) Process the correct entry.
;     The selected port is now set to the selected
;     baud rate.
;				      D. Stein 9/19/80
;------------------
; (1) Data addressing and variable definition
	jmp	START	; begin execution at main body
WBOOT	=	0	; wboot address
BDOS	=	5	; console in/out entry point
port0	=	30h
port1	=	31h
port2	=	32h
port3	=	32h
cr	=	0Dh	; carriag ret
lf	=	0Ah	; line feed
port:	.byte	0	; selected port number
buffer:	.word	80h	; beginning of command line
chrcnt:	.byte	0	; command character counter
numchr:	.byte	0	; num of command characters read
;------------------
; Data for console output
errmsg:	.ascii	[cr][lf]'*** SYNTAX ERROR ***'
	.ascii	[cr][lf]'$'
infmsg:	.ascii	[cr][lf]'The general form of the SETBAUD command is:'
	.ascii	[cr][lf]
	.ascii	[cr][lf]'SETBAUD portnumber baudrate'
	.ascii	[cr][lf]
	.ascii	[cr][lf]'where  portnumber  = 0, 1, 2, or 3'
	.ascii	[cr][lf]'and    baudrate    = 9600'
	.ascii	[cr][lf]'                     4800'
	.ascii	[cr][lf]'                     2400'
	.ascii	[cr][lf]'                     1800'
	.ascii	[cr][lf]'                     1200'		
	.ascii	[cr][lf]'                      600'
	.ascii	[cr][lf]'                      300'
	.ascii	[cr][lf]'                      110'
	.ascii	[cr][lf]' '
	.ascii	[cr][lf]'For example, the command "SETBAUD 3 300" will'
	.ascii	[cr][lf]'assign port number 3 a baud rate of 300.'
	.ascii	[cr][lf]'NOTE: Ports 2 and 3 have interlocked baud rates.'
	.ascii	[cr][lf]'See the DSC 3/4 User Manual for details.'
crlf:	.ascii	[cr][lf]'$'

START:			; MAIN BODY
;------------------
; Set stack pointer
; Get the number of command line characters in numchr
; Jump to 'prtinf' if no command line
	lxi	sp,stack; set stack pointer
	lhld	buffer
	xchg
	ldax	D
	sta	numchr	; save number of com chrs
	cpi 	0
	jz	prtinf	; print help if no comm line
	cpi	1
	jz	prtinf	; print help if only carr ret
; If all tests are failed, a command line is assumed to be
;present. 
;----------------
; Call 'getchr' and fetch a non-blank character.
; Test for 0,1,2,3 (propter port selects).
; Jump to 'error' if unacceptable entry is found.
getPORT:
..1:	call	getchr
	cpi	' '	; is it a blank?
	jrz	..1	; loop until chr found
;
	cpi	'0'
	jz	getBAUD
	cpi	'1'
	jz	getBAUD
	cpi	'2'
	jz	getBAUD
	cpi	'3'
	jz	getBAUD
;
	jmp	error	; all tests failed
;------------------
; Store the port number in 'port'
; Eat the expected blanks between chrs 1 & 2.
; Jump to error if unacceptable entry found.
; Call 'getchr' to fetch the next non-blank character.
; Test for proper baud entry.
; Jump to error if unacceptable entry found.
GETBAUD:
	sui	'0'	; convert ascii to number
	sta	port	; store port number

..1:	call	getchr	; get next command chr
	cpi	' '	; it should be a blank
	jrz	..1	; loop if still blank
			; non-blank chr found

	cpi	'9'	; possible 9600 baud
	jrnz	..2
	call	getchr
	cpi	'6'
	jnz	error
	call	eat00	; eat the remaining '00'
	mvi	H,45h
	mvi	L,13	; 9600 baud code
	jmp	setBAUD
	
..2:	cpi	'4'	; possible 4800 baud
	jrnz	..3
	call	getchr
	cpi	'8'
	jnz	error
	call	eat00	; eat the remaining '00'
	mvi	H,45h
	mvi	L,26	; 4800 baud code
	jmp	setBAUD

..3:	cpi	'2'	; possible 2400 baud
	jrnz	..4
	call	getchr
	cpi	'4'
	jnz	error
	call	eat00	; eat the remaining '00'
	mvi	H,45h
	mvi	L,52	; 2400 baud code
	jmp	setBAUD

..4:	cpi	'1'	; possible 1800 or 1200 or 110
	jrnz	..7
	call	getchr
	cpi	'8'	; 1800 baud?
	jrnz	..5
	call	eat00
	mvi	H,45h
	mvi	L,69
	jmp	setBAUD	; Select 1800 baud

..5:	cpi	'2'	; 1200 baud?
	jrnz	..6
	call	eat00
	mvi	H,45h
	mvi	L,104
	jmp	setBAUD	; Select 1200 baud

..6:	cpi	'1'	; 110 baud?
	jrnz	..7
	call	getchr
	cpi	'0'
	mvi	H,05h
	mvi	L,142
	jmp	setBAUD	; Select 110 baud

..7:	cpi	'6'	; possible 600 baud
	jrnz	..8
	call	eat00
	mvi	H,05h
	mvi	L,208
	jmp	setBAUD	; Select 600 baud

..8:	cpi	'3'	; possible 300 baud
	jnz	error	; bad entry
	call	eat00
	mvi	H,05h
	mvi	L,52
	jmp	setBAUD	; Select 300 baud
setBAUD:
	lda	port
	cpi	0
	jz	setP0
	cpi	1
	jz	setP1
	cpi	2
	jz	setP2
	cpi	3
	jz	setP3
	jmp	error	; bad port number got through

setP0:	mov	A,H
	out	port0
	mov	A,L
	out	port0	; port 0 baud rate set
	jmp	WBOOT

setp1:	mov	A,H
	out	port1
	mov	A,L
	out	port1	; port 1 baud rate set
	jmp	WBOOT

setp2:	mov	A,H
	out	port2
	mov	A,L
	out	port2	; port 2 baud rate set
	jmp	WBOOT

setp3:	mov	A,H
	out	port3
	mov	A,L
	out	port3	; port 3 baud rate set
	jmp	WBOOT
;An error has been found.  Print an arrow underneath it
;and print a help listing.
ERROR:	
	lda	chrcnt	; get num of chrs read
	adi	8	; increment past 'SETBAUD '
	push	PSW	; save space-over count in reg A

arrow:	mvi	E,' '
	mvi	C,2
	call	BDOS	; print a space
        pop	PSW
	sbi	1
	cpi	0
	push	PSW
	jnz	arrow	; repeat until under error
	pop	PSW
	mvi	E,'^'
	mvi	C,2
	call	BDOS	; print arrow under error
	lxi	D,errmsg; print SYNTAX error
	mvi	C,9
	call	BDOS

prtinf:	lxi	D,infmsg
	mvi	C,9	; string console output function
	call	BDOS	; print instruction summary
	jmp	WBOOT	; wboot
;------------------
;		Subroutine: getchr
; Regs in: none     Regs out: A (next command chr)
; Increment buffer to next command character
; Test for reading past last character,if true  exit
; read next non-blank character, incrementing chrcnt
getchr:		
	lxi	H,buffer
	inr	M	; increment to next byte
	lxi	H,chrcnt
	inr	M	; increment chr counter

	lda	numchr
	adi	1
	cmp	M	; compare with chrcnt
	jz	error	; abort if last chr read

	lhld	buffer	; read the command char
	xchg
	ldax	D	; now its in reg A
	ret		; got the chr now go back

;---------------
;     		Subroutine: eat00
; Regs  in: none
; Regs out: none
; Eat a '00' from the command line
;
EAT00:
	call	getchr	; eat a '0'
	cpi	'0'
	jnz	error
	call	getchr	; eat a '0'
	cpi	'0'
	jnz	error
	ret

EXIT:	lxi	D,crlf	; line feed addr in HL
	mvi	C,9	; console output function
	call	BDOS	 
	jmp	WBOOT	; wboot
	.blkb	30	; room for stack
stack:			; stack location
	.end

