mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
106 lines
3.1 KiB
106 lines
3.1 KiB
;
|
|
;=======================================================================
|
|
; HDIAG UART Driver
|
|
;=======================================================================
|
|
;
|
|
; Assumes the UART conventions for SBC/MBC/Zeta, base port at $68.
|
|
; Assuming a UART clock frequency of 1.8432 MHz, the baud rate
|
|
; will be 38400.
|
|
;
|
|
uart_iob .equ $68
|
|
uart_osc .equ 1843200
|
|
uart_baudrate .equ 38400
|
|
uart_divisor .equ uart_osc / uart_baudrate / 16
|
|
;
|
|
uart_rbr .equ uart_iob + 0 ; dlab=0: rcvr buffer reg (read only)
|
|
uart_thr .equ uart_iob + 0 ; dlab=0: xmit holding reg (write only)
|
|
uart_ier .equ uart_iob + 1 ; dlab=0: int enable reg
|
|
uart_iir .equ uart_iob + 2 ; int ident register (read only)
|
|
uart_fcr .equ uart_iob + 2 ; fifo control reg (write only)
|
|
uart_lcr .equ uart_iob + 3 ; line control reg
|
|
uart_mcr .equ uart_iob + 4 ; modem control reg
|
|
uart_lsr .equ uart_iob + 5 ; line status reg
|
|
uart_msr .equ uart_iob + 6 ; modem status reg
|
|
uart_scr .equ uart_iob + 7 ; scratch register
|
|
uart_dll .equ uart_iob + 0 ; dlab=1: divisor latch (ls)
|
|
uart_dlm .equ uart_iob + 1 ; dlab=1: divisor latch (ms)
|
|
;
|
|
;
|
|
;
|
|
uart_jptbl:
|
|
jp uart_cinit ; Initialize serial port
|
|
jp uart_cin ; Read byte
|
|
jp uart_cout ; Write byte
|
|
jp uart_cist ; Input status
|
|
jp uart_cost ; Output Status
|
|
;
|
|
;
|
|
;
|
|
uart_cinit:
|
|
; Test for existence
|
|
;;;xor a ; zero accum
|
|
;;;out (uart_ier),a ; ier := 0
|
|
;;;ld a,$80 ; dlab bit on
|
|
;;;out (uart_lcr),a ; output to lcr (dlab regs now active)
|
|
;;;ld a,$5A ; load test value
|
|
;;;out (uart_dlm),a ; output to dlm
|
|
;;;in a,(uart_dlm) ; read it back
|
|
;;;cp $5A ; check for test value
|
|
;;;ret nz ; nope, unknown uart or not present
|
|
;;;xor a ; dlab bit off
|
|
;;;out (uart_lcr),a ; output to lcr (dlab regs now inactive)
|
|
;;;in a,(uart_ier) ; read ier
|
|
;;;cp $5A ; check for test value
|
|
;;;jr nz,uart_cinit1 ; if *not* $5A, good to go
|
|
;;;or $FF ; signal error
|
|
;;;ret ; done
|
|
;
|
|
uart_cinit1:
|
|
ld a,$80 ; lcr := dlab on
|
|
out (uart_lcr),a ; set lcr
|
|
ld a,uart_divisor & $ff ; low byte of divisor
|
|
out (uart_dll),a ; set divisor (lsb)
|
|
ld a,uart_divisor / $100 ; high byte of divisor
|
|
out (uart_dlm),a ; set divisor (msb)
|
|
xor a ; zero accum
|
|
out (uart_ier),a ; init ier (no ints)
|
|
ld a,$03 ; value for lcr and mcr
|
|
out (uart_lcr),a ; lcr := 3, dlab off, 8 data, 1 stop, no parity
|
|
out (uart_mcr),a ; mcr := 3, dtr on, rts on
|
|
ld a,$07 ; enable & reset fifo's
|
|
out (uart_fcr),a ; do it
|
|
xor a ; signal success
|
|
ret
|
|
;
|
|
;
|
|
;
|
|
uart_cin:
|
|
call uart_cist ; received char ready?
|
|
jr z,uart_cin ; loop if not
|
|
in a,(uart_rbr) ; read byte
|
|
ret ; and done
|
|
;
|
|
;
|
|
;
|
|
uart_cout:
|
|
push af ; save incoming
|
|
uart_cout1:
|
|
call uart_cost ; ready for char?
|
|
jr z,uart_cout1 ; loop if not
|
|
pop af ; restore incoming
|
|
out (uart_thr),a ; write byte
|
|
ret ; and done
|
|
;
|
|
;
|
|
;
|
|
uart_cist:
|
|
in a,(uart_lsr) ; get status
|
|
and $01 ; isolate bit 0 (receive data ready)
|
|
ret ; a != 0 if char ready, else 0
|
|
;
|
|
;
|
|
;
|
|
uart_cost:
|
|
in a,(uart_lsr) ; get status
|
|
and $20 ; isolate bit 5
|
|
ret ; a != 0 if char ready, else 0
|
|
|