mirror of https://github.com/wwarthen/RomWBW.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1064 lines
25 KiB
1064 lines
25 KiB
;
|
|
;==================================================================================================
|
|
; 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) --
|
|
;
|
|
;
|
|
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
|
|
#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
|
|
#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
|
|
#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
|
|
|
|
;
|
|
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
|
|
;
|
|
; INTERRUPT HANDLER
|
|
;
|
|
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
|
|
;
|
|
; 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
|
|
;
|
|
;
|
|
;
|
|
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
|
|
;
|
|
;
|
|
;
|
|
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)
|
|
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
|
|
DEC C
|
|
#ENDIF
|
|
OUT (C),E ; SEND CHAR FROM E
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
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
|
|
;
|
|
;
|
|
;
|
|
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
|
|
;
|
|
;
|
|
;
|
|
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
|
|
;
|
|
; LOAD EXISTING CONFIG TO REINIT ;PS
|
|
LD E,(IY + 4) ; LOW BYTE ;PS
|
|
LD D,(IY + 5) ; HIGH BYTE ;PS
|
|
|
|
; CHANGE INIT TABLE
|
|
;
|
|
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
|
|
|
|
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
|
|
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
|
|
|
|
LD BC,SIO_INITVALS+3
|
|
LD (BC),A
|
|
|
|
#IF (SIODEBUG)
|
|
PUSH AF
|
|
PRTS(" MODE[$")
|
|
CALL PRTHEXBYTE
|
|
PRTC(']')
|
|
POP AF
|
|
#ENDIF
|
|
|
|
; THE # DATA BITS NEED TO BE CONVERTED FROM THE
|
|
; ROMWBW REPRESENTATION TO THE SIO XILOG 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
|
|
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(" TXDATA[$")
|
|
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(" RXDATA[$")
|
|
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 ; 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
|
|
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 "<NOT PRESENT>$"
|
|
SIO_STR_SIO .DB "SIO$"
|
|
;
|
|
; WORKING VARIABLES
|
|
;
|
|
SIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT
|
|
;
|
|
; 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
|
|
;
|
|
; 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
|
|
|