Fixed issue preventing RFS versions of SA-5510 and MS-BASIC from accessing RFS disks

This commit is contained in:
Philip Smart
2026-03-28 18:34:06 +00:00
parent dafb80c74f
commit 0bdc2f83c5
3 changed files with 133 additions and 77 deletions

View File

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

View File

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

BIN
roms/rfs.rom vendored

Binary file not shown.