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.
320 lines
7.9 KiB
320 lines
7.9 KiB
;
|
|
;==================================================================================================
|
|
; CENTRONICS INTERFACE DRIVER
|
|
;==================================================================================================
|
|
;
|
|
; CENTRONICS-STYLE PARALLEL PRINTER DRIVER. ASSUMES MBC PRINT BOARD
|
|
; AS HARDWARE.
|
|
;
|
|
; IMPLEMENTED AS A ROMWBW CHARACTER DEVICE. CURRENTLY HANDLES OUPUT
|
|
; ONLY.
|
|
;
|
|
; PORT 0 (INPUT/OUTPUT):
|
|
;
|
|
; D7 D6 D5 D4 D3 D2 D1 D0
|
|
; +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
; | PD7 | PD6 | PD5 | PD4 | PD3 | PD2 | PD1 | PD0 |
|
|
; +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
;
|
|
; PORT 1 (INPUT):
|
|
;
|
|
; D7 D6 D5 D4 D3 D2 D1 D0
|
|
; +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
; | BUSY | ACK | POUT | SEL | ERR | 0 | 0 | 0 |
|
|
; +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
;
|
|
; PORT 2 (INPUT/OUTPUT):
|
|
;
|
|
; D7 D6 D5 D4 D3 D2 D1 D0
|
|
; +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
; | STAT1 | STAT0 | ENBL | PINT | SEL | RES | LF | STB |
|
|
; +-------+-------+-------+-------+-------+-------+-------+-------+
|
|
;
|
|
CEN_NONE .EQU 0
|
|
CEN_MBC .EQU 1
|
|
;
|
|
; PRE-CONSOLE INITIALIZATION - DETECT AND INIT HARDWARE
|
|
;
|
|
CEN_PREINIT:
|
|
;
|
|
; SETUP THE DISPATCH TABLE ENTRIES
|
|
; NOTE: INTS WILL BE DISABLED WHEN PREINIT IS CALLED AND THEY MUST REMIAIN
|
|
; DISABLED.
|
|
;
|
|
LD B,CEN_CFGCNT ; LOOP CONTROL
|
|
XOR A ; ZERO TO ACCUM
|
|
LD (CEN_DEV),A ; CURRENT DEVICE NUMBER
|
|
LD IY,CEN_CFG ; POINT TO START OF CFG TABLE
|
|
CEN_PREINIT0:
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
CALL CEN_INITUNIT ; HAND OFF TO UNIT INIT CODE
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
;
|
|
LD A,(IY+1) ; GET THE CEN TYPE DETECTED
|
|
OR A ; SET FLAGS
|
|
JR Z,CEN_PREINIT2 ; SKIP IT IF NOTHING FOUND
|
|
;
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
PUSH IY ; CFG ENTRY ADDRESS
|
|
POP DE ; ... TO DE
|
|
LD BC,CEN_FNTBL ; BC := FUNCTION TABLE ADDRESS
|
|
CALL NZ,CIO_ADDENT ; ADD ENTRY IF CEN FOUND, BC:DE
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
;
|
|
CEN_PREINIT2:
|
|
LD DE,CEN_CFGSIZ ; SIZE OF CFG ENTRY
|
|
ADD IY,DE ; BUMP IY TO NEXT ENTRY
|
|
DJNZ CEN_PREINIT0 ; LOOP UNTIL DONE
|
|
;
|
|
CEN_PREINIT3:
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; AND RETURN
|
|
;
|
|
; CEN INITIALIZATION ROUTINE
|
|
;
|
|
CEN_INITUNIT:
|
|
CALL CEN_DETECT ; DETERMINE CEN TYPE
|
|
LD (IY+1),A ; SAVE IN CONFIG TABLE
|
|
OR A ; SET FLAGS
|
|
RET Z ; ABORT IF NOTHING THERE
|
|
;
|
|
; UPDATE WORKING CEN DEVICE NUM
|
|
LD HL,CEN_DEV ; POINT TO CURRENT DEVICE NUM
|
|
LD A,(HL) ; PUT IN ACCUM
|
|
INC (HL) ; INCREMENT IT (FOR NEXT LOOP)
|
|
LD (IY),A ; UPDATE UNIT NUM
|
|
;
|
|
; SET DEFAULT CONFIG
|
|
LD DE,-1 ; LEAVE CONFIG ALONE
|
|
; CALL INITDEV TO IMPLEMENT CONFIG, BUT NOTE THAT WE CALL
|
|
; THE INITDEV ENTRY POINT THAT DOES NOT ENABLE/DISABLE INTS!
|
|
JP CEN_INITDEVX ; IMPLEMENT IT AND RETURN
|
|
;
|
|
;
|
|
;
|
|
CEN_INIT:
|
|
LD B,CEN_CFGCNT ; COUNT OF POSSIBLE CEN UNITS
|
|
LD IY,CEN_CFG ; POINT TO START OF CFG TABLE
|
|
CEN_INIT1:
|
|
PUSH BC ; SAVE LOOP CONTROL
|
|
LD A,(IY+1) ; GET CEN TYPE
|
|
OR A ; SET FLAGS
|
|
CALL NZ,CEN_PRTCFG ; PRINT IF NOT ZERO
|
|
POP BC ; RESTORE LOOP CONTROL
|
|
LD DE,CEN_CFGSIZ ; SIZE OF CFG ENTRY
|
|
ADD IY,DE ; BUMP IY TO NEXT ENTRY
|
|
DJNZ CEN_INIT1 ; LOOP TILL DONE
|
|
;
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
; DRIVER FUNCTION TABLE
|
|
;
|
|
CEN_FNTBL:
|
|
.DW CEN_IN
|
|
.DW CEN_OUT
|
|
.DW CEN_IST
|
|
.DW CEN_OST
|
|
.DW CEN_INITDEV
|
|
.DW CEN_QUERY
|
|
.DW CEN_DEVICE
|
|
#IF (($ - CEN_FNTBL) != (CIO_FNCNT * 2))
|
|
.ECHO "*** INVALID CEN FUNCTION TABLE ***\n"
|
|
!!! ; FORCE AN ASSEMBLY ERROR
|
|
#ENDIF
|
|
;
|
|
; BYTE INTPUT
|
|
;
|
|
CEN_IN:
|
|
; INPUT NOT SUPPORTED - RETURN NULL BYTE
|
|
LD E,0 ; NULL BYTE
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; BYTE OUTPUT
|
|
;
|
|
CEN_OUT:
|
|
CALL CEN_OST ; READY TO SEND?
|
|
JR Z,CEN_OUT ; LOOP IF NOT
|
|
; *** ADD CODE TO OUTPUT BYTE ***
|
|
LD A,(IY+3)
|
|
LD C,A ; PORT 0 (DATA)
|
|
OUT (C),E ; OUTPUT DATA TO PORT
|
|
call DELAY ; ignore anything back after a reset
|
|
ld A,%00001101 ; select & strobe, LEDS OFF
|
|
INC C ; PUT CONTROL PORT IN C
|
|
INC C
|
|
OUT (C),A ; OUTPUT DATA TO PORT
|
|
call DELAY ; ignore anything back after a reset
|
|
ld A,%00001100 ; select, LEDS OFF
|
|
OUT (C),A ; OUTPUT DATA TO PORT
|
|
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; INPUT STATUS
|
|
;
|
|
CEN_IST:
|
|
; INPUT NOT SUPPORTED - RETURN NOT READY
|
|
XOR A ; ZERO BYTES AVAILABLE
|
|
RET ; DONE
|
|
;
|
|
; OUTPUT STATUS
|
|
;
|
|
CEN_OST:
|
|
LD A,(IY+3)
|
|
LD C,A ; PORT 0 (DATA)
|
|
INC C ; SELECT STATUS PORT
|
|
IN A,(C) ; GET STATUS INFO
|
|
AND %10000000 ; ONLY INTERESTED IN BUSY FLAG
|
|
RET ; DONE
|
|
;
|
|
; INITIALIZE DEVICE
|
|
;
|
|
CEN_INITDEV:
|
|
HB_DI ; AVOID CONFLICTS
|
|
CALL CEN_INITDEVX ; DO THE REAL WORK
|
|
HB_EI ; INTS BACK ON
|
|
RET ; DONE
|
|
;
|
|
; THIS ENTRY POINT BYPASSES DISABLING/ENABLING INTS WHICH IS REQUIRED BY
|
|
; PREINIT ABOVE. PREINIT IS NOT ALLOWED TO ENABLE INTS!
|
|
;
|
|
CEN_INITDEVX:
|
|
LD A,(IY+3)
|
|
LD C,A ; PORT 0 (DATA)
|
|
XOR A ; CLEAR ACCUM
|
|
OUT (C),A ; SEND IT
|
|
INC C ; BUMP TO
|
|
INC C ; ... PORT 2
|
|
LD A,%00001000 ; SELECT AND ASSERT RESET, LEDS OFF
|
|
OUT (C),A ; SEND IT
|
|
CALL LDELAY ; HALF SECOND DELAY
|
|
LD A,%00001100 ; SELECT AND DEASSERT RESET, LEDS OFF
|
|
OUT (C),A ; SEND IT
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; RETURN
|
|
;
|
|
;
|
|
;
|
|
CEN_QUERY:
|
|
LD E,(IY+4) ; FIRST CONFIG BYTE TO E
|
|
LD D,(IY+5) ; SECOND CONFIG BYTE TO D
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET ; DONE
|
|
;
|
|
;
|
|
;
|
|
CEN_DEVICE:
|
|
LD D,CIODEV_CEN ; D := DEVICE TYPE
|
|
LD E,(IY) ; E := PHYSICAL UNIT
|
|
LD C,$40 ; C := DEVICE TYPE, 0x40 IS PIO
|
|
LD H,(IY+1) ; H := MODE
|
|
LD L,(IY+3) ; L := BASE I/O ADDRESS
|
|
XOR A ; SIGNAL SUCCESS
|
|
RET
|
|
;
|
|
; CEN DETECTION ROUTINE
|
|
;
|
|
CEN_DETECT:
|
|
LD A,(IY+3) ; BASE PORT ADDRESS
|
|
ADD A,2 ; USE PORT 2 FOR DETECT
|
|
LD C,A ; PUT IN C FOR I/O
|
|
CALL CEN_DETECT2 ; CHECK IT
|
|
JR Z,CEN_DETECT1 ; FOUND IT, RECORD IT
|
|
LD A,CEN_NONE ; NOTHING FOUND
|
|
RET ; DONE
|
|
;
|
|
CEN_DETECT1:
|
|
; CEN FOUND, RECORD IT
|
|
LD A,CEN_MBC ; RETURN CHIP TYPE
|
|
RET ; DONE
|
|
;
|
|
CEN_DETECT2:
|
|
; LOOK FOR CEN AT PORT ADDRESS IN C
|
|
XOR A ; DEFAULT VALUE
|
|
OUT (C),A ; SEND IT
|
|
IN A,(C) ; READ IT
|
|
AND %11000000 ; ISOLATE STATUS BITS
|
|
CP %00000000 ; CORRECT VALUE?
|
|
RET NZ ; IF NOT, RETURN
|
|
LD A,%11000000 ; STATUS BITS ON (LEDS OFF)
|
|
OUT (C),A ; SEND IT
|
|
IN A,(C) ; READ IT
|
|
AND %11000000 ; ISOLATE STATUS BITS
|
|
CP %11000000 ; CORRECT VALUE?
|
|
RET ; RETURN (ZF SET CORRECTLY)
|
|
;
|
|
;
|
|
;
|
|
CEN_PRTCFG:
|
|
; ANNOUNCE PORT
|
|
CALL NEWLINE ; FORMATTING
|
|
PRTS("CEN$") ; 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 CEN TYPE
|
|
CALL PC_SPACE ; FORMATTING
|
|
LD A,(IY+1) ; GET CEN TYPE BYTE
|
|
RLCA ; MAKE IT A WORD OFFSET
|
|
LD HL,CEN_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 CEN WAS DETECTED
|
|
LD A,(IY+1) ; GET CEN TYPE BYTE
|
|
OR A ; SET FLAGS
|
|
RET Z ; IF ZERO, NOT PRESENT
|
|
;
|
|
; *** ADD MORE DEVICE INFO??? ***
|
|
;
|
|
XOR A
|
|
RET
|
|
;
|
|
;
|
|
;
|
|
CEN_TYPE_MAP:
|
|
.DW CEN_STR_NONE
|
|
.DW CEN_STR_MBC
|
|
;
|
|
CEN_STR_NONE .DB "<NOT PRESENT>$"
|
|
CEN_STR_MBC .DB "MBC$"
|
|
;
|
|
; WORKING VARIABLES
|
|
;
|
|
CEN_DEV .DB 0 ; DEVICE NUM USED DURING INIT
|
|
;
|
|
; CEN DEVICE CONFIGURATION TABLE
|
|
;
|
|
CEN_CFG:
|
|
;
|
|
CEN0_CFG:
|
|
; CEN MODULE A CONFIG
|
|
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB 0 ; CEN TYPE (SET DURING INIT)
|
|
.DB 0 ; MODULE ID
|
|
.DB CEN0BASE ; BASE PORT
|
|
.DW 0 ; LINE CONFIGURATION
|
|
;
|
|
CEN_CFGSIZ .EQU $ - CEN_CFG ; SIZE OF ONE CFG TABLE ENTRY
|
|
;
|
|
#IF (CENCNT >= 2)
|
|
;
|
|
CEN1_CFG:
|
|
; CEN MODULE B CONFIG
|
|
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
|
|
.DB 0 ; CEN TYPE (SET DURING INIT)
|
|
.DB 1 ; MODULE ID
|
|
.DB CEN1BASE ; BASE PORT
|
|
.DW 0 ; LINE CONFIGURATION
|
|
;
|
|
#ENDIF
|
|
;
|
|
CEN_CFGCNT .EQU ($ - CEN_CFG) / CEN_CFGSIZ
|
|
|