From 331760cd5c3ff0db6b8b92a25d9b0f9a8f34ee79 Mon Sep 17 00:00:00 2001 From: Wayne Warthen Date: Thu, 2 Aug 2018 14:51:18 -0700 Subject: [PATCH] Add IM0 Mode to SIO Driver --- Source/HBIOS/cfg_sbc.asm | 2 +- Source/HBIOS/sio.asm | 309 ++++++++++++++++++++++----------------- 2 files changed, 177 insertions(+), 134 deletions(-) diff --git a/Source/HBIOS/cfg_sbc.asm b/Source/HBIOS/cfg_sbc.asm index 7b6d0c5b..05fb656b 100644 --- a/Source/HBIOS/cfg_sbc.asm +++ b/Source/HBIOS/cfg_sbc.asm @@ -8,7 +8,7 @@ CPUOSC .EQU 8000000 ; CPU OSC FREQ RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!! DEFSERCFG .EQU SER_38400_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE) -INTMODE .EQU 1 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 +INTMODE .EQU 0 ; 0=NONE, 1=INT MODE 1, 2=INT MODE 2 ; CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...) diff --git a/Source/HBIOS/sio.asm b/Source/HBIOS/sio.asm index 0e95cc28..cb3cb2eb 100644 --- a/Source/HBIOS/sio.asm +++ b/Source/HBIOS/sio.asm @@ -15,27 +15,26 @@ 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 ; PS +SIOA_DAT .EQU SIOBASE + $01 ; PS +SIOB_CMD .EQU SIOBASE + $02 ; PS +SIOB_DAT .EQU SIOBASE + $03 ; PS #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 ; PS +SIOA_DAT .EQU SIOBASE + $00 ; PS +SIOB_CMD .EQU SIOBASE + $03 ; PS +SIOB_WR4 .EQU SIOBASE + $01 ; PS #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 (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 @@ -129,8 +128,7 @@ SIOBAUD1 .EQU 30 #IF (DEFSIOCLK/DEFSIODIV/1 ==7372800) SIOBAUD1 .EQU 31 #ENDIF - - +; #IF (DEFSIOCLK/DEFSIODIV/16 == 75) SIOBAUD2 .EQU 0 #ENDIF @@ -227,7 +225,7 @@ SIOBAUD2 .EQU 30 #IF (DEFSIOCLK/DEFSIODIV/16 ==7372800) SIOBAUD2 .EQU 31 #ENDIF - +; #IF (DEFSIOCLK/DEFSIODIV/32 == 75) SIOBAUD3 .EQU 0 #ENDIF @@ -324,7 +322,7 @@ SIOBAUD3 .EQU 30 #IF (DEFSIOCLK/DEFSIODIV/32 ==7372800) SIOBAUD3 .EQU 31 #ENDIF - +; #IF (DEFSIOCLK/DEFSIODIV/64 == 75) SIOBAUD4 .EQU 0 #ENDIF @@ -421,7 +419,6 @@ SIOBAUD4 .EQU 30 #IF (DEFSIOCLK/DEFSIODIV/64 ==7372800) SIOBAUD4 .EQU 31 #ENDIF - ; SIO_PREINIT: ; @@ -446,7 +443,7 @@ SIO_PREINIT0: POP DE ; GET ENTRY ADDRESS BACK, BUT PUT IN DE POP BC ; RESTORE LOOP CONTROL ; - LD A,(IY + 1) ; GET THE SIO TYPE DETECTED + LD A,(IY+1) ; GET THE SIO TYPE DETECTED OR A ; SET FLAGS JR Z,SIO_PREINIT2 ; SKIP IT IF NOTHING FOUND ; @@ -482,7 +479,7 @@ SIO_PREINIT3: ; SIO_INITUNIT: CALL SIO_DETECT ; DETERMINE SIO TYPE - LD (IY + 1),A ; SAVE IN CONFIG TABLE + LD (IY+1),A ; SAVE IN CONFIG TABLE OR A ; SET FLAGS RET Z ; ABORT IF NOTHING THERE @@ -513,7 +510,7 @@ SIO_INIT1: PUSH HL ; COPY CFG DATA PTR POP IY ; ... TO IY - LD A,(IY + 1) ; GET SIO TYPE + LD A,(IY+1) ; GET SIO TYPE OR A ; SET FLAGS CALL NZ,SIO_PRTCFG ; PRINT IF NOT ZERO @@ -524,7 +521,9 @@ SIO_INIT1: XOR A ; SIGNAL SUCCESS RET ; DONE ; -; INTERRUPT HANDLER +; RECEIVE INTERRUPT HANDLER +; +#IF (INTMODE > 0) ; SIO_INT: SIOA_INT: @@ -615,6 +614,8 @@ SIOB_INT1: OR $FF ; NZ SET TO INDICATE INT HANDLED RET ; AND RETURN ; +#ENDIF +; ; DRIVER FUNCTION TABLE ; SIO_FNTBL: @@ -631,8 +632,27 @@ SIO_FNTBL: ; ; ; +#IF (INTMODE == 0) +; SIO_IN: - LD A,(IY + 2) ; GET CHANNEL + 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 @@ -694,21 +714,19 @@ SIOB_IN1: 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 + LD C,(IY+3) ; C := SIO CMD PORT #IF (SIOMODE == SIOMODE_RC) INC C ; BUMP TO DATA PORT #ENDIF -#IF (SIOMODE == SIOMODE_SMB) - DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT - DEC C -#ENDIF -#IF (SIOMODE == SIOMODE_ZP) - DEC C ; DECREMENT CMD PORT TWICE TO GET DATA PORT +#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 @@ -717,8 +735,23 @@ SIO_OUT: ; ; ; +#IF (INTMODE == 0) +; SIO_IST: - LD A,(IY + 2) ; GET CHANNEL + 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 @@ -738,10 +771,12 @@ SIOB_IST: JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING RET ; DONE ; +#ENDIF +; ; ; SIO_OST: - LD C,(IY + 3) ; CMD PORT + LD C,(IY+3) ; CMD PORT XOR A ; WR0 OUT (C),A ; DO IT IN A,(C) ; GET STATUS @@ -755,162 +790,161 @@ SIO_OST: ; 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) ; 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 ; - ; LOAD EXISTING CONFIG TO REINIT ;PS - LD E,(IY + 4) ; LOW BYTE ;PS - LD D,(IY + 5) ; HIGH BYTE ;PS - -; CHANGE INIT TABLE + ; 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 ; SIO_INITDEV1: - PUSH DE ; SAVE CONFIG + PUSH DE ; SAVE CONFIG LD A,D ; GET CONFIG MSB AND $1F ; ISOLATE ENCODED BAUD RATE #IF (SIODEBUG) - PUSH AF + PUSH AF PRTS(" ENCODE[$") CALL PRTHEXBYTE PRTC(']') - POP AF + POP AF #ENDIF - - CP SIOBAUD1 ; We set the divider and the lower bit (d2) of the baud rate here - 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 ; RET NZ + + CP SIOBAUD1 ; We set the divider and the lower bit (d2) of the baud rate here + 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 ; RET NZ #IF (SIODEBUG) - PUSH AF + PUSH AF PRTS(" BR FAIL[$") CALL PRTHEXBYTE PRTC(']') - POP AF + POP AF #ENDIF ; EXITINIT: - POP DE + 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 + 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 + LD A,E ; set stop bit (d3) and add divider + AND $04 RLA - OR D ; carry gets reset here - LD D,A - + 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 + 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 LD BC,SIO_INITVALS+3 - LD (BC),A + LD (BC),A #IF (SIODEBUG) - PUSH AF + PUSH AF PRTS(" MODE[$") CALL PRTHEXBYTE PRTC(']') - POP AF + POP AF #ENDIF ; THE # DATA BITS NEED TO BE CONVERTED FROM THE -; ROMWBW REPRESENTATION TO THE SIO XILOG CODING +; 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 +; 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 + LD A,E #IF (SIODEBUG) - PUSH AF + PUSH AF PRTS(" BITS[$") CALL PRTHEXBYTE PRTC(']') - POP AF + POP AF #ENDIF ; 112233445566d1d0 CC RRA ; CC112233445566d1 d0 RRA ; d0CC112233445566 d1 - RRA ; d1d0CC1122334455 66 - LD D,A + RRA ; d1d0CC1122334455 66 + LD D,A RRA ; 66d1d0CC11223344 55 - AND $60 ; 0011110000000000 00 - OR $8a + AND $60 ; 0011110000000000 00 + OR $8a ; ; SET TRANSMIT DATA BITS WR5 ; LD BC,SIO_INITVALS+11 - LD (BC),A + LD (BC),A #IF (SIODEBUG) - PUSH AF + PUSH AF PRTS(" TXDATA[$") CALL PRTHEXBYTE PRTC(']') - POP AF + POP AF #ENDIF ; ; SET RECEIVE DATA BITS WR3 ; - LD A,D - AND $C0 - OR $01 + LD A,D + AND $C0 + OR $01 LD BC,SIO_INITVALS+9 - LD (BC),A + LD (BC),A #IF (SIODEBUG) - PUSH AF + PUSH AF PRTS(" RXDATA[$") CALL PRTHEXBYTE PRTC(']') - POP AF + POP AF #ENDIF POP DE ; RESTORE CONFIG - LD (IY + 4),E ; SAVE LOW WORD - LD (IY + 5),D ; SAVE HI WORD + 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 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 + 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 @@ -934,46 +968,46 @@ BROK: ; ; SIO_INITVALS: - .DB $00, $18 ; WR0: CHANNEL RESET - .DB $04, $00 ; WR4: CLK BAUD PARITY STOP BIT ; PST - .DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS - .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) + .DB $00, $18 ; WR0: CHANNEL RESET + .DB $04, $00 ; WR4: CLK BAUD PARITY STOP BIT ; PST + .DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS + .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 + 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 + 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 + 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 ; ; ; @@ -984,12 +1018,12 @@ SIO_PRTCFG: LD A,(IY) ; DEVICE NUM CALL PRTDECB ; PRINT DEVICE NUM PRTS(": IO=0x$") ; FORMATTING - LD A,(IY + 3) ; GET BASE PORT + 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 + 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 @@ -999,13 +1033,13 @@ SIO_PRTCFG: CALL WRITESTR ; PRINT IT ; ; ALL DONE IF NO SIO WAS DETECTED - LD A,(IY + 1) ; GET SIO TYPE BYTE + 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 + LD E,(IY+4) ; LOAD CONFIG + LD D,(IY+5) ; ... WORD TO DE CALL PS_PRTSC0 ; PRINT CONFIG ; XOR A @@ -1024,6 +1058,13 @@ SIO_STR_SIO .DB "SIO$" ; 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 @@ -1042,6 +1083,8 @@ 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: