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

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$"