@ -1,10 +1,10 @@
;
;==================================================================================================
; CENTRONICS INTERFACE DRIVER
; CENTRONICS (LPT) INTERFACE DRIVER
;==================================================================================================
;
; CENTRONICS-STYLE PARALLEL PRINTER DRIVER. ASSUMES MBC PRINT BOARD
; AS HARDWARE.
; CENTRONICS-STYLE PARALLEL PRINTER DRIVER. ASSUMES IBM STYLE
; HARDWARE INTERFACE AS DESCRIBED BELOW .
;
; IMPLEMENTED AS A ROMWBW CHARACTER DEVICE. CURRENTLY HANDLES OUPUT
; ONLY.
@ -30,56 +30,56 @@
; | STAT1 | STAT0 | ENBL | PINT | SEL | RES | LF | STB |
; +-------+-------+-------+-------+-------+-------+-------+-------+
;
CEN _NONE .EQU 0
CEN_MBC .EQU 1
LPT _NONE .EQU 0 ; NOT PRESENT
LPT_IBM .EQU 1 ; IBM PC STYLE INTERFACE
;
; PRE-CONSOLE INITIALIZATION - DETECT AND INIT HARDWARE
;
CEN _PREINIT:
LPT _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
LD B , LPT _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:
LD ( LPT _DEV), A ; CURRENT DEVICE NUMBER
LD IY , LPT _CFG ; POINT TO START OF CFG TABLE
LPT _PREINIT0:
PUSH BC ; SAVE LOOP CONTROL
CALL CEN _INITUNIT ; HAND OFF TO UNIT INIT CODE
CALL LPT _INITUNIT ; HAND OFF TO UNIT INIT CODE
POP BC ; RESTORE LOOP CONTROL
;
LD A ,( IY + 1 ) ; GET THE CEN TYPE DETECTED
LD A ,( IY + 1 ) ; GET THE LPT TYPE DETECTED
OR A ; SET FLAGS
JR Z , CEN _PREINIT2 ; SKIP IT IF NOTHING FOUND
JR Z , LPT _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
LD BC , LPT _FNTBL ; BC := FUNCTION TABLE ADDRESS
CALL NZ , CIO_ADDENT ; ADD ENTRY IF LPT FOUND, BC:DE
POP BC ; RESTORE LOOP CONTROL
;
CEN _PREINIT2:
LD DE , CEN _CFGSIZ ; SIZE OF CFG ENTRY
LPT _PREINIT2:
LD DE , LPT _CFGSIZ ; SIZE OF CFG ENTRY
ADD IY , DE ; BUMP IY TO NEXT ENTRY
DJNZ CEN _PREINIT0 ; LOOP UNTIL DONE
DJNZ LPT _PREINIT0 ; LOOP UNTIL DONE
;
CEN _PREINIT3:
LPT _PREINIT3:
XOR A ; SIGNAL SUCCESS
RET ; AND RETURN
;
; CEN INITIALIZATION ROUTINE
; LPT INITIALIZATION ROUTINE
;
CEN _INITUNIT:
CALL CEN_DETECT ; DETERMINE CEN TYPE
LPT _INITUNIT:
CALL LPT_DETECT ; DETERMINE LPT 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
; UPDATE WORKING LPT DEVICE NUM
LD HL , LPT _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
@ -88,44 +88,44 @@ CEN_INITUNIT:
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
JP LPT _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:
LPT _INIT:
LD B , LPT_CFGCNT ; COUNT OF POSSIBLE LPT UNITS
LD IY , LPT _CFG ; POINT TO START OF CFG TABLE
LPT _INIT1:
PUSH BC ; SAVE LOOP CONTROL
LD A ,( IY + 1 ) ; GET CEN TYPE
LD A ,( IY + 1 ) ; GET LPT TYPE
OR A ; SET FLAGS
CALL NZ , CEN _PRTCFG ; PRINT IF NOT ZERO
CALL NZ , LPT _PRTCFG ; PRINT IF NOT ZERO
POP BC ; RESTORE LOOP CONTROL
LD DE , CEN _CFGSIZ ; SIZE OF CFG ENTRY
LD DE , LPT _CFGSIZ ; SIZE OF CFG ENTRY
ADD IY , DE ; BUMP IY TO NEXT ENTRY
DJNZ CEN _INIT1 ; LOOP TILL DONE
DJNZ LPT _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"
LPT _FNTBL:
.DW LPT _IN
.DW LPT _OUT
.DW LPT _IST
.DW LPT _OST
.DW LPT _INITDEV
.DW LPT _QUERY
.DW LPT _DEVICE
# IF (( $ - LPT _FNTBL) ! = ( CIO_FNCNT * 2 ))
.ECHO "*** INVALID LPT FUNCTION TABLE ***\n"
! ! ! ; FORCE AN ASSEMBLY ERROR
# ENDIF
;
; BYTE INTPUT
;
CEN _IN:
LPT _IN:
; INPUT NOT SUPPORTED - RETURN NULL BYTE
LD E , 0 ; NULL BYTE
XOR A ; SIGNAL SUCCESS
@ -133,20 +133,19 @@ CEN_IN:
;
; BYTE OUTPUT
;
CEN_OUT:
CALL CEN_OST ; READY TO SEND?
JR Z , CEN_OUT ; LOOP IF NOT
; *** ADD CODE TO OUTPUT BYTE ***
LPT_OUT:
CALL LPT_OST ; READY TO SEND?
JR Z , LPT_OUT ; LOOP IF NOT
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
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
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
@ -154,14 +153,14 @@ CEN_OUT:
;
; INPUT STATUS
;
CEN _IST:
LPT _IST:
; INPUT NOT SUPPORTED - RETURN NOT READY
XOR A ; ZERO BYTES AVAILABLE
RET ; DONE
;
; OUTPUT STATUS
;
CEN _OST:
LPT _OST:
LD A ,( IY + 3 )
LD C , A ; PORT 0 (DATA)
INC C ; SELECT STATUS PORT
@ -171,16 +170,16 @@ CEN_OST:
;
; INITIALIZE DEVICE
;
CEN _INITDEV:
LPT _INITDEV:
HB_DI ; AVOID CONFLICTS
CALL CEN _INITDEVX ; DO THE REAL WORK
CALL LPT _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:
LPT _INITDEVX:
LD A ,( IY + 3 )
LD C , A ; PORT 0 (DATA)
XOR A ; CLEAR ACCUM
@ -197,7 +196,7 @@ CEN_INITDEVX:
;
;
;
CEN _QUERY:
LPT _QUERY:
LD E ,( IY + 4 ) ; FIRST CONFIG BYTE TO E
LD D ,( IY + 5 ) ; SECOND CONFIG BYTE TO D
XOR A ; SIGNAL SUCCESS
@ -205,8 +204,8 @@ CEN_QUERY:
;
;
;
CEN _DEVICE:
LD D , CIODEV_CEN ; D := DEVICE TYPE
LPT _DEVICE:
LD D , CIODEV_LPT ; D := DEVICE TYPE
LD E ,( IY ) ; E := PHYSICAL UNIT
LD C , $ 40 ; C := DEVICE TYPE, 0x40 IS PIO
LD H ,( IY + 1 ) ; H := MODE
@ -214,62 +213,71 @@ CEN_DEVICE:
XOR A ; SIGNAL SUCCESS
RET
;
; CEN DETECTION ROUTINE
; LPT DETECTION ROUTINE
;
CEN _DETECT:
LPT _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
CALL LPT _DETECT2 ; CHECK IT
JR Z , LPT _DETECT1 ; FOUND IT, RECORD IT
LD A , LPT _NONE ; NOTHING FOUND
RET ; DONE
;
CEN _DETECT1:
; CEN FOUND, RECORD IT
LD A , CEN_MBC ; RETURN CHIP TYPE
LPT _DETECT1:
; LPT FOUND, RECORD IT
LD A , LPT_IBM ; RETURN CHIP TYPE
RET ; DONE
;
CEN_DETECT2:
; LOOK FOR CEN AT PORT ADDRESS IN C
XOR A ; DEFAULT VALUE
LPT_DETECT2:
; LOOK FOR LPT AT BASE PORT ADDRESS IN C
INC C ; PORT C FOR I/O
INC C ; ...
XOR A ; DEFAULT VALUE (TRI-STATE OFF)
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)
;
;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?
;
DEC C ; BACK TO BASE PORT
DEC C ; ...
LD A , $ A5 ; TEST VALUE
OUT ( C ), A ; SEND IT
IN A ,( C ) ; READ IT
AND % 11000000 ; ISOLATE STATUS BITS
CP % 11000000 ; CORRECT VALUE?
IN A ,( C ) ; READ IT BACK
CP $ A5 ; CORRECT?
RET ; RETURN (ZF SET CORRECTLY)
;
;
;
CEN_PRTCFG:
LPT _PRTCFG:
; ANNOUNCE PORT
CALL NEWLINE ; FORMATTING
PRTS ( "CEN $" ) ; FORMATTING
PRTS ( "LPT $" ) ; 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
; PRINT THE LPT TYPE
CALL PC_SPACE ; FORMATTING
LD A ,( IY + 1 ) ; GET CEN TYPE BYTE
LD A ,( IY + 1 ) ; GET LPT TYPE BYTE
RLCA ; MAKE IT A WORD OFFSET
LD HL , CEN _TYPE_MAP ; POINT HL TO TYPE MAP TABLE
LD HL , LPT _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
; ALL DONE IF NO LPT WAS DETECTED
LD A ,( IY + 1 ) ; GET LPT TYPE BYTE
OR A ; SET FLAGS
RET Z ; IF ZERO, NOT PRESENT
;
@ -280,41 +288,41 @@ CEN_PRTCFG:
;
;
;
CEN _TYPE_MAP:
.DW CEN _STR_NONE
.DW CEN_STR_MBC
LPT _TYPE_MAP:
.DW LPT _STR_NONE
.DW LPT_STR_IBM
;
CEN _STR_NONE .DB "<NOT PRESENT>$"
CEN_STR_MBC .DB "MBC $"
LPT _STR_NONE .DB "<NOT PRESENT>$"
LPT_STR_IBM .DB "IBM $"
;
; WORKING VARIABLES
;
CEN _DEV .DB 0 ; DEVICE NUM USED DURING INIT
LPT _DEV .DB 0 ; DEVICE NUM USED DURING INIT
;
; CEN DEVICE CONFIGURATION TABLE
; LPT DEVICE CONFIGURATION TABLE
;
CEN _CFG:
LPT _CFG:
;
CEN 0_CFG:
; CEN MODULE A CONFIG
LPT 0_CFG:
; LPT MODULE A CONFIG
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; CEN TYPE (SET DURING INIT)
.DB 0 ; LPT TYPE (SET DURING INIT)
.DB 0 ; MODULE ID
.DB CEN 0BASE ; BASE PORT
.DB LPT 0BASE ; BASE PORT
.DW 0 ; LINE CONFIGURATION
;
CEN _CFGSIZ .EQU $ - CEN _CFG ; SIZE OF ONE CFG TABLE ENTRY
LPT _CFGSIZ .EQU $ - LPT _CFG ; SIZE OF ONE CFG TABLE ENTRY
;
# IF ( CEN CNT > = 2 )
# IF ( LPT CNT > = 2 )
;
CEN 1_CFG:
; CEN MODULE B CONFIG
LPT 1_CFG:
; LPT MODULE B CONFIG
.DB 0 ; DEVICE NUMBER (SET DURING INIT)
.DB 0 ; CEN TYPE (SET DURING INIT)
.DB 0 ; LPT TYPE (SET DURING INIT)
.DB 1 ; MODULE ID
.DB CEN 1BASE ; BASE PORT
.DB LPT 1BASE ; BASE PORT
.DW 0 ; LINE CONFIGURATION
;
# ENDIF
;
CEN _CFGCNT .EQU ( $ - CEN_CFG ) / CEN _CFGSIZ
LPT _CFGCNT .EQU ( $ - LPT_CFG ) / LPT _CFGSIZ