Browse Source

SIO Driver Interrupt Based Receive

pull/3/head
Wayne Warthen 8 years ago
parent
commit
51a33aaf0b
  1. 2
      Source/Apps/XM/xmdm125.asm
  2. 338
      Source/Apps/XM/xmhb.180
  3. 2
      Source/HBIOS/cfg_rc.asm
  4. 53
      Source/HBIOS/hbios.asm
  5. 2
      Source/HBIOS/ide.asm
  6. 209
      Source/HBIOS/sio.asm
  7. 1
      Source/HBIOS/std.asm
  8. 1
      Source/HBIOS/uart.asm
  9. BIN
      Source/RomDsk/RC/XMODEM.COM

2
Source/Apps/XM/xmdm125.asm

@ -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
;
;=======================================================================
;

338
Source/Apps/XM/xmhb.180

@ -67,95 +67,182 @@ MINIT:
LD C,9 ; BDOS string display function
CALL BDOS ; Do it
;
; Get system type
; 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
;
; 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!
;
HINIT:
;
; Display RomWBW notification string
LD DE,HBIOS ; BIOS notification string
LD C,9 ; BDOS string display function
CALL BDOS ; Do it
;
; 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
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)
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:
; Display port notification string
; 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
POP HL ; Recover HL
;
; 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,MINIT3 ; if not, not UNA
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,MINIT3 ; if not, not UNA
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,MINIT3 ; if not, not UNA
;
; Display UNA notification string
LD DE,UBIOS ; BIOS notification string
LD C,9 ; BDOS string display function
CALL BDOS
JR NZ,IDBIO1 ; if not, not UNA, check others
LD A,2 ; UNA BIOS id = 2
RET ; and done
;
; 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
IDBIO1:
; Check for RomWBW (HBIOS)
LD HL,(0FFFEH) ; HL := HBIOS ident location
LD A,'W' ; First byte of ident
CP (HL) ; Compare
JR NZ,MINIT4 ; Not HBIOS
JR NZ,IDBIO2 ; Not HBIOS
INC HL ; Next byte of ident
LD A,~'W' ; Second byte of ident
CP (HL) ; Compare
JR NZ,MINIT4 ; Not HBIOS
JR NZ,IDBIO2 ; Not HBIOS
LD A,1 ; HBIOS BIOS id = 1
RET ; and done
;
; Display RomWBW notification string
LD DE,HBIOS ; BIOS notification string
LD C,9 ; BDOS string display function
CALL BDOS ; Do it
IDBIO2:
; No idea what this is
XOR A ; Setup return value of 0
RET ; and done
;
; 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, $"
BIOID DB 0 ; BIOS ID, 1=HBIOS, 2=UBIOS
PLTID DB 0 ; Platform ID
CPUSPD DB 0 ; CPU speed in MHz
;
UART DB "UART0$"
ASCI DB "ASCI0$"
RBC DB "RBC, 06-Nov-2017$"
;
UBIOS DB " [UNA]", 13, 10, "$"
HBIOS DB " [WBW]", 13, 10, "$"
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

2
Source/HBIOS/cfg_rc.asm

@ -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, ...)

53
Source/HBIOS/hbios.asm

@ -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

2
Source/HBIOS/ide.asm

@ -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 ===
;

209
Source/HBIOS/sio.asm

@ -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
;

1
Source/HBIOS/std.asm

@ -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
;

1
Source/HBIOS/uart.asm

@ -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

Binary file not shown.
Loading…
Cancel
Save