Files
RomWBW/Source/BPBIOS/iio-dx.z80
2015-08-19 17:34:42 +00:00

1296 lines
39 KiB
Z80 Assembly
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;:::::::::::::::::::::::::::::::::::::::::::::::::*************************
; Byte I/O Routines *** Hardware Specific ***
; - D-X Designs Pty Ltd P112 - *************************
;
; Several serial and parallel options exist on the P112, with two serial
; ports available at RS-232 signalling levels. The primary port defined here
; as COM1 uses SCC Channel A of the Z80182. A 16550-compatible serial port
; on the SMC FDC37C665 is used as COM2. Three other serial ports (the two
; ACSI ports in the Z180 core, and SCC Channel B) are available at TTL
; voltage levels on a single header and may be defined as COM3-5 if the pins
; from the Z182 are not otherwise used.
; This code supports the additional serial channels if the MORDEV equate
; is set to YES. If any of the three additional serial ports are defined
; (ESCC_B, ASCI_0, ASCI_1), then the System Configuration Register is set to
; Zero activating the additional signals in the conditions specified herein
; as activated by options in DEF-DX.LIB.
; A full Parallel port on the SMC FDC37C655 (in Normal Centronics mode) is
; used as the primary List (Printer) Device.
;
; NOTE: At the present time, it appears that port 0D9H (ENH182) cannot be set
; so ESCC operation at 24 MHz will occur at the full clock rate instead
; of being divided by Two as specified in Zilog documentation. Code
; managing ENH182 is commented out with ";;--" markers (HFB).
;
; 1.2 - 28 Aug 01 - Final scrub for GPL release. HFB
; 1.1a- 11 May 97 - Cleaned code, fixed added port accesses. HFB
; 1.1 - 25 Jan 97 - Revised ESCC Baud rate calcs, added COM3-5. HFB
; 1.0 - 19 Jun 96 - Initial Release for the P112 from YASBEC. HFB
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Place constants for Expansions here
CSEG
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Byte Device Control Tables
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DEVCFG:
; The Clock Rate for the SCC channels on the Z80182 is based on a divider
; constant loaded in extended registers, the Processor Crystal frequency,
; and the setting of the divider in the SCC Register (1FH).
;
; NOTE: Divisor values are computed based on a compromise between the Crystal
; rates considered "standard" (6.144, 9.216, 12.288 MHz, etc) and the
; 16.000 MHz initially placed on the P112. Higher data rates (38.4 kbps
; and higher) may be out of tolerance, particularly at low CPU speeds.
;
; Clock rates for the serial port on the SMC 37C655 are based on a software
; programmable divider from the 24 MHz crystal driving the chip.
COM1: DEFB 'COM1' ; 4-Char ID
DEFB 11101011B ; Baud Rate
; ||||++++--- Baud Rate setting (19.2 kbps)
; ++++------- Maximum Baud Rate (115.2 kbps)
; Rates are as:
; 0000 = None 0001 = 134.5 0011 = 50 0011 = 75
; 0100 = 150 0101 = 300 0110 = 600 0111 = 1200
; 1000 = 2400 1001 = 4800 1010 = 9600 1011 = 19200
; 1100 = 38400 1101 = 76800 1110 = 115200 1111 = Fixed
DEFB 11100001B ; Config Byte (In,Out,CTS/RTS control,1 Stop)
; |||||||+---------- Stop Bits 1 (1), 2 (0)
; ||||||+----------- Parity Enable (1), Disable (0)
; |||||+------------ Parity Even (1), Odd (0)
; ||||+------------- Data Bits 8 (0), 7 (1)
; |||+-------------- Xon-Xoff Handshake
; ||+--------------- CTS/RTS Handshake
; |+---------------- Input Device No (0), Yes (1)
; +----------------- Output Device No (0), Yes (1)
DEFB 0FFH ; Input Data Mask
DEFB 0FFH ; Output Data Mask
DEFW COM1OT ; COM 1 Byte Output
DEFW COM1OS ; COM 1 Output Status
DEFW COM1IN ; COM 1 Byte Input
DEFW COM1IS ; COM 1 Input Status
COM2: DEFB 'COM2' ; 4-Char ID
DEFB 11101010B ; Baud Rate (115.2k Max, 9600 Set)
DEFB 11100001B ; Config Byte (In,Out,CTS/RTS control,1 Stop)
DEFB 0FFH ; Input Data Mask
DEFB 0FFH ; Output Data Mask
DEFW COM2OT ; COM 2 Byte Output
DEFW COM2OS ; COM 2 Output Status
DEFW COM2IN ; COM 2 Byte Input
DEFW COM2IS ; COM 2 Input Status
PIO1: DEFB 'PIO1' ; 4-Char ID
DEFB 00000000B ; Baud Rate (None)
DEFB 10000000B ; Config Byte (Output Only)
DEFB 0FFH ; Input Data Mask
DEFB 07FH ; Output Data Mask
DEFW PIO1OT ; PIO Byte Output
DEFW PIO1OS ; PIO Output Status
DEFW PIO1IN ; PIO Byte Input
DEFW PIO1IS ; PIO Input Status
IF MOVCPM OR [MORDEV AND NOT [ESCC_B OR ASCI_0 OR ASCI_1]]
DEFB 'NULL' ; 4-Char ID
DEFB 00000000B ; Baud Rate (None)
DEFB 11000000B ; Config Byte
DEFB 0FFH ; Input Data Mask
DEFB 0FFH ; Output Data Mask
DEFW ISFALSE ; Null Output
DEFW ISTRUE ; Null Output Status
DEFW ISFALSE ; Null Input
DEFW ISTRUE ; Null Input Status
ENDIF
IF MORDEV AND NOT MOVCPM ; Include additional devices
; Add Expansion Char IO here with Device format as above
IF ESCC_B
COM3: DEFB 'COM3' ; 4-Char ID
DEFB 11101010B ; Baud Rate (115.2k Max, 9600 Set)
DEFB 11100001B ; Config Byte (In,Out,CTS/RTS control,1 Stop)
DEFB 0FFH ; Input Data Mask
DEFB 0FFH ; Output Data Mask
DEFW COM3OT ; COM 3 Byte Output
DEFW COM3OS ; COM 3 Output Status
DEFW COM3IN ; COM 3 Byte Input
DEFW COM3IS ; COM 3 Input Status
ENDIF
IF ASCI_0
COM4: DEFB 'COM4' ; 4-Char ID
DEFB 11001010B ; Baud Rate (38.4k Max, 9600 Set)
DEFB 11100001B ; Config Byte (In,Out,CTR/RTS control, 1 Stop)
DEFB 0FFH ; Input Data Mask
DEFB 0FFH ; Output Data Mask
DEFW COM4OT ; COM 4 Byte Output
DEFW COM4OS ; COM 4 Output Status
DEFW COM4IN ; COM 4 Byte Input
DEFW COM4IS ; COM 4 Input Status
ENDIF
IF ASCI_1
COM5: DEFB 'COM5' ; 4-Char ID
DEFB 11001010B ; Baud Rate (38.4k Max, 9600 Set)
DEFB 11100001B ; Config Byte (In,Out,CTR/RTS control, 1 Stop)
DEFB 0FFH ; Input Data Mask
DEFB 0FFH ; Output Data Mask
DEFW COM5OT ; COM 5 Byte Output
DEFW COM5OS ; COM 5 Output Status
DEFW COM5IN ; COM 5 Byte Input
DEFW COM5IS ; COM 5 Input Status
ENDIF
ENDIF ;Mordev & Not Movcpm
DEFB 0 ; - End-of-Table marker
MAXBDV EQU [$-DEVCFG-1]/[COM2-COM1] ; Number of Character Devices Defined
DEVTBL: LD HL,DEVCFG ; BYTE device table
RET ; CP/M-3 device init
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; COM1 Drivers
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Uses Z80182 SCC Channel A (Default to Console)
;.....
; COM1 Input Status Test
; Bit 0 of SCC Ch.A Control Port signifies Char Ready
COM1IS: IN0 A,(SCCACNT) ; Console Input Status
RRA ; Input Ready = Bit0 -> Carry
SBC A,A ; A=00 if Not Ready, FF if Char Ready
RET
;.....
; COM1 Input Routine
; Remain in Loop until Char ready, then Return Char in A
COM1IN: CALL COM1IS ; Console input from SCC Ch.A Ready?
JR Z,COM1IN ; ..loop if Not
IN0 A,(SCCAD) ; Else Read SCC Ch.A Data
IF MOVCPM ; (No Swap allowed)
LD C,A ; Store byte temporarily
LD A,(COM1+6) ; .get Input mask
AND C ; ..and apply to byte
ELSE ; (Swapping permitted)
IPAT1: AND $-$ ; Char Mask patched in Config
ENDIF ;Movcpm
RET
;.....
; COM1 Output Status Test
COM1OS:
IF XONOFF
LD A,(COM1+5) ; Get this Chan's Config settings
AND 00010000B ; Xon/Xoff in use?
JR Z,COM1O0 ; ..jump if Not
LD A,(COM1WT) ; Else get Current flow status
RLA
LD A,00 ; (prepare for stopped)
JR C,SOSTV ; ..jump to return Not Ready if Stopped
COM1O0:
ENDIF ;Xonoff
IN0 A,(SCCACNT) ; Read SCC Ch.A Control Reg
RRA ; Output Ready = Bit 2
RRA
RRA ; -> Carry
SBC A,A ; A=00 if Not Ready, FF if Xmt Buffer Empty
RET
;.....
; COM1 Output Routine (Byte to Send in C)
COM1OT: CALL COM1OS ; Output to SCC Ch.A Ready?
JR Z,COM1OT ; ..loop if Not
IF MOVCPM ; (No Swap allowed)
LD A,(COM1+7) ; Get output mask
AND C ; .apply to byte
ELSE ; (Swapping permitted)
LD A,C ; Get Char
OPAT1: AND $-$ ; mask as set in Config
ENDIF ; Movcpm
OUT0 (SCCAD),A ; and send
RET
PAGE
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; COM2 Drivers
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Uses 16550-compatible SMC FDC37C665 Serial Port (defaults to Aux)
;.....
; COM2 Input Status Test
COM2IS: IN0 A,(_LSR) ; Input Status Reg Byte
RRA ; Rcv Rdy Bit[0] -> Carry
SBC A,A ; A=00 if Not Ready, FF if Char received
RET
;.....
; COM2 Input Routine
COM2IN: CALL COM2IS ; Char Ready?
JR Z,COM2IN ; ..loop if Not
IN0 A,(_RBR) ; Else Read Receive Buffer
IF MOVCPM ; (No Swap allowed)
LD C,A ; Save byte
LD A,(COM2+6) ; .get mask
AND C ; ..apply it
ELSE ; (Swapping permitted)
IPAT2: AND $-$ ; Mask as set in Config
ENDIF ;Movcpm
RET
;.....
; COM2 Output Status Test
COM2OS:
IF XONOFF
LD A,(COM2+5) ; Get Config Byte
AND 00010000B ; Xon/Xoff Active?
JR Z,COM2O0 ; ..jump if Not
LD A,(COM2WT) ; Get Flags Byte
RLA ; Xoff to Carry
LD A,0 ; (prepare for Xoff active)
JR C,SOSTV ; ..jump if Waiting to Return Not Rdy
COM2O0: ;..else fall thru to Check Real Status..
ENDIF ;xonoff
IF RTSCTS
LD A,(COM2+5) ; Get this Chan's Config settings
AND 00100000B ; RTS/CTS in use?
JR Z,COM2O1 ; ..jump if Not
IN0 A,(_MMSR) ; Else Get Port 1 Modem Status
BIT 4,A ; Clear-To-Send?
LD A,0 ; (prepare for No)
JR Z,SOSTV ; ..jump if Not
COM2O1:
ENDIF ;Rtscts
IN0 A,(_LSR) ; Read Status Reg
SOSTV: AND 20H ; Mask Bit of interest
RETST: RET Z ; ..return if nothing valid
ISTRUE: OR 0FFH ; Else set flags for Ready
RET
;.....
; COM2 Output Routine
COM2OT: CALL COM2OS ; Test if ready
JR Z,COM2OT ; ..loop if not
IF MOVCPM ; (No Swap allowed)
LD A,(COM2+7) ; Get output mask
AND C ; apply
ELSE ; (Swapping permitted)
LD A,C ; Get Output Char
OPAT2: AND $-$ ; mask as set in Config
ENDIF ;Movcpm
OUT0 (_THR),A ; and send char to Xmt Holding Reg
RET
PAGE
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Parallel I/O Drivers
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Uses "Standard" Parallel Centronics mode of SMC37C655 (output only)
;.....
; Parallel Input Status Test
PIO1IS: JR ISTRUE ; Not implemented
;.....
; Parallel Input Data fetch
PIO1IN: JP ISFALSE ; Not implemented
;.....
; Parallel Output Status Test
PIO1OS: IN0 A,(SPORT) ; Read Port Status
RLA ; Status Bit [7] -> Carry
SBC A,A ; A=0 if Not Ready, FF if Ready to Send
RET
;.....
; Parallel Output Routine
PIO1OT: CALL PIO1OS ; List on the parallel device
JR Z,PIO1OT
IF MOVCPM ; (No Swap Allowed)
LD A,(PIO1+7) ; Get output mask
AND C ; ..and apply to char
ELSE ; (Swapping permitted)
LD A,C ; Get Output Char
OPATP: AND $-$ ; .mask as set in Config
ENDIF ;Movcpm
OUT0 (DPORT),A ; Latch the output byte to Data Port
LD A,0DH
OUT0 (CPORT),A ; Strobe (STB) = 1 to Control Port
NOP ; (delay)
NOP
LD A,0CH
OUT0 (CPORT),A ; then Strobe = 0 to Control Port
RET
PAGE
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;---->> Additional Driver Code goes Here <<----
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; To constrain the size of the boot system to available space on
; Floppy Disks, The additional drivers are only included if a
; banked system is being assembled, and "MorDev" is set TRUE.
IF MORDEV AND NOT MOVCPM
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; COM3 Driver
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Z80182 SCC Channel B, Auxiliary Serial Port
IF ESCC_B
;.....
; COM3 Input Status Test
; Bit 0 of SCC Ch.B Control Port signifies Char Ready
COM3IS: IN0 A,(SCCBCNT) ; Input Status
RRA ; Input Ready = Bit0 -> Carry
SBC A,A ; A=00 if Not Ready, FF if Char Ready
RET
;.....
; COM3 Input Routine
; Remain in Loop until Char ready, then Return Char in A
COM3IN: CALL COM3IS ; Console input from SCC Ch.B Ready?
JR Z,COM3IN ; ..loop if Not
IN0 A,(SCCBD) ; Else Read SCC Ch.B Data
IF MOVCPM ; (No Swap allowed)
LD C,A ; Store byte temporarily
LD A,(COM3+6) ; .get Input mask
AND C ; ..and apply to byte
ELSE ; (Swapping permitted)
IPAT3: AND $-$ ; Char Mask patched in Config
ENDIF ;Movcpm
RET
;.....
; COM3 Output Status Test
COM3OS:
IF XONOFF
LD A,(COM3+5) ; Get this Chan's Config settings
AND 00010000B ; Xon/Xoff in use?
JR Z,COM3O0 ; ..jump if Not
LD A,(COM3WT) ; Else get Current flow status
RLA
LD A,00 ; (prepare for stopped)
JR C,SOSTV ; ..jump to return Not Ready if Stopped
COM3O0:
ENDIF ;Xonoff
IN0 A,(SCCACNT) ; Read SCC Ch.A Control Reg
RRA ; Output Ready = Bit 2
RRA
RRA ; -> Carry
SBC A,A ; A=00 if Not Ready, FF if Xmt Buffer Empty
RET
;.....
; COM3 Output Routine (Byte to Send in C)
COM3OT: CALL COM3OS ; Output to SCC Ch.B Ready?
JR Z,COM3OT ; ..loop if Not
IF MOVCPM ; (No Swap allowed)
LD A,(COM3+7) ; Get output mask
AND C ; .apply to byte
ELSE ; (Swapping permitted)
LD A,C ; Get Char
OPAT3: AND $-$ ; mask as set in Config
ENDIF ;Movcpm
OUT0 (SCCBD),A ; and send
RET
ENDIF ;Escc_b
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ASCI0 Driver Routines
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IF ASCI_0
IF NOT BUFFA0
;.....
; COM4 Input Status Test
COM4IS: IN0 A,(STAT0) ; Get Status byte
RLA ; RDRF Bit to Carry
SBC A,A ; set A=0 if Not Rdy, FF if Ready
RET
;.....
; COM4 Input Routine
COM4IN: CALL COM4IS ; Anything ready?
JR Z,COM4IN ; ..loop if Not
IN0 A,(RDR0)
IF MOVCPM ; (No Swap allowed)
LD C,A ; Store byte temporarily
LD A,(COM4+6) ; get input mask
AND C ; apply to byte
ELSE ; (swapping permitted)
IPAT4: AND $-$ ; Char Mask patched in Config
ENDIF ;Movcpm
RET
ELSE ; Proceed with Buffered input
;.....
; COM4 Input Status Test (Buffered)
COM4IS: LD A,(COM4Q) ; Get COM4 Queue Char Count
OR A ; Anything there?
JR RETST ; ..set appropriate flag and exit
;.....
; COM4 Input Routine (Buffered)
COM4IN: CALL COM4IS ; Anything there?
JR Z,COM4IN ; ..loop if Not
DI
PUSH HL ; Save Regs
PUSH BC
LD HL,COM4Q+QSIZE ; Point to end of Input Buffer
LD BC,QSIZE*256 ; length to B, Null in C
; "Pop" character from the Buffer
COM4LP: LD A,(HL) ; Get a byte
LD (HL),C ; store Null 1st time, else character
LD C,A ; move previous char for later save
DEC HL ; down to previous char
DJNZ COM4LP ; ..loop til Done
DEC (HL) ; Decrement Count in Queue
IF MOVCPM ; (No Swap Allowed)
LD A,(COM4+6) ; Get Input Mask
AND C ; apply setting flags based on Char
ELSE ; (swapping permitted)
IPAT4: AND $-$ ; Mask as set in Config
ENDIF ;Movcpm
POP BC ; Restore Regs
POP HL
EI
RET
ENDIF ;BuffA0
;.....
; COM4 Output Status Test
COM4OS: IN0 A,(STAT0) ; ASCI0 Output Status
RRA ; TDRE Bit
RRA ; to Carry
SBC A,A ; set status, A=0 if Not ready, FF if Rdy
RET
;.....
; COM4 Output Routine
COM4OT: CALL COM4OS ; Ready to Send?
JR Z,COM4OT ; ..loop if Not
IF MOVCPM ; (No Swap allowed)
LD A,(COM4+7) ; Get output mask
AND C ; apply to byte
ELSE ; (swapping permitted)
LD A,C ; Get Char
OPAT4: AND $-$ ; mask as set in Config
ENDIF ;Movcpm
OUT0 (TDR0),A ; and Send
RET
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Interrupt service routines for ASCI0
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IF BUFFA0
RCAA: LD (INTSP),SP
LD SP,INTSP
PUSH AF
PUSH BC
PUSH HL
IN0 A,(RDR0) ; Get character from ASCI0
LD C,A ; ..save it
IF XONOFF
LD A,(COM4+5) ; Get Config Byte
AND 00010000B ; Xon/Xoff Active?
JR Z,RCAA0 ; ..jump if Not
LD HL,COM4WT ; Else Point to Flags Byte
LD A,C ; get Byte Back
CP XON ; Is it Xon?
JR NZ,RCAA1 ; ..jump if Not
RES 7,(HL) ; Else Enable Sending again
JR RCAAX ; and Exit
RCAA1: CP XOFF ; Is it Xoff?
JR NZ,RCAA0 ; ..jump if Not to add to Queue
SET 7,(HL) ; Else Stop Sending
JR RCAAX ; and Exit
ENDIF ;Xonoff
RCAA0: LD HL,COM4Q ; Point to char count
LD A,(HL) ; ..and get it
INC A ; Bump
CP QSIZE ; Buffer Full?
JR NC,RCAAX ; ..exit if so
LD (HL),A ; Else save new char count
CALL ADDAHL ; Offset to storage in Queue
LD (HL),C ; ..and save the character
RCAAX: POP HL ; Restore Regs
POP BC
POP AF
LD SP,(INTSP) ; and Entry Stack Ptr
EI ; Ints back On
RET
ENDIF ;BuffA0
ENDIF ;Asci_0
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ASCI1 Driver Routines
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IF ASCI_1
IF NOT BUFFA1
;.....
; COM5 Input Status Test
COM5IS: IN0 A,(STAT1) ; Get Status byte
RLA ; RDRF Bit to Carry
SBC A,A ; set A=0 if Not Rdy, FF if Ready
RET
;.....
; COM5 Input Routine
COM5IN: CALL COM5IS ; Anything ready?
JR Z,COM5IN ; ..loop if Not
IN0 A,(RDR1)
IF MOVCPM ; (No Swap allowed)
LD C,A ; Store byte temporarily
LD A,(COM5+6) ; get input mask
AND C ; apply to byte
ELSE ; (swapping permitted)
IPAT5: AND $-$ ; Char Mask patched in Config
ENDIF ;Movcpm
RET
ELSE ;proceed w/buffered input
;.....
; COM5 Input Status Test (Buffered)
COM5IS: LD A,(COM5Q) ; Get COM5 Queue Char Count
OR A ; Anything there?
JP RETST
;.....
; COM5 Input Routine (Buffered)
COM5IN: CALL COM5IS ; COM5 input
JR Z,COM5IN
DI
PUSH HL ; Save registers
PUSH BC
LD HL,COM5Q+QSIZE ; Point to end of Type ahead Buffer
LD BC,QSIZE*256 ; Length in B, Null in C
; "Pop" character from the Buffer
COM5LP: LD A,(HL) ; Get a character
LD (HL),C ; Store Null 1st time, else character
LD C,A ; Move previous char for later save
DEC HL ; down to previous char
DJNZ COM5LP ; Loop til done
DEC (HL) ; Decrement Count in Queue
IF MOVCPM ; (No Swap Allowed)
LD A,(COM5+6) ; Get input mask
AND C ; apply setting flags based on char
ELSE ; (Swapping permitted)
IPAT5: AND $-$ ; Mask as set in Config
ENDIF ;Movcpm
POP BC ; Restore regs
POP HL
EI
RET
ENDIF ;buffered
;.....
; COM5 Output Status Test
COM5OS: IN0 A,(STAT1) ; ASCI1 Output Status
RRA ; TDRE Bit
RRA ; to Carry
SBC A,A ; set status, A=0 if Not ready, FF if Rdy
RET
;.....
; COM5 Output Routine
COM5OT: CALL COM5OS ; Ready to Send?
JR Z,COM5OT ; ..loop if Not
IF MOVCPM ; (No Swap allowed)
LD A,(COM5+7) ; Get output mask
AND C ; apply to byte
ELSE ; (swapping permitted)
LD A,C ; Get Char
OPAT5: AND $-$ ; mask as set in Config
ENDIF ;Movcpm
OUT0 (TDR1),A ; and Send
RET
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Interrupt service routines for ASCI1
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
IF BUFFA1
RCAB: LD (INTSP),SP
LD SP,INTSP
PUSH AF
PUSH BC
PUSH HL
IN0 A,(RDR1) ; Get character from ASCI1
LD C,A ; ..save it
IF XONOFF
LD A,(COM5+5) ; Get Config Byte
AND 00010000B ; Xon/Xoff Active?
JR Z,RCAB0 ; ..jump if Not
LD HL,COM5WT ; Else Point to Flags Byte
LD A,C ; get Byte Back
CP XON ; Is it Xon?
JR NZ,RCAB1 ; ..jump if Not
RES 7,(HL) ; Else Enable Sending again
JR RCABX ; and Exit
RCAB1: CP XOFF ; Is it Xoff?
JR NZ,RCAB0 ; ..jump if Not to add to Queue
SET 7,(HL) ; Else Stop Sending
JR RCABX ; and Exit
ENDIF ;Xonoff
RCAB0: LD HL,COM5Q ; Point to char count
LD A,(HL) ; ..and get it
INC A ; Bump
CP QSIZE ; Buffer Full?
JR NC,RCABX ; ..exit if so
LD (HL),A ; Else save new char count
CALL ADDAHL ; Offset to storage in Queue
LD (HL),C ; ..and save the character
RCABX: POP HL ; Restore Regs
POP BC
POP AF
LD SP,(INTSP) ; and Entry Stack Ptr
EI ; Ints back On
RET
ENDIF ;BuffA1
ENDIF ;Asci_1
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Skeletons for Additional Expansion IO
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;.....
; COMx Input Status (Non-buffered)
COMxIS:
;.....
; COMx Input Routine (Non-buffered)
COMxIN:
;.....
; COMx Output Status (Non-buffered)
COMxOS:
;.....
; COMx Output Routine (Non-buffered)
COMxOT:
ENDIF ;Mordev
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;:: I n t e r r u p t T a b l e ::
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; The Z80182 Interrupt Vector table is placed here on a 32-byte
; boundary for internal peripherals.
DEFS 32-[$-BIOSJT AND 31] ; Align
INTTBL:
DEFW BADINT ; FDC Controller w/Ints (FDCINT if Real Ints)
DEFW BADINT ; Parallel output port (INTPIO if Real Ints)
DEFW TIMER ; Timer0
DEFW BADINT ; Timer1
DEFW BADINT ; DMA Channel 0
DEFW BADINT ; DMA Channel 1
DEFW BADINT ; Clocked Serial IO
IF MORDEV AND ASCI_0 AND BUFFA0
DEFW RCAA ; ASCI 0
ELSE
DEFW BADINT ; ASCI 0 if Not Interrupt/Mordev
ENDIF
IF MORDEV AND ASCI_1 AND BUFFA1
DEFW RCAB ; ASCI 1
ELSE
DEFW BADINT ; ASCI 1 if Not Interrupt/Mordev
ENDIF
; Error trap for unimplemented Interrupts
BADINT: CALL PRINT
DEFC CR,LF,'Bad Int.'
JP WBOOT
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;:: D e v i c e I n i t i a l i z a t i o n ::
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CSEG
DEVINI:
IF BANKED
CALL BIOSTK
CALL GOSYSB
JP JDVINI
COMMON /BANK2/
JDVINI:
ENDIF
; Synchronize Environment Descriptor Speed byte to Bios CPU Clock Speed setting
LD A,(SPEED) ; Get Processor Speed from Bios Setting
LD HL,(ENVADR) ; Get ENV Address
LD L,2BH ; offset to CPU Clock rate
LD (HL),A ; and slam it into the ENV
; Set Clock Rate and Dividers before we initialize devices
;;--(ENH182 doesn't seem to be variable at present)
;;-- LD C,0 ; (preset ESCC Div-by-1, No Halt)
;;-- CP 20 ; < 20 MHz?
;;-- JR C,IsBy1 ; ..jump if So
;;-- LD C,00001000B ; Else Divide ESCC clock by 2
; |||||+++- (reserved)
; ||||+---- 0 = ESCC Clk Div-by-1, 1 = ESCC Clk Div-by-2
; |||+----- 1 = TxDA Disable on Halt
; ||+------ 1 = Force Halt
; ++------- (reserved)
;;--IsBy1: OUT0 (ENH182),C ; Set ESC Divider
LD C,10000000B ; (preset flags)
; |+++++++- Normal Drive, Standby/Idle Disabled
; +-------- 0 = XTAL/2 Rate, 1 = XTAL/1 Rate
CP 12+1 ; Is Clock Speed > 12 MHz?
JR NC,ISHI ; jump if Yes
LD C,0 ; Else Set for Low (Xtal / 2) Speed
ISHI: OUT0 (1FH),C ; and Set Speed
; Set Configured Wait States for IO and Memory
LD A,(WAITS) ; Get # Wait states for Memory & IO
AND 00110011B ; Mask off all but 2 LSBs in each nybble
RLCA ; move Mem bits to B7,6
RLCA
LD C,A ; Save partially shifted byte
RLCA ; Move IO to Bits 5,4
RLCA
OR C ; OR in Memory waits
AND 11110000B ; and mask off all others
OR 00001100B ; Edge Triggering for both DMA channels
OUT0 (DCNTL),A ; set parameters
; Set Refresh to Assembled Setting
IF REFRSH ; (Must be TRUE if using Dynamic RAM)
LD A,83H ; Set refreshing on for Dynamic Rams
ELSE ; (Don't need wasted time if Static Memory)
LD A,00H ; Else disable Refresh cycles
ENDIF
OUT0 (RCR),A ; Set Refresh timing specs
; Set Reload constant to values in header
LD HL,(RELOD0) ; Get the timer reload constant
OUT0 (RLDR0L),L ; send low byte
OUT0 (RLDR0H),H ; and hi byte
; Configure COM1 IO Masks and Channel characteristics
IF NOT MOVCPM ; (Swapping permitted)
LD DE,C1NAM ; Point to COM1 Name String
CALL SETPTR ; locate data returning ptr
JR Z,DEVIN0 ; jump to next if No Device Name
LD A,(HL) ; Else Get Dev+7 Mask
LD (OPAT1+1),A ; patch
DEC HL ; Down to Input Mask @ Dev+6
LD A,(HL) ; fetch
LD (IPAT1+1),A ; and patch
DEC HL ; Down to Config byte @ Dev+5
ELSE ; (No Swap Allowed)
LD HL,DEVCFG+5 ; Point to second COM1 Config byte
ENDIF ;Movcpm
LD BC,SCCACNT ; Point to SCC Channel A Control Port
CALL INSCC ; Set the SCC parameters
; Configure COM2 IO Masks and Channel Characteristics
DEVIN0:
IF NOT MOVCPM ; (Swapping permitted)
LD DE,C2NAM ; Point to COM2 Name String
CALL SETPTR ; locate data returning ptr
JR Z,DEVIN1 ; ..jump to next if No Device Name
LD A,(HL) ; Else Get Dev+7 Mask
LD (OPAT2+1),A ; patch
DEC HL ; Down to Input Mask @ Dev+6
LD A,(HL) ; fetch
LD (IPAT2+1),A ; and patch
DEC HL ; Down to Config Byte @ Dev+5
ELSE ; (No Swap Allowed)
LD HL,DEVCFG+[COM2-COM1]+5 ; Point to second COM2 Config byte
ENDIF ;Movcpm
CALL IOI550 ; Initialize 16550-compatible 37C665 Port
; Configure Parallel Port IO Masks and Characteristics and Reset
IF NOT MOVCPM ; (No Swap Allowed)
DEVIN1: LD DE,P1NAM ; Point to PIO1 Name String
CALL SETPTR ; locate data returning ptr
JR Z,DEVIN2 ; jump if No Device Name
LD A,(HL) ; Get Dev+7 Mask
LD (OPATP+1),A ; and patch
DEVIN2:
ENDIF ;Movcpm
; Reset Parallel port on FDC37C665 Multi-IO Chip
LD A,00001000B ; Command to Reset Parallel Port
OUT0 (CPORT),A ; by bringing INIT Low
LD BC,4000
PDly: DEC BC ; and
LD A,B
OR C
JR NZ,PDly ; holding there for a while
LD A,00001100B ; Re-activate Port
OUT0 (CPORT),A ; by bringing INIT High
IN0 A,(SPORT) ; Clear by
IN0 A,(SPORT) ; reading status twice
IF MORDEV AND NOT MOVCPM
; -- Add necessary Initialization for Expansion Drivers here --
IF ESCC_B
; Initialize ESCC Channel B
LD DE,C3NAM ; Point to COM3 Name String
CALL SETPTR ; locate data returning ptr
JR Z,DEVIN3 ; jump to next if No Device Name
LD A,(HL) ; Else Get Dev+7 Mask
LD (OPAT3+1),A ; patch
DEC HL ; Down to Input Mask @ Dev+6
LD A,(HL) ; fetch
LD (IPAT3+1),A ; and patch
DEC HL ; Down to Config byte @ Dev+5
LD BC,SCCBCNT ; Point to SCC Channel B Control Port
CALL INSCC ; Set the SCC parameters
ENDIF ;Escc_b
DEVIN3:
IF ASCI_0
; Initialize ASCI0
LD DE,C4NAM ; Point to COM4 Name String
CALL SETPTR ; locate data returning ptr
JR Z,DEVIN4 ; jump to next if No Device Name
LD A,(HL) ; Else Get Dev+7 Mask
LD (OPAT4+1),A ; patch
DEC HL ; Down to Input Mask @ Dev+6
LD A,(HL) ; fetch
LD (IPAT4+1),A ; and patch
DEC HL ; Down to Config byte @ Dev+5
LD BC,CNTLA0 ; B=0 for Hi-order IO Address, C=CNTLA0 Port
LD E,01100000B ; CNTLA0 Mask, RE, TE, RTS*
CALL INASCI ; and set a couple of bytes
DEVIN4:
IF BUFFA0
LD A,00001000B ; Enable ASCI0 Interrupts
ELSE
XOR A ; No Interrupts
ENDIF
OUT0 (STAT0),A
ENDIF ;Asci_0
IF ASCI_1
; Initialize ASCI1
LD DE,C5NAM ; Point to COM5 Name String
CALL SETPTR ; locate data returning ptr
JR Z,DEVIN5 ; jump to next if No Device Name
LD A,(HL) ; Else Get Dev+7 Mask
LD (OPAT5+1),A ; patch
DEC HL ; Down to Input Mask @ Dev+6
LD A,(HL) ; fetch
LD (IPAT5+1),A ; and patch
DEC HL ; Down to Config byte @ Dev+5
LD BC,CNTLA1 ; B=0 for Hi-order IO Address, C=CNTLA1 Port
LD E,01110000B ; CNTLA1 Mask, RE, TE, Internal Clk
CALL INASCI ; and set a couple of bytes
DEVIN5:
IF BUFFA1
LD A,00001100B ; Enable ASCI1 Interrupts & CTS1*
ELSE
LD A,00000100B ; No Interrupts, Enable CTS1*
ENDIF
OUT0 (STAT1),A
ENDIF ;Asci_1
ENDIF ;Mordev & Not Movcpm
; Set IOByte(s) to Configured Device Settings
IF BANKED
LD A,(TPABNK) ; Get Bank # for TPA
LD C,A ; and set for destination
LD HL,0003H ; Point to IOBYTE
LD A,(IOBYT) ; get the new settings
CALL FRPUTB ; and stuff it in TPA bank
ENDIF
LD A,(IOBYT) ; If Non-banked, just get the byte
LD (0003H),A ; and stuff it, else stuff in SYStem bank
; De-Select any IDE Drives to force re-initialization on first select
IF IDE
OR 0FFH ; Set all bits
LD (hdUnit),A ; to mismatch select on current unit
ENDIF
; Set Interrupt Conditions
LD A,00010001B ; Turn Ints On and enable downcounting
OUT0 (TCR),A
LD A,00000111B ; Activate INT0 and Internals
OUT0 (ITC),A
EI ; Insure interrupts enabled
RET
;.....
; Z182 [E]SCC Configuration Routine.
; Enter= BC -> respective Control Register SCCACNT/SCCBCNT.
; HL -> Dev+5 Configuration byte
INSCC: LD DE,0100010000101010B ; Skeleton WR4 (D), WR5 (E) contents
; |||||||||||||||+- Tx CRC Enable \---------------+
; ||||||||||||||+-- RTS |
; |||||||||||||+--- /SDLC/CRC-16 |
; ||||||||||||+---- Tx Enable WR5
; |||||||||||+----- Send Break |
; |||||||||++------ Bits/Char (00=5, 01=7, 10=6, 11=8) |
; ||||||||+-------- DTR /---------------+
; |||||||+--------- Parity Enable \---------------+
; ||||||+---------- Parity EVEN/ODD | WR4
; ||||++----------- 00=Sync, 01=1 Stop, 10=1.5 Stop, 11=2
; ||++------------- Sync Char Settings |
; ++--------------- Clock 00=X1,01=X16,10=X32,11=X64 /-+
BIT 0,(HL) ; One Stop Bit?
JR NZ,INSCC0 ; ..jump if So
SET 3,D ; Else Set for 2 Stop bits
INSCC0: BIT 1,(HL) ; Parity On?
JR Z,INSCC1 ; ..jump if Not
SET 0,D ; Else Turn it On
BIT 2,(HL) ; Is Odd parity desired?
JR NZ,INSCC1 ; ..jump if Even parity
SET 1,D ; Else set to Odd
INSCC1: BIT 3,(HL) ; 7-bit Data?
JR NZ,INSCC2 ; ..jump if So
SET 6,E ; Else set for 8-bit data
INSCC2: LD A,WR4
CALL IWdOut ; Set basic Parms
LD A,E ; Get WR4 Config Byte
SCF ; (prep to set LSB)
ADC A,A ; Move old B6/5 to B7/6 and Set LSB
AND 0C1H ; strip off Garbage
BIT 5,(HL) ; RTS/CTS Handshake selected?
JR Z,INSCC8 ; ..jump if Not
OR 00100000B ; Else Set Auto-Enables
INSCC8: LD E,A ; (position)
LD A,WR3
CALL IBytO ; Set Receive Bits/Char & activate
CALL ChkRat ; Can we set the Data Rate?
RET Z ; ..quit if Not
PUSH BC ; Else Save regs (A [0..3] = Rate index)
DEC A ; adjust index to Base 0
LD C,A ; store
LD HL,brSCC ; Pt to Start of Baud Rate Table
CALL ADDAHL ; -> appropriate constant
LD L,(HL) ; fetch constant
;;-- IN0 A,(ENH182) ; Get Enhancement Reg
;;-- AND 00001000B ; Keep ESCC Divide Rate Bit
LD A,(SPEED) ; Fetch Clock speed
;;-- JR Z,INSCC9 ; ..jump if Div-by-1
;;-- SRL A ; Else Divide Rate by 2 (by dividing Clk)
;;--INSCC9:
LD H,A
LD A,C
CP 3 ; Rate In [134.5, 50, 75]?
JR NC,INSCC3 ; ..jump if Not
LD A,H ; Else
ADD A,A ; Multiply
ADD A,H ; constant * 3
LD H,A
INSCC3: MLT HL ; Multiply Clock Rate by Constant
LD A,C
CP 7 ; Rate < 2400 bps?
JR C,INSCC4 ; ..jump if Yes
LD C,18 ; Else Compute Divisor / 18
LD B,17 ; 17 times thru loop for 16 bits
XOR A ; start w/Carry Clear
; Divide computed value in HL by 18 (in C), Ret: Remainder in A, Quotient in HL
SDiv0: ADC A,A
SBC A,C
JR NC,SDiv1
ADD A,C ; correct for underflow
SDiv1: CCF
ADC HL,HL
DJNZ SDiv0 ; ..loop til Done
SRL C ; Dividend / 2
CP C ; Rounding Needed?
JR C,INSCC4 ; ..jump if Not
INC HL ; Else round up
INSCC4: POP BC
DEC HL ; Compute Divisor
DEC HL ; - 2
LD A,H
OR L ; If Divisor = 0
JR NZ,INSCC5
INC L ; default to 1
INSCC5: LD A,WR12 ; Address Divisor Reg pair
LD E,H ; swap
LD D,L ; bytes to send Lower first
IWdOut: DI
OUT (C),A ; Address WR4
OUT (C),D ; Set values
INC A ; Bump to WR5
IBytO: OUT (C),A ; address it
OUT (C),E ; Set values
EI
RET
;.....
; Divisor factors are computed as:
; (Xtal Freq (Hz) / (2 * bps * Divisor)) - 2
; These rate constants represent a compromise between the "standard" rates of
; multiples of 6.144 and 9.216 MHz, and the 8.000/16.000 MHz used in the P112.
; All factors are based on a x16 clock divisor.
brSCC: DEFB 79 ; 1 = 134.5 bps / 3
DEFB 213 ; 2 = 50 bps / 3
DEFB 142 ; 3 = 75 bps / 3
DEFB 213 ; 4 = 150 bps
DEFB 106 ; 5 = 300 bps
DEFB 53 ; 6 = 600 bps
DEFB 26 ; 7 = 1200 bps
DEFB 240 ; 8 = 2400 bps * 18
DEFB 120 ; 9 = 4800 bps * 18
DEFB 60 ; 10 = 9600 bps * 18
DEFB 30 ; 11 = 19.2 kbps * 18
DEFB 15 ; 12 = 38.4 kbps * 18
DEFB 10 ; 13 = 57.6 kbps * 18
DEFB 5 ; 14 = 115.2 kbps * 18
;.....
; 16550-compatible Configuration Routine
IOI550: LD E,00000011B ; Start w/byte going to Line Contr Reg (LCR)
; ||||||++- Word Len in Bits (00=5, 01=6, 10=7, 11=8)
; |||||+--- Stop Bits (0=1, 1=1.5 or 2)
; ||||+---- 0 = No Parity, 1 = Parity Enabled
; ||++----- (If Parity) 00=Odd, 01=Even, 10=Mark, 11=Space
; |+-------- 0 = Normal, 1 = Send Break
; +--------- 0 = Normal, 1 = Set Baud Rate
BIT 0,(HL) ; One Stop Bit?
JR NZ,IOI55a ; ..jump if So
SET 2,E ; Else Set for 2 Stop Bits
IOI55a: BIT 1,(HL) ; Parity On?
JR Z,IOI55b ; ..jump if Not
SET 3,E ; Else Turn it On
BIT 2,(HL) ; Even Parity?
JR Z,IOI55b ; ..jump if Odd
SET 4,E ; Else Set Even Parity
IOI55b: CALL ChkRat ; Can we set the Data Rate?
JR Z,IOI55c ; ..jump if Not
ADD A,A ; Else double index
LD C,A
LD B,0
LD HL,RATE55-2 ; Pt to compensated Table
ADD HL,BC
SET 7,E ; Address DLAB
OUT0 (_LCR),E
LD A,(HL)
OUT0 (_DDL),A ; send Low Byte
INC HL
LD A,(HL)
OUT0 (_DLM),A ; and High Byte
IOI55c: RES 7,E ; Clear DLAB Bit
OUT0 (_LCR),E ; and Set configuration
LD A,00000011B
; |||||||+-- 1 = DTR Active
; ||||||+--- 1 = RTS Active
; |||||+---- (unused)
; ||||+----- 1 = Send Ints to CPU, 0 = Ints Hi-Z
; |||+------ 1 = Line Loopback
; +++------- (unused)
OUT0 (_MCR),A ; Activate Port
LD A,00000000B
; |||||||+-- 1 = Enable Rcv Buff Full Interrupt
; ||||||+--- 1 = Enable Xmt Buff Empty Interrupt
; |||||+---- 1 = Enable Line Status Interrupt
; ||||+----- 1 = Enable Delta Status Signals Inerrupt
; ++++------ (unused)
OUT0 (_IER),A ; Set Interrupt Settings
RET
; Clock Divisor factors for various rates
RATE55: DEFW 857 ; 1 = 134.5 bps
DEFW 2304 ; 2 = 50 bps
DEFW 1536 ; 3 = 75 bps
DEFW 768 ; 4 = 150 bps
DEFW 384 ; 5 = 300 bps
DEFW 192 ; 6 = 600 bps
DEFW 96 ; 7 = 1200 bps
DEFW 48 ; 8 = 2400 bps
DEFW 24 ; 9 = 4800 bps
DEFW 12 ; 10 = 9600 bps
DEFW 6 ; 11 = 19.2 kbps
DEFW 3 ; 12 = 38.4 kbps
DEFW 2 ; 13 = 57.6 kbps (non-std)
DEFW 1 ; 14 = 115.2 kbps
;.....
; Expansion Common routines may be places here
IF MORDEV AND NOT MOVCPM
IF ASCI_0 OR ASCI_1
INASCI: BIT 0,(HL) ; One Stop Bit?
JR NZ,INASC0 ; ..jump if Not
SET 0,E ; Else Set for 2 Stop bits
INASC0: BIT 1,(HL) ; Parity On?
JR Z,INASC1 ; ..jump if Not
SET 1,E ; Else Turn it On
INASC1: BIT 3,(HL) ; 7-bit Data?
JR NZ,INASC2 ; ..jump if So
SET 2,E ; Else set for 8-bit Data
INASC2: OUT (C),E ; Send the byte to CNTLA0/1
INC C ; advance to CNTLB0/1
INC C
DEC HL ; Back up to first Config byte
LD A,(HL) ; fetch
AND 0F0H ; Check Config Status
LD E,0111B ; (preset for External clock in case)
JR Z,INASCX ; ..jump if No rate to Set
LD A,(HL) ; Refetch the rate byte
AND 0FH ; masking off all but desired rate
PUSH HL ; Save Config byte pointer
LD HL,ASCRAT-1 ; pt to Rate Table (Correcting for Base 0)
CALL ADDAHL ; offsetting to desired byte
LD E,0 ; Prepare an initial mask
LD A,(SPEED) ; Check processor speed
CP 6+1 ; Is it 6 or below?
JR C,INASC8 ; ..jump assuming 6.144 MHz if <= 6
DEC HL ; (prepare for 12 test)
CP 12 ; Is it 12 MHz?
JR Z,INASC8 ; ..jump assuming 12.288 MHz if = 12
DEC HL ; (prepare for 24 test)
CP 24 ; Is it 24 MHz?
JR NC,INASC8 ; ..jump if >= 24 MHz
INC HL ; Else correct pointer
INC HL ; Advance for 18 MHz
SET 5,E ; Set additional divisor bit for 9/18 MHz
CP 16 ; Is it >= 16 MHz? (including 18 MHz)
JR NC,INASC8 ; ..jump to use 6 MHz rates if So
INC HL ; Else bump up one in Rate Table
INASC8: LD A,(HL) ; Get the Rate Setting Byte
OR E ; add in any additional divisor
LD E,A ; back to output reg
POP HL ; Restore Config byte ptr
INASCX: INC HL ; advance to second byte
BIT 2,(HL) ; Is Odd parity desired?
JR NZ,INASC9 ; ..jump if Even parity
SET 4,E ; Else set to Odd
INASC9: OUT (C),E ; Send the byte to CNTLB0/1
RET
; bps @ 6MHz 9MHz 12MHz 18MHz 24MHz
DEFB 00001110B ; 0 (protection)
ASCRAT: DEFB 00001110B ; 1 = default to lowest rate
DEFB 00001110B ; 2 = default to lowest rate
DEFB 00001110B ; 3 = default to lowest rate
DEFB 00001110B ; 4 = 150 75 300 150 600
DEFB 00001101B ; 5 = 300 150 600 300 1200
DEFB 00000110B ; 6 = 600 300 1200 600 2400
DEFB 00000101B ; 7 = 1200 600 2400 1200 4800
DEFB 00000100B ; 8 = 2400 1200 4800 2400 9600
DEFB 00000011B ; 9 = 4800 2400 9600 4800 19.2k
DEFB 00000010B ; 10 = 9600 4800 19.2k 9600 38.4k
DEFB 00000001B ; 11 = 19.2 k 9600 38.4k 19.2k 76.8k
DEFB 00000000B ; 12 = 38.4 k 19.2 k 76.8k 38.4k 153.6k
DEFB 00000000B ; 13 = default to highest rate
DEFB 00000000B ; 14 = default to highest rate
DEFB 00000000B ; 15 = default to highest rate
ENDIF ;Asci_0 | Asci_1
ENDIF ;Mordev
;.....
; Check Data Rate Config byte for authority and limits on configuration
; Enter: HL -> Second Config byte (back up to get rate byte)
; Exit : Zero Set if Can't configure
ChkRat: DEC HL ; Pt to Data Rate
LD A,(HL) ; fetch
AND 0F0H ; Any Allowed rate to set?
RET Z ; ..quit if Not (Z Set)
LD A,(HL) ; Fetch byte again
AND 0FH ; Anything to Set?
RET Z ; ..quit if Not (Z Set)
CP 0FH ; Fixed Rate?
RET ; ..exit w/Z Set if Fixed, else NZ for Ok
;.....
; Locate Named Device and return pointer to last Config byte
IF NOT MOVCPM
SETPTR: LD HL,DEVCFG-[COM2-COM1] ; Point ahead of start
SETPTL: LD BC,COM2-COM1 ; Set size of entries
ADD HL,BC ; advance to next entry
LD B,4 ; Set # chars to compare
LD A,(HL) ; Get first char
OR A ; Is it Table End?
RET Z ; ..return Zero Set if so
PUSH DE ; (save source & dest strings)
PUSH HL
SETPT0: LD A,(DE)
CP (HL) ; Compare each char
JR NZ,SETPTX ; ..quitting if mismatch
INC DE ; Else advance to next
INC HL
DJNZ SETPT0 ; ..loop to next char
SETPTX: POP HL ; Restore source & dest ptrs
POP DE
JR NZ,SETPTL ; ..try next entry if mismatch
LD DE,7 ; Else advance to Dev+7
ADD HL,DE
OR 0FFH ; Insure Zero Clear on Return
RET ; ..and quit
C1NAM: DEFB 'COM1' ; Device needing Configuration to match
C2NAM: DEFB 'COM2'
P1NAM: DEFB 'PIO1'
ENDIF ;Movcpm
; Name strings for Expansion IO added here after Primary Devices
IF MORDEV AND ESCC_B AND NOT MOVCPM
C3NAM: DEFB 'COM3' ; ESCC Channel B Expansion Device
ENDIF
IF MORDEV AND ASCI_0 AND NOT MOVCPM
C4NAM: DEFB 'COM4' ; ASCI0 Expansion Device
ENDIF
IF MORDEV AND ASCI_1 AND NOT MOVCPM
C5NAM: DEFB 'COM5' ; ASCI1 Expansion Device
ENDIF
;.....
; NOTE: BuffA0 and BuffA1 Intrpt Buffers are located at end of B/P Root module.
;===================== End of IIO-DX.Z80 ==========================