; ;================================================================================================== ; UART DRIVER (SERIAL PORT) ;================================================================================================== ; #IF (PLATFORM != PLT_N8) UART0_DIV .EQU (1843200 / (16 * BAUDRATE)) #ENDIF ; ; CHARACTER DEVICE DRIVER ENTRY ; A: RESULT (OUT), CF=ERR ; B: FUNCTION (IN) ; C: CHARACTER (IN/OUT) ; E: DEVICE/UNIT (IN) ; ; UART_DISPATCH: #IF (PLATFORM == PLT_N8) LD A,C ; GET DEVICE/UNIT AND $0F ; ISOLATE UNIT JP Z,UART0 DEC A JP Z,UART1 CALL PANIC #ENDIF ; UART0: 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 ; ; ; UART_INIT: #IF (PLATFORM == PLT_N8) ; ASCI0 PRTS("ASCI0: IO=0x$") LD A,CPU_TDR0 CALL PRTHEXBYTE CALL PC_COMMA LD A,CPU_RDR0 CALL PRTHEXBYTE PRTS(" BAUD=$") #IF ((BAUDRATE / 100) > 0) LD HL,BAUDRATE / 100 CALL PRTDEC #ENDIF #IF ((BAUDRATE % 100) < 10) PRTC("0") #ENDIF LD HL,BAUDRATE % 100 CALL PRTDEC LD A,66H OUT0 (CPU_ASEXT0),A LD A,64H OUT0 (CPU_CNTLA0),A LD A,Z180_CNTLB0 OUT0 (CPU_CNTLB0),A ; ASCI1 CALL NEWLINE PRTS("ASCI1: IO=0x$") LD A,CPU_TDR1 CALL PRTHEXBYTE CALL PC_COMMA LD A,CPU_RDR1 CALL PRTHEXBYTE PRTS(" BAUD=$") #IF ((BAUDRATE / 100) > 0) LD HL,BAUDRATE / 100 CALL PRTDEC #ENDIF #IF ((BAUDRATE % 100) < 10) PRTC("0") #ENDIF LD HL,BAUDRATE % 100 CALL PRTDEC LD A,66H OUT0 (CPU_ASEXT1),A LD A,64H OUT0 (CPU_CNTLA1),A LD A,Z180_CNTLB1 OUT0 (CPU_CNTLB1),A #ELSE PRTS("UART0: IO=0x$") LD A,SIO_BASE CALL PRTHEXBYTE PRTS(" BAUD=$") #IF ((BAUDRATE / 100) > 0) LD HL,BAUDRATE / 100 CALL PRTDEC #ENDIF #IF ((BAUDRATE % 100) < 10) PRTC("0") #ENDIF LD HL,BAUDRATE % 100 CALL PRTDEC LD A,80H OUT (SIO_LCR),A ; DLAB ON LD A,UART0_DIV OUT (SIO_DLL),A ; SET DIVISOR (LS) LD A,00H OUT (SIO_DLM),A ; SET DIVISOR (MS) LD B,03H ; B = DEFAULT SETTING FOR MCR (DTR + RTS) #IF (UARTAFC) PRTS(" AFC$") LD A,$55 ; TEST VALUE OUT (SIO_SCR),A ; SET SCRATCH REG TO TEST VALUE LD A,0BFH OUT (SIO_LCR),A ; SET LCR=$BF TO ATTEMPT TO ACCESS EFR IN A,(SIO_SCR) ; READ SCRATCH REGISTER CP $55 ; IF $55, NO EFR JR NZ,UART_AFC1 ; NZ, HAVE EFR, DO IT SET 5,B ; ENABLE AUTO FLOW CONTROL JR UART_AFC2 UART_AFC1: LD A,0C0H ; ENABLE CTS/RTS FLOW CONTROL OUT (SIO_EFR),A ; SAVE IT UART_AFC2: #ENDIF LD A,03H OUT (SIO_LCR),A ; DLAB OFF, 8 DATA, 1 STOP, NO PARITY LD A,B ; LOAD MCR VALUE TO SET OUT (SIO_MCR),A ; SAVE IT #IF (UARTFIFO) ; LD A,07H ; ENABLE AND RESET FIFOS LD A,01H ; ENABLE AND RESET FIFOS OUT (SIO_FCR),A ; ENABLE FIFOS PRTS(" FIFO$") #ENDIF #ENDIF RET ; ; ; UART0_IN: CALL UART0_IST OR A JR Z,UART0_IN #IF (PLATFORM == PLT_N8) IN0 A,(CPU_RDR0) ; READ THE CHAR FROM THE UART #ELSE IN A,(SIO_RBR) ; READ THE CHAR FROM THE UART #ENDIF LD E,A RET ; ; ; UART0_IST: #IF (PLATFORM == PLT_N8) ; CHECK FOR ERROR FLAGS IN0 A,(CPU_STAT0) AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR JR Z,UART0_IST1 ; ALL IS WELL, CHECK FOR DATA ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!! IN0 A,(CPU_CNTLA0) RES 3,A ; CLEAR EFR (ERROR FLAG RESET) OUT0 (CPU_CNTLA0),A UART0_IST1: ; CHECK FOR STAT0.RDRF (DATA READY) IN0 A,(CPU_STAT0) ; READ LINE STATUS REGISTER AND $80 ; TEST IF DATA IN RECEIVE BUFFER #ELSE IN A,(SIO_LSR) ; READ LINE STATUS REGISTER AND $01 ; TEST IF DATA IN RECEIVE BUFFER #ENDIF 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 #IF (PLATFORM == PLT_N8) OUT0 (CPU_TDR0),A #ELSE OUT (SIO_THR),A ; THEN WRITE THE CHAR TO UART #ENDIF RET ; UART0_OST: #IF (PLATFORM == PLT_N8) IN0 A,(CPU_STAT0) AND $02 #ELSE IN A,(SIO_LSR) ; READ LINE STATUS REGISTER AND $20 #ENDIF JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN XOR A INC A ; SIGNAL BUFFER EMPTY, A = 1 RET ; ; ; #IF (PLATFORM == PLT_N8) ; UART1: LD A,B ; GET REQUESTED FUNCTION AND $0F ; ISOLATE SUB-FUNCTION JR Z,UART0_IN DEC A JR Z,UART0_OUT DEC A JR Z,UART0_IST DEC A JR Z,UART0_OST CALL PANIC ; ; ; UART1_IN: CALL UART1_IST OR A JR Z,UART1_IN IN0 A,(CPU_RDR1) ; READ THE CHAR FROM THE UART LD E,A RET ; ; ; UART1_IST: ; CHECK FOR ERROR FLAGS IN0 A,(CPU_STAT1) AND 70H ; PARITY, FRAMING, OR OVERRUN ERROR JR Z,UART1_IST1 ; ALL IS WELL, CHECK FOR DATA ; CLEAR ERROR(S) OR NOTHING FURTHER CAN BE RECEIVED!!! IN0 A,(CPU_CNTLA1) RES 3,A ; CLEAR EFR (ERROR FLAG RESET) OUT0 (CPU_CNTLA1),A UART1_IST1: ; CHECK FOR STAT0.RDRF (DATA READY) IN0 A,(CPU_STAT1) ; READ LINE STATUS REGISTER AND $80 ; 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 OUT0 (CPU_TDR1),A RET ; UART1_OST: IN0 A,(CPU_STAT1) AND $02 JR Z,UART1_OST JP Z,CIO_IDLE ; DO IDLE PROCESSING AND RETURN XOR A INC A ; SIGNAL BUFFER EMPTY, A = 1 RET #ENDIF