From 0bdc2f83c51e7af78c9c5063fdb77b49d8082223 Mon Sep 17 00:00:00 2001 From: Philip Smart Date: Sat, 28 Mar 2026 18:34:06 +0000 Subject: [PATCH] Fixed issue preventing RFS versions of SA-5510 and MS-BASIC from accessing RFS disks --- asm/rfs_bank9.asm | 11 +- dis/MZ-2Z009E/mz2z009e_dz80.asm | 199 ++++++++++++++++++++------------ roms/rfs.rom | Bin 24576 -> 24576 bytes 3 files changed, 133 insertions(+), 77 deletions(-) diff --git a/asm/rfs_bank9.asm b/asm/rfs_bank9.asm index 3f66a90..7823091 100644 --- a/asm/rfs_bank9.asm +++ b/asm/rfs_bank9.asm @@ -669,9 +669,14 @@ LROMLOAD59: POP HL ; Retri LD A,L ; Autoexecute turned off? CP 0FFh JP Z,LROMLOAD99 ; Go back to monitor if it has been, else execute. - LD HL,(EXADR) - ;EI ; No need to block interrupts now as MROM bank restored. - JP (HL) ; Execution address. + ; Signal the command dispatcher (in bank 0) to execute the loaded program. + ; We cannot JP (HL) directly from bank 9 because the UROM bank would still + ; be 9 when BASIC starts — the BIOS jump table at E8A0 needs bank 0. + ; Setting RESULT to 0FEH and returning via BKSWRET restores bank 0 first, + ; then the command dispatcher sees 0FEH and does JP (HL) from bank 0. + LD A,0FEH + LD (RESULT),A + ;JP LROMLOAD99 ; Fall through to RET. LROMLOAD99: RET diff --git a/dis/MZ-2Z009E/mz2z009e_dz80.asm b/dis/MZ-2Z009E/mz2z009e_dz80.asm index a586be8..4b67352 100644 --- a/dis/MZ-2Z009E/mz2z009e_dz80.asm +++ b/dis/MZ-2Z009E/mz2z009e_dz80.asm @@ -468,7 +468,7 @@ L017B: XOR A L0182: PUSH AF CALL L0D20 POP AF - JP L0000 + JP RFS_ERR_HOOK ; --------------------------------------------------------------------------- ; SVC Dispatch Table — 80 entries (#00-#4F), each a 16-bit handler address. @@ -3998,9 +3998,11 @@ L1C9D: LD A,(01051H) RET Z JP 01F7CH - CALL L1D15 - JP NZ,RFS_SVC30_HOOK ; Was: JP NZ,L2AD2 — hook for $RFS LOAD - LD BC,(ELMD20) + JP SVC30_DBG ; Was: CALL L1D15 / JP NZ,RFS_SVC30_HOOK + NOP + NOP + NOP +SVC30_FD: LD BC,(ELMD20) PUSH BC XOR A LD IX,(ZINP) @@ -4008,9 +4010,12 @@ L1C9D: LD A,(01051H) POP BC RET - LD A,(01051H) - BIT 7,A - JP Z,01F97H + JP SVC32_DBG ; Was: LD A,(01051H) / BIT 7,A / JP Z,01F97H + NOP ; Padding (original was 8 bytes, now 3+1+1=5+...) + NOP + NOP + NOP + NOP LD BC,(ELMD20) JP L313A @@ -18060,7 +18065,7 @@ L84E0: DB 016H DS 2, 030H DB 039H L852E: DS 2, 020H - DB "V1.0L ",00DH + DB "V1.0Q ",00DH DS 3, 020H DB 043H,005H,"OPYRIGHT ",006H,"(C) 1984 ",005H,"BY ",006H,"SHARP ",005H,"CORP." DS 5, 020H @@ -18121,7 +18126,7 @@ L852E: DS 2, 020H ; --------------------------------------------------------------------------- $RFS: DW $USR ; Next device = $USR DB "RFS",000H ; Device name "RFS" - DB 05FH ; flags1: bit5=1 block device, bit6=1 + DB 05FH ; flags1: bit5=0 sequential, bit6=1 ZRO-based DIR DB 007H ; flags2 DB 0FFH ; dirmx: 255 max directory entries DW RFSINIT ; ZINIT handler @@ -18488,11 +18493,9 @@ RFSRO_END: ; --------------------------------------------------------------------------- ; RFSINP_DIR - ZINP handler for $RFS device -; Called via IOCALL from L2FD4 during DIR with A=(ZCH). -; H >= 28H → identity read; DIR_FILLED=0 → DIR fill; DIR_FILLED=1 → data xfer -; NOTE: LOAD path calls RFSINP_LD directly (via RFS_LOAD_HOOK), never here. -; The old A=0 check was wrong: for RFS1 (ZCH=0), DIR accidentally triggered -; the LOAD path, corrupting BASIC memory and breaking all subsequent LOADs. +; With sequential protocol (flags1 bit5=0), this is ONLY called from +; SVC #30's sequential path for data transfer. DIR uses RFSRO (ZRO). +; Dispatches directly to RFSINP_LD to load file data from SD. ; --------------------------------------------------------------------------- RFSINP_DIR: ; Debug: trace every ZINP call — show H register @@ -18508,6 +18511,12 @@ RFSINP_DIR: CALL DBG_CRLF POP AF ; + ; $RFS is a sequential device (flags1 bit5=0). RFSINP_DIR is only + ; called from SVC #30's sequential path for data transfer, so always + ; go directly to RFSINP_LD. (DIR uses RFSRO via ZRO, not ZINP.) + JP RFSINP_LD + ; + ; --- Dead code below (block-device dispatch, kept for reference) --- LD A,H CP 028H JP NC,RFSINP_DISKID @@ -19174,6 +19183,67 @@ MEMCLI_PATCH: LD HL,RFS_END JP L402F ; Continue with memory clear loop +; --------------------------------------------------------------------------- +; RFS_ERR_HOOK - Debug: show error code before BASIC warm restart +; A = error code from error table (L1F6A or L4AE6) +; --------------------------------------------------------------------------- +RFS_ERR_HOOK: + PUSH AF + PUSH HL + PUSH AF + LD A,'!' + OUT (050H),A + LD A,'E' + OUT (050H),A + LD A,':' + OUT (050H),A + POP AF + CALL DBG_HEX + ; Output stack return addresses: SP+4 (first return addr), SP+6 (second) + ; Stack now: [HL, AF, ret1, ret2, ...] + ; SP SP+2 SP+4 SP+6 + LD A,' ' + OUT (050H),A + LD A,'S' + OUT (050H),A + LD HL,(00004H) ; can't use this... + ; Use SP-relative addressing: SP currently points to pushed HL + ; ret1 is at SP+4, ret2 at SP+6 + LD HL,00004H + ADD HL,SP ; HL = address of ret1 on stack + LD A,(HL) + INC HL + PUSH AF ; save low byte + LD A,(HL) ; high byte of ret1 + CALL DBG_HEX + POP AF + CALL DBG_HEX + LD A,' ' + OUT (050H),A + LD HL,00006H + ADD HL,SP ; HL = address of ret2 on stack + LD A,(HL) + INC HL + PUSH AF + LD A,(HL) + CALL DBG_HEX + POP AF + CALL DBG_HEX + CALL DBG_CRLF + POP HL + POP AF + JP L0000 + +; --------------------------------------------------------------------------- +; SVC30_DBG - Debug wrapper for SVC #30 handler +; Shows L1050 (device flags) and ZINP for every SVC #30 call, then dispatches. +; --------------------------------------------------------------------------- +SVC30_DBG: + ; Original logic: CALL L1D15 + JP NZ,RFS_SVC30_HOOK + CALL L1D15 + JP NZ,RFS_SVC30_HOOK + JP SVC30_FD + ; --------------------------------------------------------------------------- ; RFS_BIT5PATH - Block-device DIR handler for $RFS ; Replaces the standard L2FD1 path (0x2F38) which doesn't work with @@ -19182,14 +19252,6 @@ MEMCLI_PATCH: ; For non-$RFS block devices ($FD/$QD), falls through to the original path. ; --------------------------------------------------------------------------- RFS_BIT5PATH: - ; Debug: bit5 DIR path entry - PUSH AF - LD A,'B' - OUT (050H),A - LD A,'5' - OUT (050H),A - CALL DBG_CRLF - POP AF ; Check if current device is $RFS PUSH HL LD HL,(ZINP) @@ -19228,41 +19290,6 @@ RFS_BIT5PATH: ; For all other block devices ($FD/$QD), fall through to original L2AD2. ; --------------------------------------------------------------------------- RFS_SVC30_HOOK: - ; Debug: SVC #30 entry — show ZINP value and RFSINP_DIR value - PUSH AF - PUSH HL - LD A,'3' - OUT (050H),A - LD A,'0' - OUT (050H),A - LD A,' ' - OUT (050H),A - ; Show ZINP contents (the runtime handler address) - LD A,'Z' - OUT (050H),A - LD A,'=' - OUT (050H),A - LD HL,(ZINP) - LD A,H - CALL DBG_HEX - LD A,L - CALL DBG_HEX - LD A,' ' - OUT (050H),A - ; Show compile-time RFSINP_DIR address - LD A,'R' - OUT (050H),A - LD A,'=' - OUT (050H),A - LD HL,RFSINP_DIR - LD A,H - CALL DBG_HEX - LD A,L - CALL DBG_HEX - CALL DBG_CRLF - POP HL - POP AF - ; PUSH HL LD HL,(ZINP) PUSH DE @@ -19272,14 +19299,6 @@ RFS_SVC30_HOOK: POP DE POP HL JP NZ,L2AD2 ; Not $RFS → original block device path - ; Debug: $RFS detected in SVC #30 - PUSH AF - LD A,'3' - OUT (050H),A - LD A,'R' - OUT (050H),A - CALL DBG_CRLF - POP AF ; $RFS: call RFSINP_LD directly (A=0 for read) XOR A CALL RFSINP_LD @@ -19290,15 +19309,6 @@ RFS_SVC30_HOOK: ; Checks if current device is $RFS; if so, uses RFSINP_LD. ; --------------------------------------------------------------------------- RFS_LOAD_HOOK: - ; Debug: L3153 trampoline entry - PUSH AF - LD A,'L' - OUT (050H),A - LD A,'H' - OUT (050H),A - CALL DBG_CRLF - POP AF - ; LD HL,(ZINP) PUSH DE LD DE,RFSINP_DIR @@ -19349,6 +19359,47 @@ DSTR_DONE: LD DE,DEVNAMEBUF POP HL RET +; --------------------------------------------------------------------------- +; SVC32_DBG - Debug wrapper for SVC #32 (file data transfer) +; Outputs "S32 L1050=xx L1051=yy" then executes original SVC #32 logic. +; --------------------------------------------------------------------------- +SVC32_DBG: + PUSH AF + PUSH HL + LD A,'S' + OUT (050H),A + LD A,'3' + OUT (050H),A + LD A,'2' + OUT (050H),A + LD A,' ' + OUT (050H),A + ; Output L1050 (flags1) + LD A,(L1050) + CALL DBG_HEX + LD A,',' + OUT (050H),A + ; Output L1051 (flags2) + LD A,(01051H) + CALL DBG_HEX + LD A,',' + OUT (050H),A + ; Output L1044 (device pointer) + LD HL,(L1044) + LD A,H + CALL DBG_HEX + LD A,L + CALL DBG_HEX + CALL DBG_CRLF + POP HL + POP AF + ; Original SVC #32 logic + LD A,(01051H) + BIT 7,A + JP Z,01F97H + LD BC,(ELMD20) + JP L313A + ; =========================================================================== ; RFS Data Variables ; =========================================================================== diff --git a/roms/rfs.rom b/roms/rfs.rom index dd85b3140452a91d6ba47af56618f43039d17de7..ff4fd1f74ace815e7896467eede449e8a8cf423a 100644 GIT binary patch delta 170 zcmZoTz}RqraRWCKx8rL?rx!21odbL|H;XZ?bZ6W#`GBW4W8!8WFHuHSjn{Vnj6MsV z6m)z2RB^GORQW$%4HjW#iEj@D7YiOXcqJI{TH@JcFBa*^3EqNC$*(8Zvq&?xPVV=1 zF=&1LFG7J)Sn8jqhRr`k3yZUTuNBOMHGyDjzQjwgxC&5Q;q3a?268~j&HSt%m^M4G U@-S`+2;$xx8oio@`Tzg_0IAVJJpcdz delta 181 zcmZoTz}RqraRWCKx5H~irx!21odbL|Hj6Q>bZ6W?`GBW4W5Q-0FHuGn_19W#f-g@B zy1ss@xL8oC{2#9di?Fi9w}*m@1rHm%67+v9@ocgei?s05t5W|MGz5Y2yl)pOun50O zdOf+GMVhf?@&s=egO=C-A`}>frT%GZ*!)wpusGZMTER?M69~5EOS}Y&s{q9n&aQiH eAP1D(%+LCPX|n?>FXN_wAa16Jh|Ph~YghnG&O}rI