Wine-Assembly articles: how a Windows 98 emulator in WebAssembly works
Wine-Assembly runs real Windows 98 programs in the browser: an x86 interpreter, a Win32 API layer, a software GDI, DirectX and a 16-bit loader, all written directly in WebAssembly Text. These articles each answer one question about how it is built. They are drawn from the full project story and the design docs, and are shorter than either.
The machine
- How to write an x86 interpreter in raw WebAssembly Text
Threaded code throughcall_indirect, the block cache, what a dispatch costs, loop super-ops, and the optimisations that measured as nothing. - Lazy flags: how an x86 emulator avoids computing EFLAGS after every instruction
Four globals instead of a flags register, the bugs the scheme produced, and a second implementation's numbers. - Letting the compiler own the memory map: WATX
Why 170 hand-placed hex bases became untenable, what the extended WAT adds, and how the cutover was verified. - A DOS emulator in WebAssembly built to answer interpreter-design questions
The toy VM: 199 DOS programs, three execution tiers, and what a region JIT found.
The operating system
- Loading real Windows DLLs in the browser
MFC42, msvcrt, d3drm: relocations, ordinal imports, DllMain, and the runtime patches that were not obvious. - Implementing the Win32 API in WebAssembly
3,300 handlers, one generated dispatch table, continuation thunks for calls that call back, and the no-silent-stubs rule. - A software GDI in WebAssembly
Why the canvas 2D API was the wrong target, and the rasteriser, regions, paths and fonts that replaced it. - DirectDraw and Direct3D in the browser
COM vtables through the thunk zone, surfaces as memory, palettes, and three generations of Direct3D. - Running 16-bit Windows 3.x programs in the browser
An NE loader, segmented execution, and Pascal-convention Win16 dispatch. - A virtual LAN for Windows 98 multiplayer games
Winsock in WAT over a frame wire, and what Hearts and Liquid War needed.
The process
- Driving a Windows 98 emulator from a script
Headless runs, frozen mode, the JSON control channel, agent handoff, and bring-your-own media. - Building an emulator with AI coding agents
What 3,700 commits with Claude Code and Codex taught about crashes, tracing, negative results and shared trees.
Compared with other emulators
- Wine-Assembly vs v86
A whole PC that boots a Windows 98 image, against a Win32 layer that runs the program directly. - Wine-Assembly vs Boxedwine
Wine compiled to WebAssembly, against a Windows layer written in WebAssembly Text from scratch. - Wine-Assembly vs DOSBox and js-dos
DOS programs on an emulated PC, against Windows programs with no operating system; where the toy VM fits.