Browse Source

Add IM0 Mode to SIO Driver

pull/9/head
Wayne Warthen 8 years ago
parent
commit
331760cd5c
  1. 2
      Source/HBIOS/cfg_sbc.asm
  2. 309
      Source/HBIOS/sio.asm

2
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, ...)

309
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:

Loading…
Cancel
Save