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.
 
 
 
 
 
 

332 lines
7.8 KiB

;
;==================================================================================================
; UART DRIVER (SERIAL PORT)
;==================================================================================================
;
#IF (UARTCNT >= 1)
UART0_RBR .EQU UART0IOB + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY)
UART0_THR .EQU UART0IOB + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY)
UART0_IER .EQU UART0IOB + 1 ; DLAB=0: INT ENABLE REG
UART0_IIR .EQU UART0IOB + 2 ; INT IDENT REGISTER (READ ONLY)
UART0_FCR .EQU UART0IOB + 2 ; FIFO CONTROL REG (WRITE ONLY)
UART0_LCR .EQU UART0IOB + 3 ; LINE CONTROL REG
UART0_MCR .EQU UART0IOB + 4 ; MODEM CONTROL REG
UART0_LSR .EQU UART0IOB + 5 ; LINE STATUS REG
UART0_MSR .EQU UART0IOB + 6 ; MODEM STATUS REG
UART0_SCR .EQU UART0IOB + 7 ; SCRATCH REGISTER
UART0_DLL .EQU UART0IOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
UART0_DLM .EQU UART0IOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
;
UART0_DIV .EQU (1843200 / (16 * UART0BAUD))
#ENDIF
;
#IF (UARTCNT >= 2)
UART1_RBR .EQU UART1IOB + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY)
UART1_THR .EQU UART1IOB + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY)
UART1_IER .EQU UART1IOB + 1 ; DLAB=0: INT ENABLE REG
UART1_IIR .EQU UART1IOB + 2 ; INT IDENT REGISTER (READ ONLY)
UART1_FCR .EQU UART1IOB + 2 ; FIFO CONTROL REG (WRITE ONLY)
UART1_LCR .EQU UART1IOB + 3 ; LINE CONTROL REG
UART1_MCR .EQU UART1IOB + 4 ; MODEM CONTROL REG
UART1_LSR .EQU UART1IOB + 5 ; LINE STATUS REG
UART1_MSR .EQU UART1IOB + 6 ; MODEM STATUS REG
UART1_SCR .EQU UART1IOB + 7 ; SCRATCH REGISTER
UART1_DLL .EQU UART1IOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
UART1_DLM .EQU UART1IOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
;
UART1_DIV .EQU (1843200 / (16 * UART1BAUD))
#ENDIF
;
#IF (UARTCNT >= 3)
UART2_RBR .EQU UART2IOB + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY)
UART2_THR .EQU UART2IOB + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY)
UART2_IER .EQU UART2IOB + 1 ; DLAB=0: INT ENABLE REG
UART2_IIR .EQU UART2IOB + 2 ; INT IDENT REGISTER (READ ONLY)
UART2_FCR .EQU UART2IOB + 2 ; FIFO CONTROL REG (WRITE ONLY)
UART2_LCR .EQU UART2IOB + 3 ; LINE CONTROL REG
UART2_MCR .EQU UART2IOB + 4 ; MODEM CONTROL REG
UART2_LSR .EQU UART2IOB + 5 ; LINE STATUS REG
UART2_MSR .EQU UART2IOB + 6 ; MODEM STATUS REG
UART2_SCR .EQU UART2IOB + 7 ; SCRATCH REGISTER
UART2_DLL .EQU UART2IOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
UART2_DLM .EQU UART2IOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
;
UART2_DIV .EQU (1843200 / (16 * UART2BAUD))
#ENDIF
;
#IF (UARTCNT >= 4)
UART3_RBR .EQU UART3IOB + 0 ; DLAB=0: RCVR BUFFER REG (READ ONLY)
UART3_THR .EQU UART3IOB + 0 ; DLAB=0: XMIT HOLDING REG (WRITE ONLY)
UART3_IER .EQU UART3IOB + 1 ; DLAB=0: INT ENABLE REG
UART3_IIR .EQU UART3IOB + 2 ; INT IDENT REGISTER (READ ONLY)
UART3_FCR .EQU UART3IOB + 2 ; FIFO CONTROL REG (WRITE ONLY)
UART3_LCR .EQU UART3IOB + 3 ; LINE CONTROL REG
UART3_MCR .EQU UART3IOB + 4 ; MODEM CONTROL REG
UART3_LSR .EQU UART3IOB + 5 ; LINE STATUS REG
UART3_MSR .EQU UART3IOB + 6 ; MODEM STATUS REG
UART3_SCR .EQU UART3IOB + 7 ; SCRATCH REGISTER
UART3_DLL .EQU UART3IOB + 0 ; DLAB=1: DIVISOR LATCH (LS)
UART3_DLM .EQU UART3IOB + 1 ; DLAB=1: DIVISOR LATCH (MS)
;
UART3_DIV .EQU (1843200 / (16 * UART3BAUD))
#ENDIF
;
; CHARACTER DEVICE DRIVER ENTRY
; A: RESULT (OUT), CF=ERR
; B: FUNCTION (IN)
; C: CHARACTER (IN/OUT)
; E: DEVICE/UNIT (IN)
;
;
UART_INIT:
#IF (UARTCNT >= 1)
CALL UART0_INIT
#ENDIF
#IF (UARTCNT >= 2)
CALL UART1_INIT
#ENDIF
#IF (UARTCNT >= 3)
CALL UART2_INIT
#ENDIF
#IF (UARTCNT >= 4)
CALL UART3_INIT
#ENDIF
RET
;
;
;
UART_DISPATCH:
LD A,C ; GET DEVICE/UNIT
AND $0F ; ISOLATE UNIT
#IF (UARTCNT >= 1)
JP Z,UART0_DISPATCH
#ENDIF
#IF (UARTCNT >= 2)
DEC A
JP Z,UART1_DISPATCH
#ENDIF
#IF (UARTCNT >= 3)
DEC A
JP Z,UART2_DISPATCH
#ENDIF
#IF (UARTCNT >= 4)
DEC A
JP Z,UART3_DISPATCH
#ENDIF
CALL PANIC
;
;
;
#IF (UARTCNT >= 1)
;
UART0_INIT:
PRTS("UART0: IO=0x$")
LD A,UART0IOB
CALL PRTHEXBYTE
PRTS(" BAUD=$")
LD HL,UART0BAUD / 10
CALL PRTDEC
PRTC('0')
LD A,80H
OUT (UART0_LCR),A ; DLAB ON
LD A,UART0_DIV % $100
OUT (UART0_DLL),A ; SET DIVISOR (LS)
LD A,UART0_DIV / $100
OUT (UART0_DLM),A ; SET DIVISOR (MS)
LD B,03H ; B = DEFAULT SETTING FOR MCR (DTR + RTS)
#IF (UART0AFC)
PRTS(" AFC$")
LD A,$55 ; TEST VALUE
OUT (UART0_SCR),A ; SET SCRATCH REG TO TEST VALUE
LD A,0BFH
OUT (UART0_LCR),A ; SET LCR=$BF TO ATTEMPT TO ACCESS EFR
IN A,(UART0_SCR) ; READ SCRATCH REGISTER
CP $55 ; IF $55, NO EFR
JR NZ,UART0_AFC1 ; NZ, HAVE EFR, DO IT
SET 5,B ; ENABLE AUTO FLOW CONTROL
JR UART0_AFC2
UART0_AFC1:
LD A,0C0H ; ENABLE CTS/RTS FLOW CONTROL
OUT (UART0_EFR),A ; SAVE IT
UART0_AFC2:
#ENDIF
LD A,03H
OUT (UART0_LCR),A ; DLAB OFF, 8 DATA, 1 STOP, NO PARITY
LD A,B ; LOAD MCR VALUE TO SET
OUT (UART0_MCR),A ; SAVE IT
#IF (UART0FIFO)
; LD A,07H ; ENABLE AND RESET FIFOS
LD A,01H ; ENABLE AND RESET FIFOS
OUT (UART0_FCR),A ; ENABLE FIFOS
PRTS(" FIFO$")
#ENDIF
RET
;
;
;
UART0_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,UART0_IN
DEC A
JP Z,UART0_OUT
DEC A
JP Z,UART0_IST
DEC A
JP Z,UART0_OST
CALL PANIC
;
;
;
UART0_IN:
CALL UART0_IST
OR A
JR Z,UART0_IN
IN A,(UART0_RBR) ; READ THE CHAR FROM THE UART
LD E,A
RET
;
;
;
UART0_IST:
IN A,(UART0_LSR) ; READ LINE STATUS REGISTER
AND $01 ; TEST IF DATA IN RECEIVE BUFFER
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL CHAR READY, A = 1
RET
;
;
;
UART0_OUT:
CALL UART0_OST
OR A
JR Z,UART0_OUT
LD A,E
OUT (UART0_THR),A ; THEN WRITE THE CHAR TO UART
RET
;
UART0_OST:
IN A,(UART0_LSR) ; READ LINE STATUS REGISTER
AND $20
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL BUFFER EMPTY, A = 1
RET
;
#ENDIF
;
;
;
#IF (UARTCNT >= 2)
;
UART1_INIT:
CALL NEWLINE
PRTS("UART1: IO=0x$")
LD A,UART1IOB
CALL PRTHEXBYTE
PRTS(" BAUD=$")
LD HL,UART1BAUD / 10
CALL PRTDEC
PRTC('0')
LD A,80H
OUT (UART1_LCR),A ; DLAB ON
LD A,UART1_DIV % $100
OUT (UART1_DLL),A ; SET DIVISOR (LS)
LD A,UART1_DIV / $100
OUT (UART1_DLM),A ; SET DIVISOR (MS)
LD B,03H ; B = DEFAULT SETTING FOR MCR (DTR + RTS)
#IF (UART1AFC)
PRTS(" AFC$")
LD A,$55 ; TEST VALUE
OUT (UART1_SCR),A ; SET SCRATCH REG TO TEST VALUE
LD A,0BFH
OUT (UART1_LCR),A ; SET LCR=$BF TO ATTEMPT TO ACCESS EFR
IN A,(UART1_SCR) ; READ SCRATCH REGISTER
CP $55 ; IF $55, NO EFR
JR NZ,UART1_AFC1 ; NZ, HAVE EFR, DO IT
SET 5,B ; ENABLE AUTO FLOW CONTROL
JR UART1_AFC2
UART1_AFC1:
LD A,0C0H ; ENABLE CTS/RTS FLOW CONTROL
OUT (UART1_EFR),A ; SAVE IT
UART1_AFC2:
#ENDIF
LD A,03H
OUT (UART1_LCR),A ; DLAB OFF, 8 DATA, 1 STOP, NO PARITY
LD A,B ; LOAD MCR VALUE TO SET
OUT (UART1_MCR),A ; SAVE IT
#IF (UART1FIFO)
; LD A,07H ; ENABLE AND RESET FIFOS
LD A,01H ; ENABLE AND RESET FIFOS
OUT (UART1_FCR),A ; ENABLE FIFOS
PRTS(" FIFO$")
#ENDIF
RET
;
;
;
UART1_DISPATCH:
LD A,B ; GET REQUESTED FUNCTION
AND $0F ; ISOLATE SUB-FUNCTION
JP Z,UART1_IN
DEC A
JP Z,UART1_OUT
DEC A
JP Z,UART1_IST
DEC A
JP Z,UART1_OST
CALL PANIC
;
;
;
UART1_IN:
CALL UART1_IST
OR A
JR Z,UART1_IN
IN A,(UART1_RBR) ; READ THE CHAR FROM THE UART
LD E,A
RET
;
;
;
UART1_IST:
IN A,(UART1_LSR) ; READ LINE STATUS REGISTER
AND $01 ; TEST IF DATA IN RECEIVE BUFFER
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL CHAR READY, A = 1
RET
;
;
;
UART1_OUT:
CALL UART1_OST
OR A
JR Z,UART1_OUT
LD A,E
OUT (UART1_THR),A ; THEN WRITE THE CHAR TO UART
RET
;
UART1_OST:
IN A,(UART1_LSR) ; READ LINE STATUS REGISTER
AND $20
JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN
XOR A
INC A ; SIGNAL BUFFER EMPTY, A = 1
RET
;
#ENDIF