Skip to content

Enable CD-ROM via a synchronous fs-backed buffer#362

Merged
felixrieseberg merged 1 commit into
mainfrom
claude/admiring-shockley
Apr 12, 2026
Merged

Enable CD-ROM via a synchronous fs-backed buffer#362
felixrieseberg merged 1 commit into
mainfrom
claude/admiring-shockley

Conversation

@felixrieseberg
Copy link
Copy Markdown
Owner

What

Re-enables the CD-ROM settings tab and makes mounted ISOs actually readable from inside Windows 95.

Why it never worked

v86's stock async loaders (AsyncXHRBuffer / AsyncFileBuffer) return from .get() immediately and resolve on the next event-loop turn. For an ATAPI PIO READ(10) that means atapi_read() leaves the drive in BSY while ~1.3 M emulated instructions run before the data callback fires.

Win95's ESDI_506/CDVSD path reads status twice right after pushing the CDB, sees 0xD0 (BSY) both times, and issues DEVICE RESET (08h) ~165 instructions later — which cancels the in-flight read via cancel_io_operations(). It retries once, gets the same result, gives up. The drive enumerates and D: appears, but the volume never mounts (label shows as "CD", dir d: is empty).

The hard disk doesn't hit this because ESDI_506 drives it via bus-master DMA, which is purely IRQ-driven on the host side.

Fix

SyncFileBuffer (src/renderer/sync-file-buffer.ts) implements v86's {get, set, load, byteLength, get_state, set_state} buffer contract on top of fs.readSync, so each 2 KB sector is available before the next emulated instruction runs. Wired in emulator.tsx in place of {url, async: true}.

Verified end-to-end with the probe harness: mount the XP SP3 ISO from ~/Downloads, boot to desktop, dir d: lists GRTMPVOL_EN with the full root directory; ATAPI trace shows 8 READ(10)s and only the boot-time detection RESET.

Also in this PR

  • WIN95_PROBE_CDROM=/path.iso and WIN95_PROBE_CDTRACE=1 harness hooks (and skill doc) for reproducing the above without the UI.
  • Pump one screen_adapter.update_screen() frame before each probe screenshot — rAF doesn't fire when the Electron window is occluded, so captures were coming back blank.

Reviewer note

Don't switch the cdrom option back to {url, async: true} without re-testing dir d: inside the guest — it'll silently regress to an unmountable drive.

v86's async loaders leave the ATAPI drive in BSY across an event-loop
turn after a READ(10) CDB. Win95's ESDI_506 reads status twice, sees
BSY both times, and issues DEVICE RESET ~165 instructions later, which
cancels the in-flight read — the drive enumerates but D: never mounts.

Serve the ISO through a small fs.readSync-backed buffer so the data is
available before the next emulated instruction runs, and re-enable the
CD-ROM settings tab.

Also: WIN95_PROBE_CDROM / WIN95_PROBE_CDTRACE harness hooks, and pump
one screen-adapter frame before screenshotting so probe captures work
when the Electron window is occluded.
@felixrieseberg felixrieseberg merged commit 6e73df1 into main Apr 12, 2026
1 check failed
@felixrieseberg felixrieseberg deleted the claude/admiring-shockley branch April 12, 2026 02:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant