From 2398b48e295ca58e5891501f17fe12f7b8ea5a1c Mon Sep 17 00:00:00 2001 From: b1ackmai1er Date: Fri, 16 Aug 2019 23:20:00 +0800 Subject: [PATCH] xmodem for usb-fifo Generates xmuf.com for usb-fifo file transfer. Is not included in the ROM drive build. --- Source/Apps/XM/Build.cmd | 3 + Source/Apps/XM/xmuf.180 | 331 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 334 insertions(+) create mode 100644 Source/Apps/XM/xmuf.180 diff --git a/Source/Apps/XM/Build.cmd b/Source/Apps/XM/Build.cmd index 26cb0ccc..a11742eb 100644 --- a/Source/Apps/XM/Build.cmd +++ b/Source/Apps/XM/Build.cmd @@ -11,9 +11,12 @@ set ZXINCDIR=%TOOLS%\cpm\include\ zx mac xmdm125.asm $PO zx slr180 -xmhb/HF +zx slr180 -xmuf/HF zx mload25 XM=xmdm125,xmhb +zx mload25 XMUF=xmdm125,xmuf rem set PROMPT=[Build] %PROMPT% rem %comspec% copy /Y XM.com ..\..\..\Binary\Apps\ +copy /Y XMUF.com ..\..\..\Binary\Apps\ diff --git a/Source/Apps/XM/xmuf.180 b/Source/Apps/XM/xmuf.180 new file mode 100644 index 00000000..53b52d86 --- /dev/null +++ b/Source/Apps/XM/xmuf.180 @@ -0,0 +1,331 @@ +;======================================================================= +; +; XMUF.Z80 - XMODEMXX PATCH FILE FOR ECB USB-FIFO +; +; Phil Summers - difficultylevelhigh@gmail.com +; Updated: 2019-08-16 +; +;======================================================================= +; +; Overlay file is Z80, build with M80: +; M80 =XMHB +; L80 XMHB,XMHB/N/X/E +; + .Z80 + ASEG +; +NO EQU 0 +YES EQU NOT NO +; +ERRDET EQU NO ; detect parity/framing/overrun errs +; +BASE EQU 100H ; start of cp/m normal program area +; +BDOS EQU 00005H ; BDOS function dispatch vector +; +;======================================================================= +; +; Jump table: The jump table must be in exactly the same sequence as the +; one in XMODEM. Note the ORG of 103H - This jump table has no jump to +; 'BEGIN'. +; + ORG BASE + 3 ;start after 'JMP BEGIN' +; + JP CONOUT ;must be 00000h if not used, see below + JP MINIT ;initialization routine (if needed) + JP UNINIT ;undo whatever 'MINIT' did (or return) +JPTBL: + JP SENDR ;send character (via pop psw) + JP CAROK ;test for carrier + JP MDIN ;receive data byte + JP GETCHR ;get character from modem + JP RCVRDY ;check receive ready + JP SNDRDY ;check send ready + JP SPEED ;get speed value for file transfer time + JP EXTRA1 ;extra for custom routine + JP EXTRA2 ;extra for custom routine + JP EXTRA3 ;extra for custom routine +; +;----------------------------------------------------------------------- +; +; Output character to console +; +CONOUT EQU 0 ; not used +; +;----------------------------------------------------------------------- +; +; Initialize modem +; +; This procedure has been usurped to dynamically detect the type +; of system we are running on and install the *real* jump table +; entries as appropriate. +; +MINIT: +; + ; Announce + LD DE,RBC ; RetroBrew Computers + LD C,9 ; BDOS string display function + CALL BDOS ; Do it +; + ; 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,HBTAG ; 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,UBTAG ; 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: + LD HL,1250 ; Smaller receive loop timeout scalar + LD (RCVSCL),HL ; ... to compensate for BIOS overhead + LD HL,UF_JPTBL ; HBIOS jump table address + LD DE,USB_FIFO ; HBIOS console 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) ; A := CPU speed in MHz + LD HL,(RCVSCL) ; HL := receive scalar + + 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 10 ; CPU speed in MHz +RCVSCL DW 2800 ; RECV loop timeout scalar +; +RBC DB "RBC, 16-Aug-2018$" +; +USB_FIFO DB ", USB-FIFO$" +; +UBTAG DB " [UNA]$" +HBTAG DB " [WBW]$" +; +CRLF DB 13, 10, "$" +; +BIOERR DB 13, 10, 13, 10, "++ Unknown BIOS ++", 13, 10, "$" +; +;----------------------------------------------------------------------- +; +; Uninitialize modem +; +UNINIT: + LD A,(BIOID) + CP 1 ; Is HBIOS? + RET NZ ; If not, just return + + ; Reset character device 0 + LD B,04H ; HBIOS CIOINIT function 0x04 + LD C,0 ; Unit = 0 + LD DE,-1 ; Reset w/ current settings + RST 08 ; Do it + RET ; not initialized, so no 'UN-INITIALIZE' +; +;----------------------------------------------------------------------- +; +; The following are all dummy routines that are unused because MINIT +; dynamically installs the real jump table. +; +SENDR: +CAROK: +MDIN: +GETCHR: +RCVRDY: +SNDRDY: +SPEED: +EXTRA1: +EXTRA2: +EXTRA3: + RET +; +;======================================================================= +;======================================================================= +; +; WILL SOWERBUTTS ECB USB-FIFO +; +;======================================================================= +;======================================================================= +; +FIFO_BASE EQU 0CH +FIFO_DATA EQU (FIFO_BASE+0) +FIFO_STATUS EQU (FIFO_BASE+1) +FIFO_SEND_IMM EQU (FIFO_BASE+2) +; +; 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). +; +UF_JPTBL: + JP UF_SENDR ;send character (via pop psw) + JP UF_CAROK ;test for carrier + JP UF_MDIN ;receive data byte + JP UF_GETCHR ;get character from modem + JP UF_RCVRDY ;check receive ready + JP UF_SNDRDY ;check send ready + JP UF_SPEED ;get speed value for file transfer time +; +;----------------------------------------------------------------------- +; +; Send character on top of stack +; +UF_SENDR: + + POP AF ; get character to send from stack + OUT (FIFO_DATA),A ; WRITE TO FIFO + OUT (FIFO_SEND_IMM),A ; SEND IMMEDIATE + RET +; +;----------------------------------------------------------------------- +; +; Test and report carrier status, Z set if carrier present +; +UF_CAROK: + XOR A ; not used, always indicate present + RET +; +;----------------------------------------------------------------------- +; +; Get a character (assume character ready has already been tested) +; +; This routine must NOT block. +; +UF_MDIN: +UF_GETCHR: + IN A,(FIFO_DATA) ; GET CHAR + RET +; +;----------------------------------------------------------------------- +; +; Test for character ready to receive, Z = ready +; Error code returned in A register +; *** Error code does not seem to be used *** +; +UF_RCVRDY: + IN A,(FIFO_STATUS) ; B7=0 IF CHAR AVAIL, =1 IF NO CHAR. + RLCA ; B0=0 IF CHAR AVAIL, =1 IF NO CHAR. + AND 00000001B ; A=0, ZF=1 IF NO CHAR, A=1, ZF=0 IF CHAR AVAIL, + LD A,0 + RET +; +;----------------------------------------------------------------------- +; +; Test for ready to send a character, Z = ready +; +UF_SNDRDY: + IN A,(FIFO_STATUS) ; Bit 0=0 IF SPACE AVAIL, =1 IF FULL + AND 00000001B ; A=0, ZF=1 IF SPACE AVAIL, A=1, ZF=0 IF FULL. + RET +; +;----------------------------------------------------------------------- +; +; Report baud rate (index into SPTBL returned in register A) +; +UF_SPEED: + LD A,8 ; arbitrarily return 9600 baud + RET +; + END