; Baud rate change
;
;
	CPU 8080        ; Specify architecture
	PAGE 0
;
; Equates for I/O mapped 8250 serial port
;
SERIAL0 equ 0		;base I/O address of first 8250 UART
SERIAL1 equ 8       ;base I/O address of second 8250 UART
RXR		equ 0		;Receiver buffer register
TXR		equ 0		;Transmitter buffer register
IER		equ 1		;Interrupt enable register
LCR		equ 3		;Line control register
MCR		equ 4		;Modem control register
LSR		equ 5		;Line status register
;
; Define monitor serial port
;
SER0_STATUS	equ SERIAL0+LSR
SER0_DATA	equ SERIAL0+RXR
SER1_STATUS	equ SERIAL1+LSR
SER1_DATA	equ SERIAL1+RXR
SER_RXRDY	equ 1	;Mask for rx buffer full
SER_TXRDY	equ 32	;Mask for tx buffer empty
;
;
;BIOS Routines
;
wboot   equ   0f403h   ;warm start
const   equ   0f406h   ;console status
conin   equ   0f409h   ;console character in
conout  equ   0f40ch   ;console character out
seldsk  equ   0f41bh   ;select disk
settrk  equ   0f41eh   ;set track number
setsec  equ   0f421h   ;set sector number
setdma  equ   0f424h   ;set dma address
read    equ   0f427h   ;read disk
write   equ   0f42ah   ;write disk
;
;
;BDOS Variables
;
tailcnt equ 80h        ;Length of command line options
tailstr equ 81h        ;null terminated command line options
;
;
    org 100h
;
;
start:
   lda tailcnt         ;any command line options?
   ora a               ;set flags
   jnz st002           ;get baud parameter and set it
st001:
   lxi d, msg_help     ;print help message
   call print          ;print current drive assignments
   ret                 ;return to CCP
;
;
;
;  Initialize S16450 UART
;
;  access baud generator, no parity, 1 stop bit, 8 data bits
;
st002:
   call getint         ;integer from parameter list
   mov a, c            ;move return value into A
   cpi 0ffh            ;invalid?
   jz st001            ;if it is print help message and exit
   cpi 0bh             ;greater than 10?
   jnc st001           ;if it is print help and exit
st003:
   mov a, c            ;get first digit
   lxi h, baud_rates   ;point to baud rate table
st004:
   ora a               ;set flags
   jz st005            ;set baud rate
   dcr a               ;count down
   inx h               ;next table value
   inx h
   jmp st004           ;try again
;
;  access baud generator, no parity, 1 stop bit, 8 data bits
;
st005:
   mvi a, 83h
   out SERIAL0+LCR
;
;  set baud rate
;
   mov a, m             ;get baud rate LSB
   out SERIAL0+RXR		;divider LSB
   inx h                ;point to MSB
   mov a, m             ;get baud rate MSB
   out SERIAL0+RXR+1	;divider MSB
;
;  access data registers, no parity, 1 stop bits, 8 data bits
;
   mvi a, 3
   out SERIAL0+LCR
;
;  no loopback, OUT2 on, OUT1 on, RTS on, DTR (LED) on
;
   mvi a, 0fH
   out SERIAL0+MCR
;
;  disable all interrupts: modem, receive error, transmit, and receive
;
   xra a
   out SERIAL0+IER
;
   ret
;
;
;Get one or two digit integer from parameter string (0-99)
;
getint:
   lxi h, tailstr      ;point to option string
   mvi c, 0ffh         ;start with invalid character
   call getint03       ;get first digit
   mov a, c            ;put it in A
   cpi 0ffh            ;invalid?
   rz                  ;exit if invalid
   sui '0'             ;convert first digit to bin
   mov b, a            ;save first digit in B
   mvi c, 0ffh         ;start with invalid character
   call getint03       ;get second digit
   mov a, c            ;put second digit in A
   cpi 0ffh            ;invalid?
   jnz getint01        ;convert second digit, multiply first by 10
   mov c, b            ;otherwise return first digit in C
   ret
getint01:
   sui '0'             ;convert second digit to hex
   mov c, a            ;move second digit into C
   mov a, b            ;get first digit
   mvi d, 10           ;multiplier
   dcr d               ;decrement to start
getint02:
   add b               ;multiply by 10
   dcr d               ;count down
   jnz getint02
   add c               ;add in second digit
   mov c, a            ;put final int value in C
   ret   
;
getint03:
   mov a, m            ;get first character
   inx h               ;point to next character
   cpi 0               ;end of parameter string?
   rz                  ;return if end of string
   cpi '0'             ;is it a character below '0'?
   jc getint03         ;if so try next param character
   cpi ':'             ;is it a character greater than '9'?
   mov c, a            ;put it in C ready for return
   rc                  ;return if 0-9
   jmp getint03        ;do again
;
;
; Print null terminated string
;
print:               ;print a message on the console
	ldax d           ;get char pointed to by D into A
	cpi 0            ;end of string?
	jz pend          ;exit if end of string
	mov c, a         ;move shar into C for console out
	call conout      ;print it
	inx d            ;point to next character
	jmp print        ;repeat
pend:
	ret              ;and exit

;
;  baud rate table
;
baud_rates:
baud_300    dw  384
baud_600    dw  192
baud_1200   dw  96
baud_2400   dw  48
baud_4800   dw  24
baud_9600   dw  12
baud_14400  dw  8
baud_19200  dw  6
baud_38400  dw  3
baud_57600  dw  2
baud_115200 dw  1
;
;
msg_help:
   dw 0d0ah
   db 'BAUD v1.0 - Set console port baud rate'
   dw 0d0ah
   dw 0d0ah
   db 'Usage: BAUD <RATE>'
   dw 0d0ah
   dw 0d0ah
   db '0 = 300     5 = 9600     10 = 115200'
   dw 0d0ah
   db '1 = 600     6 = 14400'
   dw 0d0ah
   db '2 = 1200    7 = 19200'
   dw 0d0ah
   db '3 = 2400    8 = 38400'
   dw 0d0ah
   db '4 = 4800    9 = 57600'
   dw 0d0ah
   db 0
;
;
   end