; ;================================================================================================== ; DLP-USB SERIAL DRIVER ;================================================================================================== ; ; THIS SERIAL DRIVER SUPPORTS THE DLP-USB DEVICE ON THE S100 SERIAL-IO ; BOARD. NOTE THAT THE DLP USB DEVICE IS CONNECTED IN PARALLEL TO THE ; S100 SYSTEM. IT DOES NOT ACTUALLY USE A TRUE SERIAL DATA STREAM ; EVEN THOUGH IT APPEARS AS SUCH TO THE USB-CONNECTED COMPUTER. ; ; STATUS BITS: IDLE ; 7: 0=CHAR PENDING 1 ; 6: 0=XMIT HOLDING REGISTER EMPTY 0 ; 5-0: UNDEFINED ; DLPSER_NONE .EQU 0 DLPSER_DLP .EQU 1 ; DLPSERCFG .EQU SER_9600_8N1 ; DLPSER: SERIAL LINE CONFIG ; ; ACCORDING TO THE S100 SERIAL-IO BOARD CONVENTIONS, THE PPI IS ; CONFIGURED FOR MODE 0 WITH A=INPUT, B=OUTPUT, C0-3=OUTPUT, ; C4-7=INPUT ; DLPSER_PPICTL .EQU $AB DLPSER_PPICFG .EQU %10011000 ; DLPSER_PREINIT: ; ; SETUP THE DISPATCH TABLE ENTRIES ; LD B,DLPSERCNT ; LOOP CONTROL XOR A ; ZERO TO ACCUM LD (DLPSER_DEV),A ; CURRENT DEVICE NUMBER LD IY,DLPSER_CFG ; POINT TO START OF CFG TABLE DLPSER_PREINIT0: PUSH BC ; SAVE LOOP CONTROL CALL DLPSER_INITUNIT ; HAND OFF TO GENERIC INIT CODE POP BC ; RESTORE LOOP CONTROL ; OR $FF ; $FF TO ACCUME LD (IY+2),A ; CLEAR HBIOS UNIT ASSIGNMENT LD A,(IY+1) ; GET THE DLPSER TYPE DETECTED OR A ; SET FLAGS JR Z,DLPSER_PREINIT2 ; SKIP IT IF NOTHING FOUND ; PUSH BC ; SAVE LOOP CONTROL PUSH IY ; CFG ENTRY ADDRESS POP DE ; ... TO DE LD BC,DLPSER_FNTBL ; BC := FUNCTION TABLE ADDRESS CALL NZ,CIO_ADDENT ; ADD ENTRY IF DLPSER FOUND LD (IY+2),A ; RECORD OUT HBIOS UNIT NUMBER POP BC ; RESTORE LOOP CONTROL ; DLPSER_PREINIT2: LD DE,DLPSER_CFGSIZ ; SIZE OF CFG ENTRY ADD IY,DE ; BUMP IY TO NEXT ENTRY DJNZ DLPSER_PREINIT0 ; LOOP UNTIL DONE ; XOR A ; SIGNAL SUCCESS RET ; DONE ; ; DLPSER UNIT INITIALIZATION ROUTINE ; DLPSER_INITUNIT: CALL DLPSER_DETECT ; DETECT IT LD (IY+1),A ; SAVE IN CONFIG TABLE OR A ; SET FLAGS RET Z ; ABORT IF NOTHING THERE ; ; UPDATE WORKING DLPSER DEVICE NUM LD HL,DLPSER_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 ; JP DLPSER_INITDEV ; INIT DEVICE AND RETURN ; ; ; DLPSER_INIT: LD B,DLPSERCNT ; COUNT OF POSSIBLE DLPSER UNITS LD IY,DLPSER_CFG ; POINT TO START OF CFG TABLE DLPSER_INIT1: PUSH BC ; SAVE LOOP CONTROL LD A,(IY+1) ; GET DLPSER TYPE OR A ; SET FLAGS CALL NZ,DLPSER_PRTCFG ; PRINT IF NOT ZERO POP BC ; RESTORE LOOP CONTROL LD DE,DLPSER_CFGSIZ ; SIZE OF CFG ENTRY ADD IY,DE ; BUMP IY TO NEXT ENTRY DJNZ DLPSER_INIT1 ; LOOP TILL DONE ; XOR A ; SIGNAL SUCCESS RET ; DONE ; ; DRIVER FUNCTION TABLE ; DLPSER_FNTBL: .DW DLPSER_IN .DW DLPSER_OUT .DW DLPSER_IST .DW DLPSER_OST .DW DLPSER_INITDEV .DW DLPSER_QUERY .DW DLPSER_DEVICE #IF (($ - DLPSER_FNTBL) != (CIO_FNCNT * 2)) .ECHO "*** INVALID DLPSER FUNCTION TABLE ***\n" #ENDIF ; ; ; DLPSER_IN: CALL DLPSER_IST ; CHECK FOR CHAR PENDING JR Z,DLPSER_IN ; WAIT FOR IT IF NECESSARY ;IN A,(DLPSER_DATA) ; READ THE CHAR LD C,(IY+4) ; DATA PORT IN E,(C) ; GET BYTE XOR A ; SIGNAL SUCCESS RET ; DONE ; ; ; DLPSER_IST: ;IN A,(DLPSER_STAT) ; READ LINE STATUS REGISTER LD C,(IY+3) ; STATUS PORT IN A,(C) ; GET STATUS CPL AND %10000000 ; ISOLATE DATA READY JP Z,CIO_IDLE ; RETURN VIA IDLE PROCESSING OR $FF ; SET A=$FF TO SIGNAL READY RET ; RETURN ; ; ; DLPSER_OUT: CALL DLPSER_OST ; CHECK FOR OUTPUT READY JR Z,DLPSER_OUT ; WAIT IF NECESSARY ;LD A,E ; RECOVER THE CHAR TO WRITE ;OUT (DLPSER_DATA),A ; WRITE THE CHAR LD C,(IY+4) ; DATA PORT OUT (C),E ; SEND BYTE XOR A ; SIGNAL SUCCESS RET ; DONE ; ; ; DLPSER_OST: ;IN A,(DLPSER_STAT) ; READ LINE STATUS REGISTER LD C,(IY+3) ; STATUS PORT IN A,(C) ; GET STATUS CPL AND %01000000 ; ISOLATE OUTPUT RDY JP Z,CIO_IDLE ; RETURN VIA IDLE PROCESSING OR $FF ; SET A=$FF TO SIGNAL READY RET ; RETURN ; ; ; DLPSER_INITDEV: #IF (PLATFORM == PLT_SZ80) LD A,(IY+4) ; GET THE DATA PORT CP $AA ; IS THIS THE SERIAL I/O BOARD DLP DEVICE? JR NZ,DLPSER_INITDEV1 ; IF NOT, SKIP LD A,DLPSER_PPICFG ; CONFIG 8255 PORTS OUT (DLPSER_PPICTL),A ; WRITE CONTROL WORD #ENDIF DLPSER_INITDEV1: XOR A ; NOTHING TO DO RET ; ; ; DLPSER_QUERY: LD DE,DLPSERCFG XOR A RET ; ; ; DLPSER_DEVICE: LD D,CIODEV_DLPSER ; D := DEVICE TYPE LD E,(IY) ; E := DEVICE NUM, ALWAYS 0 LD C,$00 ; C := DEVICE TYPE, 0x00 IS RS-232 LD H,0 ; H := 0, DRIVER HAS NO MODES LD L,(IY+4) ; L := BASE I/O ADDRESS XOR A ; SIGNAL SUCCESS RET ; ; TEST FOR HARDWARE PRESENCE. ; THIS DEVICE IS VERY HARD TO DETECT. WE USE THE PRESENCE OF ; THE STATUS PORT. RETURN DEVICE TYPE. ; DLPSER_DETECT: LD A,(IY+3) ; STATUS PORT LD C,A ; COPY TO C LD ($+4),A ; MODIFY CODE DLPSER_DETECT1 IN A,($FF) ; READ PORT DIRECT IN B,(C) ; READ PORT VIA C CP B ; A==B MEANS PORT EXISTS LD A,DLPSER_NONE ; ASSUME NOTHING THERE RET NZ ; IF NZ, NOTHING LD A,DLPSER_DLP ; ELSE TYPE IS DLP RET ; ; ; DLPSER_PRTCFG: ; ANNOUNCE PORT CALL NEWLINE ; FORMATTING PRTS("DLPSER$") ; FORMATTING LD A,(IY) ; DEVICE NUM CALL PRTDECB ; PRINT DEVICE NUM PRTS(": IO=0x$") ; FORMATTING LD A,(IY+4) ; GET DATA PORT CALL PRTHEXBYTE ; PRINT DATA PORT ; ; PRINT THE DLPSER TYPE CALL PC_SPACE ; FORMATTING LD A,(IY+1) ; GET DLPSER TYPE BYTE RLCA ; MAKE IT A WORD OFFSET LD HL,DLPSER_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 ; XOR A RET ; ; ; DLPSER_TYPE_MAP: .DW DLPSER_STR_NONE .DW DLPSER_STR_DLP DLPSER_STR_NONE .DB "$" DLPSER_STR_DLP .DB "DLP-USB$" ; ; UART PORT TABLE ; DLPSER_CFG: ; DLPSER0_CFG: .DB 0 ; DEVICE NUMBER (SET DURING INIT) ; +0 .DB 0 ; DLPSER TYPE (SET DURING INIT) ; +1 .DB $FF ; HBIOS CHARACTER UNIT ASSIGNED ; +2 .DB DLPSER0STAT ; STATUS PORT ; +3 .DB DLPSER0DATA ; DATA PORT ; +4 ; DEVECHO "DLPSER: IO=" DEVECHO DLPSER0DATA DEVECHO "\n" ; ; DLPSER_CFGSIZ .EQU $ - DLPSER_CFG ; SIZE OF ONE CFG TABLE ENTRY ; #IF (DLPSERCNT >= 1) DLPSER1_CFG: .DB 0 ; DEVICE NUMBER (SET DURING INIT) ; +0 .DB 0 ; DLPSER TYPE (SET DURING INIT) ; +1 .DB $FF ; HBIOS CHARACTER UNIT ASSIGNED ; +2 .DB DLPSER1STAT ; STATUS PORT ; +3 .DB DLPSER1DATA ; DATA PORT ; +4 ; DEVECHO "DLPSER: IO=" DEVECHO DLPSER1DATA DEVECHO "\n" #ENDIF ; ; WORKING VARIABLES ; DLPSER_DEV .DB 0 ; DEVICE NUM USED DURING INIT