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.
275 lines
6.8 KiB
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
|
|
|