Rebuilds libv86.js from felixrieseberg/v86@windows95-base, which now carries vga-defer-vbe-disable-v86: when a windowed DOS VM's vgabios writes dispi[4]=0, Win9x's VDD passes that through (it doesn't know about ports 1CE/1CF) while virtualising the rest of the mode-set, so v86 used to drop out of LFB rendering with the legacy registers still holding SVGA values and the screen turned to planar garbage. The fix defers the disable until a legacy attribute-mode write actually reaches the hardware. debug-harness: WIN95_PROBE_DOSBOX=1 opens command from Run, types dir, optionally Alt+Enters (WIN95_PROBE_DOSBOX_ALTENTER=1). WIN95_PROBE_VGATRACE=1 wraps the VGA io.ports[] entries (not the VGAScreen methods, which are captured by-value at registration) and dumps [port, op, value, eip+VM/PE/CPL] tuples to /tmp/win95-vgatrace.json — that EIP/mode column is what pinned the leak on V86-mode vgabios at C000:2C8x.
5.6 KiB
name, description
| name | description |
|---|---|
| update-v86 | Build and install v86 (wasm + libv86.js + BIOS) into windows95. Use when pulling upstream v86 changes, fixing a broken build, verifying the fork branches are still in sync, or setting up a fresh v86 checkout. |
Updating v86
windows95 builds v86 from source — not from copy.sh. Two small bugfix patches ride along on a fork branch until the upstream PRs land.
Sources
| File | Built from |
|---|---|
src/renderer/lib/libv86.js |
make build/libv86.js in ../v86 |
src/renderer/lib/build/v86.wasm |
make build/v86.wasm |
bios/seabios.bin, bios/vgabios.bin |
copied from ../v86/bios/ |
tools/update-v86.js runs those targets, copies the artifacts, runs 5
sanity checks, and fails loudly if any prerequisite is missing. No
fallbacks, no fetching from copy.sh.
The fork branch
v86 should be checked out on felixrieseberg/v86:windows95-base.
That branch merges four feature branches, each upstreamable on its own:
electron-renderer-fs-loader(PR #1540) —src/lib.jsusesrequire("fs")instead ofawait import("node:fs/promises"). Dynamic import ofnode:URLs doesn't work in an Electron renderer.ide-shared-registers(PR #1541) —src/ide.jswrites ATA Command Block registers (Features, Sector Count, LBA Low/Mid/High) to both master and slave. Without this, Win95/98 hang at the splash screen on any disk >~535MiB. Root cause: v86 commit1b90d2e7changed those writes to target onlycurrent_interface, but per ATA spec they're channel-shared (one register file on the IDE cable; both drives latch the same value).vmware-abspointer—src/vmware.jsimplements the VMware mouse backdoor (port0x5658, GETVERSION + ABSPOINTER_*) so a guest driver (VBADOS VBMOUSE) can read absolute cursor position and track the host cursor 1:1 without pointer lock. Consumes themouse-absolutebus event thatMouseAdapteralready emits.vga-defer-vbe-disable-v86—src/vga.jsdefersdispi[4]=0written from V86 mode until a legacy attribute-mode write reaches the hardware. Win9x's VDD virtualises ports 3B0–3DF for a windowed DOS VM but not 1CE/1CF, so vgabios's VBE-disable leaks through while the rest of its mode-set is captured into the VM's virtual register file — without this the screen turns to planar garbage the moment you open a DOS box.
Prerequisites
rustup target add wasm32-unknown-unknown
brew install openjdk
# one-time: fetch the Closure compiler v86's Makefile pins to
curl -sL https://repo1.maven.org/maven2/com/google/javascript/closure-compiler/v20210601/closure-compiler-v20210601.jar \
-o ../v86/closure-compiler/compiler.jar
Closure must be v20210601 — newer versions hit closure-compiler#3972 on v86's source. The pin is in v86's Makefile.
Steps
cd ../v86
git fetch fork origin
git checkout windows95-base
git rebase fork/windows95-base # in case fork was updated elsewhere
cd ../windows95
node tools/update-v86.js
That's it. Script runs both make targets, copies, verifies.
Sanity-check WARNs
The 5 checks assert invariants src/renderer/smb/index.ts and
tools/parcel-build.js depend on. A WARN means upstream changed
something load-bearing — don't ignore it:
await import("node:...")still present → PR #1540 was reverted or the pattern moved. Electron renderer will fail to load disk images.master.features_reg=missing in minified → PR #1541 was reverted orwindows95-baselost the commit. Win95 will hang at splash on disks >535MiB. Checkcd ../v86 && git log --oneline windows95-base.- Export pattern changed →
tools/parcel-build.jsshim needs updating. Look formodule.exports.V86=andwindow.V86=. tcp-connectionevent gone → SMB falls back to the old-API theft hack insrc/renderer/smb/index.ts— still works, but surprising.on_tcp_connectiongone → old-API fallback is dead. SMB integration only works via thetcp-connectionbus event now. Harmless; update the comment inindex.tsand retire the theft code.
After updating, probe-test
node tools/update-v86.js && tools/probe-boot.sh
Should land SUCCESS in ~40s. If FAIL_SPLASH_HANG, the IDE fix didn't
take — check grep master.features_reg src/renderer/lib/libv86.js. If
FAIL_VXDLINK, retry — sporadic bluescreens are normal (see the
probe-win95 skill).
When a PR merges upstream
Rebase windows95-base to drop the now-redundant commit:
cd ../v86
git fetch origin
git checkout windows95-base
git rebase origin/master # drops the merged commit cleanly
git push fork windows95-base --force-with-lease
If both PRs are upstream, retire the fork branch entirely:
- Point
tools/update-v86.jsdefault atorigin/master(it already uses../v86, so justgit checkout masterthere) - Delete
fork/windows95-base - Remove this skill's "The fork branch" section
- Confirm the 5 sanity checks still pass — they're version-agnostic
Integration contract with SMB
The SMB server sits on top of v86's network adapter. Details in
src/renderer/smb/README.md. Short version: the new path uses the
tcp-connection bus event; the fallback path uses
adapter.on_tcp_connection callback + connection-theft (stealing a
TCPConnection the HTTP probe builds for us). Both use .on_data on
the conn, not .on("data"), because Closure dead-code-eliminates the
event emitter plumbing.
If any v86 update breaks these assumptions, src/renderer/smb/index.ts
needs updating, not just tools/update-v86.js.