From add0f3df07e563cfaada5582a41101ecd5b14878 Mon Sep 17 00:00:00 2001 From: b1ackmai1er <39449559+b1ackmai1er@users.noreply.github.com> Date: Fri, 3 Aug 2018 19:46:24 +0800 Subject: [PATCH 1/5] Separate the baud encoding conditional for readability --- Source/HBIOS/siobaud.inc | 390 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100644 Source/HBIOS/siobaud.inc diff --git a/Source/HBIOS/siobaud.inc b/Source/HBIOS/siobaud.inc new file mode 100644 index 00000000..bb819775 --- /dev/null +++ b/Source/HBIOS/siobaud.inc @@ -0,0 +1,390 @@ +; +; SIOBAUD1, SIOBAUD2, SIOBAUD3, SIOBAUD4 ARE SET TO THE +; ENCODED VALUE OF EACH POSSIBLE BAUD RATE WITH A FIXED CLOCK. +; + +#IF (DEFSIOCLK/DEFSIODIV/1 == 75) +SIOBAUD1 .EQU 0 E +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 150) +SIOBAUD1 .EQU 1 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 300) +SIOBAUD1 .EQU 2 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 600) +SIOBAUD1 .EQU 3 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 1200) +SIOBAUD1 .EQU 4 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 2400) +SIOBAUD1 .EQU 5 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 4800) +SIOBAUD1 .EQU 6 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 9600) +SIOBAUD1 .EQU 7 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 19200) +SIOBAUD1 .EQU 8 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 38400) +SIOBAUD1 .EQU 9 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 76800) +SIOBAUD1 .EQU 10 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 153600) +SIOBAUD1 .EQU 11 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 307200) +SIOBAUD1 .EQU 12 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 614400) +SIOBAUD1 .EQU 13 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 ==1228800) +SIOBAUD1 .EQU 14 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 ==2457600) +SIOBAUD1 .EQU 15 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 225) +SIOBAUD1 .EQU 16 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 450) +SIOBAUD1 .EQU 17 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 900) +SIOBAUD1 .EQU 18 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 1800) +SIOBAUD1 .EQU 19 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 3600) +SIOBAUD1 .EQU 20 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 7200) +SIOBAUD1 .EQU 21 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 14400) +SIOBAUD1 .EQU 22 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 28800) +SIOBAUD1 .EQU 23 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 57600) +SIOBAUD1 .EQU 24 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 115200) +SIOBAUD1 .EQU 25 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 230400) +SIOBAUD1 .EQU 26 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 == 921600) +SIOBAUD1 .EQU 28 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 ==1843200) +SIOBAUD1 .EQU 29 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 ==3686400) +SIOBAUD1 .EQU 30 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/1 ==7372800) +SIOBAUD1 .EQU 31 +#ENDIF + + +#IF (DEFSIOCLK/DEFSIODIV/16 == 75) +SIOBAUD2 .EQU 0 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 150) +SIOBAUD2 .EQU 1 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 300) +SIOBAUD2 .EQU 2 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 600) +SIOBAUD2 .EQU 3 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 1200) +SIOBAUD2 .EQU 4 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 2400) +SIOBAUD2 .EQU 5 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 4800) +SIOBAUD2 .EQU 6 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 9600) +SIOBAUD2 .EQU 7 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 19200) +SIOBAUD2 .EQU 8 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 38400) +SIOBAUD2 .EQU 9 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 76800) +SIOBAUD2 .EQU 10 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 153600) +SIOBAUD2 .EQU 11 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 307200) +SIOBAUD2 .EQU 12 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 614400) +SIOBAUD2 .EQU 13 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 ==1228800) +SIOBAUD2 .EQU 14 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 ==2457600) +SIOBAUD2 .EQU 15 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 225) +SIOBAUD2 .EQU 16 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 450) +SIOBAUD2 .EQU 17 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 900) +SIOBAUD2 .EQU 18 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 1800) +SIOBAUD2 .EQU 19 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 3600) +SIOBAUD2 .EQU 20 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 7200) +SIOBAUD2 .EQU 21 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 14400) +SIOBAUD2 .EQU 22 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 28800) +SIOBAUD2 .EQU 23 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 57600) +SIOBAUD2 .EQU 24 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 115200) +SIOBAUD2 .EQU 25 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 230400) +SIOBAUD2 .EQU 26 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 460800) +SIOBAUD2 .EQU 27 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 == 921600) +SIOBAUD2 .EQU 28 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 ==1843200) +SIOBAUD2 .EQU 29 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 ==3686400) +SIOBAUD2 .EQU 30 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/16 ==7372800) +SIOBAUD2 .EQU 31 +#ENDIF + +#IF (DEFSIOCLK/DEFSIODIV/32== 75) +SIOBAUD3 .EQU 0 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 150) +SIOBAUD3 .EQU 1 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 300) +SIOBAUD3 .EQU 2 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 600) +SIOBAUD3 .EQU 3 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 1200) +SIOBAUD3 .EQU 4 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 2400) +SIOBAUD3 .EQU 5 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 4800) +SIOBAUD3 .EQU 6 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 9600) +SIOBAUD3 .EQU 7 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 19200) +SIOBAUD3 .EQU 8 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 38400) +SIOBAUD3 .EQU 9 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 76800) +SIOBAUD3 .EQU 10 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 153600) +SIOBAUD3 .EQU 11 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 307200) +SIOBAUD3 .EQU 12 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 614400) +SIOBAUD3 .EQU 13 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32==1228800) +SIOBAUD3 .EQU 14 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32==2457600) +SIOBAUD3 .EQU 15 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 225) +SIOBAUD3 .EQU 16 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 450) +SIOBAUD3 .EQU 17 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 900) +SIOBAUD3 .EQU 18 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 1800) +SIOBAUD3 .EQU 19 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 3600) +SIOBAUD3 .EQU 20 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 7200) +SIOBAUD3 .EQU 21 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 14400) +SIOBAUD3 .EQU 22 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 28800) +SIOBAUD3 .EQU 23 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 57600) +SIOBAUD3 .EQU 24 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 115200) +SIOBAUD3 .EQU 25 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 230400) +SIOBAUD3 .EQU 26 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 460800) +SIOBAUD3 .EQU 27 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32== 921600) +SIOBAUD3 .EQU 28 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32==1843200) +SIOBAUD3 .EQU 29 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32==3686400) +SIOBAUD3 .EQU 30 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/32==7372800) +SIOBAUD3 .EQU 31 +#ENDIF + +#IF (DEFSIOCLK/DEFSIODIV/64== 75) +SIOBAUD4 .EQU 0 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 150) +SIOBAUD4 .EQU 1 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 300) +SIOBAUD4 .EQU 2 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 600) +SIOBAUD4 .EQU 3 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 1200) +SIOBAUD4 .EQU 4 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 2400) +SIOBAUD4 .EQU 5 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 4800) +SIOBAUD4 .EQU 6 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 9600) +SIOBAUD4 .EQU 7 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 19200) +SIOBAUD4 .EQU 8 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 38400) +SIOBAUD4 .EQU 9 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 76800) +SIOBAUD4 .EQU 10 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 153600) +SIOBAUD4 .EQU 11 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 307200) +SIOBAUD4 .EQU 12 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 614400) +SIOBAUD4 .EQU 13 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64==1228800) +SIOBAUD4 .EQU 14 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64==2457600) +SIOBAUD4 .EQU 15 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 225) +SIOBAUD4 .EQU 16 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 450) +SIOBAUD4 .EQU 17 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 900) +SIOBAUD4 .EQU 18 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 1800) +SIOBAUD4 .EQU 19 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 3600) +SIOBAUD4 .EQU 20 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 7200) +SIOBAUD4 .EQU 21 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 14400) +SIOBAUD4 .EQU 22 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 28800) +SIOBAUD4 .EQU 23 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 57600) +SIOBAUD4 .EQU 24 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 115200) +SIOBAUD4 .EQU 25 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 230400) +SIOBAUD4 .EQU 26 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 460800) +SIOBAUD4 .EQU 27 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64== 921600) +SIOBAUD4 .EQU 28 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64==1843200) +SIOBAUD4 .EQU 29 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64==3686400) +SIOBAUD4 .EQU 30 +#ENDIF +#IF (DEFSIOCLK/DEFSIODIV/64==7372800) +SIOBAUD4 .EQU 31 +#ENDIF From f66b6f155e2be5cd61b068cfe0ee5986af66d13d Mon Sep 17 00:00:00 2001 From: b1ackmai1er <39449559+b1ackmai1er@users.noreply.github.com> Date: Fri, 3 Aug 2018 22:37:17 +0800 Subject: [PATCH 2/5] Fixes port address and cleanups --- sio.asm | 725 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 725 insertions(+) create mode 100644 sio.asm diff --git a/sio.asm b/sio.asm new file mode 100644 index 00000000..c30ab09f --- /dev/null +++ b/sio.asm @@ -0,0 +1,725 @@ +; +;================================================================================================== +; SIO DRIVER (SERIAL PORT) +;================================================================================================== +; +; SETUP PARAMETER WORD: +; +-------+---+-------------------+ +---+---+-----------+---+-------+ +; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 | +; +-------+---+---+---------------+ ----+---+-----------+---+-------+ +; F E D C B A 9 8 7 6 5 4 3 2 1 0 +; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- +; +; FOR THE ECB-ZILOG-PERIPHERALS BOARD, INFORMATION ON JUMPER SETTINGS +; AND BAUD RATES CAN BE FOUND HERE: +; https://www.retrobrewcomputers.org/doku.php?id=boards:ecb:zilog-peripherals:clock-divider +; +; SIO PORT A (COM1:) and SIO PORT B (COM2:) ARE MAPPED TO DEVICE UC1: AND UL1: IN CP/M. +; +SIO_NONE .EQU 0 +SIO_SIO .EQU 1 +; +#IF (SIOMODE == SIOMODE_RC) +SIOA_CMD .EQU SIOBASE + $00 +SIOA_DAT .EQU SIOBASE + $01 +SIOB_CMD .EQU SIOBASE + $02 +SIOB_DAT .EQU SIOBASE + $03 +#ENDIF +; +#IF (SIOMODE == SIOMODE_SMB) +SIOA_CMD .EQU SIOBASE + $02 +SIOA_DAT .EQU SIOBASE + $00 +SIOB_CMD .EQU SIOBASE + $03 +SIOB_DAT .EQU SIOBASE + $01 +#ENDIF +; +#IF (SIOMODE == SIOMODE_ZP) +SIOA_CMD .EQU SIOBASE + $06 +SIOA_DAT .EQU SIOBASE + $04 +SIOB_CMD .EQU SIOBASE + $07 +SIOB_DAT .EQU SIOBASE + $05 +#ENDIF +; +; CONDITIONALS THAT DETERMINE THE ENCODED VALUE OF THE BAUD RATE +; +#INCLUDE "siobaud.inc" +; +SIO_PREINIT: +; +; SETUP THE DISPATCH TABLE ENTRIES +; + LD B,SIO_CNT ; LOOP CONTROL + LD C,0 ; PHYSICAL UNIT INDEX + XOR A ; ZERO TO ACCUM + LD (SIO_DEV),A ; CURRENT DEVICE NUMBER +SIO_PREINIT0: + PUSH BC ; SAVE LOOP CONTROL + LD A,C ; PHYSICAL UNIT TO A + RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES) + RLCA ; ... + RLCA ; ... TO GET OFFSET INTO CFG TABLE + LD HL,SIO_CFG ; POINT TO START OF CFG TABLE + CALL ADDHLA ; HL := ENTRY ADDRESS + PUSH HL ; SAVE IT + PUSH HL ; COPY CFG DATA PTR + POP IY ; ... TO IY + CALL SIO_INITUNIT ; HAND OFF TO GENERIC INIT CODE + POP DE ; GET ENTRY ADDRESS BACK, BUT PUT IN DE + POP BC ; RESTORE LOOP CONTROL +; + LD A,(IY+1) ; GET THE SIO TYPE DETECTED + OR A ; SET FLAGS + JR Z,SIO_PREINIT2 ; SKIP IT IF NOTHING FOUND +; + PUSH BC ; SAVE LOOP CONTROL + LD BC,SIO_FNTBL ; BC := FUNCTION TABLE ADDRESS + CALL NZ,CIO_ADDENT ; ADD ENTRY IF SIO FOUND, BC:DE + POP BC ; RESTORE LOOP CONTROL +; +SIO_PREINIT2: + INC C ; NEXT PHYSICAL UNIT + DJNZ SIO_PREINIT0 ; LOOP UNTIL DONE +; +#IF (INTMODE == 1) + ; ADD IM1 INT CALL LIST ENTRY IF APPROPRIATE + LD A,(SIO_DEV) ; GET NEXT DEVICE NUM + OR A ; SET FLAGS + JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES + LD HL,SIO_INT ; GET INT VECTOR + CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST +#ENDIF +; +#IF (INTMODE == 2) + ; SETUP SIO INTERRUPT VECTOR IN IVT + LD HL,INT_SIO + LD (HBX_IVT + IVT_SER0),HL +#ENDIF +; +SIO_PREINIT3: + XOR A ; SIGNAL SUCCESS + RET ; AND RETURN +; +; SIO INITIALIZATION ROUTINE +; +SIO_INITUNIT: + CALL SIO_DETECT ; DETERMINE SIO TYPE + LD (IY+1),A ; SAVE IN CONFIG TABLE + OR A ; SET FLAGS + RET Z ; ABORT IF NOTHING THERE + + ; UPDATE WORKING SIO DEVICE NUM + LD HL,SIO_DEV ; POINT TO CURRENT UART DEVICE NUM + LD A,(HL) ; PUT IN ACCUM + INC (HL) ; INCREMENT IT (FOR NEXT LOOP) + LD (IY),A ; UPDATE UNIT NUM + + ; SET DEFAULT CONFIG + LD DE,-1 ; LEAVE CONFIG ALONE + JP SIO_INITDEV ; IMPLEMENT IT AND RETURN +; +; +; +SIO_INIT: + LD B,SIO_CNT ; COUNT OF POSSIBLE SIO UNITS + LD C,0 ; INDEX INTO SIO CONFIG TABLE +SIO_INIT1: + PUSH BC ; SAVE LOOP CONTROL + + LD A,C ; PHYSICAL UNIT TO A + RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES) + RLCA ; ... + RLCA ; ... TO GET OFFSET INTO CFG TABLE + LD HL,SIO_CFG ; POINT TO START OF CFG TABLE + CALL ADDHLA ; HL := ENTRY ADDRESS + PUSH HL ; COPY CFG DATA PTR + POP IY ; ... TO IY + + LD A,(IY+1) ; GET SIO TYPE + OR A ; SET FLAGS + CALL NZ,SIO_PRTCFG ; PRINT IF NOT ZERO + + POP BC ; RESTORE LOOP CONTROL + INC C ; NEXT UNIT + DJNZ SIO_INIT1 ; LOOP TILL DONE +; + XOR A ; SIGNAL SUCCESS + RET ; DONE +; +; RECEIVE INTERRUPT HANDLER +; +#IF (INTMODE > 0) +; +SIO_INT: +SIOA_INT: + ; CHECK FOR RECEIVE PENDING ON CHANNEL A + XOR A ; A := 0 + OUT (SIOA_CMD),A ; ADDRESS RD0 + IN A,(SIOA_CMD) ; GET RD0 + AND $01 ; ISOLATE RECEIVE READY BIT + JR Z,SIOB_INT ; CHECK CHANNEL B +; +SIOA_INT00: + ; HANDLE CHANNEL A + IN A,(SIOA_DAT) ; READ PORT + LD E,A ; SAVE BYTE READ + LD A,(SIOA_CNT) ; GET CURRENT BUFFER USED COUNT + CP SIOA_BUFSZ ; COMPARE TO BUFFER SIZE + RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED + INC A ; INCREMENT THE COUNT + LD (SIOA_CNT),A ; AND SAVE IT + CP SIOA_BUFSZ - 5 ; BUFFER GETTING FULL? + JR NZ,SIOA_INT0 ; IF NOT, BYPASS CLEARING RTS + LD A,5 ; RTS IS IN WR5 + OUT (SIOA_CMD),A ; ADDRESS WR5 + LD A,$E8 ; VALUE TO CLEAR RTS + OUT (SIOA_CMD),A ; DO IT +SIOA_INT0: + LD HL,(SIOA_HD) ; GET HEAD POINTER + LD A,L ; GET LOW BYTE + CP SIOA_BUFEND & $FF ; PAST END? + JR NZ,SIOA_INT1 ; IF NOT, BYPASS POINTER RESET + LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER +SIOA_INT1: + LD A,E ; RECOVER BYTE READ + LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION + INC HL ; INCREMENT HEAD POINTER + LD (SIOA_HD),HL ; SAVE IT +; + ; CHECK FOR MORE PENDING... + XOR A ; A := 0 + OUT (SIOA_CMD),A ; ADDRESS RD0 + IN A,(SIOA_CMD) ; GET RD0 + RRA ; READY BIT TO CF + JR C,SIOA_INT00 ; IF SET, DO SOME MORE + OR $FF ; NZ SET TO INDICATE INT HANDLED + RET ; AND RETURN +; +SIOB_INT: + ; CHECK FOR RECEIVE PENDING ON CHANNEL B + XOR A ; A := 0 + OUT (SIOB_CMD),A ; ADDRESS RD0 + IN A,(SIOB_CMD) ; GET RD0 + AND $01 ; ISOLATE RECEIVE READY BIT + RET Z ; IF NOT, RETURN WITH Z SET +; +SIOB_INT00: + ; HANDLE CHANNEL B + IN A,(SIOB_DAT) ; READ PORT + LD E,A ; SAVE BYTE READ + LD A,(SIOB_CNT) ; GET CURRENT BUFFER USED COUNT + CP SIOB_BUFSZ ; COMPARE TO BUFFER SIZE + RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED + INC A ; INCREMENT THE COUNT + LD (SIOB_CNT),A ; AND SAVE IT + CP SIOB_BUFSZ - 5 ; BUFFER GETTING FULL? + JR NZ,SIOB_INT0 ; IF NOT, BYPASS CLEARING RTS + LD A,5 ; RTS IS IN WR5 + OUT (SIOB_CMD),A ; ADDRESS WR5 + LD A,$E8 ; VALUE TO CLEAR RTS + OUT (SIOB_CMD),A ; DO IT +SIOB_INT0: + LD HL,(SIOB_HD) ; GET HEAD POINTER + LD A,L ; GET LOW BYTE + CP SIOB_BUFEND & $FF ; PAST END? + JR NZ,SIOB_INT1 ; IF NOT, BYPASS POINTER RESET + LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER +SIOB_INT1: + LD A,E ; RECOVER BYTE READ + LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION + INC HL ; INCREMENT HEAD POINTER + LD (SIOB_HD),HL ; SAVE IT +; + ; CHECK FOR MORE PENDING... + XOR A ; A := 0 + OUT (SIOB_CMD),A ; ADDRESS RD0 + IN A,(SIOB_CMD) ; GET RD0 + RRA ; READY BIT TO CF + JR C,SIOB_INT00 ; IF SET, DO SOME MORE + OR $FF ; NZ SET TO INDICATE INT HANDLED + RET ; AND RETURN +; +#ENDIF +; +; DRIVER FUNCTION TABLE +; +SIO_FNTBL: + .DW SIO_IN + .DW SIO_OUT + .DW SIO_IST + .DW SIO_OST + .DW SIO_INITDEV + .DW SIO_QUERY + .DW SIO_DEVICE +#IF (($ - SIO_FNTBL) != (CIO_FNCNT * 2)) + .ECHO "*** INVALID SIO FUNCTION TABLE ***\n" +#ENDIF +; +; +; +#IF (INTMODE == 0) +; +SIO_IN: + CALL SIO_IST ; CHAR WAITING? + JR Z,SIO_IN ; LOOP IF NOT + LD C,(IY+3) ; C := SIO CMD PORT +#IF (SIOMODE == SIOMODE_RC) + INC C ; BUMP TO DATA PORT +#ENDIF +#IF ((SIOMODE == SIOMODE_SMB) | (SIOMODE == SIOMODE_ZP)) + DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT + DEC C +#ENDIF + IN E,(C) ; GET CHAR + XOR A ; SIGNAL SUCCESS + RET +; +#ELSE +; +SIO_IN: + LD A,(IY+2) ; GET CHANNEL + OR A ; SET FLAGS + JR Z,SIOA_IN ; HANDLE CHANNEL A + DEC A ; TEST FOR NEXT DEVICE + JR Z,SIOB_IN ; HANDLE CHANNEL B + CALL PANIC ; ELSE FATAL ERROR + RET ; ... AND RETURN +; +SIOA_IN: + CALL SIOA_IST ; RECEIVED CHAR READY? + JR Z,SIOA_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER + HB_DI ; AVOID COLLISION WITH INT HANDLER + LD A,(SIOA_CNT) ; GET COUNT + DEC A ; DECREMENT COUNT + LD (SIOA_CNT),A ; SAVE SAVE IT + CP 5 ; BUFFER LOW THRESHOLD + JR NZ,SIOA_IN0 ; IF NOT, BYPASS SETTING RTS + LD A,5 ; RTS IS IN WR5 + OUT (SIOA_CMD),A ; ADDRESS WR5 + LD A,$EA ; VALUE TO SET RTS + OUT (SIOA_CMD),A ; DO IT +SIOA_IN0: + LD HL,(SIOA_TL) ; GET BUFFER TAIL POINTER + LD E,(HL) ; GET BYTE + INC HL ; BUMP TAIL POINTER + LD A,L ; GET LOW BYTE + CP SIOA_BUFEND & $FF ; PAST END? + JR NZ,SIOA_IN1 ; IF NOT, BYPASS POINTER RESET + LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER +SIOA_IN1: + LD (SIOA_TL),HL ; SAVE UPDATED TAIL POINTER + HB_EI ; INTERRUPTS OK AGAIN + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +SIOB_IN: + CALL SIOB_IST ; RECEIVED CHAR READY? + JR Z,SIOB_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER + HB_DI ; AVOID COLLISION WITH INT HANDLER + LD A,(SIOB_CNT) ; GET COUNT + DEC A ; DECREMENT COUNT + LD (SIOB_CNT),A ; SAVE SAVE IT + CP 5 ; BUFFER LOW THRESHOLD + JR NZ,SIOB_IN0 ; IF NOT, BYPASS SETTING RTS + LD A,5 ; RTS IS IN WR5 + OUT (SIOB_CMD),A ; ADDRESS WR5 + LD A,$EA ; VALUE TO SET RTS + OUT (SIOB_CMD),A ; DO IT +SIOB_IN0: + LD HL,(SIOB_TL) ; GET BUFFER TAIL POINTER + LD E,(HL) ; GET BYTE + INC HL ; BUMP TAIL POINTER + LD A,L ; GET LOW BYTE + CP SIOB_BUFEND & $FF ; PAST END? + JR NZ,SIOB_IN1 ; IF NOT, BYPASS POINTER RESET + LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER +SIOB_IN1: + LD (SIOB_TL),HL ; SAVE UPDATED TAIL POINTER + HB_EI ; INTERRUPTS OK AGAIN + XOR A ; SIGNAL SUCCESS + RET ; AND DONE +; +#ENDIF +; +; +; +SIO_OUT: + CALL SIO_OST ; READY FOR CHAR? + JR Z,SIO_OUT ; LOOP IF NOT + LD C,(IY+3) ; C := SIO CMD PORT +#IF (SIOMODE == SIOMODE_RC) + INC C ; BUMP TO DATA PORT +#ENDIF +#IF ((SIOMODE == SIOMODE_SMB) | (SIOMODE == SIOMODE_ZP)) + DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT + DEC C +#ENDIF + OUT (C),E ; SEND CHAR FROM E + XOR A ; SIGNAL SUCCESS + RET +; +; +; +#IF (INTMODE == 0) +; +SIO_IST: + LD C,(IY+3) ; CMD PORT + XOR A ; WR0 + OUT (C),A ; DO IT + IN A,(C) ; GET STATUS + AND $01 ; ISOLATE BIT 0 (RX READY) + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + XOR A ; ZERO ACCUM + INC A ; ASCCUM := 1 TO SIGNAL 1 CHAR WAITING + RET ; DONE +; +#ELSE +; +SIO_IST: + LD A,(IY+2) ; GET CHANNEL + OR A ; SET FLAGS + JR Z,SIOA_IST ; HANDLE CHANNEL A + DEC A ; TEST FOR NEXT DEVICE + JR Z,SIOB_IST ; HANDLE CHANNEL B + CALL PANIC ; ELSE FATAL ERROR + RET ; ... AND RETURN +; +SIOA_IST: + LD A,(SIOA_CNT) ; GET BUFFER UTILIZATION COUNT + OR A ; SET FLAGS + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET ; AND DONE +; +SIOB_IST: + LD A,(SIOB_CNT) ; GET BUFFER UTILIZATION COUNT + OR A ; SET FLAGS + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + RET ; DONE +; +#ENDIF +; +; +; +SIO_OST: + LD C,(IY+3) ; CMD PORT + XOR A ; WR0 + OUT (C),A ; DO IT + IN A,(C) ; GET STATUS + AND $04 ; ISOLATE BIT 2 (TX EMPTY) + JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING + XOR A ; ZERO ACCUM + INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION + RET ; DONE +; +; AT INITIALIZATION THE SETUP PARAMETER WORD IS TRANSLATED TO THE FORMAT +; REQUIRED BY THE SIO AND STORED IN A PORT/REGISTER INITIALIZATION TABLE, +; WHICH IS THEN LOADED INTO THE SIO. +; +; RTS, DTR AND XON SETTING IS NOT CURRENTLY SUPPORTED. +; MARK & SPACE PARITY AND 1.5 STOP BITS IS NOT SUPPORTED BY THE SIO. +; INITIALIZATION WILL NOT BE COMPLETED IF AN INVALID SETTING IS DETECTED. +; +SIO_INITDEV: +; + ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) + LD A,D ; TEST DE FOR + AND E ; ... VALUE OF -1 + INC A ; ... SO Z SET IF -1 + JR NZ,SIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG +; + ; LOAD EXISTING CONFIG TO REINIT + LD E,(IY+4) ; LOW BYTE + LD D,(IY+5) ; HIGH BYTE +; +SIO_INITDEV1: + PUSH DE ; SAVE CONFIG + + LD A,D ; GET CONFIG MSB + AND $1F ; ISOLATE ENCODED BAUD RATE + +#IF (SIODEBUG) + PUSH AF + PRTS(" ENCODE[$") + CALL PRTHEXBYTE + PRTC(']') + POP AF +#ENDIF +; +; ONLY FOUR BAUD RATES ARE POSSIBLE WITH A FIXED CLOCK. +; THESE ARE PREDETERMINED BY HARDWARE SETTINGS AND MATCHING +; CONFIGURATION SETTINGS. WE PRECALCULATED THE FOUR +; POSSIBLE ENCODED VALUES. +; + CP SIOBAUD1 ; We set the divider and the lower bit (d2) of the stop bits + LD D,$04 ; /1 N,8,1 + JR Z,BROK + CP SIOBAUD2 + LD D,$44 ; /16 N,8,1 + JR Z,BROK + CP SIOBAUD3 + LD D,$84 ; /32 N,8,1 + JR Z,BROK + CP SIOBAUD4 + LD D,$C4 ; /64 N,8,1 + JR Z,BROK + +#IF (SIODEBUG) + PUSH AF + PRTS(" BR FAIL[$") + CALL PRTHEXBYTE + PRTC(']') + POP AF +#ENDIF +; +EXITINIT: + POP DE + RET ; NZ status here indicating fail / invalid baud rate. + +BROK: + LD A,E + AND $E0 + JR NZ,EXITINIT ; NZ status here indicates dtr, xon, parity mark or space so return + + LD A,E ; set stop bit (d3) and add divider + AND $04 + RLA + OR D ; carry gets reset here + LD D,A + + LD A,E ; get the parity bits + SRL A ; move them to bottom two bits + SRL A ; we know top bits are zero from previous test + SRL A ; add stop bits + OR D ; carry = 0 +; +; SET DIVIDER, STOP AND PARITY WR4 +; + LD BC,SIO_INITVALS+3 + LD (BC),A + +#IF (SIODEBUG) + PUSH AF + PRTS(" WR4[$") + CALL PRTHEXBYTE + PRTC(']') + POP AF +#ENDIF + + LD A,E ; 112233445566d1d0 CC + RRA ; CC112233445566d1 d0 + RRA ; d0CC112233445566 d1 + RRA ; d1d0CC1122334455 66 + LD D,A + RRA ; 66d1d0CC11223344 55 + AND $60 ; 0011110000000000 00 + OR $8a +; +; SET TRANSMIT DATA BITS WR5 +; + LD BC,SIO_INITVALS+11 + LD (BC),A + +#IF (SIODEBUG) + PUSH AF + PRTS(" WR5[$") + CALL PRTHEXBYTE + PRTC(']') + POP AF +#ENDIF +; +; SET RECEIVE DATA BITS WR3 +; + LD A,D + AND $C0 + OR $01 + + LD BC,SIO_INITVALS+9 + LD (BC),A + +#IF (SIODEBUG) + PUSH AF + PRTS(" WR3[$") + CALL PRTHEXBYTE + PRTC(']') + POP AF +#ENDIF + + POP DE ; RESTORE CONFIG + + LD (IY+4),E ; SAVE LOW WORD + LD (IY+5),D ; SAVE HI WORD + + HB_DI ; AVOID CONFLICTS +; + ; PROGRAM THE SIO CHIP CHANNEL + LD C,(IY+3) ; COMMAND PORT + LD HL,SIO_INITVALS ; POINT TO INIT VALUES + LD B,SIO_INITLEN ; COUNT OF BYTES TO WRITE + OTIR ; WRITE ALL VALUES +; + ; RESET THE RECEIVE BUFFER + LD E,(IY+6) + LD D,(IY+7) ; DE := _CNT + XOR A ; A := 0 + LD (DE),A ; _CNT = 0 + INC DE ; DE := ADR OF _HD + PUSH DE ; SAVE IT + INC DE + INC DE + INC DE + INC DE ; DE := ADR OF _BUF + POP HL ; HL := ADR OF _HD + LD (HL),E + INC HL + LD (HL),D ; _HD := _BUF + INC HL + LD (HL),E + INC HL + LD (HL),D ; _TL := _BUF +; + HB_EI ; READY FOR INTS AGAIN + XOR A ; SIGNAL SUCCESS + RET ; RETURN +; +; +SIO_INITVALS: + .DB $00, $18 ; WR0: CHANNEL RESET + .DB $04, $00 ; WR4: CLK BAUD PARITY STOP BIT +#IF (INTMODE == 0) + .DB $01, $00 ; WR1: NO INTERRUPTS +#ELSE + .DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS +#ENDIF + .DB $02, IVT_SER0 ; WR2: INTERRUPT VECTOR OFFSET + .DB $03, $C1 ; WR3: 8 BIT RCV, RX ENABLE + .DB $05, $EA ; WR5: DTR, 8 BITS SEND, TX ENABLE, RTS 1 11 0 1 0 1 0 (1=DTR,11=8bits,0=sendbreak,1=TxEnable,0=sdlc,1=RTS,0=txcrc) +SIO_INITLEN .EQU $ - SIO_INITVALS +; +; +; +SIO_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 +; +; +; +SIO_DEVICE: + LD D,CIODEV_SIO ; D := DEVICE TYPE + LD E,(IY) ; E := PHYSICAL UNIT + XOR A ; SIGNAL SUCCESS + RET +; +; SIO DETECTION ROUTINE +; +SIO_DETECT: + LD C,(IY+3) ; COMMAND PORT + XOR A + OUT (C),A ; ACCESS RD0 + IN A,(C) ; GET RD0 VALUE + LD B,A ; SAVE IT + LD A,1 + OUT (C),A ; ACCESS RD1 + IN A,(C) ; GET RD1 VALUE + CP B ; COMPARE + LD A,SIO_NONE ; ASSUME NOTHING THERE + RET Z ; RD0=RD1 MEANS NOTHING THERE + LD A,SIO_SIO ; GUESS WE HAVE A VALID SIO HERE + RET ; DONE +; +; +; +SIO_PRTCFG: + ; ANNOUNCE PORT + CALL NEWLINE ; FORMATTING + PRTS("SIO$") ; FORMATTING + LD A,(IY) ; DEVICE NUM + CALL PRTDECB ; PRINT DEVICE NUM + PRTS(": IO=0x$") ; FORMATTING + LD A,(IY+3) ; GET BASE PORT + CALL PRTHEXBYTE ; PRINT BASE PORT + + ; PRINT THE SIO TYPE + CALL PC_SPACE ; FORMATTING + LD A,(IY+1) ; GET SIO TYPE BYTE + RLCA ; MAKE IT A WORD OFFSET + LD HL,SIO_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 SIO WAS DETECTED + LD A,(IY+1) ; GET SIO TYPE BYTE + OR A ; SET FLAGS + RET Z ; IF ZERO, NOT PRESENT +; + PRTS(" MODE=$") ; FORMATTING + LD E,(IY+4) ; LOAD CONFIG + LD D,(IY+5) ; ... WORD TO DE + CALL PS_PRTSC0 ; PRINT CONFIG +; + XOR A + RET +; +; +; +SIO_TYPE_MAP: + .DW SIO_STR_NONE + .DW SIO_STR_SIO + +SIO_STR_NONE .DB "$" +SIO_STR_SIO .DB "SIO$" +; +; WORKING VARIABLES +; +SIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT +; +#IF (INTMODE == 0) +; +SIOA_RCVBUF .EQU 0 +SIOB_RCVBUF .EQU 0 +; +#ELSE +; +; CHANNEL A RECEIVE BUFFER +SIOA_RCVBUF: +SIOA_CNT .DB 0 ; CHARACTERS IN RING BUFFER +SIOA_HD .DW SIOA_BUF ; BUFFER HEAD POINTER +SIOA_TL .DW SIOA_BUF ; BUFFER TAIL POINTER +SIOA_BUF .FILL 32,0 ; RECEIVE RING BUFFER +SIOA_BUFEND .EQU $ ; END OF BUFFER +SIOA_BUFSZ .EQU $ - SIOA_BUF ; SIZE OF RING BUFFER +; +; CHANNEL B RECEIVE BUFFER +SIOB_RCVBUF: +SIOB_CNT .DB 0 ; CHARACTERS IN RING BUFFER +SIOB_HD .DW SIOB_BUF ; BUFFER HEAD POINTER +SIOB_TL .DW SIOB_BUF ; BUFFER TAIL POINTER +SIOB_BUF .FILL 32,0 ; RECEIVE RING BUFFER +SIOB_BUFEND .EQU $ ; END OF BUFFER +SIOB_BUFSZ .EQU $ - SIOB_BUF ; SIZE OF RING BUFFER +; +#ENDIF +; +; SIO PORT TABLE +; +SIO_CFG: + ; SIO CHANNEL A + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; SIO TYPE (SET DURING INIT) + .DB 0 ; SIO CHANNEL (A) + .DB SIOA_CMD ; BASE PORT (CMD PORT) + .DW DEFSIOACFG ; LINE CONFIGURATION + .DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT +; + ; SIO CHANNEL B + .DB 0 ; DEVICE NUMBER (SET DURING INIT) + .DB 0 ; SIO TYPE (SET DURING INIT) + .DB 1 ; SIO CHANNEL (B) + .DB SIOB_CMD ; BASE PORT (CMD PORT) + .DW DEFSIOBCFG ; LINE CONFIGURATION + .DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT +; +SIO_CNT .EQU ($ - SIO_CFG) / 8 From 41c5eba03434017cb5a80cee6f1223c7b274e0b8 Mon Sep 17 00:00:00 2001 From: b1ackmai1er <39449559+b1ackmai1er@users.noreply.github.com> Date: Fri, 3 Aug 2018 22:38:58 +0800 Subject: [PATCH 3/5] Delete sio.asm --- sio.asm | 725 -------------------------------------------------------- 1 file changed, 725 deletions(-) delete mode 100644 sio.asm diff --git a/sio.asm b/sio.asm deleted file mode 100644 index c30ab09f..00000000 --- a/sio.asm +++ /dev/null @@ -1,725 +0,0 @@ -; -;================================================================================================== -; SIO DRIVER (SERIAL PORT) -;================================================================================================== -; -; SETUP PARAMETER WORD: -; +-------+---+-------------------+ +---+---+-----------+---+-------+ -; | |RTS| ENCODED BAUD RATE | |DTR|XON| PARITY |STP| 8/7/6 | -; +-------+---+---+---------------+ ----+---+-----------+---+-------+ -; F E D C B A 9 8 7 6 5 4 3 2 1 0 -; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- -; -; FOR THE ECB-ZILOG-PERIPHERALS BOARD, INFORMATION ON JUMPER SETTINGS -; AND BAUD RATES CAN BE FOUND HERE: -; https://www.retrobrewcomputers.org/doku.php?id=boards:ecb:zilog-peripherals:clock-divider -; -; SIO PORT A (COM1:) and SIO PORT B (COM2:) ARE MAPPED TO DEVICE UC1: AND UL1: IN CP/M. -; -SIO_NONE .EQU 0 -SIO_SIO .EQU 1 -; -#IF (SIOMODE == SIOMODE_RC) -SIOA_CMD .EQU SIOBASE + $00 -SIOA_DAT .EQU SIOBASE + $01 -SIOB_CMD .EQU SIOBASE + $02 -SIOB_DAT .EQU SIOBASE + $03 -#ENDIF -; -#IF (SIOMODE == SIOMODE_SMB) -SIOA_CMD .EQU SIOBASE + $02 -SIOA_DAT .EQU SIOBASE + $00 -SIOB_CMD .EQU SIOBASE + $03 -SIOB_DAT .EQU SIOBASE + $01 -#ENDIF -; -#IF (SIOMODE == SIOMODE_ZP) -SIOA_CMD .EQU SIOBASE + $06 -SIOA_DAT .EQU SIOBASE + $04 -SIOB_CMD .EQU SIOBASE + $07 -SIOB_DAT .EQU SIOBASE + $05 -#ENDIF -; -; CONDITIONALS THAT DETERMINE THE ENCODED VALUE OF THE BAUD RATE -; -#INCLUDE "siobaud.inc" -; -SIO_PREINIT: -; -; SETUP THE DISPATCH TABLE ENTRIES -; - LD B,SIO_CNT ; LOOP CONTROL - LD C,0 ; PHYSICAL UNIT INDEX - XOR A ; ZERO TO ACCUM - LD (SIO_DEV),A ; CURRENT DEVICE NUMBER -SIO_PREINIT0: - PUSH BC ; SAVE LOOP CONTROL - LD A,C ; PHYSICAL UNIT TO A - RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES) - RLCA ; ... - RLCA ; ... TO GET OFFSET INTO CFG TABLE - LD HL,SIO_CFG ; POINT TO START OF CFG TABLE - CALL ADDHLA ; HL := ENTRY ADDRESS - PUSH HL ; SAVE IT - PUSH HL ; COPY CFG DATA PTR - POP IY ; ... TO IY - CALL SIO_INITUNIT ; HAND OFF TO GENERIC INIT CODE - POP DE ; GET ENTRY ADDRESS BACK, BUT PUT IN DE - POP BC ; RESTORE LOOP CONTROL -; - LD A,(IY+1) ; GET THE SIO TYPE DETECTED - OR A ; SET FLAGS - JR Z,SIO_PREINIT2 ; SKIP IT IF NOTHING FOUND -; - PUSH BC ; SAVE LOOP CONTROL - LD BC,SIO_FNTBL ; BC := FUNCTION TABLE ADDRESS - CALL NZ,CIO_ADDENT ; ADD ENTRY IF SIO FOUND, BC:DE - POP BC ; RESTORE LOOP CONTROL -; -SIO_PREINIT2: - INC C ; NEXT PHYSICAL UNIT - DJNZ SIO_PREINIT0 ; LOOP UNTIL DONE -; -#IF (INTMODE == 1) - ; ADD IM1 INT CALL LIST ENTRY IF APPROPRIATE - LD A,(SIO_DEV) ; GET NEXT DEVICE NUM - OR A ; SET FLAGS - JR Z,SIO_PREINIT3 ; IF ZERO, NO SIO DEVICES - LD HL,SIO_INT ; GET INT VECTOR - CALL HB_ADDIM1 ; ADD TO IM1 CALL LIST -#ENDIF -; -#IF (INTMODE == 2) - ; SETUP SIO INTERRUPT VECTOR IN IVT - LD HL,INT_SIO - LD (HBX_IVT + IVT_SER0),HL -#ENDIF -; -SIO_PREINIT3: - XOR A ; SIGNAL SUCCESS - RET ; AND RETURN -; -; SIO INITIALIZATION ROUTINE -; -SIO_INITUNIT: - CALL SIO_DETECT ; DETERMINE SIO TYPE - LD (IY+1),A ; SAVE IN CONFIG TABLE - OR A ; SET FLAGS - RET Z ; ABORT IF NOTHING THERE - - ; UPDATE WORKING SIO DEVICE NUM - LD HL,SIO_DEV ; POINT TO CURRENT UART DEVICE NUM - LD A,(HL) ; PUT IN ACCUM - INC (HL) ; INCREMENT IT (FOR NEXT LOOP) - LD (IY),A ; UPDATE UNIT NUM - - ; SET DEFAULT CONFIG - LD DE,-1 ; LEAVE CONFIG ALONE - JP SIO_INITDEV ; IMPLEMENT IT AND RETURN -; -; -; -SIO_INIT: - LD B,SIO_CNT ; COUNT OF POSSIBLE SIO UNITS - LD C,0 ; INDEX INTO SIO CONFIG TABLE -SIO_INIT1: - PUSH BC ; SAVE LOOP CONTROL - - LD A,C ; PHYSICAL UNIT TO A - RLCA ; MULTIPLY BY CFG TABLE ENTRY SIZE (8 BYTES) - RLCA ; ... - RLCA ; ... TO GET OFFSET INTO CFG TABLE - LD HL,SIO_CFG ; POINT TO START OF CFG TABLE - CALL ADDHLA ; HL := ENTRY ADDRESS - PUSH HL ; COPY CFG DATA PTR - POP IY ; ... TO IY - - LD A,(IY+1) ; GET SIO TYPE - OR A ; SET FLAGS - CALL NZ,SIO_PRTCFG ; PRINT IF NOT ZERO - - POP BC ; RESTORE LOOP CONTROL - INC C ; NEXT UNIT - DJNZ SIO_INIT1 ; LOOP TILL DONE -; - XOR A ; SIGNAL SUCCESS - RET ; DONE -; -; RECEIVE INTERRUPT HANDLER -; -#IF (INTMODE > 0) -; -SIO_INT: -SIOA_INT: - ; CHECK FOR RECEIVE PENDING ON CHANNEL A - XOR A ; A := 0 - OUT (SIOA_CMD),A ; ADDRESS RD0 - IN A,(SIOA_CMD) ; GET RD0 - AND $01 ; ISOLATE RECEIVE READY BIT - JR Z,SIOB_INT ; CHECK CHANNEL B -; -SIOA_INT00: - ; HANDLE CHANNEL A - IN A,(SIOA_DAT) ; READ PORT - LD E,A ; SAVE BYTE READ - LD A,(SIOA_CNT) ; GET CURRENT BUFFER USED COUNT - CP SIOA_BUFSZ ; COMPARE TO BUFFER SIZE - RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED - INC A ; INCREMENT THE COUNT - LD (SIOA_CNT),A ; AND SAVE IT - CP SIOA_BUFSZ - 5 ; BUFFER GETTING FULL? - JR NZ,SIOA_INT0 ; IF NOT, BYPASS CLEARING RTS - LD A,5 ; RTS IS IN WR5 - OUT (SIOA_CMD),A ; ADDRESS WR5 - LD A,$E8 ; VALUE TO CLEAR RTS - OUT (SIOA_CMD),A ; DO IT -SIOA_INT0: - LD HL,(SIOA_HD) ; GET HEAD POINTER - LD A,L ; GET LOW BYTE - CP SIOA_BUFEND & $FF ; PAST END? - JR NZ,SIOA_INT1 ; IF NOT, BYPASS POINTER RESET - LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER -SIOA_INT1: - LD A,E ; RECOVER BYTE READ - LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION - INC HL ; INCREMENT HEAD POINTER - LD (SIOA_HD),HL ; SAVE IT -; - ; CHECK FOR MORE PENDING... - XOR A ; A := 0 - OUT (SIOA_CMD),A ; ADDRESS RD0 - IN A,(SIOA_CMD) ; GET RD0 - RRA ; READY BIT TO CF - JR C,SIOA_INT00 ; IF SET, DO SOME MORE - OR $FF ; NZ SET TO INDICATE INT HANDLED - RET ; AND RETURN -; -SIOB_INT: - ; CHECK FOR RECEIVE PENDING ON CHANNEL B - XOR A ; A := 0 - OUT (SIOB_CMD),A ; ADDRESS RD0 - IN A,(SIOB_CMD) ; GET RD0 - AND $01 ; ISOLATE RECEIVE READY BIT - RET Z ; IF NOT, RETURN WITH Z SET -; -SIOB_INT00: - ; HANDLE CHANNEL B - IN A,(SIOB_DAT) ; READ PORT - LD E,A ; SAVE BYTE READ - LD A,(SIOB_CNT) ; GET CURRENT BUFFER USED COUNT - CP SIOB_BUFSZ ; COMPARE TO BUFFER SIZE - RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED - INC A ; INCREMENT THE COUNT - LD (SIOB_CNT),A ; AND SAVE IT - CP SIOB_BUFSZ - 5 ; BUFFER GETTING FULL? - JR NZ,SIOB_INT0 ; IF NOT, BYPASS CLEARING RTS - LD A,5 ; RTS IS IN WR5 - OUT (SIOB_CMD),A ; ADDRESS WR5 - LD A,$E8 ; VALUE TO CLEAR RTS - OUT (SIOB_CMD),A ; DO IT -SIOB_INT0: - LD HL,(SIOB_HD) ; GET HEAD POINTER - LD A,L ; GET LOW BYTE - CP SIOB_BUFEND & $FF ; PAST END? - JR NZ,SIOB_INT1 ; IF NOT, BYPASS POINTER RESET - LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER -SIOB_INT1: - LD A,E ; RECOVER BYTE READ - LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION - INC HL ; INCREMENT HEAD POINTER - LD (SIOB_HD),HL ; SAVE IT -; - ; CHECK FOR MORE PENDING... - XOR A ; A := 0 - OUT (SIOB_CMD),A ; ADDRESS RD0 - IN A,(SIOB_CMD) ; GET RD0 - RRA ; READY BIT TO CF - JR C,SIOB_INT00 ; IF SET, DO SOME MORE - OR $FF ; NZ SET TO INDICATE INT HANDLED - RET ; AND RETURN -; -#ENDIF -; -; DRIVER FUNCTION TABLE -; -SIO_FNTBL: - .DW SIO_IN - .DW SIO_OUT - .DW SIO_IST - .DW SIO_OST - .DW SIO_INITDEV - .DW SIO_QUERY - .DW SIO_DEVICE -#IF (($ - SIO_FNTBL) != (CIO_FNCNT * 2)) - .ECHO "*** INVALID SIO FUNCTION TABLE ***\n" -#ENDIF -; -; -; -#IF (INTMODE == 0) -; -SIO_IN: - CALL SIO_IST ; CHAR WAITING? - JR Z,SIO_IN ; LOOP IF NOT - LD C,(IY+3) ; C := SIO CMD PORT -#IF (SIOMODE == SIOMODE_RC) - INC C ; BUMP TO DATA PORT -#ENDIF -#IF ((SIOMODE == SIOMODE_SMB) | (SIOMODE == SIOMODE_ZP)) - DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT - DEC C -#ENDIF - IN E,(C) ; GET CHAR - XOR A ; SIGNAL SUCCESS - RET -; -#ELSE -; -SIO_IN: - LD A,(IY+2) ; GET CHANNEL - OR A ; SET FLAGS - JR Z,SIOA_IN ; HANDLE CHANNEL A - DEC A ; TEST FOR NEXT DEVICE - JR Z,SIOB_IN ; HANDLE CHANNEL B - CALL PANIC ; ELSE FATAL ERROR - RET ; ... AND RETURN -; -SIOA_IN: - CALL SIOA_IST ; RECEIVED CHAR READY? - JR Z,SIOA_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER - HB_DI ; AVOID COLLISION WITH INT HANDLER - LD A,(SIOA_CNT) ; GET COUNT - DEC A ; DECREMENT COUNT - LD (SIOA_CNT),A ; SAVE SAVE IT - CP 5 ; BUFFER LOW THRESHOLD - JR NZ,SIOA_IN0 ; IF NOT, BYPASS SETTING RTS - LD A,5 ; RTS IS IN WR5 - OUT (SIOA_CMD),A ; ADDRESS WR5 - LD A,$EA ; VALUE TO SET RTS - OUT (SIOA_CMD),A ; DO IT -SIOA_IN0: - LD HL,(SIOA_TL) ; GET BUFFER TAIL POINTER - LD E,(HL) ; GET BYTE - INC HL ; BUMP TAIL POINTER - LD A,L ; GET LOW BYTE - CP SIOA_BUFEND & $FF ; PAST END? - JR NZ,SIOA_IN1 ; IF NOT, BYPASS POINTER RESET - LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER -SIOA_IN1: - LD (SIOA_TL),HL ; SAVE UPDATED TAIL POINTER - HB_EI ; INTERRUPTS OK AGAIN - XOR A ; SIGNAL SUCCESS - RET ; AND DONE -; -SIOB_IN: - CALL SIOB_IST ; RECEIVED CHAR READY? - JR Z,SIOB_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER - HB_DI ; AVOID COLLISION WITH INT HANDLER - LD A,(SIOB_CNT) ; GET COUNT - DEC A ; DECREMENT COUNT - LD (SIOB_CNT),A ; SAVE SAVE IT - CP 5 ; BUFFER LOW THRESHOLD - JR NZ,SIOB_IN0 ; IF NOT, BYPASS SETTING RTS - LD A,5 ; RTS IS IN WR5 - OUT (SIOB_CMD),A ; ADDRESS WR5 - LD A,$EA ; VALUE TO SET RTS - OUT (SIOB_CMD),A ; DO IT -SIOB_IN0: - LD HL,(SIOB_TL) ; GET BUFFER TAIL POINTER - LD E,(HL) ; GET BYTE - INC HL ; BUMP TAIL POINTER - LD A,L ; GET LOW BYTE - CP SIOB_BUFEND & $FF ; PAST END? - JR NZ,SIOB_IN1 ; IF NOT, BYPASS POINTER RESET - LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER -SIOB_IN1: - LD (SIOB_TL),HL ; SAVE UPDATED TAIL POINTER - HB_EI ; INTERRUPTS OK AGAIN - XOR A ; SIGNAL SUCCESS - RET ; AND DONE -; -#ENDIF -; -; -; -SIO_OUT: - CALL SIO_OST ; READY FOR CHAR? - JR Z,SIO_OUT ; LOOP IF NOT - LD C,(IY+3) ; C := SIO CMD PORT -#IF (SIOMODE == SIOMODE_RC) - INC C ; BUMP TO DATA PORT -#ENDIF -#IF ((SIOMODE == SIOMODE_SMB) | (SIOMODE == SIOMODE_ZP)) - DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT - DEC C -#ENDIF - OUT (C),E ; SEND CHAR FROM E - XOR A ; SIGNAL SUCCESS - RET -; -; -; -#IF (INTMODE == 0) -; -SIO_IST: - LD C,(IY+3) ; CMD PORT - XOR A ; WR0 - OUT (C),A ; DO IT - IN A,(C) ; GET STATUS - AND $01 ; ISOLATE BIT 0 (RX READY) - JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING - XOR A ; ZERO ACCUM - INC A ; ASCCUM := 1 TO SIGNAL 1 CHAR WAITING - RET ; DONE -; -#ELSE -; -SIO_IST: - LD A,(IY+2) ; GET CHANNEL - OR A ; SET FLAGS - JR Z,SIOA_IST ; HANDLE CHANNEL A - DEC A ; TEST FOR NEXT DEVICE - JR Z,SIOB_IST ; HANDLE CHANNEL B - CALL PANIC ; ELSE FATAL ERROR - RET ; ... AND RETURN -; -SIOA_IST: - LD A,(SIOA_CNT) ; GET BUFFER UTILIZATION COUNT - OR A ; SET FLAGS - JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING - RET ; AND DONE -; -SIOB_IST: - LD A,(SIOB_CNT) ; GET BUFFER UTILIZATION COUNT - OR A ; SET FLAGS - JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING - RET ; DONE -; -#ENDIF -; -; -; -SIO_OST: - LD C,(IY+3) ; CMD PORT - XOR A ; WR0 - OUT (C),A ; DO IT - IN A,(C) ; GET STATUS - AND $04 ; ISOLATE BIT 2 (TX EMPTY) - JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING - XOR A ; ZERO ACCUM - INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION - RET ; DONE -; -; AT INITIALIZATION THE SETUP PARAMETER WORD IS TRANSLATED TO THE FORMAT -; REQUIRED BY THE SIO AND STORED IN A PORT/REGISTER INITIALIZATION TABLE, -; WHICH IS THEN LOADED INTO THE SIO. -; -; RTS, DTR AND XON SETTING IS NOT CURRENTLY SUPPORTED. -; MARK & SPACE PARITY AND 1.5 STOP BITS IS NOT SUPPORTED BY THE SIO. -; INITIALIZATION WILL NOT BE COMPLETED IF AN INVALID SETTING IS DETECTED. -; -SIO_INITDEV: -; - ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) - LD A,D ; TEST DE FOR - AND E ; ... VALUE OF -1 - INC A ; ... SO Z SET IF -1 - JR NZ,SIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG -; - ; LOAD EXISTING CONFIG TO REINIT - LD E,(IY+4) ; LOW BYTE - LD D,(IY+5) ; HIGH BYTE -; -SIO_INITDEV1: - PUSH DE ; SAVE CONFIG - - LD A,D ; GET CONFIG MSB - AND $1F ; ISOLATE ENCODED BAUD RATE - -#IF (SIODEBUG) - PUSH AF - PRTS(" ENCODE[$") - CALL PRTHEXBYTE - PRTC(']') - POP AF -#ENDIF -; -; ONLY FOUR BAUD RATES ARE POSSIBLE WITH A FIXED CLOCK. -; THESE ARE PREDETERMINED BY HARDWARE SETTINGS AND MATCHING -; CONFIGURATION SETTINGS. WE PRECALCULATED THE FOUR -; POSSIBLE ENCODED VALUES. -; - CP SIOBAUD1 ; We set the divider and the lower bit (d2) of the stop bits - LD D,$04 ; /1 N,8,1 - JR Z,BROK - CP SIOBAUD2 - LD D,$44 ; /16 N,8,1 - JR Z,BROK - CP SIOBAUD3 - LD D,$84 ; /32 N,8,1 - JR Z,BROK - CP SIOBAUD4 - LD D,$C4 ; /64 N,8,1 - JR Z,BROK - -#IF (SIODEBUG) - PUSH AF - PRTS(" BR FAIL[$") - CALL PRTHEXBYTE - PRTC(']') - POP AF -#ENDIF -; -EXITINIT: - POP DE - RET ; NZ status here indicating fail / invalid baud rate. - -BROK: - LD A,E - AND $E0 - JR NZ,EXITINIT ; NZ status here indicates dtr, xon, parity mark or space so return - - LD A,E ; set stop bit (d3) and add divider - AND $04 - RLA - OR D ; carry gets reset here - LD D,A - - LD A,E ; get the parity bits - SRL A ; move them to bottom two bits - SRL A ; we know top bits are zero from previous test - SRL A ; add stop bits - OR D ; carry = 0 -; -; SET DIVIDER, STOP AND PARITY WR4 -; - LD BC,SIO_INITVALS+3 - LD (BC),A - -#IF (SIODEBUG) - PUSH AF - PRTS(" WR4[$") - CALL PRTHEXBYTE - PRTC(']') - POP AF -#ENDIF - - LD A,E ; 112233445566d1d0 CC - RRA ; CC112233445566d1 d0 - RRA ; d0CC112233445566 d1 - RRA ; d1d0CC1122334455 66 - LD D,A - RRA ; 66d1d0CC11223344 55 - AND $60 ; 0011110000000000 00 - OR $8a -; -; SET TRANSMIT DATA BITS WR5 -; - LD BC,SIO_INITVALS+11 - LD (BC),A - -#IF (SIODEBUG) - PUSH AF - PRTS(" WR5[$") - CALL PRTHEXBYTE - PRTC(']') - POP AF -#ENDIF -; -; SET RECEIVE DATA BITS WR3 -; - LD A,D - AND $C0 - OR $01 - - LD BC,SIO_INITVALS+9 - LD (BC),A - -#IF (SIODEBUG) - PUSH AF - PRTS(" WR3[$") - CALL PRTHEXBYTE - PRTC(']') - POP AF -#ENDIF - - POP DE ; RESTORE CONFIG - - LD (IY+4),E ; SAVE LOW WORD - LD (IY+5),D ; SAVE HI WORD - - HB_DI ; AVOID CONFLICTS -; - ; PROGRAM THE SIO CHIP CHANNEL - LD C,(IY+3) ; COMMAND PORT - LD HL,SIO_INITVALS ; POINT TO INIT VALUES - LD B,SIO_INITLEN ; COUNT OF BYTES TO WRITE - OTIR ; WRITE ALL VALUES -; - ; RESET THE RECEIVE BUFFER - LD E,(IY+6) - LD D,(IY+7) ; DE := _CNT - XOR A ; A := 0 - LD (DE),A ; _CNT = 0 - INC DE ; DE := ADR OF _HD - PUSH DE ; SAVE IT - INC DE - INC DE - INC DE - INC DE ; DE := ADR OF _BUF - POP HL ; HL := ADR OF _HD - LD (HL),E - INC HL - LD (HL),D ; _HD := _BUF - INC HL - LD (HL),E - INC HL - LD (HL),D ; _TL := _BUF -; - HB_EI ; READY FOR INTS AGAIN - XOR A ; SIGNAL SUCCESS - RET ; RETURN -; -; -SIO_INITVALS: - .DB $00, $18 ; WR0: CHANNEL RESET - .DB $04, $00 ; WR4: CLK BAUD PARITY STOP BIT -#IF (INTMODE == 0) - .DB $01, $00 ; WR1: NO INTERRUPTS -#ELSE - .DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS -#ENDIF - .DB $02, IVT_SER0 ; WR2: INTERRUPT VECTOR OFFSET - .DB $03, $C1 ; WR3: 8 BIT RCV, RX ENABLE - .DB $05, $EA ; WR5: DTR, 8 BITS SEND, TX ENABLE, RTS 1 11 0 1 0 1 0 (1=DTR,11=8bits,0=sendbreak,1=TxEnable,0=sdlc,1=RTS,0=txcrc) -SIO_INITLEN .EQU $ - SIO_INITVALS -; -; -; -SIO_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 -; -; -; -SIO_DEVICE: - LD D,CIODEV_SIO ; D := DEVICE TYPE - LD E,(IY) ; E := PHYSICAL UNIT - XOR A ; SIGNAL SUCCESS - RET -; -; SIO DETECTION ROUTINE -; -SIO_DETECT: - LD C,(IY+3) ; COMMAND PORT - XOR A - OUT (C),A ; ACCESS RD0 - IN A,(C) ; GET RD0 VALUE - LD B,A ; SAVE IT - LD A,1 - OUT (C),A ; ACCESS RD1 - IN A,(C) ; GET RD1 VALUE - CP B ; COMPARE - LD A,SIO_NONE ; ASSUME NOTHING THERE - RET Z ; RD0=RD1 MEANS NOTHING THERE - LD A,SIO_SIO ; GUESS WE HAVE A VALID SIO HERE - RET ; DONE -; -; -; -SIO_PRTCFG: - ; ANNOUNCE PORT - CALL NEWLINE ; FORMATTING - PRTS("SIO$") ; FORMATTING - LD A,(IY) ; DEVICE NUM - CALL PRTDECB ; PRINT DEVICE NUM - PRTS(": IO=0x$") ; FORMATTING - LD A,(IY+3) ; GET BASE PORT - CALL PRTHEXBYTE ; PRINT BASE PORT - - ; PRINT THE SIO TYPE - CALL PC_SPACE ; FORMATTING - LD A,(IY+1) ; GET SIO TYPE BYTE - RLCA ; MAKE IT A WORD OFFSET - LD HL,SIO_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 SIO WAS DETECTED - LD A,(IY+1) ; GET SIO TYPE BYTE - OR A ; SET FLAGS - RET Z ; IF ZERO, NOT PRESENT -; - PRTS(" MODE=$") ; FORMATTING - LD E,(IY+4) ; LOAD CONFIG - LD D,(IY+5) ; ... WORD TO DE - CALL PS_PRTSC0 ; PRINT CONFIG -; - XOR A - RET -; -; -; -SIO_TYPE_MAP: - .DW SIO_STR_NONE - .DW SIO_STR_SIO - -SIO_STR_NONE .DB "$" -SIO_STR_SIO .DB "SIO$" -; -; WORKING VARIABLES -; -SIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT -; -#IF (INTMODE == 0) -; -SIOA_RCVBUF .EQU 0 -SIOB_RCVBUF .EQU 0 -; -#ELSE -; -; CHANNEL A RECEIVE BUFFER -SIOA_RCVBUF: -SIOA_CNT .DB 0 ; CHARACTERS IN RING BUFFER -SIOA_HD .DW SIOA_BUF ; BUFFER HEAD POINTER -SIOA_TL .DW SIOA_BUF ; BUFFER TAIL POINTER -SIOA_BUF .FILL 32,0 ; RECEIVE RING BUFFER -SIOA_BUFEND .EQU $ ; END OF BUFFER -SIOA_BUFSZ .EQU $ - SIOA_BUF ; SIZE OF RING BUFFER -; -; CHANNEL B RECEIVE BUFFER -SIOB_RCVBUF: -SIOB_CNT .DB 0 ; CHARACTERS IN RING BUFFER -SIOB_HD .DW SIOB_BUF ; BUFFER HEAD POINTER -SIOB_TL .DW SIOB_BUF ; BUFFER TAIL POINTER -SIOB_BUF .FILL 32,0 ; RECEIVE RING BUFFER -SIOB_BUFEND .EQU $ ; END OF BUFFER -SIOB_BUFSZ .EQU $ - SIOB_BUF ; SIZE OF RING BUFFER -; -#ENDIF -; -; SIO PORT TABLE -; -SIO_CFG: - ; SIO CHANNEL A - .DB 0 ; DEVICE NUMBER (SET DURING INIT) - .DB 0 ; SIO TYPE (SET DURING INIT) - .DB 0 ; SIO CHANNEL (A) - .DB SIOA_CMD ; BASE PORT (CMD PORT) - .DW DEFSIOACFG ; LINE CONFIGURATION - .DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT -; - ; SIO CHANNEL B - .DB 0 ; DEVICE NUMBER (SET DURING INIT) - .DB 0 ; SIO TYPE (SET DURING INIT) - .DB 1 ; SIO CHANNEL (B) - .DB SIOB_CMD ; BASE PORT (CMD PORT) - .DW DEFSIOBCFG ; LINE CONFIGURATION - .DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT -; -SIO_CNT .EQU ($ - SIO_CFG) / 8 From e7cc7906c516f6bda41913b6b43cc2b7d83e362e Mon Sep 17 00:00:00 2001 From: b1ackmai1er <39449559+b1ackmai1er@users.noreply.github.com> Date: Fri, 3 Aug 2018 22:40:07 +0800 Subject: [PATCH 4/5] Fixes to port address and cleanups --- Source/HBIOS/sio.asm | 492 +++++-------------------------------------- 1 file changed, 53 insertions(+), 439 deletions(-) diff --git a/Source/HBIOS/sio.asm b/Source/HBIOS/sio.asm index ade6e588..c30ab09f 100644 --- a/Source/HBIOS/sio.asm +++ b/Source/HBIOS/sio.asm @@ -10,415 +10,39 @@ ; F E D C B A 9 8 7 6 5 4 3 2 1 0 ; -- MSB (D REGISTER) -- -- LSB (E REGISTER) -- ; -; +; FOR THE ECB-ZILOG-PERIPHERALS BOARD, INFORMATION ON JUMPER SETTINGS +; AND BAUD RATES CAN BE FOUND HERE: +; https://www.retrobrewcomputers.org/doku.php?id=boards:ecb:zilog-peripherals:clock-divider +; +; SIO PORT A (COM1:) and SIO PORT B (COM2:) ARE MAPPED TO DEVICE UC1: AND UL1: IN CP/M. +; SIO_NONE .EQU 0 SIO_SIO .EQU 1 ; #IF (SIOMODE == SIOMODE_RC) -SIOA_CMD .EQU SIOBASE + $00 ; PS -SIOA_DAT .EQU SIOBASE + $01 ; PS -SIOB_CMD .EQU SIOBASE + $02 ; PS -SIOB_DAT .EQU SIOBASE + $03 ; PS +SIOA_CMD .EQU SIOBASE + $00 +SIOA_DAT .EQU SIOBASE + $01 +SIOB_CMD .EQU SIOBASE + $02 +SIOB_DAT .EQU SIOBASE + $03 #ENDIF ; #IF (SIOMODE == SIOMODE_SMB) -SIOA_CMD .EQU SIOBASE + $02 ; PS -SIOA_DAT .EQU SIOBASE + $00 ; PS -SIOB_CMD .EQU SIOBASE + $03 ; PS -SIOB_WR4 .EQU SIOBASE + $01 ; PS +SIOA_CMD .EQU SIOBASE + $02 +SIOA_DAT .EQU SIOBASE + $00 +SIOB_CMD .EQU SIOBASE + $03 +SIOB_DAT .EQU SIOBASE + $01 #ENDIF ; -#IF (SIOMODE == SIOMODE_ZP) ; PS -SIOA_CMD .EQU SIOBASE + $06 ; PS -SIOA_DAT .EQU SIOBASE + $04 ; PS -SIOB_CMD .EQU SIOBASE + $07 ; PS -SIOB_DAT .EQU SIOBASE + $05 ; PS -#ENDIF ; PS -; -#IF (DEFSIOCLK/DEFSIODIV/1 == 75) -SIOBAUD1 .EQU 0 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 150) -SIOBAUD1 .EQU 1 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 300) -SIOBAUD1 .EQU 2 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 600) -SIOBAUD1 .EQU 3 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 1200) -SIOBAUD1 .EQU 4 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 2400) -SIOBAUD1 .EQU 5 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 4800) -SIOBAUD1 .EQU 6 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 9600) -SIOBAUD1 .EQU 7 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 19200) -SIOBAUD1 .EQU 8 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 38400) -SIOBAUD1 .EQU 9 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 76800) -SIOBAUD1 .EQU 10 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 153600) -SIOBAUD1 .EQU 11 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 307200) -SIOBAUD1 .EQU 12 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 614400) -SIOBAUD1 .EQU 13 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 ==1228800) -SIOBAUD1 .EQU 14 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 ==2457600) -SIOBAUD1 .EQU 15 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 225) -SIOBAUD1 .EQU 16 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 450) -SIOBAUD1 .EQU 17 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 900) -SIOBAUD1 .EQU 18 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 1800) -SIOBAUD1 .EQU 19 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 3600) -SIOBAUD1 .EQU 20 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 7200) -SIOBAUD1 .EQU 21 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 14400) -SIOBAUD1 .EQU 22 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 28800) -SIOBAUD1 .EQU 23 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 57600) -SIOBAUD1 .EQU 24 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 115200) -SIOBAUD1 .EQU 25 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 230400) -SIOBAUD1 .EQU 26 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 == 921600) -SIOBAUD1 .EQU 28 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 ==1843200) -SIOBAUD1 .EQU 29 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 ==3686400) -SIOBAUD1 .EQU 30 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/1 ==7372800) -SIOBAUD1 .EQU 31 +#IF (SIOMODE == SIOMODE_ZP) +SIOA_CMD .EQU SIOBASE + $06 +SIOA_DAT .EQU SIOBASE + $04 +SIOB_CMD .EQU SIOBASE + $07 +SIOB_DAT .EQU SIOBASE + $05 #ENDIF ; -#IF (DEFSIOCLK/DEFSIODIV/16 == 75) -SIOBAUD2 .EQU 0 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 150) -SIOBAUD2 .EQU 1 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 300) -SIOBAUD2 .EQU 2 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 600) -SIOBAUD2 .EQU 3 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 1200) -SIOBAUD2 .EQU 4 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 2400) -SIOBAUD2 .EQU 5 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 4800) -SIOBAUD2 .EQU 6 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 9600) -SIOBAUD2 .EQU 7 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 19200) -SIOBAUD2 .EQU 8 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 38400) -SIOBAUD2 .EQU 9 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 76800) -SIOBAUD2 .EQU 10 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 153600) -SIOBAUD2 .EQU 11 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 307200) -SIOBAUD2 .EQU 12 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 614400) -SIOBAUD2 .EQU 13 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 ==1228800) -SIOBAUD2 .EQU 14 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 ==2457600) -SIOBAUD2 .EQU 15 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 225) -SIOBAUD2 .EQU 16 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 450) -SIOBAUD2 .EQU 17 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 900) -SIOBAUD2 .EQU 18 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 1800) -SIOBAUD2 .EQU 19 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 3600) -SIOBAUD2 .EQU 20 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 7200) -SIOBAUD2 .EQU 21 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 14400) -SIOBAUD2 .EQU 22 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 28800) -SIOBAUD2 .EQU 23 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 57600) -SIOBAUD2 .EQU 24 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 115200) -SIOBAUD2 .EQU 25 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 230400) -SIOBAUD2 .EQU 26 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 460800) -SIOBAUD2 .EQU 27 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 == 921600) -SIOBAUD2 .EQU 28 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 ==1843200) -SIOBAUD2 .EQU 29 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 ==3686400) -SIOBAUD2 .EQU 30 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/16 ==7372800) -SIOBAUD2 .EQU 31 -#ENDIF +; CONDITIONALS THAT DETERMINE THE ENCODED VALUE OF THE BAUD RATE ; -#IF (DEFSIOCLK/DEFSIODIV/32 == 75) -SIOBAUD3 .EQU 0 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 150) -SIOBAUD3 .EQU 1 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 300) -SIOBAUD3 .EQU 2 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 600) -SIOBAUD3 .EQU 3 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 1200) -SIOBAUD3 .EQU 4 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 2400) -SIOBAUD3 .EQU 5 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 4800) -SIOBAUD3 .EQU 6 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 9600) -SIOBAUD3 .EQU 7 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 19200) -SIOBAUD3 .EQU 8 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 38400) -SIOBAUD3 .EQU 9 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 76800) -SIOBAUD3 .EQU 10 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 153600) -SIOBAUD3 .EQU 11 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 307200) -SIOBAUD3 .EQU 12 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 614400) -SIOBAUD3 .EQU 13 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 ==1228800) -SIOBAUD3 .EQU 14 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 ==2457600) -SIOBAUD3 .EQU 15 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 225) -SIOBAUD3 .EQU 16 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 450) -SIOBAUD3 .EQU 17 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 900) -SIOBAUD3 .EQU 18 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 1800) -SIOBAUD3 .EQU 19 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 3600) -SIOBAUD3 .EQU 20 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 7200) -SIOBAUD3 .EQU 21 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 14400) -SIOBAUD3 .EQU 22 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 28800) -SIOBAUD3 .EQU 23 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 57600) -SIOBAUD3 .EQU 24 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 115200) -SIOBAUD3 .EQU 25 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 230400) -SIOBAUD3 .EQU 26 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 460800) -SIOBAUD3 .EQU 27 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 == 921600) -SIOBAUD3 .EQU 28 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 ==1843200) -SIOBAUD3 .EQU 29 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 ==3686400) -SIOBAUD3 .EQU 30 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/32 ==7372800) -SIOBAUD3 .EQU 31 -#ENDIF -; -#IF (DEFSIOCLK/DEFSIODIV/64 == 75) -SIOBAUD4 .EQU 0 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 150) -SIOBAUD4 .EQU 1 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 300) -SIOBAUD4 .EQU 2 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 600) -SIOBAUD4 .EQU 3 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 1200) -SIOBAUD4 .EQU 4 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 2400) -SIOBAUD4 .EQU 5 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 4800) -SIOBAUD4 .EQU 6 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 9600) -SIOBAUD4 .EQU 7 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 19200) -SIOBAUD4 .EQU 8 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 38400) -SIOBAUD4 .EQU 9 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 76800) -SIOBAUD4 .EQU 10 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 153600) -SIOBAUD4 .EQU 11 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 307200) -SIOBAUD4 .EQU 12 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 614400) -SIOBAUD4 .EQU 13 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 ==1228800) -SIOBAUD4 .EQU 14 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 ==2457600) -SIOBAUD4 .EQU 15 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 225) -SIOBAUD4 .EQU 16 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 450) -SIOBAUD4 .EQU 17 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 900) -SIOBAUD4 .EQU 18 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 1800) -SIOBAUD4 .EQU 19 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 3600) -SIOBAUD4 .EQU 20 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 7200) -SIOBAUD4 .EQU 21 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 14400) -SIOBAUD4 .EQU 22 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 28800) -SIOBAUD4 .EQU 23 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 57600) -SIOBAUD4 .EQU 24 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 115200) -SIOBAUD4 .EQU 25 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 230400) -SIOBAUD4 .EQU 26 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 460800) -SIOBAUD4 .EQU 27 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 == 921600) -SIOBAUD4 .EQU 28 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 ==1843200) -SIOBAUD4 .EQU 29 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 ==3686400) -SIOBAUD4 .EQU 30 -#ENDIF -#IF (DEFSIOCLK/DEFSIODIV/64 ==7372800) -SIOBAUD4 .EQU 31 -#ENDIF +#INCLUDE "siobaud.inc" ; SIO_PREINIT: ; @@ -786,21 +410,25 @@ SIO_OST: INC A ; ACCUM := 1 TO SIGNAL 1 BUFFER POSITION RET ; DONE ; +; AT INITIALIZATION THE SETUP PARAMETER WORD IS TRANSLATED TO THE FORMAT +; REQUIRED BY THE SIO AND STORED IN A PORT/REGISTER INITIALIZATION TABLE, +; WHICH IS THEN LOADED INTO THE SIO. ; +; RTS, DTR AND XON SETTING IS NOT CURRENTLY SUPPORTED. +; MARK & SPACE PARITY AND 1.5 STOP BITS IS NOT SUPPORTED BY THE SIO. +; INITIALIZATION WILL NOT BE COMPLETED IF AN INVALID SETTING IS DETECTED. ; SIO_INITDEV: ; - ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) ; PS - LD A,D ; TEST DE FOR ; PS - AND E ; ... VALUE OF -1 ; PS - INC A ; ... SO Z SET IF -1 ; PS - JR NZ,SIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG ; PS + ; TEST FOR -1 WHICH MEANS USE CURRENT CONFIG (JUST REINIT) + LD A,D ; TEST DE FOR + AND E ; ... VALUE OF -1 + INC A ; ... SO Z SET IF -1 + JR NZ,SIO_INITDEV1 ; IF DE == -1, REINIT CURRENT CONFIG ; - ; LOAD EXISTING CONFIG TO REINIT ; PS - LD E,(IY+4) ; LOW BYTE ; PS - LD D,(IY+5) ; HIGH BYTE ; PS -; -; CHANGE INIT TABLE BASED ON DESIRED SERIAL LINE CHARACTERISTICS + ; LOAD EXISTING CONFIG TO REINIT + LD E,(IY+4) ; LOW BYTE + LD D,(IY+5) ; HIGH BYTE ; SIO_INITDEV1: PUSH DE ; SAVE CONFIG @@ -815,8 +443,13 @@ SIO_INITDEV1: PRTC(']') POP AF #ENDIF - - CP SIOBAUD1 ; We set the divider and the lower bit (d2) of the baud rate here +; +; ONLY FOUR BAUD RATES ARE POSSIBLE WITH A FIXED CLOCK. +; THESE ARE PREDETERMINED BY HARDWARE SETTINGS AND MATCHING +; CONFIGURATION SETTINGS. WE PRECALCULATED THE FOUR +; POSSIBLE ENCODED VALUES. +; + CP SIOBAUD1 ; We set the divider and the lower bit (d2) of the stop bits LD D,$04 ; /1 N,8,1 JR Z,BROK CP SIOBAUD2 @@ -827,8 +460,8 @@ SIO_INITDEV1: JR Z,BROK CP SIOBAUD4 LD D,$C4 ; /64 N,8,1 - JR Z,BROK ; RET NZ - + JR Z,BROK + #IF (SIODEBUG) PUSH AF PRTS(" BR FAIL[$") @@ -857,43 +490,24 @@ BROK: SRL A ; we know top bits are zero from previous test SRL A ; add stop bits OR D ; carry = 0 - +; +; SET DIVIDER, STOP AND PARITY WR4 +; LD BC,SIO_INITVALS+3 LD (BC),A #IF (SIODEBUG) PUSH AF - PRTS(" MODE[$") + PRTS(" WR4[$") CALL PRTHEXBYTE PRTC(']') POP AF #ENDIF -; THE # DATA BITS NEED TO BE CONVERTED FROM THE -; ROMWBW REPRESENTATION TO THE SIO ZILOG CODING - -; XOR A -; RR E ; d0 of bits into carry -; RR A ; d0 into msb -; RR E ; d1 of bits into carry -; RR A ; d1 into msb -;; SCF ; 1 into msb -; RR A -; OR $8a - - LD A,E - - #IF (SIODEBUG) - PUSH AF - PRTS(" BITS[$") - CALL PRTHEXBYTE - PRTC(']') - POP AF -#ENDIF - ; 112233445566d1d0 CC + LD A,E ; 112233445566d1d0 CC RRA ; CC112233445566d1 d0 RRA ; d0CC112233445566 d1 - RRA ; d1d0CC1122334455 66 + RRA ; d1d0CC1122334455 66 LD D,A RRA ; 66d1d0CC11223344 55 AND $60 ; 0011110000000000 00 @@ -906,7 +520,7 @@ BROK: #IF (SIODEBUG) PUSH AF - PRTS(" TXDATA[$") + PRTS(" WR5[$") CALL PRTHEXBYTE PRTC(']') POP AF @@ -923,7 +537,7 @@ BROK: #IF (SIODEBUG) PUSH AF - PRTS(" RXDATA[$") + PRTS(" WR3[$") CALL PRTHEXBYTE PRTC(']') POP AF @@ -969,7 +583,7 @@ BROK: ; SIO_INITVALS: .DB $00, $18 ; WR0: CHANNEL RESET - .DB $04, $00 ; WR4: CLK BAUD PARITY STOP BIT ; PST + .DB $04, $00 ; WR4: CLK BAUD PARITY STOP BIT #IF (INTMODE == 0) .DB $01, $00 ; WR1: NO INTERRUPTS #ELSE From 1fc2017db50cd9c1c02e5958760e8270cd9dc51b Mon Sep 17 00:00:00 2001 From: b1ackmai1er <39449559+b1ackmai1er@users.noreply.github.com> Date: Fri, 3 Aug 2018 22:45:13 +0800 Subject: [PATCH 5/5] Fix typo. --- Source/HBIOS/siobaud.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/HBIOS/siobaud.inc b/Source/HBIOS/siobaud.inc index bb819775..c315c9bf 100644 --- a/Source/HBIOS/siobaud.inc +++ b/Source/HBIOS/siobaud.inc @@ -4,7 +4,7 @@ ; #IF (DEFSIOCLK/DEFSIODIV/1 == 75) -SIOBAUD1 .EQU 0 E +SIOBAUD1 .EQU 0 #ENDIF #IF (DEFSIOCLK/DEFSIODIV/1 == 150) SIOBAUD1 .EQU 1