forked from MirrorRepos/RomWBW
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.
338 lines
9.9 KiB
338 lines
9.9 KiB
;
|
|
;==================================================================================================
|
|
; eZ80 UART DRIVER (SERIAL PORT)
|
|
;==================================================================================================
|
|
;
|
|
;
|
|
; Supported Line Characteristics are encoded as follows in the DE register pair:
|
|
;
|
|
; | **Bits** | **Characteristic** |
|
|
; |---------:|----------------------------------------|
|
|
; | 15-14 | Reserved (set to 0) |
|
|
; | 13 | RTS (Not implemented) |
|
|
; | 12-8 | Baud Rate* (see below) |
|
|
; | 7 | DTR (Not implemented) |
|
|
; | 6 | XON/XOFF Flow Control (not implemented)|
|
|
; | 5 | Stick Parity (not implemented) |
|
|
; | 4 | Even Parity (set for true) |
|
|
; | 3 | Parity Enable (set for true) |
|
|
; | 2 | Stop Bits (0-> 1 BIT, 1-> 2 BITS) |
|
|
; | 1-0 | Data Bits (5-8 encoded as 0-3) |
|
|
;
|
|
; * The 5-bit Baud Rate value (V) is encoded as V = 75 * 2^X * 3^Y. The
|
|
; bits are defined as YXXXX.
|
|
;
|
|
; STICK & EVEN & PARITY -> MARK PARITY -> NOT SUPPORTED
|
|
; STICK & !EVEN & PARITY -> SPACE PARITY -> NOT SUPPORTED
|
|
; THEREFORE, MARK PARITY WILL BE INTERPRETED AS EVEN PARITY
|
|
; AND SPACE PARITY WILL BE INTERPRETED AS ODD PARITY
|
|
|
|
UART0_LSR .EQU $C5
|
|
UART0_THR .EQU $C0
|
|
UART0_RBR .EQU $C0
|
|
|
|
LSR_THRE .EQU $20
|
|
LSR_DR .EQU $01
|
|
|
|
|
|
EZUART_PREINIT:
|
|
LD BC, EZUART_FNTBL
|
|
LD DE, EZUART_CFG
|
|
CALL CIO_ADDENT
|
|
LD (EZUART_ID), A
|
|
|
|
XOR A
|
|
RET
|
|
|
|
EZUART_INIT:
|
|
XOR A
|
|
RET
|
|
;
|
|
; ### Function 0x00 -- Character Input (CIOIN)
|
|
;
|
|
; Read and return a Character (E). If no character(s) are available in the
|
|
; input buffer, this function will wait indefinitely. The returned Status
|
|
; (A) is a standard HBIOS result code.
|
|
;
|
|
; Outputs:
|
|
; E: Character
|
|
; A: Status (0-OK, else error)
|
|
;
|
|
EZUART_IN:
|
|
LD A, 3 ; UART
|
|
LD B, 0 ; UART-IN
|
|
EZ80_FN ; CHAR RETURNED IN E
|
|
RET
|
|
;
|
|
; ### Function 0x01 -- Character Output (CIOOUT)
|
|
;
|
|
; Send the Character (E). If there is no space available in the unit's output
|
|
; buffer, the function will wait indefinitely. The returned Status (A) is a
|
|
; standard HBIOS result code.
|
|
;
|
|
; Inputs:
|
|
; E: Character
|
|
;
|
|
; Outputs:
|
|
; A: Status (0-OK, else error)
|
|
;
|
|
EZUART_OUT:
|
|
LD A, 3 ; UART
|
|
LD B, 1 ; UART-OUT
|
|
EZ80_FN
|
|
RET
|
|
;
|
|
; ### Function 0x02 -- Character Input Status (CIOIST)
|
|
;
|
|
; Return the count of Characters Pending (A) in the input buffer.
|
|
;
|
|
; The value returned in register A is used as both a Status (A) code and
|
|
; the return value. Negative values (bit 7 set) indicate a standard HBIOS
|
|
; result (error) code. Otherwise, the return value represents the number
|
|
; of characters in the input buffer.
|
|
;
|
|
; Outputs:
|
|
; A: Status / Characters Pending
|
|
;
|
|
EZUART_IST:
|
|
LD A, 3 ; UART
|
|
LD B, 2 ; UART-IST
|
|
EZ80_FN
|
|
RET
|
|
;
|
|
; ### Function 0x03 -- Character Output Status (CIOOST)
|
|
;
|
|
; Return the status of the output FIFO. 0 means the output FIFO is full and
|
|
; no more characters can be sent. 1 means the output FIFO is not full and at
|
|
; least one character can be sent. Negative values (bit 7 set) indicate a
|
|
; standard HBIOS result (error) code.
|
|
;
|
|
; Outputs
|
|
; A: Status (0 -> Full, 1 -> OK to send, < 0 -> HBIOS error code)
|
|
;
|
|
EZUART_OST:
|
|
LD A, 3 ; UART
|
|
LD B, 3 ; UART-OST
|
|
EZ80_FN
|
|
RET
|
|
|
|
BAUD_RATE .EQU 115200
|
|
;
|
|
; ### Function 0x04 -- Character I/O Initialization (CIOINIT)
|
|
;
|
|
; Apply the requested line Characteristics in (DE). The definition of the
|
|
; line characteristics value is described above. If DE contains -1 (0xFFFF),
|
|
; then the input and output buffers will be flushed and reset.
|
|
; The Status (A) is a standard HBIOS result code.
|
|
;
|
|
; Inputs:
|
|
; DE: Line Characteristics
|
|
;
|
|
; Outputs:
|
|
; A: Status (0-OK, else error)
|
|
;
|
|
EZUART_INITDEV:
|
|
LD A, D
|
|
CP E
|
|
JR NZ, NOT_RESET
|
|
CP $FF
|
|
JR NZ, NOT_RESET
|
|
|
|
; reset requested
|
|
LD A, 3 ; UART
|
|
LD B, 6 ; UART-RESET
|
|
EZ80_FN
|
|
RET
|
|
|
|
NOT_RESET:
|
|
PUSH DE ; SAVE LINE CHARACTERISTICS
|
|
LD A, D
|
|
AND $1F ; ISOLATE ENCODED BAUD RATE
|
|
LD L, A ; PUT IN L
|
|
LD H, 0 ; H IS ALWAYS ZERO
|
|
LD DE, 75 ; BAUD RATE DECODE CONSTANT
|
|
CALL DECODE ; DE:HL := BAUD RATE
|
|
|
|
;; convert E:HL{15:0} to HL{23:0}
|
|
LD A, 0
|
|
LD B, 1 ; UTIL - LD HL, E:HL
|
|
EZ80_FN ;
|
|
|
|
POP DE ; RESTORE REQUESTED LINE CHARACTERISTICS
|
|
LD A, E
|
|
AND 3 ; MASK FOR DATA BITS
|
|
RLCA
|
|
RLCA
|
|
RLCA ; SHIFT TO BITS 4:3
|
|
LD D, A ; SAVE INTO D
|
|
|
|
BIT 2, E ; STOP BITS (1 OR 2)
|
|
JR Z, ISKIP1
|
|
SET 2, D ; APPLY TO D
|
|
ISKIP1:
|
|
|
|
BIT 3, E ; PARITY ENABLE
|
|
JR Z, ISKIP2
|
|
SET 1, D ; APPLY TO D
|
|
ISKIP2:
|
|
|
|
BIT 4, E ; EVEN PARITY
|
|
JR Z, ISKIP3
|
|
SET 0, D ; APPLY TO D
|
|
ISKIP3:
|
|
|
|
; D NOW CONTAINS THE LINE CONTROL BITS AS PER EZ80 FUNCTION
|
|
|
|
LD A, 3 ; UART
|
|
LD B, 4 ; UART-CONFIG
|
|
EZ80_FN
|
|
RET
|
|
|
|
#DEFINE TRANSLATE(nnn,rrr) \
|
|
#defcont \ LDBCMM.LIL(nnn)
|
|
#defcont \ SBCHLBC.LIL
|
|
#defcont \ JR NC, $+7
|
|
#defcont \ LD D, rrr
|
|
#defcont \ JP uart_query_end
|
|
;
|
|
; ### Function 0x05 -- Character I/O Query (CIOQUERY)
|
|
;
|
|
; Returns the current Line Characteristics (DE). The definition of the line
|
|
; characteristics value is described above. The returned status (A) is a
|
|
; standard HBIOS result code.
|
|
;
|
|
; As the eZ80 UART driver supports more than the defined HBIOS baud rates, the
|
|
; returned baud rate may be an approximation of the actual baud rate.
|
|
;
|
|
; Outputs:
|
|
; DE: Line Characteristics
|
|
; A: Status (0-OK, else error)
|
|
;
|
|
EZUART_QUERY:
|
|
LD A, 3 ; UART
|
|
LD B, 5 ; UART-QUERY
|
|
EZ80_FN
|
|
; HL{23:0} := BAUD RATE
|
|
; D = LINE CONTROL BITS
|
|
PUSH DE ; SAVE D
|
|
|
|
OR A
|
|
; HL24 bit has the baud rate, we need to convert to the 5 bit representation?
|
|
TRANSLATE(112, 00000b) ; BAUDRATE=75 (BETWEEN 0 AND 112)
|
|
TRANSLATE(187-112, 00001b) ; BAUDRATE=150 (BETWEEN 113 AND 187)
|
|
TRANSLATE(262-187, 10000b) ; BAUDRATE=225 (BETWEEN 188 AND 262)
|
|
TRANSLATE(375-262, 00010b) ; BAUDRATE=300 (BETWEEN 263 AND 375)
|
|
TRANSLATE(525-375, 10001b) ; BAUDRATE=450 (BETWEEN 376 AND 525)
|
|
TRANSLATE(750-525, 00011b) ; BAUDRATE=600 (BETWEEN 526 AND 750)
|
|
TRANSLATE(1050-750, 10010b) ; BAUDRATE=900 (BETWEEN 751 AND 1050)
|
|
TRANSLATE(1500-1050, 00100b) ; BAUDRATE=1200 (BETWEEN 1051 AND 1500)
|
|
TRANSLATE(2100-1500, 10011b) ; BAUDRATE=1800 (BETWEEN 1501 AND 2100)
|
|
TRANSLATE(3000-2100, 00101b) ; BAUDRATE=2400 (BETWEEN 2101 AND 3000)
|
|
TRANSLATE(4200-3000, 10100b) ; BAUDRATE=3600 (BETWEEN 3001 AND 4200)
|
|
TRANSLATE(6000-4200, 00110b) ; BAUDRATE=4800 (BETWEEN 4201 AND 6000)
|
|
TRANSLATE(8400-6000, 10101b) ; BAUDRATE=7200 (BETWEEN 6001 AND 8400)
|
|
TRANSLATE(12000-8400, 00111b) ; BAUDRATE=9600 (BETWEEN 8401 AND 12000)
|
|
TRANSLATE(16800-12000, 10110b) ; BAUDRATE=14400 (BETWEEN 12001 AND 16800)
|
|
TRANSLATE(24000-16800, 01000b) ; BAUDRATE=19200 (BETWEEN 16801 AND 24000)
|
|
TRANSLATE(33600-24000, 10111b) ; BAUDRATE=28800 (BETWEEN 24001 AND 33600)
|
|
TRANSLATE(48000-33600, 01001b) ; BAUDRATE=38400 (BETWEEN 33601 AND 48000)
|
|
TRANSLATE(67200-48000, 11000b) ; BAUDRATE=57600 (BETWEEN 48001 AND 67200)
|
|
TRANSLATE(96000-67200, 01010b) ; BAUDRATE=76800 (BETWEEN 67201 AND 96000)
|
|
TRANSLATE(134400-96000, 11001b) ; BAUDRATE=115200 (BETWEEN 96001 AND 134400)
|
|
TRANSLATE(192000-134400, 01011b) ; BAUDRATE=153600 (BETWEEN 134401 AND 192000)
|
|
TRANSLATE(268800-192000, 11010b) ; BAUDRATE=230400 (BETWEEN 192001 AND 268800)
|
|
TRANSLATE(384000-268800, 01100b) ; BAUDRATE=307200 (BETWEEN 268801 AND 384000)
|
|
TRANSLATE(537600-384000, 11011b) ; BAUDRATE=460800 (BETWEEN 384001 AND 537600)
|
|
TRANSLATE(768000-537600, 01101b) ; BAUDRATE=614400 (BETWEEN 537601 AND 768000)
|
|
TRANSLATE(1075200-768000, 11100b) ; BAUDRATE=921600 (BETWEEN 768001 AND 1075200)
|
|
TRANSLATE(1536000-1075200, 01110b) ; BAUDRATE=1228800 (BETWEEN 1075201 AND 1536000)
|
|
TRANSLATE(2150400-1536000, 11101b) ; BAUDRATE=1843200 (BETWEEN 1536001 AND 2150400)
|
|
TRANSLATE(3072000-2150400, 01111b) ; BAUDRATE=2457600 (BETWEEN 2150401 AND 3072000)
|
|
TRANSLATE(5529600-3072000, 11110b) ; BAUDRATE=3686400 (BETWEEN 3072001 AND 5529600)
|
|
|
|
LD D, 11111b ; BAUDRATE=7372800 (>=5529601)
|
|
uart_query_end:
|
|
|
|
POP BC ; B = LINE CONTROL BITS
|
|
|
|
; Convert from line control settings from:
|
|
;
|
|
; B{0:1} = Parity (00 -> NONE, 01 -> NONE, 10 -> ODD, 11 -> EVEN)
|
|
; B{2} = Stop Bits (0 -> 1, 1 -> 2)
|
|
; B{3:4} = Data Bits (00 -> 5, 01 -> 6, 10 -> 7, 11 -> 8)
|
|
; B{5:5} = Hardware Flow Control CTS (0 -> OFF, 1 -> ON)
|
|
;
|
|
; to
|
|
;
|
|
; E{7} = TODO: DTR
|
|
; E{6} = NOT IMPLEMENTED: XON/XOFF Flow Control
|
|
; E{5} = NOT SUPPORTED: Stick Parity (set for true)
|
|
; E{4} = Even Parity (set for true)
|
|
; E{3} = Parity Enable (set for true)
|
|
; E{2} = Stop Bits (set for true)
|
|
; E{1:0} = Data Bits (5-8 encoded as 0-3)
|
|
|
|
XOR A
|
|
OR 3 << 3 ; ISOLATE DATA BITS
|
|
AND B ; MASK IN DATA BITS
|
|
|
|
RRCA ; SHIFT TO BITS 1:0
|
|
RRCA
|
|
RRCA
|
|
LD H, A ; H{1:0} DATA BITS
|
|
|
|
BIT 2, B ; STOP BITS
|
|
JR Z, SKIP1
|
|
SET 2, H ; APPLY TO H
|
|
|
|
SKIP1:
|
|
BIT 1, B ; PARITY ENABLE
|
|
JR Z, SKIP2
|
|
SET 3, H ; APPLY TO H
|
|
|
|
SKIP2:
|
|
BIT 0, B ; EVEN PARITY
|
|
JR Z, SKIP3
|
|
SET 4, H ; APPLY TO H
|
|
|
|
SKIP3:
|
|
LD E, H
|
|
XOR A
|
|
RET
|
|
;
|
|
; ### Function 0x06 -- Character I/O Device (CIODEVICE)
|
|
;
|
|
; Returns device information. The status (A) is a standard HBIOS result
|
|
; code.
|
|
;
|
|
; Outputs
|
|
; A: Status (0 - OK)
|
|
; C: Device Attribute (0 - RS/232)
|
|
; D: Device Type (CIODEV_EZ80UART)
|
|
; E: Physical Device Number
|
|
; H: Device Mode (0)
|
|
; L: Device I/O Base Address - Not Supported (0)
|
|
;
|
|
EZUART_DEVICE:
|
|
LD D, CIODEV_EZ80UART ; D := DEVICE TYPE
|
|
LD E, (IY) ; E := PHYSICAL UNIT
|
|
LD C, 0 ; C := DEVICE TYPE, 0x00 IS RS-232
|
|
LD HL, 0 ; H := MODE, L := BASE I/O ADDRESS
|
|
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
|
|
EZUART_CFG:
|
|
EZUART_ID: .DB 0
|
|
|
|
|
|
EZUART_FNTBL:
|
|
.DW EZUART_IN
|
|
.DW EZUART_OUT
|
|
.DW EZUART_IST
|
|
.DW EZUART_OST
|
|
.DW EZUART_INITDEV
|
|
.DW EZUART_QUERY
|
|
.DW EZUART_DEVICE
|
|
#IF (($ - EZUART_FNTBL) != (CIO_FNCNT * 2))
|
|
.ECHO "*** INVALID EZUART FUNCTION TABLE ***\n"
|
|
|