Wine-Assembly design docs and reverse-engineering notes
Wine-Assembly runs real Windows 98 executables in the browser: an x86 interpreter and a Win32 API layer written directly in WebAssembly Text. These pages are the working notes behind it — the memory map, the interpreter's dispatch and lazy-flag design, the software GDI rasterizer, the DirectX and Win16 layers, the performance ledger, and one file per game or application we have taken apart to make it run. They are rendered from the Markdown in docs/ on GitHub.
Emulator design and performance
- Bug Fixes — Flag System, Shift CF, and IDIV Overflow
Bug Fixes — Flag System, Shift CF, and IDIV Overflow: notes from the Wine-Assembly Windows 98 emulator. - SIMD Support Design (SSE/MMX)
Transitioning the emulator to support SIMD involves mapping x86 vector registers to WebAssembly v128 types and handling the architectural aliasing between… - Splitting the guest-memory accessors so V8 inlines their fast paths — a null
Measured 2026-08-31 on branch worktree-agent-aefd5647b019c4c9d (a9131389). - AoE Performance Optimization Notes
The bottleneck is the WAT x86 interpreter, not canvas repaint and not mostly DIB conversion. - Win9x bitmap font review
Status: decision implemented for the deterministic GDI stock-font path on 2026-08-14. - Block chaining (round 15, alternative A)
docs/block-executor-review-2026-09-15.md §3 alternative (A), §5 round 15. - A per-block executor for every basic block — design + prototype, 2026-09
dispatch-attribution-2026-09.md ranked four levers by process-time share and put this one first: - Block executor: design review after round 13 (2026-09-15)
Read-only review of block-executor-design.md (rounds 6-13), hot-loop-vocabulary-2026-09.md, dispatch-attribution-2026-09.md, region-census-2026-09.md,… - Empty clipboard payloads versus absent formats — 2026-09-22
The string/handle audit found that format availability was inferred from clipboard_len > 0 and clipboard_rtf_len > 0. - Clipboard owning string copies — 2026-09-22
Pass-5 #5's remaining string-copy audit found a private implementation in clipboard_store_rtf_data. - Basic COM reference-count aliases — 2026-09-22
Pass-5 #5 calls for shared COM AddRef/Release implementations and generated per-interface dispatch. - One COM vtable initialization/restore inventory — 2026-09-22
The worker-sync test was stale: it called DirectSound3DListener the last registered interface, although more interfaces had been appended. - Shared control-session lifecycle
Pass-5 #6 requires a shared control client, including reply routing and pending-request teardown. - Plan: Controls as Real Windows
Currently, dialog controls (buttons, checkboxes, edit fields, static text) are rendered as dumb visual elements by the JS renderer. - D3D backend coverage: what actually draws on each backend, 2026-09-20
First pass at the D3D backlog item "gameplay captured on both rendering backends". - D3D device creation: allocation failure
2026-09-22 follow-up to the shared lifetime implementation. - Direct3D device enumeration lifetime
2026-09-22. Scope: IDirect3D1/2/3/7 EnumDevices invocation ownership, not a new native Win98 capability census. - Legacy D3D root lifetime
2026-09-22. Review items: shared COM lifetime implementations and silent-success handlers (P5 #5/#7). - D3D root QueryInterface identity
2026-09-22. Scope: the root-family branch of the shared D3DIM QI core, called by IDirect3D1/2/3/7. - D3D9 resource forwarding consolidation — 2026-09-22
Pass-5 recommendations 4/5/7: eleven resource wrappers did nothing except call the existing IDirect3DShader9 handler with the same six handler arguments. - D3D child creation returns the declared interface
2026-09-22. Creation-path follow-up to the material lifetime review. - D3DIM enumeration aliases — 2026-09-22
Three more exact handler pairs now share generated dispatch targets: - D3D format enumeration lifetime — 2026-09-22
The enumeration-alias audit found process-global texture/z callback state and format allocations with no completion cleanup. - ExecuteBuffer payload lifetime
2026-09-22. Ownership follow-up to the child QueryInterface review. - D3DIM execute-buffer QueryInterface
2026-09-22. P5 COM correctness/shared-implementation follow-up. - ExecuteData across sparse pages
2026-09-22. Public buffer-access follow-up to ExecuteBuffer lifetime work. - D3DIM: WebGL executor vs the WAT software rasterizer, 2026-09-19
First corpus-wide comparison of lib/d3dim-gpu.js against the software D3DIM path, run with tools/d3dim-mode-sweep.js on the Mac (caffeinate -d -u,… - D3DIM light QueryInterface
2026-09-22. P5 false-success/shared-COM follow-up. - Material lazy-allocation failure
2026-09-22. False-success and ownership follow-up. - D3DIM material QueryInterface
2026-09-22. P5 shared-COM cleanup and false-success follow-up. - Material structures across sparse guest pages
2026-09-22. Shared implementation and guest-memory correctness follow-up. - Pick instruction and vertex traversal
2026-09-22. ExecuteBuffer sparse-address follow-up. - D3DIM vertex-buffer handler aliases
2026-09-22: four byte-identical VertexBuffer7 handlers now enter their existing VertexBuffer counterparts via api_table.handler: Release, Lock,… - Vertex-buffer creation allocation rollback
2026-09-22. P5 false-success and ownership follow-up. - Vertex-buffer descriptor readback across sparse pages
2026-09-22. Guest-pointer and shared-implementation follow-up. - Vertex-buffer interface audit: native prerequisite
The emulator's vertex-buffer QI branch accepts every IID and returns the current vtable. This is not valid interface negotiation. - D3DIM viewport QueryInterface
2026-09-22. P5 shared-COM cleanup and false-success follow-up. - Shared Viewport / Viewport2 Release
2026-09-22. The Viewport2 Release entry now aliases the byte-identical Viewport implementation. - Agent control channel: live event streams into a running session
Status: phases 1 and 2 IMPLEMENTED, plus frozen (agent-stepped) mode and the multi-session dashboard — see those two sections below; the phase-2 pause/run… - Bring Your Own Media — design
Status: all six phases landed (4d7497ed provider/lazy-VFS, 6a876ff0 zip, 60407f55 iso + WAT parking, 29dab90a/9c1003b9 overlay, 0995b5a7 save… - Frozen session recording
Record an agent-driven frozen emulator session as a video that plays back as continuous realtime gameplay. Frames and audio are reconstructed on the - Design: real OS threads for guest threads
worktree-real-threads. Written 2026-08-16, updated 2026-08-20. - Production desktop idle CPU audit
Goal: all non-realtime games on the production desktop should use little CPU while idle. Local acceptance complete; merged, not deployed. - Diablo gameplay benchmark
Important qualification from the walking investigation: an ordinary breakpoint sets dbg_any, which disables fast block transfers. - Design D: a multi-block diamond loop matcher
Every loop fold in the tree today is a hand-written special case for one app, and the corpus censuses say so plainly: - Direct3D software and WebGL implementation plan
Status: implementation started, 2026-09-10; neither backend is complete. See the implementation ledger for evidence and open delivery gates. - Dual Direct3D implementation ledger
Reset presentation follow-up48855 PASS: native56-byte parameter extent guard, one-buffer DISCARD/COPY selection, explicit rejection of FLIP/multiple… - DirectAnimation support — design notes
Status: design only, not implemented. Captures what we learned while investigating CORBIS/FASHION/HORROR/WOTRAVEL screensavers (Plus!98) so a future… - DirectDraw attachment query ownership
Follow-up to the COM lifetime work in fable-review.md P5 #5. - Clipper QueryInterface — 2026-09-22
The native clipper handler returned success for every IID, did not acquire a reference, and wrote through NULL output. - DirectDraw display-mode enumeration lifetime — 2026-09-22
EnumDisplayModes used five mutable globals for callback, user context, caller return, descriptor and current index. - DirectDraw palette QueryInterface review — 2026-09-22
The palette handler always returned E_NOINTERFACE, including for its own IID and IUnknown. - DirectSound playback-frequency state — 2026-09-22
The audit following volume/pan found the same lost-before-Play setter pattern in SetFrequency. - DirectSound live rate-clock integration — 2026-09-22
The preceding WAT frequency-state fix exposed a separate host accounting bug: the cursor was elapsed * currentFrequency, so SetFrequency retrospectively… - Frozen DirectSound recording rate boundaries — 2026-09-22
The recording tap had independent fixed-rate accounting even after live cursor integration was repaired. - DirectSound volume/pan state review — 2026-09-22
Implemented on main in src/09a8-handlers-directx.wat. - Where guest CPU actually goes: dispatch attribution, 2026-09
Four levers are on the table for the x86 interpreter, and each deletes a - DOS corpus: what is still not drawing, and why
The 199-program demo corpus in /tmp/demos is swept with - Pass-5 carried cleanup: current-state audit — 2026-09-22
Scope: recommendation #8, not the whole review. The September 8 status table in fable-review.md still calls the 09a/09c3 split open. - Review checkpoint and shared-server regression
Current-state check after 06631548, on the shared main worktree. This is not a full-review completion audit or pristine-release verification. - Review duplicate ratchet checkpoint — 2026-09-21
The Pass-5 recommendation to ratchet duplication requires lowering the ceiling after removals, not only rejecting additions. - Pass-5 exact-twin families: audit — 2026-09-22
Scope: the nine rows of §P5-3's Byte-identical twins table, referenced by recommendation #5. - Validating the folds that ship on by default
Six loop folds are enabled for every user with no flag: - Shared font-resource resolution — 2026-09-22
Pass-5 identifies the duplicated AddFontResourceA / RemoveFontResourceA ladder: bitmap registry, TrueType registry, scalable-resource association, then… - Frame-pacing census: can we cap guest frame production at display refresh?
Measured 2026-08-31. Tools written for this survey: tools/pacing-census.js, tools/lock-pause-ab.js, and one flag, test/run.js --dx-lock-pause-ms=N. - GDI migration status
The machine-readable source is gdi-migration-status.json. It contains the exact keep/delete API lists for the JavaScript GDI bridge. - A backend-neutral render stream: scope, 2026-09-22
Today, one frontend already has the whole topology and the other does not: - Packed guest-page translation experiment
Wine Assembly's common image-relative and DIB guest addresses already use constant-time arithmetic. - Guest-span exhaustion must not return a false contiguous pointer
2026-09-22. Shared safety follow-up to the ExecuteBuffer sparse-page audit. - Guest-write audit checkpoint — 2026-09-21
Snapshot: main after 03bb39f1, with other agents' uncommitted work present. This is a candidate inventory, not a coverage certificate or a new build gate. - Hot-idiom census across five apps (2026-09-19)
Question: which interpreter idioms are hot in every app, so that a fixed build-time handler (no runtime codegen) pays across the corpus rather than in one… - Is there a fixed vocabulary of integer expression trees worth fusing?
2026-09-14. Read-only study. No emulator source was changed; the deliverables are tools/hot-loop-corpus.js and this document with its data directory… - Integer expression-region benchmark
tools/int-expr-region-bench.js — the integer twin of the x87 region bench (tools/x87-realistic-region-bench.js / docs/x87-realistic-region-bench.md,… - How much of a DOS demo is an expression?
tools/toyvm/expr-fold-census.js, core ten + three, 20M dispatches each. - Integer expression fusion: is there a ceiling worth building for?
A decode-time integer expression fold would take a basic block whose interior is a chain of full-width 32-bit integer ops, build one dataflow expression… - Interpreter Dispatch: What Has Actually Been Measured
Companion docs: wasm-stack-threaded-code.md (the proposal this constrains), aoe-performance-optimization.md (the older experiment table),… - Censusing a long load: how to find out whether an app has a hot loop at all
2026-09-14. Method note plus the measurement that motivated it. - Loop Idiom Superinstructions
Companion docs: interpreter-dispatch-perf.md (why "fewer dispatches" is the only lever, and why it is not automatically a win),… - Loop Microbenchmark Harness
Companion docs: interpreter-dispatch-perf.md (the four timing passes that resolved nothing, and why), page-compile-design.md §14 (CASE_CHAIN's whole-app… - Mapping dirty-page tracking: audit and first cost experiment
2026-09-21; production baseline 62f8332d. Status: not implemented. - Memory Map — wine-assembly vs Windows 98
The shared memory is fixed at 8192 WebAssembly pages. - Menu string ownership and shared duplication — 2026-09-22
Pass-5 #5 asks for one guest string-duplication implementation. - Analog mouse joystick (Blobby Volley / DX-Ball)
Local implementation, 2026-09-10; not deployed to production. - Writing
$nextout at its 405 call sites — a measured negative
Measured 2026-09-01 on main (working tree at ad5d5391 plus other lanes' in-flight edits; both A/B artifacts built from the same tree, so nothing but this… - Non-GDI Work Plan
Status: planning baseline for work that can proceed while the software-GDI rewrite is owned separately. - OLE clipboard lifetime review — 2026-09-22
The quiet-handler inventory includes OleIsCurrentClipboard, but inspection shows it already returns S_OK only for a non-NULL current owner and S_FALSE… - Rejected OLE operations must not mutate data — 2026-09-22
While reviewing the shared structured-storage handlers, four front doors used WAT select to choose between a mutating call and a high-word error: - Static OLE identity/lifetime audit — controlling identity fixed, follow-ups open
Initial reproduction: 2026-09-21, after 9078985f. The original observations below are preserved; the implemented correction and remaining gaps follow. - Embedded OLE reference-count aliases, 2026-09-21
Addresses the remaining Pass-5 recommendation 5 duplicate-handler drain in fable-review.md. - Packed-average cursor recognizers — 2026-09-22
Pass-5 §P5-3 names loop_try_avg_shift_cursor and loop_try_avg_round_cursor as the two largest near-duplicate recognizers. - Page compilation: address-ordered threaded code with a parallel index
Status: experiment, branch perf/page-compile, forked at 7d471df9. Baseline worktree pinned at the same commit: /private/tmp/wa-pagecomp-base. - Paint refactor — remaining work
The longer-term pixel-storage and rasterization architecture is tracked in docs/software-gdi-design.md. - Performance: the consolidated ledger
Every performance effort on this interpreter, what it measured, and its verdict. Read this first; the linked docs carry the detail and the raw numbers. - PNG comparison consolidation — 2026-09-19
Follow-up to the Pass-5 addendum in fable-review.md: tests should reuse tools/png-diff.js, but must retain their original comparison metric. - QueryPerformanceCounter arithmetic, 2026-09-21
The existing handler advertises 1 MHz but computed ticks_ms * 1000 + perf_counter_lo in i32 and wrote zero into the output high DWORD. - Recovery execution — 2026-09-10
User authorized active-owner checks, review, benchmarks, and integration of useful recovered work. No deployment or cleanup of old worktrees is included. - Refactor: Controls as Real Windows, JS as Dumb Renderer
Status: STEPs 1-6 done. STEP 8 partially done (find dialog only — first dialog with zero JS-side state mirroring). - How often does an app-scale region occur? — measured 2026-09-13
region-descriptor-bench-2026-09.md measured the mechanism and returned GO: a fixed handler (H454) interpreting a multi-block region descriptor beats… - Does a region descriptor beat threaded dispatch? — measured 2026-09-13
The single-self-loop tree fold (tree-fold-design-a.md) is finished. - Carrying toyvm's live region JIT into the WAT x86 interpreter — a measurement study
Recommendation at the end is DO A NARROWER THING.** - Replicated dispatch (
repl_tailcall) for the main emulator
src/04-cache.wat, expanded at all 419 tail sites, each expanding function declaring $nx_fn/$nx_op (the 9450d792 legacy-compiler transform below was… - Review P5-3: shared IsChar predicates and real runtime coverage
2026-09-19: six IsChar wrappers now share $is_char_type(ch, mask, wide). - Review P5-3: shared child exclusion scan
2026-09-19: dc_exclude_children_for_clip now retains its WS_CLIPCHILDREN guard and delegates the visible-child rectangle scan to… - Review P5-8: common-control wndproc split
2026-09-19: split the 9,327-line src/09c3-wndprocs.wat at existing top-level section boundaries. - Review P5-8: core handler fragment split
2026-09-19: replace the 8,759-line 09a-handlers.wat monolith with six contiguous, ordered fragments. - EnumDisplayMonitors: remove fixed-address callback scratch
2026-09-19 follow-up to the P5-8 core split / region-literal inventory. - Review P5-3: remaining encoded front doors
2026-09-19: the three remaining A/W census entries do not represent three duplicated implementations. - Review follow-up: native control marker duplication
Scope: fable-review.md P5-3's $statusbar_native_mark_slot / $tab_native_mark_slot near-twin finding. Inspected on main after f4d16032. - Review P5-3: shared OLE guest callback frame builder
2026-09-19: the six $ole_guest_callback_invoke1..6 helpers retain their arity-specific signatures but delegate frame construction to one private helper. - Review follow-up: toolbar width near-twins
Scope: the $toolbar_button_raw_width / $toolbar_button_width pair named in fable-review.md P5-3. - Review P5-3: shared Win16 image ownership lookup
2026-09-19: $win16_image_ne_off and $win16_image_base_addr now query one $win16_current_image_record scan in src/08c-ne-loader.wat. - Review follow-up: Win16 rectangle GDI bridges
Scope: P5-3's near-duplicate Win16 Ellipse, Rectangle, ExcludeClipRect, and IntersectClipRect handlers. - Review P5-3: Win16 positioning bridge and deferred gap
2026-09-19: the two Win16 positioning wrappers duplicated insert-after conversion, but performed it after calling the Win32 handler. - Mutable WINDOWPOS Z-order follow-through
2026-09-20: fixed SetWindowPos forwarding the original hWndInsertAfter argument to the host after accepting a replacement from the guest's… - RichEdit Compatibility Task Design
Status: active task design for making native RichEdit usable across WordPad, installers, and other Win9x-era apps. - Runtime TrueType hinting design
TrueType programs run in WAT at runtime. They are not converted into bitmap strikes during the build, and this work does not change the independent MS… - Safari Private Browsing performance
Safari Private Browsing can make Wine-Assembly startup dramatically slower when its advanced tracking and fingerprinting protections are active. - Scalable font design
Design started 2026-08-14. Assets are committed, fonts/substitutions.json is written, and src/10c-truetype.wat parses font tables and derives metrics:… - Semantic expression fusion benchmark brief
Can a stack or register interpreter profitably lower short arithmetic sequences to expression dataflow, instead of dispatching one handler per guest opcode? - SHRegGetUSValueA failure-path ABI — 2026-09-22
The quiet-handler audit found that both api_table.json and the handler described six arguments, popping 28 bytes including the return address. - SHRegGetUSValueA implementation — 2026-09-22
The constant ERROR_FILE_NOT_FOUND handler is replaced by registry lookup and default-data behavior checked against the native Win98 fixture. - SHRegGetUSValueA native observations — 2026-09-22
Two fresh v86 Windows 98 runs of the expanded 22-case probe have byte-identical serial output, including successful cleanup. GetVersion reports c0000a04. - Silent-handler inventory history
The build gate in tools/check-silent-stubs.js rejects additions or mutations to straight-line handlers that cannot delegate work, publish output, branch,… - Site and SEO work: what is built, how it is generated, what is left
The public site of Wine-Assembly: how the app, article, design and story pages are generated, what was done to make them findable, and the open list. - Software GDI rasterizer design
Implementation started 2026-08-12. WAT now owns canonical bitmap and window surfaces, GDI object/DC state, regions and explicit clipping, native-format… - Stack calls and region address reuse
Results and benchmark tooling integrated into main; no production runtime optimization merged by this integration. - Remaining test-call wrappers — 2026-09-22
Pass-5 #7 asks for API-metadata-generated test exports. The current audit started at 191 generated / 68 handwritten wrappers. - Window-title replacement ownership — 2026-09-22
The remaining string-copy audit found that title_table_set freed the old title before allocating/copying its replacement. - Native-targeted TLS allocation and release — 2026-09-22
The native Win98 fixture exposed five runtime differences: 64 rather than 80 slots, no reusable indices, no cross-thread clearing, successful double-free,… - The three backends over the twenty-program set (2026-09-01)
One measurement of every optimization the toy VM has, on the same twenty programs (tools/toyvm/bench-set-20.txt), on the same evening, at commit f2c76827. - Dead flag writes in the toy VM
Most flag writes are never read. A basic block is typically a few arithmetic ops and then a compare and a branch, and only the compare's flags are ever… - Moving the toy VM's decoder into wasm
tools/toyvm/decode.js opens by saying the decoder is on the host deliberately: - The toy VM: comparing dispatch shells on real 16-bit programs
Companion docs: interpreter-dispatch-perf.md (what the production interpreter measured, and why "fewer dispatches" is not "faster"),… - The interrupt schedule
A fold that changes how often the guest hands back must not change what the guest hears. Before this, it did. - Lazy flags in the toy VM
Every arithmetic instruction called an eager helper that computed all six arithmetic flags and stored the word. - Pinning the register a handler reaches for
A guest register lives in a wasm global. A handler gets at one by calling $rget16 / $rset8 / … with an index, and those helpers are a br_table over eight… - The region JIT, in the live run loop
through DosSession's afterSlice hook, builds a serializable bundle ({samples, mem, regs, machine, ...}), hands it to a backend, and installs what comes back. - Not running the loop that waits
After fusion, dead-flag elimination and trace blocks, the obvious next move was to find the biggest remaining handler pair and fuse it too. - The loops that are worth folding are not the ones that stop
The spin fold does not run a loop that cannot end. - Superinstructions in the toy VM's threaded code
Threaded code pays for every operation twice: once to do the work, and once to get to it. - Compiling through a conditional branch
A threaded-code op pays a dispatch. A block transfer pays a dispatch and then something else on top of it: the successor's arena address is loaded out of… - Pricing a trace JIT before building one
The dispatch shootout asks how to make the interpreter's dispatch cheaper. This asks a different question: what is left once dispatch is gone entirely? - The expression-tree fold
--tree-fold, off by default. tools/toyvm/tree-fold.js, the pass in compileProgram, test/test-toyvm-tree-fold.js. - VBE in the toy VM: what the corpus asks for, and what we answer
tools/toyvm/dos.js carries a small VBE 1.2 — the VESA BIOS Extension half of int 10h. - Tracing & debug flag performance
Every --trace-, --break, --watch, and --count flag adds per-block or per-API work to the emulator hot path. - Is any tree-fold arm worth a default flip? (2026-09-12)
Measurement only. Nothing in src/ or tools/toyvm/ moved for this; the only new code is tools/fold-ab.js, the harness that produced every number below. - TREE_FOLD — the first real decode-time expression fold (Design A)
Status: implemented, OFF by default, gated behind --block-exec. - Fused micro-op shapes — the census that decides whether to hand-write them
Status: census only. No fused handler was built, and this says not to build a vocabulary of them. - Indexed-color undithering design
Status: design only. No implementation is implied by this document. - VFS close/duplicate lifetime audit — 2026-09-21
Status: open. CRT termination issues stream closes (f903f56b), file duplicates have independent identities (800a543a), and closed VFS handles now reject… - Virtual LAN party design
This document specifies a virtual LAN for unmodified Win32 games running in Wine-Assembly. Liquid War 5.6.2 is the first target. - Volume buffer bounds and output ordering — 2026-09-22
The native Win98 fixture established that rejecting a short buffer is not a transaction over the whole call: scalar outputs precede filesystem output,… - WebAssembly Engine Feature Support
The build already ships two wasm binaries — build/wine-assembly.wasm (return_call) and build/wine-assembly.compat.wasm (call; return) — chosen at load… - Wasm Stack-Threaded Code Proposal
Measured constraints this proposal must respect are in interpreter-dispatch-perf.md. - WAT OpenGL command encoder
This implements the GL transport proposal from Claude session 107a07a4-b280-4ca1-ba54-fd68ab0e4e9c (session). - Struct layouts in WATX — deleting the hand-spelled field offsets
12,587 memory sites reach their fields through hand-spelled arithmetic. tools/struct-offset-census.js counts and classifies them. - WATX migration — Milestone 2 syntax/opcode gap census
Corpus-driven gap list for docs/watx-migration-plan.md §2.3. - Milestone 4 — compiler-Worker measurements
What this answers: the open gate in docs/watx-migration-plan.md §"Milestone 4 — Browser source compilation" — "Measure cold compile time and peak process… - WATX migration plan
Status: Phase 1 complete — WATX is the canonical compiler (cutover 2026-08-31 at byte identity). - Memory regions in WATX — deleting the magic numbers
Milestone 6 of docs/watx-migration-plan.md. This document decides the feature before the bulk of it is written. - WATX typed pointers, casts, and layout unions
Status: specification, user-signed-off 2026-09-01. Three tiers, each with its own oracle. - Widescreen / high-res opportunities per app
Status 2026-08-31. This is a backlog document: no app settings, config seeds, or byte pokes have been applied. - Win16 Entertainment Pack source provenance
This document records the source and byte-level verification for the three Entertainment Pack files repaired locally on 2026-08-20. - Win16 DDE incoming transaction ownership
2026-09-22: fixed two data-handle leaks in win16_dde_deliver on main. - Win16 EXECUTE command transport
2026-09-22. Microsoft's XTYP_EXECUTE contract places the command string in hdata, the topic in hsz1, and leaves hsz2 unused. - DDE room frame validation
2026-09-22: the receiver now validates its private DDE1 frame before any allocation, callback enqueue or pending/conversation update. - Win16 native Windows 98 visual audit
This audit compares every Win16 application registered in lib/apps.js with the same binary running natively in the pinned Windows 98 v86 reference. - WAT-native WinHelp design
Status: implementation in progress. Phase 1's WAT-owned file buffer, bounded-reader foundation, directory B+tree parser, and raw VFS load path are… - WSAIsBlocking registration and final test adapter — 2026-09-22
Pass-5 #7's last handwritten test_call_* wrapper called an existing handle_WSAIsBlocking directly. - x87 micro-region stack representation shootout
This experiment asks a narrow question: once the decoder has proved a balanced x87 region, how should that region carry ST(i) values around its loop? It… - Realistic x87 region representation benchmark
This is the finite-trip follow-up to docs/x87-microregion-representation-bench.md.
Reverse-engineering notes, one per application
- Abe's Oddysee demo
The registered abedemo payload launches test/binaries/shareware/abe/installed/abedemo.exe and explicitly mounts its four DDV movies plus c1.lvl, r1.lvl,… - Age of Empires (1997 shareware demo)
lib/apps.js id aoe1, exe test/binaries/shareware/aoe/aoe_ex/Empires.exe (1,607,680 bytes, imageBase 0x400000). - Sid Meier's Alpha Centauri Classic (Windows 95 ISO)
Established against SidMeierAlphaCentauriClassic-Windows95.iso, Joliet volume SMAC-E1_0Z (2,781 files). - Age of Empires II Trial
binaries/shareware/aoe2/aoe2_ex/EMPIRES2.EXE now reaches live Random Map gameplay through the registered aoe2 app on the same asset manifest used by the… - Atomic Bomberman demo
The registry has one Atomic Bomberman, the June 1997 public demo (atomic_bomberman_june_demo, below). - Baldur's Gate previews
Three distinct official previews are useful local-only Infinity Engine fixtures. - Beneath a Steel Sky — GOG Windows ScummVM
The local fixture is the GOG offline installer recorded under gog-free-beneath-a-steel-sky in test/candidate-corpus/manifest.json and sources.md. - Black & White 2 demo
test/binaries/win98-games-a-d/Black and White 2-DX9-D3D.exe is the 647,216,200-byte Black & White 2 demo InstallShield 11 self-extractor. - Blobby Volley 1.0
Binary: packages/freeware/blobby-volley/volley.exe, image base 0x00400000. Delphi/VCL, German UI. - Bricks I (
bricks.exe)
App id bricks. test/binaries/wep32-community/Bricks/bricks.exe, a Klotski remake. - Broken Sword demo
tools/install-broken-sword-demo.js runs the original SETUP.EXE, accepts its DirectX check, follows the launched GAMECFIG.EXE into the full-screen… - Caesar III demo
The playable payload is produced by the original Sierra/Impressions demo installer chain documented in sources.md: - Captain Claw Demo
The local fixture starts with the unchanged 11,275,313-byte claw_demo.exe self-extractor linked from sources.md. - The Curse of Monkey Island demo
The local original demo comes from the Windows 98 A-D distribution linked in sources.md. The package and playable files remain local-only. - Classic WordZap local idle audit
2026-09-10, source304, headful Chrome,1280x900. Game/Start command40003 alone is not proof of a running round: it shows the startup art/instruction overlay. - The Elder Scrolls II: Daggerfall (GOG build 28043)
The local fixture came from the Internet Archive gog_collection item and is pinned in test/candidate-corpus/manifest.json as SHA-1… - Darkstone demo 1.0
The local package comes from the Windows 98 A-D archive recorded in sources.md. - Deus Ex demo — local candidate
The official 1.002f demo installer is pinned in test/candidate-corpus/manifest.json from Archive item DeusExDemo. - Diablo retail (CD install, v1.00)
Companion to diablo-shareware.md — same engine, but the retail disc adds the install flow and the CD check. - Diablo Shareware
test/binaries/candidates/diablo-shareware/installed/, registry id diablo_shareware (lib/apps.js). - Diablo II Shareware demo
The local package is Blizzard's DiabloIIDemo.exe: - Dungeon Keeper demo
The local Windows demo comes from the Windows 98 A-D archive recorded in sources.md. - DX5 SDK
boids.exe— 33,423 draws, one-colour frame
test/binaries/dx-sdk/bin/boids.exe, image base 0x400000. A DirectDraw + Direct3D Immediate Mode v2 sample: flocking birds over a wireframe ground grid. - DX SDK Direct3D Retained Mode samples (globe, viewer, flip3dtl)
--app=dx_globe, --app=dx_viewer, --app=dx_flip3dtl. - DX-Ball (
dxball.exe)
App id dxball. test/binaries/candidates/dxball/installed/dxball.exe, imageBase=0x400000, loads at 0x400000 (delta 0, so original VAs are runtime VAs). - Elasto Mania 1.0
Registered executable: test/binaries/candidates/elasto-mania/Elma/Elma.exe, app id elasto_mania, image base 0x400000. Imports DSOUND.dll!DirectSoundCreate. - The Elder Scrolls: Arena (GOG)
The local fixture comes from the Internet Archive gog_collection item pinned in test/candidate-corpus/manifest.json. - EmPipe local idle audit
2026-09-10, source304, headful Chrome,1280x900. Game/New command100 resets the title screen; it does not start the pipe board. - Fallout Win95 Interactive Demo
The fallout-demo candidate pins falldemo.zip from the Archive.org FalloutDemo item (SHA-1 214c6b8931f75aa2a9a11f521a26b0cb8e565ad9). - Flight of the Amazon Queen — GOG Windows ScummVM
The local fixture is the GOG offline installer recorded under gog-free-flight-of-the-amazon-queen in test/candidate-corpus/manifest.json and sources.md. - Four Stones
Registry fourstones, test/binaries/wep32-community/Funpack/FourStones.exe with FunPack.dll. Win32 Connect Four game, window400x300 at desktop(20,20). - Funtris local idle audit
2026-09-10, source304, headful Chrome. This is a realtime falling-tetromino game. - Grand Theft Auto 2 Wild Demo
f8fc0a9653932f008a03e56ea892fb31dbeb98d228cc4df61b910bcb35d08d21. - Half-Life Uplink demo
The local-only installer is test/binaries/candidates/half-life-uplink-installer/hluplink.exe (50,872,079 bytes). It is a Win9x InstallShield package. - Heroes of Might and Magic II (demo)
Frozen CLI gameplay reproduces the user's momentary "stretched" image when a hero walks far enough to auto-pan the camera. - Heroes of Might and Magic III Demo
The local-only candidate is the March 1999 demo. - Icewind Dale demo — local candidate
The official English demo is pinned in test/candidate-corpus/manifest.json from Archive item icewind_dale_eng_demo. - Icy Tower v1.3.1
Local app ids icy_tower and icy_tower_installer. - Jardinains! v1.2
Jardinains! 1.2 is a Win32 Blitz/DirectDraw Breakout-style shareware game. - Jazz Jackrabbit 2 Shareware 1.23s
The source fixture is the unchanged 20,069,847-byte J2swc123.exe; installed files remain local test material and are not a replacement distribution. - Liquid War 5.6.2
Binary: test/binaries/candidates/liquid-war/LW5/lwwin.exe, image base 0x00400000. - Little Fighter 2 v1.9
Local-only app ids little_fighter_2 and little_fighter_2_installer. - Lure of the Temptress — GOG Windows ScummVM
The local fixture is the GOG offline installer recorded under gog-free-lure-of-the-temptress in test/candidate-corpus/manifest.json and sources.md. - Marbles (
MARBLES.EXE)
App id marbles. test/binaries/plus98/MARBLES.EXE, the marble-solitaire game from Microsoft Plus! 98. - MechWarrior 3 demo
for std::_Lockit (??0_Lockit@std@@QAE@XZ and ??1_Lockit@std@@QAE@XZ). - Classic Media Player (
mplay32.exe)
Fixture: test/binaries/win98-apps/mplay32.exe, SHA-256 c229b5af9f5bb641654dc0ebe6bbd0a66f215fd97ae50ae0a748cb5a2cf2e040. - Moorhuhn 1, 2, Winter-Edition, 3, Tennis and CD extras
Local candidates moorhuhn, moorhuhn-2, moorhuhn-winter in test/candidate-corpus/manifest.json (archive.org item moorhuhn_1__2_with_addins); app ids… - Morrowind (GOTY retail ISO) — local-only candidate
Retail, so localhost only: morrowind is in LOCAL_CANDIDATE_APPS (the dropdown index.html shows only on localhost), never DESKTOP_APPS. - Motocross Madness demo
The browser build can reach a live race without Wine. With a persisted profile, the reliable 640x480 guest-coordinate route is: - Paint: dock-collapse geometry (2026-09-19)
Binary: test/binaries/mspaint.exe, using its registered CLI companion DLLs. Repro: node test/test-mspaint-dock-toggle.js. - NetHack 3.4.3 for Windows
This target is the native Win32 graphical build, NetHackW.exe, from the official NetHack 3.4.3 package. - Organic Art / D3DRM screensavers (Plus! 98)
test/binaries/screensavers/{ARCHITEC,FALLINGL,GEOMETRY,JAZZ,OASAVER,ROCKROLL,SCIFI}.SCR - Over 1000 Games for Windows (Nodtronics, 2001) — the titles that came up blank
A 2001 shareware CD, mostly 16-bit NE. The corpus is local-only under the Nodtronics EULA — nothing here may be published or deployed. - Pawn 3
A chess program. --app=pawn, exe binaries/wep32-community/Pawn/Pawn.exe. Renders its board through Direct3D 9 and reads the mouse through DirectInput 7. - Space Cadet Pinball mobile presentation
App pinball, executable test/binaries/pinball/pinball.exe. Investigation: 2026-09-10, local LAN8088 isolated branch; not production. - Plus! 98 Direct3D screensavers (ARCHITEC, FALLINGL, GEOMETRY, JAZZ, OASAVER, ROCKROLL, SCIFI)
--app=scr_architec and its six siblings, from binaries/screensavers/. - Pocket Tanks v1.6 shareware
Local-only app ids pocket_tanks and pocket_tanks_installer. - Quake II 3.14 demo
C:\WINDOWS\Desktop\Quake2 Demo; the playable executable is Install\Data\quake2.exe beneath that directory. - Rodent's Revenge 2000 (VB6 remake)
test/binaries/wep32-community/Rodent2000/Rodent2000.exe — James Emmrich and Alexander Popov, 2002. - RollerCoaster Tycoon (shareware/demo)
test/binaries/shareware/rct/English/RCT.exe — Chris Sawyer / Hasbro Interactive, - Shadow Warrior Classic Complete (GOG build 2.0.0.7)
The local fixture came from the Internet Archive gog_collection item and is pinned in test/candidate-corpus/manifest.json as SHA-1… - SimCity 2000 Win95 Demo (
simdemo.exe)
Registry id simcity2000_demo, local-only (test/binaries/candidates/simcity-2000-demo/installed/). Maxis/MFC, MDI frame + one MDI child. - Sid Meier's SimGolf Demo
The local fixture comes from https://archive.org/details/Simgolfdemo. - SkiFree (
ski32.exe, Microsoft Entertainment Pack)
test/binaries/entertainment-pack/ski32.exe, app id ski32. - Snood 2.2W
Local app ids snood and snood_installer. The original package is test/binaries/candidates/snood/SnoodWin22Install.exe; the optional installed browser… - Solitaire (NT debug build in Entertainment Pack)
2026-09-10 mobile assertion diagnosis; no runtime fix implemented. - StarCraft shareware
test/binaries/candidates/starcraft-shareware/installed/, registry id starcraft_shareware (lib/apps.js). - Total Annihilation Demo
The local fixture is the unchanged 21,540,864-byte Total Annihilation.exe self-extractor linked from sources.md. Wine-Assembly runs that executable directly. - Total Annihilation demo
The original Total Annihilation.exe self-extractor is retained locally at test/binaries/candidates/total-annihilation-demo/. - Ultima IV: Quest of the Avatar (GOG)
The local fixture comes from the Internet Archive gog_collection item pinned in test/candidate-corpus/manifest.json. - Unreal-family demo installers
Status: verified locally on 2026-09-13. These are proprietary demos and remain localOnly candidate-corpus fixtures. No host Wine was used. - Visual Basic 5.0 Control Creation Edition (and the other free VB/Delphi editions)
Status 2026-09-22: VB5 CCE installs, opens the IDE in design mode, and runs a shipped sample (F5). - Warcraft III: Reign of Chaos — Demo
App id warcraft3_demo (lib/apps.js), install tree at test/binaries/candidates/warcraft3-demo/. Provenance is in test/candidate-corpus/manifest.json. - Chip's Challenge (Win16 WEP4)
test/test-win16-wep4-gameplay.js formerly clicked screen (200,310), then held Right under --real-ticks with a 700 ms host sleep. - Fuji Golf (Win16 WEP3)
App wep16_fujigolf, test/binaries/wep16/WEP3/FUJIGOLF.EXE, with FUJIGOLF.DAT mounted beside it. See the historical native comparison in win16-v86-audit.md. - Go Figure! (Win16 WEP4)
App: wep16_gofigure, test/binaries/wep16/WEP4/GOFIGURE.EXE, VBRUN100. - Rodent's Revenge (WEP2, 16-bit)
test/binaries/wep16/WEP2/RODENT.EXE — Microsoft Entertainment Pack 2, 1991, Christopher Lee Fraley, written in Visual Basic 1 (NE, links VBRUN100 plus the… - Tetris for Windows (WEP1 / Win16)
The old test's first failure required an active blue main caption while the modal About DLL was open. - TriPeaks (Win16 Entertainment Pack)
The registered app is wep16_tripeaks. After accepting the player dialog and pressing F2, the broken runtime showed an empty green board and an “Out of… - WordZap (Win16 WEP3): display-DC publication
App ID wep16_wordzap, not the separate Win32 cwordzap game. - Winamp wVis popup routing
test/binaries/plugins/candidates/vis_w.dll, preferred image base 0x10000000, SHA-256 45505bb5e232c5f28b2ef0223ecf2c2103e4800a0c02276c0c6fbf6638bcd7c6. - Worms 2 October demo
Local app id worms2_demo. The original setup media is prepared beneath test/binaries/candidates/worms-2-demo/installer-10oct/; any installed browser…