|
|
|
@ -144,6 +144,12 @@ DUART_SR_PARITY .EQU %00100000 ; PARITY ERROR |
|
|
|
DUART_SR_FRAMING .EQU %01000000 ; FRAMING ERROR |
|
|
|
DUART_SR_BREAK .EQU %10000000 ; RECEIVED BREAK |
|
|
|
; |
|
|
|
; DUART MODE REGISTER 0 |
|
|
|
; |
|
|
|
DUART_MR0_NORMAL .EQU %00000000 ; NORMAL BAUD RATE TABLE |
|
|
|
DUART_MR0_EXT1 .EQU %00000001 ; EXTENDED BAUD RATE TABLE 1 |
|
|
|
DUART_MR0_EXT2 .EQU %00000100 ; EXTENDED BAUD RATE TABLE 2 |
|
|
|
; |
|
|
|
; DUART MODE REGISTER 1 |
|
|
|
; |
|
|
|
DUART_MR1_RXRTS .EQU %10000000 ; RECEIVER CONTROLS RTS |
|
|
|
@ -341,33 +347,16 @@ DUART_INITDEV1A: |
|
|
|
DUART_OUTP(DUART_CR) ; RESET TRANSMITTER |
|
|
|
LD A,DUART_CR_RESET_ERR |
|
|
|
DUART_OUTP(DUART_CR) ; RESET ERROR STATUS |
|
|
|
LD A,L ; GET BAUD TABLE ENTRY IN A |
|
|
|
AND DUART_BAUD_X1 ; SEE IF SELECT EXTEND BIT SHOULD BE SET |
|
|
|
JR Z,DUART_INITDEV2 ; NO, CLEAR IT |
|
|
|
LD A,DUART_CR_SET_RX_X ; YES, SET EXTEND BIT |
|
|
|
DUART_OUTP(DUART_CR) ; SET FOR RECEIVER |
|
|
|
LD A,DUART_CR_SET_TX_X |
|
|
|
DUART_OUTP(DUART_CR) ; SET FOR TRANSMITTER |
|
|
|
JR DUART_INITDEV3 |
|
|
|
LD A,(IY + 1) ; GET DUART TYPE |
|
|
|
CP DUART_26C92 ; IS IT A 26C92? |
|
|
|
JR Z,DUART_INITDEV1B ; YES |
|
|
|
CALL DUART_SETBAUD_681 ; NO, CALL '681 BRG SETUP |
|
|
|
JR DUART_INITDEV2 |
|
|
|
; |
|
|
|
DUART_INITDEV2: |
|
|
|
; CLEAR EXTEND BIT |
|
|
|
LD A,DUART_CR_CLR_RX_X |
|
|
|
DUART_OUTP(DUART_CR) ; CLEAR FOR RECEIVER |
|
|
|
LD A,DUART_CR_CLR_TX_X |
|
|
|
DUART_OUTP(DUART_CR) ; CLEAR FOR TRANSMITTER |
|
|
|
DUART_INITDEV1B: |
|
|
|
CALL DUART_SETBAUD_92 ; CALL '92 BRG SETUP |
|
|
|
; |
|
|
|
DUART_INITDEV3: |
|
|
|
; SET BRG CLOCK SELECT |
|
|
|
LD A,L ; GET BAUD TABLE ENTRY IN A |
|
|
|
AND $0F ; GET CLOCK SELECT BITS |
|
|
|
LD L,A ; SAVE IT IN L |
|
|
|
RLA |
|
|
|
RLA |
|
|
|
RLA |
|
|
|
RLA ; MOVE IT INTO THE HIGH NIBBLE |
|
|
|
OR L ; AND MERGE BACK IN LOW NIBBLE |
|
|
|
DUART_OUTP(DUART_CSR) ; SET CLOCK SELECT |
|
|
|
DUART_INITDEV2: |
|
|
|
; |
|
|
|
; SET PARITY AND WORD SIZE |
|
|
|
LD A,DUART_CR_MR1 |
|
|
|
@ -420,13 +409,59 @@ DUART_INITDEV5: |
|
|
|
; |
|
|
|
DUART_INITDEVZ: |
|
|
|
; |
|
|
|
#IF (DUART_DEBUG) |
|
|
|
PRTC(']') |
|
|
|
#ENDIF |
|
|
|
; INVALID BAUD RATE |
|
|
|
DEC A ; A WAS $00, GET BACK $FF |
|
|
|
RET ; RETURN ERROR STATUS |
|
|
|
; |
|
|
|
; INITIALIZE BRG FOR '681 DUART |
|
|
|
; |
|
|
|
DUART_SETBAUD_681: |
|
|
|
; SET ACR |
|
|
|
LD C,(IY + 6) ; GET SHADOW ACR FOR THIS CHIP |
|
|
|
LD B,(IY + 7) ; BC IS POINTER |
|
|
|
LD A,(BC) ; GET SHADOW ACR IN A |
|
|
|
AND %01111111 ; MASK OUT BIT 7 |
|
|
|
LD H,A ; SAVE IT IN H |
|
|
|
LD A,L ; TABLE ENTRY IS IN L, GET IT IN A |
|
|
|
AND DUART_BAUD_ACR7 ; SEE IF ACR[7] SHOULD BE SET (BIT MASK SHOULD ACTUALLY _BE_ BIT 7) |
|
|
|
OR H ; MERGE IN REST OF ACR |
|
|
|
LD H,A ; SAVE IT IN H |
|
|
|
LD A,(IY + 2) ; GET CHIP BASE IN A |
|
|
|
ADD A,DUART_ACR ; ADD OFFSET OF ACR |
|
|
|
LD C,A ; C = ACR PORT |
|
|
|
; YES, THIS OVERWRITES ACR[7] REGARDLESS OF THE OTHER CHANNEL, |
|
|
|
; BUT CURRENTLY THE TABLE IS SET SO EVERY VALID RATE HAS ACR[7] SET |
|
|
|
OUT (C),H ; WRITE VALUE |
|
|
|
; SELECT PER-CHANNEL EXTENDED TABLE |
|
|
|
LD A,L ; CALLED WITH TABLE ENTRY IN L, MOVE IT TO A |
|
|
|
AND DUART_BAUD_X1 ; SEE IF SELECT EXTEND BIT SHOULD BE SET |
|
|
|
JR Z,DUART_SETBAUD_681A ; NO, CLEAR IT |
|
|
|
LD A,DUART_CR_SET_RX_X ; YES, SET EXTEND BIT |
|
|
|
DUART_OUTP(DUART_CR) ; SET FOR RECEIVER |
|
|
|
LD A,DUART_CR_SET_TX_X |
|
|
|
DUART_OUTP(DUART_CR) ; SET FOR TRANSMITTER |
|
|
|
JR DUART_SETBAUD_681B |
|
|
|
; |
|
|
|
DUART_SETBAUD_681A: |
|
|
|
; CLEAR EXTEND BIT |
|
|
|
LD A,DUART_CR_CLR_RX_X |
|
|
|
DUART_OUTP(DUART_CR) ; CLEAR FOR RECEIVER |
|
|
|
LD A,DUART_CR_CLR_TX_X |
|
|
|
DUART_OUTP(DUART_CR) ; CLEAR FOR TRANSMITTER |
|
|
|
; |
|
|
|
DUART_SETBAUD_681B: |
|
|
|
; SET BRG CLOCK SELECT |
|
|
|
LD A,L ; GET BAUD TABLE ENTRY IN A |
|
|
|
AND $0F ; GET CLOCK SELECT BITS |
|
|
|
LD L,A ; SAVE IT IN L |
|
|
|
RLA |
|
|
|
RLA |
|
|
|
RLA |
|
|
|
RLA ; MOVE IT INTO THE HIGH NIBBLE |
|
|
|
OR L ; AND MERGE BACK IN LOW NIBBLE |
|
|
|
DUART_OUTP(DUART_CSR) ; SET CLOCK SELECT |
|
|
|
RET |
|
|
|
; |
|
|
|
DUART_BAUDTBL_681: |
|
|
|
; ASSUME XR88C681 RUNS AT 3.6864MHZ |
|
|
|
.DB %0000 | DUART_BAUD_X1 ; 75 |
|
|
|
@ -462,6 +497,64 @@ DUART_BAUDTBL_681: |
|
|
|
.DB DUART_BAUD_INV ; 3686400 |
|
|
|
.DB DUART_BAUD_INV ; 7372800 |
|
|
|
; |
|
|
|
; INITIALIZE BRG FOR '92 DUART |
|
|
|
; |
|
|
|
DUART_SETBAUD_92: |
|
|
|
; SET ACR |
|
|
|
LD C,(IY + 6) ; GET SHADOW ACR FOR THIS CHIP |
|
|
|
LD B,(IY + 7) ; BC IS POINTER |
|
|
|
LD A,(BC) ; GET SHADOW ACR IN A |
|
|
|
AND %01111111 ; MASK OUT BIT 7 |
|
|
|
LD H,A ; SAVE IT IN H |
|
|
|
LD A,L ; TABLE ENTRY IS IN L, GET IT IN A |
|
|
|
AND DUART_BAUD_ACR7 ; SEE IF ACR[7] SHOULD BE SET (BIT MASK SHOULD ACTUALLY _BE_ BIT 7) |
|
|
|
OR H ; MERGE IN REST OF ACR |
|
|
|
LD H,A ; SAVE IT IN H |
|
|
|
LD A,(IY + 2) ; GET CHIP BASE IN A |
|
|
|
ADD A,DUART_ACR ; ADD OFFSET OF ACR |
|
|
|
LD C,A ; C = ACR PORT |
|
|
|
; YES, THIS OVERWRITES ACR[7] REGARDLESS OF THE OTHER CHANNEL, |
|
|
|
; BUT CURRENTLY THE TABLE IS SET SO EVERY VALID RATE HAS ACR[7] SET |
|
|
|
OUT (C),H ; WRITE VALUE |
|
|
|
; SELECT NORMAL OR EXTENDED BAUD RATE TABLES |
|
|
|
LD H,DUART_MR0_NORMAL ; ASSUME NORMAL |
|
|
|
LD A,L ; GET TABLE ENTRY IN A AGAIN |
|
|
|
AND DUART_BAUD_EXT1 ; SHOULD EXT1 BE SET? |
|
|
|
JR Z,DUART_SETBAUD_92A ; NO, CHECK NEXT VALUE |
|
|
|
LD H,DUART_MR0_EXT1 ; YES, SET IT |
|
|
|
JR DUART_SETBAUD_92C |
|
|
|
; |
|
|
|
DUART_SETBAUD_92A: |
|
|
|
LD A,L ; GET TABLE ENTRY IN A ONCE MORE |
|
|
|
AND DUART_BAUD_EXT2 ; SHOULD EXT2 BE SET? |
|
|
|
JR Z,DUART_SETBAUD_92C ; NO, CONTINUE |
|
|
|
LD H,DUART_MR0_EXT2 ; YES, SET IT |
|
|
|
; |
|
|
|
DUART_SETBAUD_92C: |
|
|
|
; H NOW CONTAINS MR0 |
|
|
|
LD A,(IY + 2) ; GET CHIP BASE IN A |
|
|
|
ADD A,DUART_CR ; WE WANT TO WRITE THE COMMAND REGISTER OF CHANNEL A, EVEN IF WE'RE CHANNEL B |
|
|
|
LD C,A ; C = CRA |
|
|
|
LD A,DUART_CR_MR0 ; RESET MR POINTER TO MR0 |
|
|
|
OUT (C),A ; WRITE COMMAND |
|
|
|
LD A,(IY + 2) ; GET CHIP BASE IN A |
|
|
|
ADD A,DUART_MR ; NOW WE WANT TO WRITE TO MR0 OF CHANNEL A |
|
|
|
LD C,A ; C = MRA |
|
|
|
; AS WITH ACR[7] THE TABLE IS SET SO EVERY VALID RATE IS FROM |
|
|
|
; THE SAME TABLE |
|
|
|
OUT (C),H |
|
|
|
; SET BRG CLOCK SELECT |
|
|
|
LD A,L ; GET BAUD TABLE ENTRY IN A YET AGAIN |
|
|
|
AND $0F ; GET CLOCK SELECT BITS |
|
|
|
LD L,A ; SAVE IT IN L |
|
|
|
RLA |
|
|
|
RLA |
|
|
|
RLA |
|
|
|
RLA ; MOVE IT INTO THE HIGH NIBBLE |
|
|
|
OR L ; AND MERGE BACK IN LOW NIBBLE |
|
|
|
DUART_OUTP(DUART_CSR) ; SET CLOCK SELECT OF CURRENT CHANNEL |
|
|
|
RET |
|
|
|
; |
|
|
|
DUART_BAUDTBL_92: |
|
|
|
; ASSUME SC26C92 RUNS AT 7.3728MHZ |
|
|
|
.DB DUART_BAUD_INV ; 75 |
|
|
|
@ -530,12 +623,21 @@ DUART_DETECT: |
|
|
|
; |
|
|
|
; FIRST SEE IF IT LOOKS LIKE A 16X50-STYLE UART |
|
|
|
LD A,(IY + 2) ; GET BASE PORT OF CHIP |
|
|
|
ADD A,6 ; BASE + 6 = CTU (DUART), MSR (1ST 16X50) |
|
|
|
ADD A,4 ; BASE + 4 = ACR (DUART), MCR (1ST 16X50) |
|
|
|
LD H,A ; H := ACR/MCR PORT ADDRESS |
|
|
|
ADD A,2 ; BASE + 6 = CTU (DUART), MSR (1ST 16X50) |
|
|
|
LD B,A ; B := CTU/MSR PORT ADDRESS |
|
|
|
INC A ; BASE + 7 = CTL (DUART), SCR (1ST 16X50) |
|
|
|
LD D,A ; D := CTL/SCR PORT ADDRESS |
|
|
|
ADD A,7 ; BASE + 14 = STCR (DUART), MSR (2ND 16X50) |
|
|
|
LD E,A ; E := STCR/MSR PORT ADDRESS |
|
|
|
INC A ; BASE + 15 = SPCR (DUART), SCR (2ND 16X50) |
|
|
|
LD C,A ; SPCR |
|
|
|
IN A,(C) ; STOP COUNTER/TIMER, JUST IN CASE |
|
|
|
LD C,H ; ACR/MCR |
|
|
|
IN L,(C) ; GET ORIGINAL VALUE (ACTUALLY IPCR ON DUART) IN L |
|
|
|
LD A,$30 ; ENABLE A SOURCE FOR THE COUNTER/TIMER |
|
|
|
OUT (C),A ; WRITE TO ACR/MCR |
|
|
|
LD A,$A5 ; TEST VALUE |
|
|
|
LD C,B ; CTU |
|
|
|
OUT (C),A ; WRITE TEST VALUE TO CTU |
|
|
|
@ -544,6 +646,10 @@ DUART_DETECT: |
|
|
|
OUT (C),A ; WRITE LARGE VALUE TO CTL |
|
|
|
LD C,E ; STCR |
|
|
|
IN A,(C) ; START COUNTER/TIMER (LATCH CTU, CTL) |
|
|
|
INC C ; C := SPCR |
|
|
|
IN A,(C) ; STOP COUNTER/TIMER |
|
|
|
LD C,H ; ACR/MCR |
|
|
|
OUT (C),L ; WRITE ORIGINAL VALUE OF MCR (ACR GETS SET ON DUART LATER) |
|
|
|
LD C,B ; CTU |
|
|
|
IN A,(C) ; READ BACK TEST VALUE |
|
|
|
CP $A5 ; CHECK FOR TEST VALUE |
|
|
|
|