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.
 
 
 
 
 
 

275 lines
6.8 KiB

;
;==================================================================================================
; 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 "<NOT PRESENT>$"
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