|
|
|
@ -3,8 +3,26 @@ |
|
|
|
; UART DRIVER (SERIAL PORT) |
|
|
|
;================================================================================================== |
|
|
|
; |
|
|
|
; Setup Parameter Word: |
|
|
|
; _______________________________ _______________________________ |
|
|
|
; | | | encoded || | | | | | |
|
|
|
; | |rts| Baud Rate ||dtr|xon| parity |stp| 8/7/6 | |
|
|
|
; |_______|___|___|_______________||___|___|___________|___|_______| |
|
|
|
; 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
|
|
|
; D register E register |
|
|
|
; |
|
|
|
; _______________________________ _______________________________ |
|
|
|
; | | | || | | | | | |
|
|
|
; | 0 0 |AFE|LP OT2 OT1 RTS DTR||DLB|BRK|STK EPS PEN|STB| WLS | |
|
|
|
; |_______|___|___________________||___|___|___________|___|_______| |
|
|
|
; 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 |
|
|
|
; -- MCR -- -- LCR -- |
|
|
|
; |
|
|
|
; |
|
|
|
UART_DEBUG .EQU FALSE |
|
|
|
; |
|
|
|
UART_DEFCFG .EQU %0010100110000011 |
|
|
|
; |
|
|
|
UART_NONE .EQU 0 ; UNKNOWN OR NOT PRESENT |
|
|
|
UART_8250 .EQU 1 |
|
|
|
UART_16450 .EQU 2 |
|
|
|
@ -63,30 +81,59 @@ UART_INIT0: |
|
|
|
LD HL,UART_CFG ; POINT TO START OF CFG TABLE |
|
|
|
CALL ADDHLA ; HL := ENTRY ADDRESS |
|
|
|
PUSH HL ; SAVE IT |
|
|
|
CALL UART_INIT1 ; DO HARDWARE INIT FOR CURRENT UART |
|
|
|
PUSH HL ; COPY CFG DATA PTR |
|
|
|
POP IY ; ... TO IY |
|
|
|
CALL UART_INITP ; HAND OFF TO GENERIC INIT CODE |
|
|
|
POP DE ; GET ENTRY ADDRESS BACK, BUT PUT IN DE |
|
|
|
POP BC ; RESTORE LOOP CONTROL |
|
|
|
|
|
|
|
LD A,(UART_TYPE) ; GET THE UART TYPE DETECTED |
|
|
|
; |
|
|
|
LD A,(IY + 1) ; GET THE UART TYPE DETECTED |
|
|
|
OR A ; SET FLAGS |
|
|
|
JR Z,UART_INIT00 ; SKIP IT IF NOTHING FOUND |
|
|
|
|
|
|
|
JR Z,UART_INIT1 ; SKIP IT IF NOTHING FOUND |
|
|
|
; |
|
|
|
PUSH BC ; SAVE LOOP CONTROL |
|
|
|
LD BC,UART_DISPATCH ; BC := DISPATCH ADDRESS |
|
|
|
CALL NZ,CIO_ADDENT ; ADD ENTRY IF UART FOUND, BC:DE |
|
|
|
POP BC ; RESTORE LOOP CONTROL |
|
|
|
|
|
|
|
UART_INIT00: |
|
|
|
; |
|
|
|
UART_INIT1: |
|
|
|
INC C ; NEXT PHYSICAL UNIT |
|
|
|
DJNZ UART_INIT0 ; LOOP UNTIL DONE |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET ; AND RETURN |
|
|
|
; |
|
|
|
UART_INIT1: |
|
|
|
PUSH HL ; COPY CFG DATA PTR |
|
|
|
POP IY ; ... TO IY |
|
|
|
; UART INITIALIZATION ROUTINE |
|
|
|
; |
|
|
|
JP UART_INITP ; HAND OFF TO GENERIC INIT CODE |
|
|
|
UART_INITP: |
|
|
|
; WAIT FOR ANY IN-FLIGHT DATA TO BE SENT |
|
|
|
LD B,0 ; LOOP TIMEOUT COUNTER |
|
|
|
UART_INITP1: |
|
|
|
UART_INP(UART_LSR) ; GET LINE STATUS REGISTER |
|
|
|
BIT 6,A ; TEST BIT 6 (TRANSMITTER EMPTY) |
|
|
|
JR NZ,UART_INITP2 ; EMPTY, CONTINUE |
|
|
|
LD DE,100 ; DELAY 100 * 16US |
|
|
|
CALL VDELAY ; NORMALIZE TIMEOUT TO CPU SPEED |
|
|
|
DJNZ UART_INITP1 ; KEEP CHECKING UNTIL TIMEOUT |
|
|
|
|
|
|
|
UART_INITP2: |
|
|
|
; DETECT THE UART TYPE |
|
|
|
CALL UART_DETECT ; DETERMINE UART TYPE |
|
|
|
LD (IY + 1),A ; ALSO SAVE IN CONFIG TABLE |
|
|
|
OR A ; SET FLAGS |
|
|
|
RET Z ; ABORT IF NOTHING THERE |
|
|
|
|
|
|
|
; UPDATE WORKING UART DEVICE NUM |
|
|
|
LD HL,UART_DEV ; POINT TO CURRENT UART DEVICE NUM |
|
|
|
LD A,(HL) ; PUT IN ACCUM |
|
|
|
INC (HL) ; INCREMENT IT (FOR NEXT LOOP) |
|
|
|
LD (IY),A ; UDPATE UNIT NUM |
|
|
|
|
|
|
|
; SET DEFAULT CONFIG |
|
|
|
LD DE,-1 ; LEAVE CONFIG ALONE |
|
|
|
CALL UART_INITDEV ; IMPLEMENT IT |
|
|
|
|
|
|
|
; DISPLAY UART CONFIG AND RETURN |
|
|
|
JP UART_PRTCFG |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
@ -119,7 +166,7 @@ UART_FTBL: |
|
|
|
UART_IN: |
|
|
|
CALL UART_IST ; RECEIVED CHAR READY? |
|
|
|
JR Z,UART_IN ; LOOP IF NOT |
|
|
|
LD C,(IY + 1) ; C := BASE UART PORT (WHICH IS ALSO RBR REG) |
|
|
|
LD C,(IY + 2) ; C := BASE UART PORT (WHICH IS ALSO RBR REG) |
|
|
|
IN E,(C) ; CHAR READ TO E |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET ; AND DONE |
|
|
|
@ -129,7 +176,7 @@ UART_IN: |
|
|
|
UART_OUT: |
|
|
|
CALL UART_OST ; READY FOR CHAR? |
|
|
|
JR Z,UART_OUT ; LOOP IF NOT |
|
|
|
LD C,(IY + 1) ; C := BASE UART PORT (WHICH IS ALSO THR REG) |
|
|
|
LD C,(IY + 2) ; C := BASE UART PORT (WHICH IS ALSO THR REG) |
|
|
|
OUT (C),E ; SEND CHAR FROM E |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET |
|
|
|
@ -137,7 +184,7 @@ UART_OUT: |
|
|
|
; |
|
|
|
; |
|
|
|
UART_IST: |
|
|
|
LD C,(IY + 2) ; C := LINE STATUS REG (LSR) |
|
|
|
LD C,(IY + 3) ; C := LINE STATUS REG (LSR) |
|
|
|
IN A,(C) ; GET STATUS |
|
|
|
AND $01 ; ISOLATE BIT 0 (RECEIVE DATA READY) |
|
|
|
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING |
|
|
|
@ -148,7 +195,7 @@ UART_IST: |
|
|
|
; |
|
|
|
; |
|
|
|
UART_OST: |
|
|
|
LD C,(IY + 2) ; C := LINE STATUS REG (LSR) |
|
|
|
LD C,(IY + 3) ; C := LINE STATUS REG (LSR) |
|
|
|
IN A,(C) ; GET STATUS |
|
|
|
AND $20 ; ISOLATE BIT 5 () |
|
|
|
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING |
|
|
|
@ -159,142 +206,69 @@ UART_OST: |
|
|
|
; |
|
|
|
; |
|
|
|
UART_INITDEV: |
|
|
|
XOR A ; NOT IMPLEMENTED!!! |
|
|
|
RET |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
UART_QUERY: |
|
|
|
PUSH IY ; COPY CFG ENTRY POINTER (IY) |
|
|
|
POP HL ; ... TO HL |
|
|
|
LD A,4 ; OFFSET OF BAUD RATE IS 4 |
|
|
|
CALL ADDHLA ; BUMP HL TO START OF BAUD RATE DWORD |
|
|
|
CALL LD32 ; LOAD IT |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET ; DONE |
|
|
|
; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) |
|
|
|
LD A,D |
|
|
|
AND E |
|
|
|
INC A |
|
|
|
JR Z,UART_INITDEV1 ; IF DE == -1, BYPASS UPDATE |
|
|
|
; |
|
|
|
; UDPATE CONFIG BYTES |
|
|
|
LD (IY + 4),E ; SAVE LOW WORD |
|
|
|
LD (IY + 5),D ; SAVE HI WORD |
|
|
|
; |
|
|
|
; |
|
|
|
UART_DEVICE: |
|
|
|
LD D,CIODEV_UART ; D := DEVICE TYPE |
|
|
|
LD E,C ; E := PHYSICAL UNIT |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET |
|
|
|
; |
|
|
|
; UART INITIALIZATION ROUTINE |
|
|
|
; |
|
|
|
UART_INITP: |
|
|
|
; WAIT FOR ANY IN-FLIGHT DATA TO BE SENT |
|
|
|
LD B,0 ; LOOP TIMEOUT COUNTER |
|
|
|
UART_INITP00: |
|
|
|
UART_INP(UART_LSR) ; GET LINE STATUS REGISTER |
|
|
|
BIT 6,A ; TEST BIT 6 (TRANSMITTER EMPTY) |
|
|
|
JR NZ,UART_INITP0 ; EMPTY, CONTINUE |
|
|
|
LD DE,100 ; DELAY 100 * 16US |
|
|
|
CALL VDELAY ; NORMALIZE TIMEOUT TO CPU SPEED |
|
|
|
DJNZ UART_INITP00 ; KEEP CHECKING UNTIL TIMEOUT |
|
|
|
|
|
|
|
UART_INITP0: |
|
|
|
; DETECT THE UART TYPE |
|
|
|
CALL UART_DETECT ; DETERMINE UART TYPE |
|
|
|
LD (UART_TYPE),A ; SAVE TYPE |
|
|
|
OR A ; SET FLAGS |
|
|
|
RET Z ; ABORT IF NOTHING THERE |
|
|
|
|
|
|
|
; UPDATE WORKING UART DEVICE NUM |
|
|
|
LD HL,UART_DEV ; POINT TO CURRENT UART DEVICE NUM |
|
|
|
LD A,(HL) ; PUT IN ACCUM |
|
|
|
INC (HL) ; INCREMENT IT (FOR NEXT LOOP) |
|
|
|
LD (IY),A ; UDPATE UNIT NUM |
|
|
|
|
|
|
|
; SETUP FOR GENERIC INIT ROUTINE |
|
|
|
LD A,(IY + 3) ; GET FEATURES BYTE |
|
|
|
LD (UART_FUNC),A ; SAVE IT |
|
|
|
|
|
|
|
; RESET FEATURE BITS |
|
|
|
LD HL,UART_FEAT ; HL POINTS TO FEATURE FLAGS BYTE |
|
|
|
XOR A ; RESET ALL FEATURES |
|
|
|
LD (HL),A ; SAVE IT |
|
|
|
|
|
|
|
UART_INITDEV1: |
|
|
|
; START OF UART INITIALIZATION, SET BAUD RATE |
|
|
|
LD A,80H |
|
|
|
UART_OUTP(UART_LCR) ; DLAB ON |
|
|
|
CALL UART_COMPDIV ; COMPUTE DIVISOR TO BC |
|
|
|
LD A,80H ; DLAB IS BIT 7 OF LCR |
|
|
|
UART_OUTP(UART_LCR) ; DLAB ON |
|
|
|
LD A,B |
|
|
|
UART_OUTP(UART_DLM) ; SET DIVISOR (MS) |
|
|
|
LD A,C |
|
|
|
UART_OUTP(UART_DLL) ; SET DIVISOR (LS) |
|
|
|
|
|
|
|
; SET LCR TO DEFAULT |
|
|
|
; |
|
|
|
; SETUP FCR (DLAB MUST STILL BE ON FOR ACCESS TO BIT 5) |
|
|
|
LD A,%00100111 ; FIFO ENABLE & RESET, 64 BYTE FIFO ENABLE ON 750+ |
|
|
|
UART_OUTP(UART_FCR) ; DO IT |
|
|
|
; |
|
|
|
; SETUP LCR TO DEFAULT (DLAB IS CLEARED) |
|
|
|
LD A,$03 ; DLAB OFF, 8 DATA, 1 STOP, NO PARITY |
|
|
|
UART_OUTP(UART_LCR) ; SAVE IT |
|
|
|
|
|
|
|
; SET MCR TO DEFAULT |
|
|
|
LD A,$03 ; DTR + RTS |
|
|
|
; |
|
|
|
; SETUP MCR FROM FIRST CONFIG BYTE |
|
|
|
LD A,(IY + 5) ; GET CONFIG BYTE |
|
|
|
AND ~$1F ; REMOVE ENCODED BAUD RATE BITS |
|
|
|
OR $03 ; FORCE RTS & DTR |
|
|
|
UART_OUTP(UART_MCR) ; SAVE IT |
|
|
|
|
|
|
|
LD A,(UART_TYPE) ; GET UART TYPE |
|
|
|
CP UART_16550A ; 16550A OR BETTER? |
|
|
|
JP C,UART_INITP1 ; NOPE, SKIP FIFO & AFC FEATURES |
|
|
|
|
|
|
|
LD B,0 ; START BY ASSUMING NO FIFOS, FCR=0 |
|
|
|
LD A,(UART_FUNC) ; LOAD FIFO ENABLE REQUEST VALUE |
|
|
|
BIT UART_FIFO,A ; TEST FOR FIFO REQUESTED |
|
|
|
JR Z,UART_FIFO1 ; NOPE |
|
|
|
LD B,$07 ; VALUE TO ENABLE AND RESET FIFOS |
|
|
|
LD HL,UART_FEAT ; HL POINTS TO FEATURE FLAGS BYTE |
|
|
|
SET UART_FIFO,(HL) ; RECORD FEATURE ENABLED |
|
|
|
UART_FIFO1: |
|
|
|
LD A,B ; MOVE VALUE TO A |
|
|
|
UART_OUTP(UART_FCR) ; DO IT |
|
|
|
|
|
|
|
LD A,(UART_TYPE) ; GET UART TYPE |
|
|
|
CP UART_16550C ; 16550C OR BETTER? |
|
|
|
JR C,UART_INITP1 ; NOPE, SKIP AFC FEATURES |
|
|
|
|
|
|
|
; BRANCH BASED ON TYPE AFC CONFIGURATION (EFR OR MCR) |
|
|
|
LD A,(UART_TYPE) ; GET UART TYPE |
|
|
|
; |
|
|
|
; SPECIAL HANDLING FOR AFC ON UARTS WITH EFR REGISTER |
|
|
|
BIT 5,A ; IS FLOW CONTOL REQUESTED? |
|
|
|
JR Z,UART_INITDEV3 ; NOPE, SKIP AHEAD |
|
|
|
; |
|
|
|
; TEST FOR EFR CAPABLE CHIPS |
|
|
|
LD A,(IY + 1) ; GET UART TYPE |
|
|
|
CP UART_16650 ; 16650? |
|
|
|
JR Z,UART_AFC2 ; USE EFR REGISTER |
|
|
|
CP UART_16850 ; 16750? |
|
|
|
JR Z,UART_AFC2 ; USE EFR REGISTER |
|
|
|
|
|
|
|
; SET AFC VIA MCR |
|
|
|
LD B,$03 ; START WITH DEFAULT MCR |
|
|
|
LD A,(UART_FUNC) ; LOAD AFC ENABLE REQUEST VALUE |
|
|
|
BIT UART_AFC,A ; TEST FOR AFC REQUESTED |
|
|
|
JR Z,UART_AFC1 ; NOPE |
|
|
|
SET 5,B ; SET MCR BIT TO ENABLE AFC |
|
|
|
LD HL,UART_FEAT ; HL POINTS TO FEATURE FLAGS BYTE |
|
|
|
SET UART_AFC,(HL) ; RECORD FEATURE ENABLED |
|
|
|
UART_AFC1: |
|
|
|
LD A,B ; MOVE VALUE TO Ar |
|
|
|
UART_OUTP(UART_MCR) ; SET AFC VALUE VIA MCR |
|
|
|
JR UART_INITP1 ; AND CONTINUE |
|
|
|
|
|
|
|
UART_AFC2: ; SET AFC VIA EFR |
|
|
|
JR Z,UART_INITDEV2 ; USE EFR REGISTER |
|
|
|
CP UART_16850 ; 16850? |
|
|
|
JR Z,UART_INITDEV2 ; USE EFR REGISTER |
|
|
|
JR UART_INITDEV3 ; NO EFT, SKIP AHEAD |
|
|
|
; |
|
|
|
UART_INITDEV2: |
|
|
|
; WE HAVE AN EFR CAPABLE CHIP, SET AUTOFLOW |
|
|
|
UART_INP(UART_LCR) ; GET CURRENT LCR VALUE |
|
|
|
PUSH AF ; SAVE IT |
|
|
|
LD A,$BF ; VALUE TO ACCESS EFR |
|
|
|
UART_OUTP(UART_LCR) ; SET VALUE IN LCR |
|
|
|
|
|
|
|
LD B,0 ; ASSUME AFC OFF, EFR=0 |
|
|
|
LD A,(UART_FUNC) ; LOAD AFC ENABLE REQUEST VALUE |
|
|
|
BIT UART_AFC,A ; TEST FOR AFC REQUESTED |
|
|
|
JR Z,UART_AFC3 ; NOPE |
|
|
|
LD B,$C0 ; ENABLE CTS/RTS FLOW CONTROL |
|
|
|
LD HL,UART_FEAT ; HL POINTS TO FEATURE FLAGS BYTE |
|
|
|
SET UART_AFC,(HL) ; RECORD FEATURE ENABLED |
|
|
|
UART_AFC3: |
|
|
|
LD A,B ; MOVE VALUE TO A |
|
|
|
LD A,$C0 ; ENABLE CTS/RTS FLOW CONTROL |
|
|
|
UART_OUTP(UART_EFR) ; SAVE IT |
|
|
|
LD A,$03 ; NORMAL LCR VALUE |
|
|
|
UART_OUTP(UART_LCR) ; SAVE IT |
|
|
|
|
|
|
|
UART_INITP1: |
|
|
|
POP AF ; RECOVER ORIGINAL LCR VALUE |
|
|
|
UART_OUTP(UART_LCR) ; AND SAVE IT |
|
|
|
; |
|
|
|
UART_INITDEV3: |
|
|
|
#IF (UART_DEBUG) |
|
|
|
PRTS(" [$") |
|
|
|
|
|
|
|
; DEBUG: DUMP UART TYPE |
|
|
|
LD A,(UART_TYPE) |
|
|
|
LD A,(IY + 1) |
|
|
|
CALL PRTHEXBYTE |
|
|
|
|
|
|
|
; DEBUG: DUMP IIR |
|
|
|
@ -313,11 +287,14 @@ UART_INITP1: |
|
|
|
CALL PRTHEXBYTE |
|
|
|
|
|
|
|
; DEBUG: DUMP EFR |
|
|
|
UART_INP(UART_LCR) |
|
|
|
PUSH AF |
|
|
|
LD A,$BF |
|
|
|
UART_OUTP(UART_LCR) |
|
|
|
UART_INP(UART_EFR) |
|
|
|
PUSH AF |
|
|
|
LD A,$03 |
|
|
|
LD H,A |
|
|
|
EX (SP),HL |
|
|
|
LD A,H |
|
|
|
UART_OUTP(UART_LCR) |
|
|
|
POP AF |
|
|
|
CALL PC_SPACE |
|
|
|
@ -326,64 +303,24 @@ UART_INITP1: |
|
|
|
PRTC(']') |
|
|
|
#ENDIF |
|
|
|
|
|
|
|
; ANNOUNCE PORT |
|
|
|
CALL NEWLINE ; FORMATTING |
|
|
|
PRTS("UART$") ; FORMATTING |
|
|
|
LD A,(IY) ; DEVICE NUM |
|
|
|
CALL PRTDECB ; PRINT DEVICE NUM |
|
|
|
PRTS(": IO=0x$") ; FORMATTING |
|
|
|
LD A,(IY + 1) ; GET BASE PORT |
|
|
|
CALL PRTHEXBYTE ; PRINT BASE PORT |
|
|
|
|
|
|
|
; PRINT THE UART TYPE |
|
|
|
LD A,(UART_TYPE) |
|
|
|
RLCA |
|
|
|
LD HL,UART_TYPE_MAP |
|
|
|
LD D,0 |
|
|
|
LD E,A |
|
|
|
ADD HL,DE ; HL NOW POINTS TO MAP ENTRY |
|
|
|
LD A,(HL) |
|
|
|
INC HL |
|
|
|
LD D,(HL) |
|
|
|
LD E,A ; HL NOW POINTS TO STRING |
|
|
|
CALL PC_SPACE |
|
|
|
CALL WRITESTR ; PRINT THE STRING |
|
|
|
XOR A ; NOT IMPLEMENTED!!! |
|
|
|
RET |
|
|
|
; |
|
|
|
; ALL DONE IF NO UART WAS DETECTED |
|
|
|
LD A,(UART_TYPE) |
|
|
|
OR A |
|
|
|
JR Z,UART_INITP3 |
|
|
|
; |
|
|
|
; PRINT BAUD RATE |
|
|
|
PRTS(" BAUD=$") |
|
|
|
; CALL PRTDEC |
|
|
|
|
|
|
|
; BAUD RATE -> DE:HL |
|
|
|
PUSH IY ; DATA PTR |
|
|
|
POP HL ; ... TO HL |
|
|
|
INC HL |
|
|
|
INC HL |
|
|
|
INC HL |
|
|
|
INC HL |
|
|
|
CALL LD32 ; BAUD RATE -> DE:HL |
|
|
|
LD BC,UART_INITBUF |
|
|
|
CALL BIN2BCD |
|
|
|
CALL PRTBCD |
|
|
|
; |
|
|
|
; PRINT FEATURES ENABLED |
|
|
|
LD A,(UART_FEAT) |
|
|
|
BIT UART_FIFO,A |
|
|
|
JR Z,UART_INITP2 |
|
|
|
PRTS(" FIFO$") |
|
|
|
UART_INITP2: |
|
|
|
BIT UART_AFC,A |
|
|
|
JR Z,UART_INITP3 |
|
|
|
PRTS(" AFC$") |
|
|
|
UART_INITP3: |
|
|
|
; |
|
|
|
RET |
|
|
|
UART_QUERY: |
|
|
|
LD E,(IY + 4) ; FIRST CONFIG BYTE TO E |
|
|
|
LD D,(IY + 5) ; SECOND CONFIG BYTE TO D |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET ; DONE |
|
|
|
; |
|
|
|
UART_INITBUF .FILL 5,0 ; WORKING BUFFER FOR BCD NUMBER |
|
|
|
; |
|
|
|
; |
|
|
|
UART_DEVICE: |
|
|
|
LD D,CIODEV_UART ; D := DEVICE TYPE |
|
|
|
LD E,C ; E := PHYSICAL UNIT |
|
|
|
XOR A ; SIGNAL SUCCESS |
|
|
|
RET |
|
|
|
; |
|
|
|
; UART DETECTION ROUTINE |
|
|
|
; |
|
|
|
@ -452,10 +389,10 @@ UART_DETECT2: ; PICK BETWEEN 16550A/C |
|
|
|
JR UART_DETECT_16550C ; IS SET, SO 16550C |
|
|
|
; |
|
|
|
UART_DETECT_NONE: |
|
|
|
LD A,(IY + 1) |
|
|
|
CP $68 |
|
|
|
LD A,(IY + 2) ; BASE IO PORT |
|
|
|
CP $68 ; IS THIS PRIMARY SBC PORT? |
|
|
|
JR Z,UART_DETECT_8250 ; SPECIAL CASE FOR PRIMARY UART! |
|
|
|
LD A,UART_NONE |
|
|
|
LD A,UART_NONE ; IF SO, TREAT AS 8250 NO MATTER WHAT |
|
|
|
RET |
|
|
|
; |
|
|
|
UART_DETECT_8250: |
|
|
|
@ -493,51 +430,108 @@ UART_DETECT_16850: |
|
|
|
; COMPUTE DIVISOR TO BC |
|
|
|
; |
|
|
|
UART_COMPDIV: |
|
|
|
; SETUP DE:HL WITH OSC FREQUENCY |
|
|
|
;LD DE,(UART_OSCHI) |
|
|
|
;LD HL,(UART_OSCLO) |
|
|
|
LD DE,UARTOSC >> 16 ; GET HI WORD OF UART OSC FREQ |
|
|
|
LD HL,UARTOSC & $FFFF ; GET LO WORD OF UART OSC FREQ |
|
|
|
; DIVIDE OSC FREQ BY PRESCALE FACTOR OF 16 |
|
|
|
LD B,4 ; 4 ITERATIONS |
|
|
|
UART_COMPDIV1: |
|
|
|
SRL D |
|
|
|
RR E |
|
|
|
RR H |
|
|
|
RR L |
|
|
|
DJNZ UART_COMPDIV1 |
|
|
|
; CONVERT FROM DE:HL -> A:HL (THROW AWAY HIGH BYTE) |
|
|
|
LD A,E |
|
|
|
PUSH AF |
|
|
|
PUSH HL |
|
|
|
; SETUP C:DE WITH TARGET BAUD RATE |
|
|
|
;LD BC,(UART_BAUDHI) |
|
|
|
;LD DE,(UART_BAUDLO) |
|
|
|
PUSH IY |
|
|
|
POP HL |
|
|
|
INC HL |
|
|
|
INC HL |
|
|
|
INC HL |
|
|
|
INC HL |
|
|
|
CALL LD32 |
|
|
|
PUSH DE |
|
|
|
POP BC |
|
|
|
EX DE,HL |
|
|
|
; RECOVER OSC FREQ IN A:HL |
|
|
|
POP HL |
|
|
|
POP AF |
|
|
|
; DIVIDE OSC FREQ AND BAUD BY 2 UNTIL FREQ FITS IN 16 BITS |
|
|
|
UART_COMPDIV2: |
|
|
|
SRL A |
|
|
|
RR H |
|
|
|
RR L |
|
|
|
SRL C |
|
|
|
RR D |
|
|
|
RR E |
|
|
|
OR A |
|
|
|
JR NZ,UART_COMPDIV2 |
|
|
|
; DIVIDE ADJUSTED VALUES (OSC FREQ / BAUD RATE) |
|
|
|
CALL DIV16 |
|
|
|
; WE WANT TO DETERMINE A DIVISOR FOR THE UART CLOCK |
|
|
|
; THAT RESULTS IN THE DESIRED BAUD RATE. |
|
|
|
; BAUD RATE = UART CLK / DIVISOR, OR TO SOLVE FOR DIVISOR |
|
|
|
; DIVISOR = UART CLK / BAUDRATE. |
|
|
|
; THE UART CLOCK IS THE UART OSC PRESCALED BY 16. ALSO, WE CAN |
|
|
|
; TAKE ADVANTAGE OF ENCODED BAUD RATES ALWAYS BEING A FACTOR OF 75. |
|
|
|
; SO, WE CAN USE (UART OSC / 16 / 75) / (BAUDRATE / 75) |
|
|
|
; |
|
|
|
; FIRST WE DECODE THE BAUDRATE, BUT WE USE A CONSTANT OF 1 INSTEAD |
|
|
|
; OF THE NORMAL 75. THIS PRODUCES (BAUDRATE / 75). |
|
|
|
; |
|
|
|
LD A,(IY + 5) ; GET SECOND CONFIG BYTE |
|
|
|
AND $1F ; ISOLATE ENCODED BAUD RATE |
|
|
|
LD L,A ; PUT IN L |
|
|
|
LD H,0 ; H IS ALWAYS ZERO |
|
|
|
LD DE,1 ; USE 1 FOR ENCODING CONSTANT |
|
|
|
CALL DECODE ; DE:HL := BAUD RATE, ERRORS IGNORED |
|
|
|
EX DE,HL ; DE := (BAUDRATE / 75), DISCARD HL |
|
|
|
LD HL,UARTOSC / 16 / 75 ; HL := (UART OSC / 16 / 75) |
|
|
|
JP DIV16 ; BC := HL/DE == DIVISOR AND RETURN |
|
|
|
; |
|
|
|
; |
|
|
|
; |
|
|
|
UART_PRTCFG: |
|
|
|
; ANNOUNCE PORT |
|
|
|
CALL NEWLINE ; FORMATTING |
|
|
|
PRTS("UART$") ; FORMATTING |
|
|
|
LD A,(IY) ; DEVICE NUM |
|
|
|
CALL PRTDECB ; PRINT DEVICE NUM |
|
|
|
PRTS(": IO=0x$") ; FORMATTING |
|
|
|
LD A,(IY + 2) ; GET BASE PORT |
|
|
|
CALL PRTHEXBYTE ; PRINT BASE PORT |
|
|
|
|
|
|
|
; PRINT THE UART TYPE |
|
|
|
CALL PC_SPACE ; FORMATTING |
|
|
|
LD A,(IY + 1) ; GET UART TYPE BYTE |
|
|
|
RLCA ; MAKE IT A WORD OFFSET |
|
|
|
LD HL,UART_TYPE_MAP ; POINT HL TO TYPE MAP TABLE |
|
|
|
CALL ADDHLA ; HL := ENTRY |
|
|
|
LD E,(HL) ; DEREFERENCE |
|
|
|
INC HL ; ... |
|
|
|
LD D,(HL) ; ... TO GET STRING POINTER |
|
|
|
CALL WRITESTR ; PRINT IT |
|
|
|
; |
|
|
|
; ALL DONE IF NO UART WAS DETECTED |
|
|
|
LD A,(IY + 1) ; GET UART TYPE BYTE |
|
|
|
OR A ; SET FLAGS |
|
|
|
RET Z ; IF ZERO, NOT PRESENT |
|
|
|
; |
|
|
|
; PRINT BAUD RATE |
|
|
|
CALL PC_SPACE |
|
|
|
LD A,(IY + 5) ; GET SECOND CONFIG BYTE |
|
|
|
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 |
|
|
|
LD BC,HB_BCDTMP ; POINT TO TEMP BCD BUF |
|
|
|
CALL BIN2BCD ; CONVERT TO BCD |
|
|
|
CALL PRTBCD ; AND PRINT IN DECIMAL |
|
|
|
; |
|
|
|
; PRINT DATA BITS |
|
|
|
CALL PC_COMMA ; FORMATTING |
|
|
|
LD A,(IY + 4) ; GET CONFIG BYTE |
|
|
|
AND $03 ; ISOLATE DATA BITS VALUE |
|
|
|
ADD A,'5' ; CONVERT TO CHARACTER |
|
|
|
CALL COUT ; AND PRINT |
|
|
|
; |
|
|
|
; PRINT PARITY |
|
|
|
CALL PC_COMMA ; FORMATTING |
|
|
|
LD A,(IY + 4) ; GET CONFIG BYTE |
|
|
|
RLCA ; SHIFT RELEVANT BITS |
|
|
|
RLCA ; ... |
|
|
|
RLCA ; ... |
|
|
|
AND $07 ; AND ISOLATE DATA BITS VALUE |
|
|
|
LD HL,UART_PAR_MAP ; CHARACTER LOOKUP TABLE |
|
|
|
CALL ADDHLA ; APPLY OFFSET |
|
|
|
LD A,(HL) ; GET CHARACTER |
|
|
|
CALL COUT ; AND PRINT |
|
|
|
; |
|
|
|
; PRINT STOP BITS |
|
|
|
CALL PC_COMMA ; FORMATTING |
|
|
|
LD A,(IY + 4) ; GET CONFIG BYTE |
|
|
|
RLCA ; SHIFT RELEVANT BITS |
|
|
|
RLCA ; ... |
|
|
|
AND $01 ; AND ISOLATE DATA BITS VALUE |
|
|
|
ADD A,'1' ; MAKE IT A CHARACTER |
|
|
|
CALL COUT ; AND PRINT |
|
|
|
; |
|
|
|
;; |
|
|
|
; ; PRINT FEATURES ENABLED |
|
|
|
; LD A,(UART_FEAT) |
|
|
|
; BIT UART_FIFO,A |
|
|
|
; JR Z,UART_INITP2 |
|
|
|
; PRTS(" FIFO$") |
|
|
|
;UART_INITP2: |
|
|
|
; BIT UART_AFC,A |
|
|
|
; JR Z,UART_INITP3 |
|
|
|
; PRTS(" AFC$") |
|
|
|
;UART_INITP3: |
|
|
|
; |
|
|
|
XOR A |
|
|
|
RET |
|
|
|
; |
|
|
|
; ROUTINES TO READ/WRITE PORTS INDIRECTLY |
|
|
|
@ -547,7 +541,7 @@ UART_COMPDIV2: |
|
|
|
UART_INP_IMP: |
|
|
|
EX (SP),HL ; SWAP HL AND TOS |
|
|
|
PUSH BC ; PRESERVE BC |
|
|
|
LD A,(IY + 1) ; GET UART IO BASE PORT |
|
|
|
LD A,(IY + 2) ; GET UART IO BASE PORT |
|
|
|
OR (HL) ; OR IN REGISTER ID BITS |
|
|
|
LD C,A ; C := PORT |
|
|
|
IN A,(C) ; READ PORT INTO A |
|
|
|
@ -562,7 +556,7 @@ UART_OUTP_IMP: |
|
|
|
EX (SP),HL ; SWAP HL AND TOS |
|
|
|
PUSH BC ; PRESERVE BC |
|
|
|
LD B,A ; PUT VALUE TO WRITE IN B |
|
|
|
LD A,(IY + 1) ; GET UART IO BASE PORT |
|
|
|
LD A,(IY + 2) ; GET UART IO BASE PORT |
|
|
|
OR (HL) ; OR IN REGISTER ID BITS |
|
|
|
LD C,A ; C := PORT |
|
|
|
OUT (C),B ; WRITE VALUE TO PORT |
|
|
|
@ -594,11 +588,10 @@ UART_STR_16650 .DB "16650$" |
|
|
|
UART_STR_16750 .DB "16750$" |
|
|
|
UART_STR_16850 .DB "16850$" |
|
|
|
; |
|
|
|
UART_PAR_MAP .DB "NONENMNS" |
|
|
|
; |
|
|
|
; WORKING VARIABLES |
|
|
|
; |
|
|
|
UART_TYPE .DB 0 ; UART TYPE DISCOVERED |
|
|
|
UART_FUNC .DB 0 ; UART FUNCTIONS REQUESTED |
|
|
|
UART_FEAT .DB 0 ; UART FEATURES DISCOVERED |
|
|
|
UART_DEV .DB 0 ; DEVICE NUM USED DURING INIT |
|
|
|
; |
|
|
|
; UART PORT TABLE |
|
|
|
@ -606,65 +599,65 @@ UART_DEV .DB 0 ; DEVICE NUM USED DURING INIT |
|
|
|
UART_CFG: |
|
|
|
#IF (UARTCNT >= 1) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART0IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART0IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART0FEAT |
|
|
|
.DW UART0BAUD & $FFFF |
|
|
|
.DW UART0BAUD >> 16 |
|
|
|
.DW UART0CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 2) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART1IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART1IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART1IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART1FEAT |
|
|
|
.DW UART1BAUD & $FFFF |
|
|
|
.DW UART1BAUD >> 16 |
|
|
|
.DW UART1CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 3) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART2IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART2IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART2IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART2FEAT |
|
|
|
.DW UART2BAUD & $FFFF |
|
|
|
.DW UART2BAUD >> 16 |
|
|
|
.DW UART2CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 4) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART3IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART3IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART3IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART3FEAT |
|
|
|
.DW UART3BAUD & $FFFF |
|
|
|
.DW UART3BAUD >> 16 |
|
|
|
.DW UART3CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 5) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART4IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART4IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART4IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART4FEAT |
|
|
|
.DW UART4BAUD & $FFFF |
|
|
|
.DW UART4BAUD >> 16 |
|
|
|
.DW UART4CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 6) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART5IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART5IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART5IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART5FEAT |
|
|
|
.DW UART5BAUD & $FFFF |
|
|
|
.DW UART5BAUD >> 16 |
|
|
|
.DW UART5CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 7) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART6IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART6IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART6IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART6FEAT |
|
|
|
.DW UART6BAUD & $FFFF |
|
|
|
.DW UART6BAUD >> 16 |
|
|
|
.DW UART6CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
#IF (UARTCNT >= 8) |
|
|
|
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT) |
|
|
|
.DB UART7IOB ; IO PORT BASE |
|
|
|
.DB 0 ; UART TYPE |
|
|
|
.DB UART7IOB ; IO PORT BASE (RBR, THR) |
|
|
|
.DB UART7IOB + UART_LSR ; LINE STATUS PORT (LSR) |
|
|
|
.DB UART7FEAT |
|
|
|
.DW UART7BAUD & $FFFF |
|
|
|
.DW UART7BAUD >> 16 |
|
|
|
.DW UART7CFG ; LINE CONFIGURATION |
|
|
|
.FILL 2,$FF ; FILLER |
|
|
|
#ENDIF |
|
|
|
|