Browse Source

26C92 support (untested)

cleanup
remove debugging (it didn't work when the DUART was the primary device anyways)
simplify configuration tables
pull/133/head
Chris Odorjan 6 years ago
parent
commit
0f0eae6bd7
  1. 227
      Source/HBIOS/duart.asm

227
Source/HBIOS/duart.asm

@ -74,12 +74,14 @@ DUART_DEBUG .EQU FALSE
;
DUART_NONE .EQU 0 ; UNKNOWN OR NOT PRESETN
DUART_2681 .EQU 1 ; OLD '681 WITHOUT IVR/GPR
DUART_2692 .EQU 2 ; '92 WITH MR0
DUART_26C92 .EQU 2 ; '92 WITH MR0
DUART_XR88C681 .EQU 3 ; EXAR/MAXLINEAR CHIP WITH Z-MODE
;
DUART_BAUD_INV .EQU $FF ; INVALID BAUD RATE
DUART_BAUD_ACR7 .EQU %10000000 ; ACR BIT 7 = 1
DUART_BAUD_X1 .EQU %01000000 ; BRG EXTEND BIT = 1
DUART_BAUD_X1 .EQU %01000000 ; BRG EXTEND BIT = 1 ('681)
DUART_BAUD_EXT1 .EQU %00100000 ; EXTENDED TABLE 1 ('92)
DUART_BAUD_EXT2 .EQU %00010000 ; EXTENDED TABLE 2 ('92)
;
; PER CHANNEL REGISTERS (CHANNEL A AT OFFSET 0, CHANNEL B AT OFFSET 8)
;
@ -125,7 +127,7 @@ DUART_CR_SET_RX_X .EQU $80 ; SET RECEIVER BRG EXTEND BIT (X=1)
DUART_CR_CLR_RX_X .EQU $90 ; CLEAR RECEIVER BRG EXTEND BIT (X=0)
DUART_CR_SET_TX_X .EQU $A0 ; SET TRANSMITTER BRG EXTEND BIT (X=1)
DUART_CR_CLR_TX_X .EQU $B0 ; CLEAR TRANSMITTER BRG EXTEND BIT (X=0)
DUART_CR_MR0 .EQU $B0 ; RESET MR POINTER TO MR0 (2692 ONLY)
DUART_CR_MR0 .EQU $B0 ; RESET MR POINTER TO MR0 (26C92 ONLY)
DUART_CR_STANDBY .EQU $C0 ; SET STANDBY MODE (CHANNEL A ONLY)
DUART_CR_RESET_IUS .EQU $C0 ; RESET IUS LATCH (CHANNEL B ONLY)
DUART_CR_ACTIVE .EQU $D0 ; SET ACTIVE MODE (CHANNEL A ONLY)
@ -305,46 +307,29 @@ DUART_INITDEV:
JR NZ,DUART_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG
;
; LOAD EXISTING CONFIG TO REINIT
LD E,(IY + 7) ; LOW BYTE
LD D,(IY + 8) ; HIGH BYTE
LD E,(IY + 8) ; LOW BYTE
LD D,(IY + 9) ; HIGH BYTE
;
DUART_INITDEV1:
#IF (DUART_DEBUG)
PRTS(" [TYPE=$")
; DEBUG: DUMP DUART TYPE
LD A,(IY + 1)
CALL PRTHEXBYTE
; DEBUG: DUMP PREVIOUS BAUD TABLE ENTRY
PRTS(" OLDBAUDTBL=$")
LD A,(IY + 5)
CALL PRTHEXBYTE
#ENDIF
;
; GET CLOCK SELECT FROM TABLE
LD HL,DUART_BAUDTBL ; GET START OF TABLE IN HL
LD HL,DUART_BAUDTBL_681 ; GET START OF XR88C681 TABLE IN HL
LD A,(IY + 1) ; GET DUART TYPE
CP DUART_26C92 ; IS IT A 26C92?
JR NZ,DUART_INITDEV1A ; NO, SKIP NEXT INSTRUCTION
LD HL,DUART_BAUDTBL_92 ; GET START OF SC26C92 TABLE IN HL
;
DUART_INITDEV1A:
LD A,D ; GET CONFIG MSB
AND $1F ; ISOLATE ENCODED BAUD RATE
CALL ADDHLA ; HL -> ENTRY
LD A,(HL) ; A = ENTRY
;
#IF (DUART_DEBUG)
; DEBUG: DUMP BAUD TABLE ENTRY
PUSH AF
PRTS(" BAUDTBL=$")
CALL PRTHEXBYTE
POP AF
#ENDIF
;
INC A ; A = $FF?
JP Z,DUART_INITDEVZ ; INVALID RATE, ERROR OUT
DEC A ; GET ORIGINAL VALUE BACK
;
; GOT A VALID RATE, COMMIT NEW CONFIG
LD (IY + 7),E ; SAVE LOW WORD
LD (IY + 8),D ; SAVE HI WORD
LD (IY + 5),A ; SAVE BAUD TABLE ENTRY
LD (IY + 8),E ; SAVE LOW WORD
LD (IY + 9),D ; SAVE HI WORD
;
; START OF ACTUAL DUART CHANNEL CONFIGURATION
LD L,A ; SAVE BAUD TABLE ENTRY IN L
@ -363,12 +348,6 @@ DUART_INITDEV1:
DUART_OUTP(DUART_CR) ; SET FOR RECEIVER
LD A,DUART_CR_SET_TX_X
DUART_OUTP(DUART_CR) ; SET FOR TRANSMITTER
;
#IF (DUART_DEBUG)
; DEBUG: DUMP BRG SELECT EXTEND BIT
PRTS(" X=1$")
#ENDIF
;
JR DUART_INITDEV3
;
DUART_INITDEV2:
@ -378,11 +357,6 @@ DUART_INITDEV2:
LD A,DUART_CR_CLR_TX_X
DUART_OUTP(DUART_CR) ; CLEAR FOR TRANSMITTER
;
#IF (DUART_DEBUG)
; DEBUG: DUMP BRG SELECT EXTEND BIT
PRTS(" X=0$")
#ENDIF
;
DUART_INITDEV3:
; SET BRG CLOCK SELECT
LD A,L ; GET BAUD TABLE ENTRY IN A
@ -393,15 +367,6 @@ DUART_INITDEV3:
RLA
RLA ; MOVE IT INTO THE HIGH NIBBLE
OR L ; AND MERGE BACK IN LOW NIBBLE
;
#IF (DUART_DEBUG)
; DEBUG: DUMP CLOCK SELECT REGISTER
PUSH AF
PRTS(" CSR=$")
CALL PRTHEXBYTE
POP AF
#ENDIF
;
DUART_OUTP(DUART_CSR) ; SET CLOCK SELECT
;
; SET PARITY AND WORD SIZE
@ -419,15 +384,6 @@ DUART_INITDEV3:
AND %00000011 ; WORD LENGTH BITS ARE THE SAME
OR B ; MERGE PARITY BITS
OR DUART_MR1_RXRTS ; ALWAYS ENABLE RECEIVER CONTROL OF RTS
;
#IF (DUART_DEBUG)
; DEBUG: DUMP MODE REGISTER 1
PUSH AF
PRTS(" MR1=$")
CALL PRTHEXBYTE
POP AF
#ENDIF
;
DUART_OUTP(DUART_MR) ; WRITE MR1 (AND SET MR POINTER TO MR2)
;
; SET STOP BITS
@ -440,15 +396,6 @@ DUART_INITDEV3:
DUART_INITDEV4:
LD A,B ; GET MR2 IN A
;OR DUART_MR2_TXCTS ; ALWAYS ENABLE CTS CONTROL OF TRANSMITTER
;
#IF (DUART_DEBUG)
; DEBUG: DUMP MODE REGISTER 2
PUSH AF
PRTS(" MR2=$")
CALL PRTHEXBYTE
POP AF
#ENDIF
;
DUART_OUTP(DUART_MR) ; WRITE MR2
;
; RE-ENABLE RECEIVER AND TRANSMITTER
@ -457,23 +404,16 @@ DUART_INITDEV4:
;
; EXPLICITLY ASSERT RTS (SEEMS TO BE REQUIRED FOR SOME CHIPS TO DO AUTO-RTS)
LD L,%00000001 ; RTS FOR CHANNEL A IS IN BIT 0
LD A,(IY + 2) ; GET MODULE IN A
LD A,(IY) ; GET UNIT NUMBER IN A
AND L ; MASK ALL BUT CHANNEL
JR Z,DUART_INITDEV5 ; ZERO INDICATES CHANNEL A
SLA L ; MOVE INTO BIT 1, RTS FOR CHANNEL B
;
DUART_INITDEV5:
LD A,(IY + 3) ; GET BASE ADDRESS OF CHIP
LD A,(IY + 2) ; GET BASE ADDRESS OF CHIP
ADD A,DUART_SOPR ; SET OUTPUT BITS
LD C,A ; GET PORT IN C
OUT (C),L ; OUTPUT PORT IS INVERTED BUT SO IS RTS
;
#IF (DUART_DEBUG)
PRTS(" SOPR=$")
LD A,L
CALL PRTHEXBYTE
PRTC(']')
#ENDIF
;
XOR A ; SIGNAL SUCCESS
RET
@ -487,7 +427,8 @@ DUART_INITDEVZ:
DEC A ; A WAS $00, GET BACK $FF
RET ; RETURN ERROR STATUS
;
DUART_BAUDTBL:
DUART_BAUDTBL_681:
; ASSUME XR88C681 RUNS AT 3.6864MHZ
.DB %0000 | DUART_BAUD_X1 ; 75
.DB %0011 | DUART_BAUD_X1 ; 150
.DB %0100 ; 300
@ -521,10 +462,40 @@ DUART_BAUDTBL:
.DB DUART_BAUD_INV ; 3686400
.DB DUART_BAUD_INV ; 7372800
;
#IF (($ - DUART_BAUDTBL) != 32)
.ECHO "*** ERROR: DUART_BAUDTBL MUST CONTAIN 32 ENTRIES!!!\n"
!!! ; FORCE AN ASSEMBLY ERROR
#ENDIF
DUART_BAUDTBL_92:
; ASSUME SC26C92 RUNS AT 7.3728MHZ
.DB DUART_BAUD_INV ; 75
.DB DUART_BAUD_INV ; 150
.DB DUART_BAUD_INV ; 300
.DB DUART_BAUD_INV ; 600
.DB DUART_BAUD_INV ; 1200
.DB DUART_BAUD_INV ; 2400
.DB DUART_BAUD_INV ; 4800
.DB %1001 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 9600
.DB %1011 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 19200
.DB %1100 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 38400
.DB DUART_BAUD_INV ; 76800
.DB DUART_BAUD_INV ; 153600
.DB DUART_BAUD_INV ; 307200
.DB DUART_BAUD_INV ; 614400
.DB DUART_BAUD_INV ; 1228800
.DB DUART_BAUD_INV ; 2457600
.DB DUART_BAUD_INV ; 225
.DB DUART_BAUD_INV ; 450
.DB DUART_BAUD_INV ; 900
.DB DUART_BAUD_INV ; 1800
.DB DUART_BAUD_INV ; 3600
.DB DUART_BAUD_INV ; 7200
.DB %0000 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 14400
.DB %0011 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 28800
.DB %0100 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 57600
.DB %0101 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 115200
.DB %0110 | DUART_BAUD_EXT2 | DUART_BAUD_ACR7 ; 230400
.DB DUART_BAUD_INV ; 460800
.DB DUART_BAUD_INV ; 921600
.DB DUART_BAUD_INV ; 1843200
.DB DUART_BAUD_INV ; 3686400
.DB DUART_BAUD_INV ; 7372800
;
DUART_PARTBL:
.DB DUART_MR1_PARNONE ; 0 = NO PARITY (ALSO ALL EVEN ENTRIES)
@ -536,16 +507,11 @@ DUART_PARTBL:
.DB DUART_MR1_PARNONE
.DB DUART_MR1_PARSPACE ; 7 = SPACE PARITY
;
#IF (($ - DUART_PARTBL) != 8)
.ECHO "*** ERROR: DUART_PARTBL MUST CONTAIN 8 ENTRIES!!!\n"
!!! ; FORCE AN ASSEMBLY ERROR
#ENDIF
;
;
;
DUART_QUERY:
LD E,(IY + 7) ; FIRST CONFIG BYTE TO E
LD D,(IY + 8) ; SECOND CONFIG BYTE TO D
LD E,(IY + 8) ; FIRST CONFIG BYTE TO E
LD D,(IY + 9) ; SECOND CONFIG BYTE TO D
XOR A ; SIGNAL SUCCESS
RET ; DONE
;
@ -563,7 +529,7 @@ DUART_DEVICE:
DUART_DETECT:
;
; FIRST SEE IF IT LOOKS LIKE A 16X50-STYLE UART
LD A,(IY + 3) ; GET BASE PORT OF CHIP
LD A,(IY + 2) ; GET BASE PORT OF CHIP
ADD A,6 ; BASE + 6 = CTU (DUART), MSR (1ST 16X50)
LD B,A ; B := CTU/MSR PORT ADDRESS
INC A ; BASE + 7 = CTL (DUART), SCR (1ST 16X50)
@ -605,11 +571,11 @@ DUART_DETECT:
CP $5A ; CHECK IT
JR NZ,DUART_DETECT_2681 ; OLD CHIP
;
; TEST FOR MR0 REGISTER, IN WHICH CASE WE HAVE A 2692 OF SOME SORT
; TEST FOR MR0 REGISTER, IN WHICH CASE WE HAVE A 26C92 OF SOME SORT
LD A,DUART_CR_MR0 ; SET MR POINTER TO MR0
DUART_OUTP(DUART_CR) ; THIS IS HARMLESS ON OTHER CHIPS
LD A,1 ; WRITE TEST VALUE TO MR0
DUART_OUTP(DUART_MR) ; WRITE TO MR0 ON 2692, MR2 STILL SET ON OTHERS
DUART_OUTP(DUART_MR) ; WRITE TO MR0 ON 26C92, MR2 STILL SET ON OTHERS
LD A,DUART_CR_MR1 ; SET MR POINTER TO MR1
DUART_OUTP(DUART_CR) ; THIS WORKS ON ALL CHIPS
XOR A ; WRITE 0 TO MR1
@ -620,7 +586,7 @@ DUART_DETECT:
DUART_OUTP(DUART_CR) ; POINTER IS STILL MR2 ON OTHER CHIPS
DUART_INP(DUART_MR) ; GET VALUE OF MR0 IN A
CP 1 ; CHECK FOR TEST VALUE
JR Z,DUART_DETECT_2692 ; YES, MUST BE A '92 WITH MR0
JR Z,DUART_DETECT_26C92 ; YES, MUST BE A '92 WITH MR0
JR DUART_DETECT_XR88C681 ; ASSUME WE HAVE A FANCY EXAR CHIP
;
@ -632,8 +598,8 @@ DUART_DETECT_2681:
LD A,DUART_2681
RET
;
DUART_DETECT_2692:
LD A,DUART_2692
DUART_DETECT_26C92:
LD A,DUART_26C92
RET
;
DUART_DETECT_XR88C681
@ -649,7 +615,7 @@ DUART_PRTCFG:
LD A,(IY) ; DEVICE NUM
CALL PRTDECB ; PRINT DEVICE NUM
PRTS(": IO=0x$") ; FORMATTING
LD A,(IY + 4) ; GET CHANNEL BASE PORT
LD A,(IY + 3) ; GET CHANNEL BASE PORT
CALL PRTHEXBYTE ; PRINT BASE PORT
; PRINT THE DUART TYPE
@ -669,16 +635,9 @@ DUART_PRTCFG:
RET Z ; IF ZERO, NOT PRESENT
;
PRTS(" MODE=$") ; FORMATTING
LD E,(IY + 7) ; LOAD CONFIG
LD D,(IY + 8) ; ... WORD TO DE
LD E,(IY + 8) ; LOAD CONFIG
LD D,(IY + 9) ; ... WORD TO DE
CALL PS_PRTSC0 ; PRINT CONFIG
;
#IF (DUART_DEBUG)
; DEBUG: DUMP BAUD TABLE ENTRY
PRTS(" BAUDTBL=$")
LD A,(IY + 5)
CALL PRTHEXBYTE
#ENDIF
;
XOR A
RET
@ -690,7 +649,7 @@ DUART_PRTCFG:
DUART_INP_IMP:
EX (SP),HL ; SWAP HL AND TOS
PUSH BC ; PRESERVE BC
LD A,(IY + 4) ; GET DUART IO BASE PORT
LD A,(IY + 3) ; GET DUART IO BASE PORT
OR (HL) ; OR IN REGISTER ID BITS
LD C,A ; C := PORT
IN A,(C) ; READ PORT INTO A
@ -705,7 +664,7 @@ DUART_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 + 4) ; GET DUART IO BASE PORT
LD A,(IY + 3) ; GET DUART IO BASE PORT
OR (HL) ; OR IN REGISTER ID BITS
LD C,A ; C := PORT
OUT (C),B ; WRITE VALUE TO PORT
@ -719,18 +678,28 @@ DUART_OUTP_IMP:
DUART_TYPE_MAP:
.DW DUART_STR_NONE
.DW DUART_STR_2681
.DW DUART_STR_2692
.DW DUART_STR_26C92
.DW DUART_STR_XR88C681
DUART_STR_NONE .DB "<NOT PRESENT>$"
DUART_STR_2681 .DB "2681$"
DUART_STR_2692 .DB "2692$"
DUART_STR_26C92 .DB "26C92$"
DUART_STR_XR88C681 .DB "XR88C681$"
;
; WORKING VARIABLES
;
DUART_DEV .DB 0 ; DEVICE NUM USED DURING INIT
;
; PER-CHIP VARIABLES
;
DUART0_ACR .DB 0 ; SHADOW ACR (DUART 0)
;
#IF (DUARTCNT >= 2)
;
DUART1_ACR .DB 0 ; SHADOW ACR (DUART 1)
;
#ENDIF
;
; DUART PORT TABLE
;
DUART_CFG:
@ -739,14 +708,12 @@ DUART0A_CFG:
; 1ST DUART MODULE CHANNEL A
.DB 0 ; IY DEVICE NUMBER (SET DURING INIT)
.DB 0 ; IY+1 DUART TYPE (SET DURING INIT)
.DB %00000000 ; IY+2 MODULE 0, CHANNEL A
.DB DUART0BASE ; IY+3 BASE PORT (CHIP)
.DB DUART0BASE + $00 ; IY+4 BASE PORT (CHANNEL)
.DB 0 ; IY+5 BAUD TABLE ENTRY (SET DURING INITDEV)
.DB 0 ; IY+6 SHADOW ACR (SET DURING INITDEV)
.DW DUART0ACFG ; IY+7 LINE CONFIGURATION
.DW DUART0CLK & $FFFF ; IY+9 CLOCK FREQ AS
.DW DUART0CLK >> 16 ; IY+11 ... DWORD VALUE
.DB DUART0BASE ; IY+2 BASE PORT (CHIP)
.DB DUART0BASE + $00 ; IY+3 BASE PORT (CHANNEL)
.DW DUART0B_CFG ; IY+4 POINTER TO OTHER CHANNEL
.DW DUART0_ACR ; IY+6 POINTER TO SHADOW ACR FOR THIS CHIP
.DW DUART0ACFG ; IY+8 LINE CONFIGURATION
.DB 1 ; IY+10 MULTIPLIER WRT 3.6864MHZ CLOCK
;
DUART_CFGSIZ .EQU $ - DUART_CFG ; SIZE OF ONE CFG TABLE ENTRY
;
@ -754,14 +721,12 @@ DUART0B_CFG:
; 1ST DUART MODULE CHANNEL B
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; DUART TYPE (SET DURING INIT)
.DB %00000001 ; MODULE 0, CHANNEL B
.DB DUART0BASE ; BASE PORT (CHIP)
.DB DUART0BASE + $08 ; BASE PORT (CHANNEL)
.DB 0 ; BAUD TABLE ENTRY (SET DURING INITDEV)
.DB 0 ; SHADOW ACR (SET DURING INITDEV)
.DW DUART0A_CFG ; POINTER TO OTHER CHANNEL
.DW DUART0_ACR ; POINTER TO SHADOW ACR FOR THIS CHIP
.DW DUART0BCFG ; LINE CONFIGURATION
.DW DUART0CLK & $FFFF ; CLOCK FREQ AS
.DW DUART0CLK >> 16 ; ... DWORD VALUE
.DB 1 ; MULTIPLIER WRT 3.6864MHZ CLOCK
;
#IF (DUARTCNT >= 2)
;
@ -769,27 +734,23 @@ DUART1A_CFG:
; 2ND DUART MODULE CHANNEL A
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; DUART TYPE (SET DURING INIT)
.DB %00000010 ; MODULE 1, CHANNEL A
.DB DUART1BASE ; BASE PORT (CHIP)
.DB DUART1BASE + $00 ; BASE PORT (CHANNEL)
.DB 0 ; BAUD TABLE ENTRY (SET DURING INITDEV)
.DB 0 ; SHADOW ACR (SET DURING INITDEV)
.DW DUART1B_CFG ; POINTER TO OTHER CHANNEL
.DW DUART1_ACR ; POINTER TO SHADOW ACR FOR THIS CHIP
.DW DUART1ACFG ; LINE CONFIGURATION
.DW DUART1CLK & $FFFF ; CLOCK FREQ AS
.DW DUART1CLK >> 16 ; ... DWORD VALUE
.DB 1 ; MULTIPLIER WRT 3.6864MHZ CLOCK
;
DUART1B_CFG:
; 2ND DUART MODULE CHANNEL B
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; DUART TYPE (SET DURING INIT)
.DB %00000011 ; MODULE 1, CHANNEL B
.DB DUART1BASE ; BASE PORT (CHIP)
.DB DUART1BASE + $08 ; BASE PORT (CHANNEL)
.DB 0 ; BAUD TABLE ENTRY (SET DURING INITDEV)
.DB 0 ; SHADOW ACR (SET DURING INITDEV)
.DW DUART1A_CFG ; POINTER TO OTHER CHANNEL
.DW DUART1_ACR ; POINTER TO SHADOW ACR FOR THIS CHIP
.DW DUART1BCFG ; LINE CONFIGURATION
.DW DUART1CLK & $FFFF ; CLOCK FREQ AS
.DW DUART1CLK >> 16 ; ... DWORD VALUE
.DB 1 ; MULTIPLIER WRT 3.6864MHZ CLOCK
;
#ENDIF
;

Loading…
Cancel
Save