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.
350 lines
9.1 KiB
350 lines
9.1 KiB
|
|
PIO0A .EQU ; ECB-ZP
|
|
PIO0B .EQU ; ECB-ZP
|
|
PIO1A .EQU ; ECB-ZP
|
|
PIO1B .EQU ; ECB-ZP
|
|
|
|
PIO2A .EQU ; ECB-4PIO
|
|
PIO2B .EQU ; ECB-4PIO
|
|
PIO3A .EQU ; ECB-4PIO
|
|
PIO3B .EQU ; ECB-4PIO
|
|
PIO4A .EQU ; ECB-4PIO
|
|
PIO4B .EQU ; ECB-4PIO
|
|
PIO5A .EQU ; ECB-4PIO
|
|
PIO5B .EQU ; ECB-4PIO
|
|
|
|
PIO_Input .EQU $0000
|
|
PIO_Output .EQU $0001
|
|
PIO_BiDir .Equ $0002
|
|
|
|
DEFPIOCFGA .EQU $8000 + PIO_Input
|
|
DEFPIOCFGB .EQU $8000 + PIO_Output
|
|
DEFPIOCFGX .EQU $8000 + PIO_BiDir
|
|
|
|
PIO_NONE .EQU 0
|
|
PIO_ZPIO .EQU 1
|
|
PIO_8255 .EQU 2
|
|
;
|
|
PIO_PREINIT:
|
|
;
|
|
; SETUP THE DISPATCH TABLE ENTRIES
|
|
;
|
|
LD B,PIO_CNT ; LOOP CONTROL
|
|
LD C,0 ; PHYSICAL UNIT INDEX
|
|
XOR A ; ZERO TO ACCUM
|
|
LD (PIO_DEV),A ; CURRENT DEVICE NUMBER
|
|
PIO_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,PIO_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 PIO_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 PIO TYPE DETECTED
|
|
OR A ; SET FLAGS
|
|
JR Z,PIO_PREINIT2 ; SKIP IT IF NOTHING FOUND
|
|
;
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
LD BC,PIO_FNTBL ; BC := FUNCTION TABLE ADDRESS
|
|
CALL NZ,CIO_ADDENT ; ADD ENTRY IF PIO FOUND, BC:DE
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
;
|
|
PIO_PREINIT2:
|
|
INC C ; NEXT PHYSICAL UNIT
|
|
DJNZ PIO_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,PIO_PREINIT3 ; IF ZERO, NO SIO DEVICES
|
|
; LD HL,PIO_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_PIO
|
|
; LD (HBX_IVT + IVT_SER0),HL
|
|
;#ENDIF
|
|
;
|
|
PIO_PREINIT3:
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; AND RETURN
|
|
;
|
|
PIO_INITUNIT:
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; AND RETURN
|
|
;
|
|
PIO_INIT:
|
|
LD B,PIO_CNT ; COUNT OF POSSIBLE SIO UNITS
|
|
LD C,0 ; INDEX INTO SIO CONFIG TABLE
|
|
PIO_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,PIO_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 PIO TYPE
|
|
OR A ; SET FLAGS
|
|
CALL NZ,PIO_PRTCFG ; PRINT IF NOT ZERO
|
|
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
INC C ; NEXT UNIT
|
|
DJNZ PIO_INIT1 ; LOOP TILL DONE
|
|
;
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
|
|
;
|
|
PIO_LPT:
|
|
IN A,($F6) ; get device status
|
|
AND $20 ; device ready?
|
|
JR Z,PIO_LPT ; no, busy wait
|
|
IN A,($F5) ; get transmit buffer register status ready?
|
|
AND $20 ; ready?
|
|
JR Z,PIO_LPT ; no, busy wait
|
|
LD A,C ; ready, char A for output through data port
|
|
OUT ($F0),A ; output char
|
|
RET
|
|
;
|
|
; PIO PORT TABLE
|
|
;
|
|
PIO_CFG:
|
|
; PIO CHANNEL A
|
|
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB PIOBASE+2 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGA ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 1 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB PIOBASE+3 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL A
|
|
.DB 2 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB PIOBASE+6 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGA ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 3 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB PIOBASE+7 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
; PIO CHANNEL A
|
|
.DB 4 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB 4PIOBASE+2 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGX ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 5 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB 4PIOBASE+3 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL A
|
|
.DB 6 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB 4PIOBASE+6 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGA ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 7 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB 4PIOBASE+7 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL A
|
|
.DB 8 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB 4PIOBASE+10 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGA ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 9 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB 4PIOBASE+11 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL A
|
|
.DB 10 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB 4PIOBASE+14 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGA ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 11 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB 4PIOBASE+15 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL A
|
|
.DB 12 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_ZPIO ; PIO TYPE (SET DURING INIT)
|
|
.DB 0 ; PIO CHANNEL (A)
|
|
.DB 4PIOBASE+14 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGA ; LINE CONFIGURATION
|
|
.DW SIOA_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
; PIO CHANNEL B
|
|
.DB 13 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB PIO_8255 ; PIO TYPE (SET DURING INIT)
|
|
.DB 1 ; PIO CHANNEL (B)
|
|
.DB 4PIOBASE+15 ; BASE PORT (CMD PORT)
|
|
.DW DEFPIOCFGB ; LINE CONFIGURATION
|
|
.DW SIOB_RCVBUF ; POINTER TO RCV BUFFER STRUCT
|
|
;
|
|
;
|
|
PIO_CNT .EQU ($ - PIO_CFG) / 8
|
|
;
|
|
; DRIVER FUNCTION TABLE
|
|
;
|
|
PIO_FNTBL:
|
|
.DW PIO_IN
|
|
.DW PIO_OUT
|
|
.DW PIO_IST
|
|
.DW PIO_OST
|
|
.DW PIO_INITDEV
|
|
.DW PIO_QUERY
|
|
.DW PIO_DEVICE
|
|
#IF (($ - PIO_FNTBL) != (CIO_FNCNT * 2))
|
|
.ECHO "*** INVALID SIO FUNCTION TABLE ***\n"
|
|
#ENDIF
|
|
;
|
|
PIO_OUT:
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
PIO_IN:
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
PIO_IST:
|
|
RET
|
|
;
|
|
PIO_OST:
|
|
RET
|
|
;
|
|
; PIO_INITDEV - Configure device.
|
|
; If DE = FFFF then extract the configuratio information from the table of devices and program the device using those settings.
|
|
; Otherwise use the configuration information in DE to program those settings and save them in the device table
|
|
|
|
PIO_INITDEV:
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
PIO_QUERY:
|
|
LD E,(IY+4) ; FIRST CONFIG BYTE TO E
|
|
LD D,(IY+5) ; SECOND CONFIG BYTE TO D
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
;
|
|
;TTY_DEVICE:
|
|
; LD D,CIODEV_TERM ; TYPE IS TERMINAL
|
|
; LD A,(TTY_DEVNUM) ; GET DEVICE NUMBER
|
|
; LD E,A ; PUT IT IN E
|
|
; LD A,(TTY_VDAUNIT) ; GET VDA UNIT NUM
|
|
; SET 7,A ; SET BIT 7 TO INDICATE TERMINAL TYPE
|
|
; LD C,A ; PUT IT IN C
|
|
; XOR A ; SIGNAL SUCCESS
|
|
; RET
|
|
;
|
|
;
|
|
PIO_DEVICE:
|
|
LD D,CIODEV_PIO ; D := DEVICE TYPE
|
|
LD E,(IY) ; E := PHYSICAL UNIT
|
|
LD A,E
|
|
SET 7,A
|
|
LD C,A
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
PIO_PRTCFG:
|
|
; ANNOUNCE PORT
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("PIO$") ; 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 PIO TYPE
|
|
CALL PC_SPACE ; FORMATTING
|
|
LD A,(IY+1) ; GET PIO TYPE BYTE
|
|
RLCA ; MAKE IT A WORD OFFSET
|
|
LD HL,PIO_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 PIO 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_PRTPC0 ; PRINT CONFIG
|
|
;
|
|
XOR A
|
|
RET
|
|
;
|
|
; WORKING VARIABLES
|
|
;
|
|
PIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT
|
|
;
|
|
PIO_TYPE_MAP:
|
|
.DW PIO_STR_NONE
|
|
.DW PIO_STR_PIO
|
|
.DW PIO_STR_8255
|
|
|
|
PIO_STR_NONE .DB "<NOT PRESENT>$"
|
|
PIO_STR_PIO .DB "Zilog PIO$"
|
|
PIO_STR_8255 .DB "i8255 PIO$"
|