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 "$" PIO_STR_PIO .DB "Zilog PIO$" PIO_STR_8255 .DB "i8255 PIO$"