mirror of
https://github.com/wwarthen/RomWBW.git
synced 2026-02-06 22:43:15 -06:00
SIO Driver Interrupt Based Receive
This commit is contained in:
@@ -328,7 +328,7 @@ MAXMIN EQU 60 ; Minutes for maximum file transfer time.
|
||||
; Length of external patch program. If over 128 bytes, get/set size
|
||||
;
|
||||
LARGEIO EQU YES ; Yes, if modem patch area over 128 bytes
|
||||
LARSIZE EQU 180H ; If 'LARGEIO' set patch area size (bytes) here
|
||||
LARSIZE EQU 500H ; If 'LARGEIO' set patch area size (bytes) here
|
||||
;
|
||||
;=======================================================================
|
||||
;
|
||||
|
||||
@@ -67,95 +67,182 @@ MINIT:
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
;
|
||||
; Get system type
|
||||
LD DE,00202H ; D := 2, E := 2
|
||||
MLT DE ; DE := D * E == 4
|
||||
BIT 2,E ; Bit 2 wil be set if mlt happend
|
||||
LD HL,U_JPTBL ; Assume Z80 (UART)
|
||||
LD DE,UART ; UART port notification string
|
||||
JR Z,MINIT2 ; Yes, Z80, do vector copy
|
||||
LD HL,A_JPTBL ; Otherwise Z180 (ASCI)
|
||||
LD DE,ASCI ; ASCI port notification string
|
||||
; Identify BIOS (RomWBW HBIOS or UNA UBIOS)
|
||||
CALL IDBIO ; 1=HBIOS, 2=UBIOS
|
||||
LD (BIOID),A ; Save it
|
||||
DEC A ; Test for HBIOS
|
||||
JR Z,HINIT ; Do HBIOS setup
|
||||
DEC A ; Test for UBIOS
|
||||
JR Z,UINIT ; Do UBIOS setup
|
||||
;
|
||||
MINIT2:
|
||||
; Display port notification string
|
||||
PUSH HL ; Save HL
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
POP HL ; Recover HL
|
||||
;
|
||||
; Copy real vectors into active jump table
|
||||
LD DE,JPTBL ; Real jump table is destination
|
||||
LD BC,7 * 3 ; Copy 7 3-byte entries
|
||||
LDIR ; Do the copy
|
||||
;
|
||||
; Check for UNA (UBIOS)
|
||||
LD A,(0FFFDH) ; fixed location of UNA API vector
|
||||
CP 0C3H ; jp instruction?
|
||||
JR NZ,MINIT3 ; if not, not UNA
|
||||
LD HL,(0FFFEH) ; get jp address
|
||||
LD A,(HL) ; get byte at target address
|
||||
CP 0FDH ; first byte of UNA push ix instruction
|
||||
JR NZ,MINIT3 ; if not, not UNA
|
||||
INC HL ; point to next byte
|
||||
LD A,(HL) ; get next byte
|
||||
CP 0E5H ; second byte of UNA push ix instruction
|
||||
JR NZ,MINIT3 ; if not, not UNA
|
||||
;
|
||||
; Display UNA notification string
|
||||
LD DE,UBIOS ; BIOS notification string
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS
|
||||
;
|
||||
; Get CPU speed from UNA and return
|
||||
LD C,0F8H ; UNA BIOS Get PHI function
|
||||
RST 08 ; Returns speed in Hz in DE:HL
|
||||
LD B,4 ; Divide MHz in DE:HL by 100000H
|
||||
MINIT2A:
|
||||
SRL D ; ... to get approx CPU speed in
|
||||
RR E ; ...MHz. Throw away HL, and
|
||||
DJNZ MINIT2A ; ...right shift DE by 4.
|
||||
INC E ; Fix up for value truncation
|
||||
LD A,E ; Put in A
|
||||
RET ; Done
|
||||
;
|
||||
MINIT3:
|
||||
; Not UNA, try RomwBW HBIOS for CPU speed lookup
|
||||
LD HL,(0FFFEH) ; HL := HBIOS ident location
|
||||
LD A,'W' ; First byte of ident
|
||||
CP (HL) ; Compare
|
||||
JR NZ,MINIT4 ; Not HBIOS
|
||||
INC HL ; Next byte of ident
|
||||
LD A,~'W' ; Second byte of ident
|
||||
CP (HL) ; Compare
|
||||
JR NZ,MINIT4 ; Not HBIOS
|
||||
;
|
||||
; Display RomWBW notification string
|
||||
LD DE,HBIOS ; BIOS notification string
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
;
|
||||
; Get CPU speed from RomWBW HBIOS and return
|
||||
LD B,0F8H ; HBIOS SYSGET function 0xF8
|
||||
LD C,0F0H ; CPUINFO subfunction 0xF0
|
||||
RST 08 ; Do it, L := CPU speed in MHz
|
||||
LD A,L ; Move it to A
|
||||
RET ; Done
|
||||
;
|
||||
MINIT4:
|
||||
; Neither UNA nor RomWBW
|
||||
LD DE,BIOERR ; BIOS error message
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
JP 0 ; Bail out!
|
||||
;
|
||||
RBC DB "RBC, 28-Aug-2017, $"
|
||||
HINIT:
|
||||
;
|
||||
UART DB "UART0$"
|
||||
ASCI DB "ASCI0$"
|
||||
; Display RomWBW notification string
|
||||
LD DE,HBIOS ; BIOS notification string
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
;
|
||||
UBIOS DB " [UNA]", 13, 10, "$"
|
||||
HBIOS DB " [WBW]", 13, 10, "$"
|
||||
; Get platform id from RomWBW HBIOS and save it
|
||||
LD B,0F1H ; HBIOS VER function 0xF1
|
||||
LD C,0 ; Required reserved value
|
||||
RST 08 ; Do it, L := Platform ID
|
||||
LD A,L ; Move to A
|
||||
LD (PLTID),A ; Save it
|
||||
;
|
||||
; Get CPU speed from RomWBW HBIOS and save it
|
||||
LD B,0F8H ; HBIOS SYSGET function 0xF8
|
||||
LD C,0F0H ; CPUINFO subfunction 0xF0
|
||||
RST 08 ; Do it, L := CPU speed in MHz
|
||||
LD A,L ; Move it to A
|
||||
LD (CPUSPD),A ; Save it
|
||||
JR MINIT1 ; Continue general initialization
|
||||
;
|
||||
UINIT:
|
||||
;
|
||||
; Display UNA notification string
|
||||
LD DE,UBIOS ; BIOS notification string
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
;
|
||||
; Get CPU speed from UNA and save it
|
||||
LD C,0F8H ; UNA BIOS Get PHI function
|
||||
RST 08 ; Returns speed in Hz in DE:HL
|
||||
LD B,4 ; Divide MHz in DE:HL by 100000H
|
||||
UINIT1:
|
||||
SRL D ; ... to get approx CPU speed in
|
||||
RR E ; ...MHz. Throw away HL, and
|
||||
DJNZ UINIT1 ; ...right shift DE by 4.
|
||||
INC E ; Fix up for value truncation
|
||||
LD A,E ; Put in A
|
||||
LD (CPUSPD),A ; Save it
|
||||
JR MINIT1 ; Continue general initialization
|
||||
;
|
||||
MINIT1:
|
||||
; NOTE: PLTID is only set if RomWBW HBIOS is active. This is OK
|
||||
; because RC2014 is only support by RomWBW HBIOS at this point.
|
||||
LD A,(PLTID) ; Get the platform id
|
||||
CP 7 ; Check for RC2014
|
||||
JR Z,RCINIT ; Handle RC2014 special
|
||||
;
|
||||
; Check for Z180 which implies ASCI serial port
|
||||
LD DE,00202H ; D := 2, E := 2
|
||||
MLT DE ; DE := D * E == 4
|
||||
BIT 2,E ; Bit 2 wil be set if mlt happend
|
||||
JR Z,MINIT2 ; Not Z180 (ASCI), look for others
|
||||
LD HL,ASCI_JPTBL ; Point to Z180 (ASCI) jump table
|
||||
LD DE,ASCI ; ASCI port notification string
|
||||
JR MINIT3 ; Complete the initialization
|
||||
;
|
||||
MINIT2:
|
||||
; Not a Z180, so assume RBC standard UART serial port
|
||||
LD HL,UART_JPTBL ; Assume Z80 (UART)
|
||||
LD DE,UART ; UART port notification string
|
||||
JR MINIT3 ; Complete the initialization
|
||||
;
|
||||
RCINIT:
|
||||
; Check for SIO/2 serial port
|
||||
LD C,080H ; SIO command port
|
||||
XOR A ; RD0
|
||||
OUT (C),A ; Access RD0
|
||||
IN A,(C) ; Get RD0 value
|
||||
LD B,A ; Save it
|
||||
LD A,1 ; RD1
|
||||
OUT (C),A ; Access RD1
|
||||
IN A,(C) ; Get RD1 value
|
||||
CP B ; Compare
|
||||
JR Z,RCINIT1 ; If equal, no SIO port there
|
||||
LD HL,SIO_JPTBL ; SIO jump table address
|
||||
LD DE,SIO ; SIO port notification string
|
||||
JR MINIT3 ; Complete the initialization
|
||||
;
|
||||
RCINIT1:
|
||||
; Assume RC2014 ACIA port
|
||||
LD HL,ACIA_JPTBL ; ACIA jump table address
|
||||
LD DE,ACIA ; ACIA port notification string
|
||||
JR MINIT3 ; Complete the initialization
|
||||
;
|
||||
MINIT3:
|
||||
PUSH HL ; Save HL
|
||||
|
||||
; Display port notification string
|
||||
LD C,9 ; BDOS string display function
|
||||
CALL BDOS ; Do it
|
||||
;
|
||||
; Newline
|
||||
LD C,9 ; BDOS string display function
|
||||
LD DE,CRLF ; Newline
|
||||
CALL BDOS ; Do it
|
||||
;
|
||||
; Copy real vectors into active jump table
|
||||
POP HL ; Recover HL
|
||||
LD DE,JPTBL ; Real jump table is destination
|
||||
LD BC,7 * 3 ; Copy 7 3-byte entries
|
||||
LDIR ; Do the copy
|
||||
;
|
||||
; Return with CPU speed in A
|
||||
LD A,(CPUSPD) ; Get CPU speed saved above
|
||||
RET ; and return
|
||||
;
|
||||
; Identify active BIOS. RomWBW HBIOS=1, UNA UBIOS=2, else 0
|
||||
;
|
||||
IDBIO:
|
||||
;
|
||||
; Check for UNA (UBIOS)
|
||||
LD A,(0FFFDH) ; fixed location of UNA API vector
|
||||
CP 0C3H ; jp instruction?
|
||||
JR NZ,IDBIO1 ; if not, not UNA
|
||||
LD HL,(0FFFEH) ; get jp address
|
||||
LD A,(HL) ; get byte at target address
|
||||
CP 0FDH ; first byte of UNA push ix instruction
|
||||
JR NZ,IDBIO1 ; if not, not UNA
|
||||
INC HL ; point to next byte
|
||||
LD A,(HL) ; get next byte
|
||||
CP 0E5H ; second byte of UNA push ix instruction
|
||||
JR NZ,IDBIO1 ; if not, not UNA, check others
|
||||
LD A,2 ; UNA BIOS id = 2
|
||||
RET ; and done
|
||||
;
|
||||
IDBIO1:
|
||||
; Check for RomWBW (HBIOS)
|
||||
LD HL,(0FFFEH) ; HL := HBIOS ident location
|
||||
LD A,'W' ; First byte of ident
|
||||
CP (HL) ; Compare
|
||||
JR NZ,IDBIO2 ; Not HBIOS
|
||||
INC HL ; Next byte of ident
|
||||
LD A,~'W' ; Second byte of ident
|
||||
CP (HL) ; Compare
|
||||
JR NZ,IDBIO2 ; Not HBIOS
|
||||
LD A,1 ; HBIOS BIOS id = 1
|
||||
RET ; and done
|
||||
;
|
||||
IDBIO2:
|
||||
; No idea what this is
|
||||
XOR A ; Setup return value of 0
|
||||
RET ; and done
|
||||
;
|
||||
;
|
||||
;
|
||||
BIOID DB 0 ; BIOS ID, 1=HBIOS, 2=UBIOS
|
||||
PLTID DB 0 ; Platform ID
|
||||
CPUSPD DB 0 ; CPU speed in MHz
|
||||
;
|
||||
RBC DB "RBC, 06-Nov-2017$"
|
||||
;
|
||||
UART DB ", UART0$"
|
||||
ASCI DB ", ASCI0$"
|
||||
SIO DB ", SIO0$"
|
||||
ACIA DB ", ACIA0$"
|
||||
;
|
||||
UBIOS DB " [UNA]$"
|
||||
HBIOS DB " [WBW]$"
|
||||
;
|
||||
CRLF DB 13, 10, "$"
|
||||
;
|
||||
BIOERR DB 13, 10, 13, 10, "*** Unknown BIOS ***", 13, 10, "$"
|
||||
;
|
||||
@@ -211,7 +298,7 @@ U_FRME EQU 08H ; bit for framing error
|
||||
; table at program startup. See MINIT above. Note that only a
|
||||
; subset of the jump table is overlaid (SENDR to SPEED).
|
||||
;
|
||||
U_JPTBL:
|
||||
UART_JPTBL:
|
||||
JP U_SENDR ; send character (via pop psw)
|
||||
JP U_CAROK ; test for carrier
|
||||
JP U_MDIN ; receive data byte
|
||||
@@ -325,7 +412,7 @@ A_FRME EQU 10H ;Z180 STAT:FE - framing error bit
|
||||
; table at program startup. See MINIT above. Note that only a
|
||||
; subset of the jump table is overlaid (SENDR to SPEED).
|
||||
;
|
||||
A_JPTBL:
|
||||
ASCI_JPTBL:
|
||||
JP A_SENDR ;send character (via pop psw)
|
||||
JP A_CAROK ;test for carrier
|
||||
JP A_MDIN ;receive data byte
|
||||
@@ -408,5 +495,148 @@ A_SNDRDY:
|
||||
A_SPEED:
|
||||
LD A,8 ; arbitrarily return 9600 baud
|
||||
RET
|
||||
;
|
||||
;=======================================================================
|
||||
;=======================================================================
|
||||
;
|
||||
; RC2014 SIO/2
|
||||
;
|
||||
;=======================================================================
|
||||
;=======================================================================
|
||||
;
|
||||
; SIO port constants
|
||||
;
|
||||
S_CMD EQU 80H ; SIO Command port
|
||||
S_DAT EQU 81H ; SIO Data port
|
||||
;
|
||||
; Following jump table is dynamically patched over initial jump
|
||||
; table at program startup. See MINIT above. Note that only a
|
||||
; subset of the jump table is overlaid (SENDR to SPEED).
|
||||
;
|
||||
SIO_JPTBL:
|
||||
JP S_SENDR ;send character (via pop psw)
|
||||
JP S_CAROK ;test for carrier
|
||||
JP S_MDIN ;receive data byte
|
||||
JP S_GETCHR ;get character from modem
|
||||
JP S_RCVRDY ;check receive ready
|
||||
JP S_SNDRDY ;check send ready
|
||||
JP S_SPEED ;get speed value for file transfer time
|
||||
;
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Send character on top of stack
|
||||
;
|
||||
S_SENDR:
|
||||
POP AF ; get character to send from stack
|
||||
OUT (S_DAT),A ; send to port
|
||||
RET
|
||||
;
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Test and rep;ort carrier status, Z set if carrier present
|
||||
;
|
||||
S_CAROK:
|
||||
XOR A ; not used, always indicate present
|
||||
RET
|
||||
;
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Get a character (assume character ready has already been tested)
|
||||
;
|
||||
S_MDIN:
|
||||
S_GETCHR:
|
||||
IN A,(S_DAT) ; read character from port
|
||||
RET
|
||||
;
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Test for character ready to receive, Z = ready
|
||||
; Error code returned in A register
|
||||
; *** Error code does not seem to be used ***
|
||||
;
|
||||
S_RCVRDY:
|
||||
XOR A ; A := 0
|
||||
OUT (S_CMD),A ; Access RD0
|
||||
IN A,(S_CMD) ; Get RD0
|
||||
AND 00000001B ; Isolate rx ready bit
|
||||
CP 00000001B ; ZF = rx ready
|
||||
;
|
||||
IF ERRDET
|
||||
;
|
||||
; With error detection (slower)
|
||||
PUSH BC ; save BC
|
||||
PUSH AF ; save AF
|
||||
LD A,1 ; A := 1
|
||||
OUT (S_CMD),A ; Access RD1
|
||||
IN A,(S_CMD) ; Get RD1
|
||||
AND 01110000B ; isolate line err bits
|
||||
POP AF ; restore AF
|
||||
LD A,B ; err bits (B) to A
|
||||
POP BC ; restore BC
|
||||
;
|
||||
ELSE
|
||||
;
|
||||
; No error detection (faster)
|
||||
LD A,0 ; report no line errors
|
||||
;
|
||||
ENDIF
|
||||
;
|
||||
RET
|
||||
;
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Test for ready to send a character, Z = ready
|
||||
;
|
||||
S_SNDRDY:
|
||||
XOR A ; A := 0
|
||||
OUT (S_CMD),A ; Access RD0
|
||||
IN A,(S_CMD) ; Get RD0
|
||||
AND 00000100B ; Isolate tx empty bit
|
||||
CP 00000100B ; ZF = tx empty
|
||||
RET
|
||||
;
|
||||
;-----------------------------------------------------------------------
|
||||
;
|
||||
; Report baud rate (index into SPTBL returned in regsiter A)
|
||||
;
|
||||
S_SPEED:
|
||||
LD A,8 ; arbitrarily return 9600 baud
|
||||
RET
|
||||
;
|
||||
;=======================================================================
|
||||
;=======================================================================
|
||||
;
|
||||
; RC2014 ACIA
|
||||
;
|
||||
;=======================================================================
|
||||
;=======================================================================
|
||||
;
|
||||
; ACIA port constants
|
||||
;
|
||||
C_CMD EQU 80H ; SIO Command port
|
||||
C_DAT EQU 81H ; SIO Data port
|
||||
;
|
||||
; Following jump table is dynamically patched over initial jump
|
||||
; table at program startup. See MINIT above. Note that only a
|
||||
; subset of the jump table is overlaid (SENDR to SPEED).
|
||||
;
|
||||
ACIA_JPTBL:
|
||||
JP C_SENDR ;send character (via pop psw)
|
||||
JP C_CAROK ;test for carrier
|
||||
JP C_MDIN ;receive data byte
|
||||
JP C_GETCHR ;get character from modem
|
||||
JP C_RCVRDY ;check receive ready
|
||||
JP C_SNDRDY ;check send ready
|
||||
JP C_SPEED ;get speed value for file transfer time
|
||||
;
|
||||
C_SENDR:
|
||||
C_CAROK:
|
||||
C_MDIN:
|
||||
C_GETCHR:
|
||||
C_RCVRDY:
|
||||
C_SNDRDY:
|
||||
C_SPEED:
|
||||
; Not yet implemeted...
|
||||
JP 0
|
||||
;
|
||||
END
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
CPUOSC .EQU 7372800 ; CPU OSC FREQ
|
||||
RAMSIZE .EQU 512 ; SIZE OF RAM IN KB, MUST MATCH YOUR HARDWARE!!!
|
||||
DEFSERCFG .EQU SER_115200_8N1 ; DEFAULT SERIAL LINE CONFIG (SHOULD MATCH ABOVE)
|
||||
INTTYPE .EQU IT_NONE ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...)
|
||||
INTTYPE .EQU IT_RC ; INTERRUPT HANDLING TYPE (IT_NONE, IT_SIMH, IT_Z180, IT_CTC, ...)
|
||||
;
|
||||
CRTACT .EQU FALSE ; CRT ACTIVATION AT STARTUP
|
||||
VDAEMU .EQU EMUTYP_ANSI ; DEFAULT VDA EMULATION (EMUTYP_TTY, EMUTYP_ANSI, ...)
|
||||
|
||||
@@ -476,8 +476,24 @@ INT_TIMER: ; TIMER INTERRUPT HANDLER
|
||||
;
|
||||
INT_BAD: ; BAD INTERRUPT HANDLER
|
||||
PUSH HL ; SAVE HL
|
||||
LD HL,HB_BADINT
|
||||
JR HBX_INT
|
||||
LD HL,HB_BADINT ; HL := INT HANDLER IN BIOS BANK
|
||||
JR HBX_INT ; TO TO ROUTING CODE
|
||||
;
|
||||
#IF (SIOENABLE)
|
||||
INT_SIO: ; SIO DEVICE INTERRUPT HANDLER
|
||||
;PUSH AF
|
||||
;IN A,(SIOA_DAT)
|
||||
;LD A,'='
|
||||
;OUT (SIOA_DAT),A
|
||||
;POP AF
|
||||
;EI
|
||||
;RETI
|
||||
|
||||
|
||||
PUSH HL ; SAVE HL
|
||||
LD HL,SIO_INT ; HL := SIO INT HANDLER IN BIOS BANK
|
||||
JR HBX_INT ; TO TO ROUTING CODE
|
||||
#ENDIF
|
||||
;
|
||||
; COMMON INTERRUPT DISPATCHING CODE
|
||||
; SETUP AND CALL HANDLER IN BIOS BANK
|
||||
@@ -791,8 +807,39 @@ HB_START1: ; BNKCALL ARRIVES HERE, BUT NOW RUNNING IN RAM BANK
|
||||
;
|
||||
#ENDIF
|
||||
;
|
||||
#IF (INTTYPE == IT_RC)
|
||||
;
|
||||
; SETUP Z80 IVT
|
||||
LD A,HBX_IVT >> 8 ; SETUP HI BYTE OF IVT ADDRESS
|
||||
LD I,A ; ... AND PLACE IT IN I REGISTER
|
||||
;
|
||||
IM 2 ; SWITCH TO INT MODE 2
|
||||
;
|
||||
#IF (SIOENABLE)
|
||||
; SETUP SIO INTERRUPT VECTOR IN IVT
|
||||
LD HL,INT_SIO
|
||||
LD (HBX_IVT + 4),HL
|
||||
#ENDIF
|
||||
|
||||
|
||||
|
||||
|
||||
;
|
||||
; IM 1
|
||||
;
|
||||
;#IF (SIOENABLE)
|
||||
;;
|
||||
; ; SETUP SIO INT VECTOR VIA INT MODE 1 IN PAGE ZERO
|
||||
; ;LD A,$C3 ; JP OPCODE
|
||||
; ;LD ($38),A ; ... AT INT VECTOR ADDRESS
|
||||
; ;LD HL,INT_SIO ; ADDRESS OF SIO INT HANDLER
|
||||
; ;LD ($39),HL ; ... IS TARGET OF JP
|
||||
;;
|
||||
;#ENDIF
|
||||
;
|
||||
#ENDIF
|
||||
;
|
||||
#ENDIF
|
||||
|
||||
HB_EI ; END OF CRITICAL SECTION
|
||||
;
|
||||
; DISPLAY PLATFORM INFORMATION
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
; | IDE_IO_STAT | 0x07 | R | STATUS REGISTER |
|
||||
; | IDE_IO_CMD | 0x07 | W | COMMAND REGISTER (EXECUTE) |
|
||||
; +-----------------------+-------+-------+-------------------------------+
|
||||
; * LBA0-4 ARE ALTERNATE DEFINITIONS OF SECT, CYL, AND DRVHD PORTS
|
||||
; * LBA0-3 ARE ALTERNATE DEFINITIONS OF SECT, CYL, AND DRVHD PORTS
|
||||
;
|
||||
; === STATUS REGISTER ===
|
||||
;
|
||||
|
||||
@@ -11,10 +11,17 @@
|
||||
; F E D C B A 9 8 7 6 5 4 3 2 1 0
|
||||
; -- MSB (D REGISTER) -- -- LSB (E REGISTER) --
|
||||
;
|
||||
SIO_DEBUG .EQU FALSE
|
||||
;
|
||||
SIO_NONE .EQU 0
|
||||
SIO_SIO .EQU 1
|
||||
SIO_DEBUG .EQU FALSE
|
||||
;
|
||||
SIO_NONE .EQU 0
|
||||
SIO_SIO .EQU 1
|
||||
;
|
||||
;
|
||||
;
|
||||
SIOA_CMD .EQU $80
|
||||
SIOA_DAT .EQU $81
|
||||
SIOB_CMD .EQU $82
|
||||
SIOB_DAT .EQU $83
|
||||
;
|
||||
;
|
||||
;
|
||||
@@ -24,6 +31,8 @@ SIO_PREINIT:
|
||||
;
|
||||
LD B,SIO_CNT ; LOOP CONTROL
|
||||
LD C,0 ; PHYSICAL UNIT INDEX
|
||||
XOR A ; ZERO TO ACCUM
|
||||
LD (SIO_DEV),A ; CURRENT DEVICE NUMBER
|
||||
SIO_PREINIT0:
|
||||
PUSH BC ; SAVE LOOP CONTROL
|
||||
LD A,C ; PHYSICAL UNIT TO A
|
||||
@@ -51,10 +60,11 @@ SIO_PREINIT0:
|
||||
SIO_PREINIT2:
|
||||
INC C ; NEXT PHYSICAL UNIT
|
||||
DJNZ SIO_PREINIT0 ; LOOP UNTIL DONE
|
||||
;
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; AND RETURN
|
||||
;
|
||||
;
|
||||
; SIO INITIALIZATION ROUTINE
|
||||
;
|
||||
SIO_INITUNIT:
|
||||
CALL SIO_DETECT ; DETERMINE SIO TYPE
|
||||
@@ -89,6 +99,8 @@ SIO_INIT1:
|
||||
PUSH HL ; COPY CFG DATA PTR
|
||||
POP IY ; ... TO IY
|
||||
|
||||
LD A,(IY + 1) ; GET SIO TYPE
|
||||
OR A ; SET FLAGS
|
||||
CALL NZ,SIO_PRTCFG ; PRINT IF NOT ZERO
|
||||
|
||||
POP BC ; RESTORE LOOP CONTROL
|
||||
@@ -98,6 +110,78 @@ SIO_INIT1:
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; DONE
|
||||
;
|
||||
; INTERRUPT HANDLER
|
||||
;
|
||||
SIO_INT:
|
||||
; CHECK FOR RECEIVE PENDING ON CHANNEL A
|
||||
XOR A ; A := 0
|
||||
OUT (SIOA_CMD),A ; ADDRESS RD0
|
||||
IN A,(SIOA_CMD) ; GET RD0
|
||||
RRA ; RECEIVE READY BIT TO CF
|
||||
JR NC,SIOB_INT ; NOTHING HERE, TRY B CHANNEL
|
||||
;
|
||||
; HANDLE CHANNEL A
|
||||
IN A,(SIOA_DAT) ; READ PORT
|
||||
LD E,A ; SAVE BYTE READ
|
||||
LD A,(SIOA_CNT) ; GET CURRENT BUFFER USED COUNT
|
||||
CP SIOA_BUFSZ ; COMPARE TO BUFFER SIZE
|
||||
RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
|
||||
INC A ; INCREMENT THE COUNT
|
||||
LD (SIOA_CNT),A ; AND SAVE IT
|
||||
CP SIOA_BUFSZ - 5 ; BUFFER GETTING FULL?
|
||||
JR NZ,SIOA_INT0 ; IF NOT, BYPASS CLEARING RTS
|
||||
LD A,5 ; RTS IS IN WR5
|
||||
OUT (SIOA_CMD),A ; ADDRESS WR5
|
||||
LD A,$E8 ; VALUE TO CLEAR RTS
|
||||
OUT (SIOA_CMD),A ; DO IT
|
||||
SIOA_INT0:
|
||||
LD HL,(SIOA_HD) ; GET HEAD POINTER
|
||||
LD A,L ; GET LOW BYTE
|
||||
CP SIOA_BUFEND & $FF ; PAST END?
|
||||
JR NZ,SIO_INT1 ; IF NOT, BYPASS POINTER RESET
|
||||
LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER
|
||||
SIO_INT1:
|
||||
LD A,E ; RECOVER BYTE READ
|
||||
LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION
|
||||
INC HL ; INCREMENT HEAD POINTER
|
||||
LD (SIOA_HD),HL ; SAVE IT
|
||||
RET ; AND RETURN
|
||||
;
|
||||
SIOB_INT:
|
||||
; CHECK FOR RECEIVE PENDING ON CHANNEL B
|
||||
XOR A ; A := 0
|
||||
OUT (SIOB_CMD),A ; ADDRESS RD0
|
||||
IN A,(SIOB_CMD) ; GET RD0
|
||||
RRA ; RECEIVE READY BIT TO CF
|
||||
RET NC ; NOTHING HERE, GIVE UP
|
||||
;
|
||||
; HANDLE CHANNEL B
|
||||
IN A,(SIOB_DAT) ; READ PORT
|
||||
LD E,A ; SAVE BYTE READ
|
||||
LD A,(SIOB_CNT) ; GET CURRENT BUFFER USED COUNT
|
||||
CP SIOB_BUFSZ ; COMPARE TO BUFFER SIZE
|
||||
RET Z ; BAIL OUT IF BUFFER FULL, RCV BYTE DISCARDED
|
||||
INC A ; INCREMENT THE COUNT
|
||||
LD (SIOB_CNT),A ; AND SAVE IT
|
||||
CP SIOB_BUFSZ - 5 ; BUFFER GETTING FULL?
|
||||
JR NZ,SIOB_INT0 ; IF NOT, BYPASS CLEARING RTS
|
||||
LD A,5 ; RTS IS IN WR5
|
||||
OUT (SIOB_CMD),A ; ADDRESS WR5
|
||||
LD A,$E8 ; VALUE TO CLEAR RTS
|
||||
OUT (SIOB_CMD),A ; DO IT
|
||||
SIOB_INT0:
|
||||
LD HL,(SIOB_HD) ; GET HEAD POINTER
|
||||
LD A,L ; GET LOW BYTE
|
||||
CP SIOB_BUFEND & $FF ; PAST END?
|
||||
JR NZ,SIOB_INT1 ; IF NOT, BYPASS POINTER RESET
|
||||
LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER
|
||||
SIOB_INT1:
|
||||
LD A,E ; RECOVER BYTE READ
|
||||
LD (HL),A ; SAVE RECEIVED BYTE TO HEAD POSITION
|
||||
INC HL ; INCREMENT HEAD POINTER
|
||||
LD (SIOB_HD),HL ; SAVE IT
|
||||
RET ; AND RETURN
|
||||
;
|
||||
;
|
||||
;
|
||||
SIO_DISPATCH:
|
||||
@@ -127,10 +211,65 @@ SIO_FTBL:
|
||||
;
|
||||
;
|
||||
SIO_IN:
|
||||
CALL SIO_IST ; RECEIVED CHAR READY?
|
||||
JR Z,SIO_IN ; LOOP IF NOT
|
||||
LD C,(IY + 2) ; C := BASE SIO PORT (WHICH IS ALSO RBR REG)
|
||||
IN E,(C) ; CHAR READ TO E
|
||||
LD A,(IY + 0) ; GET DEVICE NUMBER
|
||||
OR A ; SET FLAGS
|
||||
JR Z,SIOA_IN ; HANDLE CHANNEL A
|
||||
DEC A ; TEST FOR NEXT DEVICE
|
||||
JR Z,SIOB_IN ; HANDLE CHANNEL B
|
||||
CALL PANIC ; ELSE FATAL ERROR
|
||||
RET ; ... AND RETURN
|
||||
;
|
||||
SIOA_IN:
|
||||
CALL SIOA_IST ; RECEIVED CHAR READY?
|
||||
JR Z,SIOA_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER
|
||||
DI ; AVOID COLLISION WITH INT HANDLER
|
||||
LD A,(SIOA_CNT) ; GET COUNT
|
||||
DEC A ; DECREMENT COUNT
|
||||
LD (SIOA_CNT),A ; SAVE SAVE IT
|
||||
CP 5 ; BUFFER LOW THRESHOLD
|
||||
JR NZ,SIOA_IN0 ; IF NOT, BYPASS SETTING RTS
|
||||
LD A,5 ; RTS IS IN WR5
|
||||
OUT (SIOA_CMD),A ; ADDRESS WR5
|
||||
LD A,$EA ; VALUE TO SET RTS
|
||||
OUT (SIOA_CMD),A ; DO IT
|
||||
SIOA_IN0:
|
||||
LD HL,(SIOA_TL) ; GET BUFFER TAIL POINTER
|
||||
LD E,(HL) ; GET BYTE
|
||||
INC HL ; BUMP TAIL POINTER
|
||||
LD A,L ; GET LOW BYTE
|
||||
CP SIOA_BUFEND & $FF ; PAST END?
|
||||
JR NZ,SIOA_IN1 ; IF NOT, BYPASS POINTER RESET
|
||||
LD HL,SIOA_BUF ; ... OTHERWISE, RESET TO START OF BUFFER
|
||||
SIOA_IN1:
|
||||
LD (SIOA_TL),HL ; SAVE UPDATED TAIL POINTER
|
||||
EI ; INTERRUPTS OK AGAIN
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; AND DONE
|
||||
;
|
||||
SIOB_IN:
|
||||
CALL SIOB_IST ; RECEIVED CHAR READY?
|
||||
JR Z,SIOB_IN ; LOOP TILL WE HAVE SOMETHING IN BUFFER
|
||||
DI ; AVOID COLLISION WITH INT HANDLER
|
||||
LD A,(SIOB_CNT) ; GET COUNT
|
||||
DEC A ; DECREMENT COUNT
|
||||
LD (SIOB_CNT),A ; SAVE SAVE IT
|
||||
CP 5 ; BUFFER LOW THRESHOLD
|
||||
JR NZ,SIOB_IN0 ; IF NOT, BYPASS SETTING RTS
|
||||
LD A,5 ; RTS IS IN WR5
|
||||
OUT (SIOA_CMD),A ; ADDRESS WR5
|
||||
LD A,$EA ; VALUE TO SET RTS
|
||||
OUT (SIOA_CMD),A ; DO IT
|
||||
SIOB_IN0:
|
||||
LD HL,(SIOB_TL) ; GET BUFFER TAIL POINTER
|
||||
LD E,(HL) ; GET BYTE
|
||||
INC HL ; BUMP TAIL POINTER
|
||||
LD A,L ; GET LOW BYTE
|
||||
CP SIOB_BUFEND & $FF ; PAST END?
|
||||
JR NZ,SIOB_IN1 ; IF NOT, BYPASS POINTER RESET
|
||||
LD HL,SIOB_BUF ; ... OTHERWISE, RESET TO START OF BUFFER
|
||||
SIOB_IN1:
|
||||
LD (SIOB_TL),HL ; SAVE UPDATED TAIL POINTER
|
||||
EI ; INTERRUPTS OK AGAIN
|
||||
XOR A ; SIGNAL SUCCESS
|
||||
RET ; AND DONE
|
||||
;
|
||||
@@ -147,14 +286,24 @@ SIO_OUT:
|
||||
;
|
||||
;
|
||||
SIO_IST:
|
||||
LD C,(IY + 3) ; CMD PORT
|
||||
XOR A ; WR0
|
||||
OUT (C),A ; DO IT
|
||||
IN A,(C) ; GET STATUS
|
||||
AND $01 ; ISOLATE BIT 0 (RECEIVE DATA READY)
|
||||
LD A,(IY + 0) ; GET DEVICE NUMBER
|
||||
OR A ; SET FLAGS
|
||||
JR Z,SIOA_IST ; HANDLE CHANNEL A
|
||||
DEC A ; TEST FOR NEXT DEVICE
|
||||
JR Z,SIOB_IST ; HANDLE CHANNEL B
|
||||
CALL PANIC ; ELSE FATAL ERROR
|
||||
RET ; ... AND RETURN
|
||||
;
|
||||
SIOA_IST:
|
||||
LD A,(SIOA_CNT) ; GET BUFFER UTILIZATION COUNT
|
||||
OR A ; SET FLAGS
|
||||
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING
|
||||
RET ; AND DONE
|
||||
;
|
||||
SIOB_IST:
|
||||
LD A,(SIOB_CNT) ; GET BUFFER UTILIZATION COUNT
|
||||
OR A ; SET FLAGS
|
||||
JP Z,CIO_IDLE ; NOT READY, RETURN VIA IDLE PROCESSING
|
||||
XOR A ; ZERO ACCUM
|
||||
INC A ; ACCUM := 1 TO SIGNAL 1 CHAR WAITING
|
||||
RET ; DONE
|
||||
;
|
||||
;
|
||||
@@ -183,7 +332,9 @@ SIO_INITDEV:
|
||||
SIO_INITVALS:
|
||||
.DB $00, $18 ; WR0: CHANNEL RESET
|
||||
.DB $04, $C4 ; WR4: CLK/64=115200 BAUD, NO PARITY, 1 STOP BIT
|
||||
.DB $01, $00 ; WR1: NO INTERRUPTS
|
||||
; .DB $01, $00 ; WR1: NO INTERRUPTS
|
||||
.DB $01, $18 ; WR1: INTERRUPT ON ALL RECEIVE CHARACTERS
|
||||
.DB $02, $04 ; WR2: INTERRUPT VECTOR OFFSET
|
||||
.DB $03, $C1 ; WR3: 8 BIT RCV, RX ENABLE
|
||||
.DB $05, $EA ; WR5: DTR, 8 BITS SEND, TX ENABLE, RTS
|
||||
SIO_INITLEN .EQU $ - SIO_INITVALS
|
||||
@@ -270,22 +421,38 @@ SIO_STR_SIO .DB "SIO$"
|
||||
;
|
||||
SIO_DEV .DB 0 ; DEVICE NUM USED DURING INIT
|
||||
;
|
||||
; CHANNEL A RECEIVE BUFFER
|
||||
SIOA_CNT .DB 0 ; CHARACTERS IN RING BUFFER
|
||||
SIOA_BUF .FILL 32,'%' ; RECEIVE RING BUFFER
|
||||
SIOA_BUFEND .EQU $ ; END OF BUFFER
|
||||
SIOA_BUFSZ .EQU $ - SIOA_BUF ; SIZE OF RING BUFFER
|
||||
SIOA_HD .DW SIOA_BUF ; BUFFER HEAD POINTER
|
||||
SIOA_TL .DW SIOA_BUF ; BUFFER TAIL POINTER
|
||||
;
|
||||
; CHANNEL B RECEIVE BUFFER
|
||||
SIOB_CNT .DB 0 ; CHARACTERS IN RING BUFFER
|
||||
SIOB_BUF .FILL 32,'%' ; RECEIVE RING BUFFER
|
||||
SIOB_BUFEND .EQU $ ; END OF BUFFER
|
||||
SIOB_BUFSZ .EQU $ - SIOB_BUF ; SIZE OF RING BUFFER
|
||||
SIOB_HD .DW SIOB_BUF ; BUFFER HEAD POINTER
|
||||
SIOB_TL .DW SIOB_BUF ; BUFFER TAIL POINTER
|
||||
;
|
||||
; SIO PORT TABLE
|
||||
;
|
||||
SIO_CFG:
|
||||
; SIO/2 CHANNEL A
|
||||
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
|
||||
.DB 0 ; SIO TYPE
|
||||
.DB $81 ; DATA PORT
|
||||
.DB $80 ; CMD PORT
|
||||
.DB SIOA_DAT ; DATA PORT
|
||||
.DB SIOA_CMD ; CMD PORT
|
||||
.DW DEFSERCFG ; LINE CONFIGURATION
|
||||
.FILL 2,$FF ; FILLER
|
||||
;
|
||||
; SIO/2 CHANNEL B
|
||||
.DB 0 ; DEVICE NUMBER (UPDATED DURING INIT)
|
||||
.DB 0 ; SIO TYPE
|
||||
.DB $83 ; DATA PORT
|
||||
.DB $82 ; CMD PORT
|
||||
.DB SIOB_DAT ; DATA PORT
|
||||
.DB SIOB_CMD ; CMD PORT
|
||||
.DW DEFSERCFG ; LINE CONFIGURATION
|
||||
.FILL 2,$FF ; FILLER
|
||||
;
|
||||
|
||||
@@ -163,6 +163,7 @@ IT_NONE .EQU 0
|
||||
IT_SIMH .EQU 1
|
||||
IT_Z180 .EQU 2
|
||||
IT_CTC .EQU 3
|
||||
IT_RC .EQU 4
|
||||
;
|
||||
#INCLUDE "build.inc" ; INCLUDE USER CONFIG, ADD VARIANT, TIMESTAMP, & ROMSIZE
|
||||
;
|
||||
|
||||
@@ -116,7 +116,6 @@ UART_INITUNIT:
|
||||
;
|
||||
;
|
||||
;
|
||||
;
|
||||
UART_INIT:
|
||||
LD B,UART_CNT ; COUNT OF POSSIBLE UART UNITS
|
||||
LD C,0 ; INDEX INTO UART CONFIG TABLE
|
||||
|
||||
BIN
Source/RomDsk/RC/XMODEM.COM
Normal file
BIN
Source/RomDsk/RC/XMODEM.COM
Normal file
Binary file not shown.
Reference in New Issue
Block a user