mirror of
https://github.com/felixrieseberg/windows95.git
synced 2026-05-09 00:24:09 +00:00
Update to v86 HEAD with IDE shared-register fix
Patches src/ide.js before building: restores the dual master+slave writes for ATA Command Block registers (Features, Sector Count, LBA Low/Mid/High) that 1b90d2e7 changed to current_interface-only. Those registers are channel-shared per ATA spec; Win95's ESDI_506.PDR writes them then switches drive-select expecting the values to persist. Found via JS-only bisect. Boots fresh in ~32s with the same sporadic-bluescreen rate as the prod build. The new build has the tcp-connection bus event so SMB uses the clean path instead of the connection-theft hack (guard added for the old-API monkeypatch to skip if the bus handler already accepted). tools/update-v86.js applies the source patch automatically. v86 checkout left clean (patch stashed).
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -15,3 +15,4 @@ trusted-signing-metadata.json
|
||||
.env
|
||||
electron-windows-sign.log
|
||||
.npmrc
|
||||
/.claude/
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -148,6 +148,10 @@ export function setupSmbShare(emulator: V86, hostPath: string) {
|
||||
const orig = adapter.on_tcp_connection.bind(adapter);
|
||||
adapter.on_tcp_connection = function (packet: any, tuple: string): boolean {
|
||||
if (packet.tcp.dport !== 139) return orig(packet, tuple);
|
||||
// New v86 fires the tcp-connection bus event BEFORE this callback;
|
||||
// if our bus handler already accepted the conn, it's in tcp_conn —
|
||||
// claim it so the original (which would otherwise RST) doesn't run.
|
||||
if (adapter.tcp_conn[tuple]) return true;
|
||||
|
||||
const adapterAny = adapter as any;
|
||||
adapterAny.receive = () => {};
|
||||
|
||||
@@ -51,10 +51,48 @@ function download(url, dest) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* v86 commit 1b90d2e7 (May 2025) changed ATA Command Block register writes
|
||||
* to only target current_interface instead of both master and slave. Those
|
||||
* registers (ports 0x1F1-0x1F6) are channel-shared per the ATA spec — both
|
||||
* drives on the cable see the same register file. Win95's ESDI_506.PDR
|
||||
* writes them, switches drive-select, expects them to still be there.
|
||||
* Result: IDE IRQ never fires, splash screen hang.
|
||||
*
|
||||
* Found via JS-only bisect: prod wasm + freshly-built libv86.js, parent
|
||||
* 3c944a02 boots, 1b90d2e7 hangs deterministically.
|
||||
*/
|
||||
function patchIdeSharedRegisters(ideJsPath) {
|
||||
let s = fs.readFileSync(ideJsPath, 'utf-8');
|
||||
const re = /this\.current_interface\.(\w+_reg) = \(this\.current_interface\.\1 << 8 \| data\) & 0xFFFF;/g;
|
||||
const matches = [...s.matchAll(re)];
|
||||
if (matches.length === 0) {
|
||||
console.log(' ide.js: shared-register patch already applied or upstream fixed it');
|
||||
return;
|
||||
}
|
||||
if (matches.length < 5) {
|
||||
throw new Error(`ide.js: expected ≥5 register write sites, found ${matches.length} — pattern changed`);
|
||||
}
|
||||
s = s.replace(re, (_, reg) =>
|
||||
`this.master.${reg} = (this.master.${reg} << 8 | data) & 0xFFFF;\n` +
|
||||
` this.slave.${reg} = (this.slave.${reg} << 8 | data) & 0xFFFF;`
|
||||
);
|
||||
fs.writeFileSync(ideJsPath, s);
|
||||
console.log(` ide.js: restored shared-register writes (${matches.length} sites)`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const jsDest = path.join(LIB_DIR, 'libv86.js');
|
||||
const wasmDest = path.join(LIB_DIR, 'build/v86.wasm');
|
||||
|
||||
// ─── source patch (before any build) ─────────────────────────────────────
|
||||
if (!JS_ONLY) {
|
||||
const ideJs = path.join(V86_DIR, 'src/ide.js');
|
||||
if (fs.existsSync(ideJs)) {
|
||||
patchIdeSharedRegisters(ideJs);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── wasm ────────────────────────────────────────────────────────────────
|
||||
let wasmDate;
|
||||
if (JS_ONLY) {
|
||||
|
||||
Reference in New Issue
Block a user