{"id":50927995,"url":"https://github.com/vgrichina/wine-assembly","last_synced_at":"2026-06-17T01:04:19.908Z","repository":{"id":354750133,"uuid":"1200317361","full_name":"vgrichina/wine-assembly","owner":"vgrichina","description":"x86 Windows 98 PE interpreter in raw WebAssembly Text (WAT)","archived":false,"fork":false,"pushed_at":"2026-06-11T05:14:20.000Z","size":13042,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T07:11:48.511Z","etag":null,"topics":["emulators","webassembly","wine"],"latest_commit_sha":null,"homepage":"https://wine-assembly.berrry.app","language":"WebAssembly","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vgrichina.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-03T09:16:25.000Z","updated_at":"2026-06-11T05:14:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/vgrichina/wine-assembly","commit_stats":null,"previous_names":["vgrichina/wine-assembly"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vgrichina/wine-assembly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fwine-assembly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fwine-assembly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fwine-assembly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fwine-assembly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vgrichina","download_url":"https://codeload.github.com/vgrichina/wine-assembly/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fwine-assembly/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34429501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["emulators","webassembly","wine"],"created_at":"2026-06-17T01:04:19.200Z","updated_at":"2026-06-17T01:04:19.899Z","avatar_url":"https://github.com/vgrichina.png","language":"WebAssembly","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Wine-Assembly\n\nRun real Windows 98 executables in your browser. No emulation layer, no porting — just raw WebAssembly interpreting x86 machine code.\n\n\u003ca href=\"https://www.producthunt.com/products/wine-assembly?embed=true\u0026amp;utm_source=badge-featured\u0026amp;utm_medium=badge\u0026amp;utm_campaign=badge-wine-assembly\" target=\"_blank\" rel=\"noopener noreferrer\"\u003e\u003cimg alt=\"Wine Assembly - Run Windows apps securely in browser using WebAssembly | Product Hunt\" width=\"250\" height=\"54\" src=\"https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1142094\u0026amp;theme=light\u0026amp;t=1778312100355\"\u003e\u003c/a\u003e\n\n**Live demo:** https://wine-assembly.berrry.app  \n**Project story:** [PROJECT_STORY.md](PROJECT_STORY.md) — a retrospective of the first ~810 commits in 34 days.\n\nWine-Assembly is an x86 PE interpreter written entirely in hand-crafted WebAssembly Text (WAT). It loads unmodified Win32 `.exe` files, decodes x86 instructions into a Forth-style threaded code representation, and executes them while reimplementing the Win32 API surface needed by each application.\n\n## What Works\n\n- **Notepad** — full text editing, menus, help system\n- **Calculator** — standard and scientific modes\n- **Solitaire, FreeCell** — card games with full GDI rendering\n- **Minesweeper** — both Win98 and XP versions\n- **SkiFree** — sprite animation, timer-driven gameplay\n- **Paint** — basic drawing (NT version via MFC42/MSVCRT DLL loading)\n- **Entertainment Pack** — Golf, Reversi, Pegged, Taipei, TicTactics, Rattler Race\n- **Space Cadet Pinball** — playable, table renders and physics run\n- **Winamp 2.95** — skinned UI, MP3 decode in flight (multi-thread)\n- **Plus! 98 screensavers** — Marbles (DirectDraw 8bpp), Organic Art (D3D Retained Mode in progress)\n- **MFC apps** — via real msvcrt.dll + mfc42u.dll loaded with relocations\n\n## How It Works\n\n1. **PE Loading** — Parses the PE header, maps sections into WASM linear memory, resolves imports via an FNV-1a hash table mapping API names to handler IDs.\n\n2. **x86 Decoding** — Each basic block of x86 code is decoded into a sequence of `(opcode, operand)` pairs stored in a threaded code cache. The `$next` function dispatches opcodes through an indirect call table.\n\n3. **Lazy Flags** — Instead of computing CPU flags after every instruction, the operands and operation type are saved. Flags are computed on-demand only when actually read (e.g., by a conditional jump).\n\n4. **Win32 API** — Each imported API function is replaced with a thunk. When execution reaches a thunk, a `br_table` dispatches to the corresponding hand-written WAT handler that reimplements the API behavior.\n\n5. **GDI Rendering** — Drawing commands (`TextOut`, `BitBlt`, `FillRect`, etc.) are forwarded to a JS canvas renderer that reproduces the Win98 look and feel, including 3D button borders, window chrome, and menu rendering.\n\n6. **DLL Support** — Real Win32 DLLs (msvcrt.dll, mfc42u.dll) can be loaded with full relocation and import patching, enabling MFC applications.\n\n## Quick Start\n\n### Browser\n\n```bash\nbash tools/build.sh\npython3 -m http.server 8080\n# Open http://localhost:8080/index.html\n```\n\nSelect an application from the dropdown and click Launch.\n\nOn iPhone/iPad, open the live demo in Safari and use **Share → Add to Home Screen** to launch it as a standalone web app without Safari tabs/address bar. Touch input is mapped to the Win98 mouse, and text input uses a hidden keyboard proxy so the iOS software keyboard can type into canvas-backed controls like Notepad.\n\n### CLI\n\n```bash\nnode test/run.js --exe=test/binaries/notepad.exe\n```\n\nKey flags:\n- `--trace-api` — log all Win32 API calls\n- `--png=output.png` — render final frame to PNG\n- `--max-batches=N` — limit execution steps\n- `--break=0xADDR` — break at x86 address\n- `--break-api=Name` — break on API call\n- `--verbose` — detailed logging\n\n## Building\n\nRequires Node.js. The project uses its own JS WAT compiler (`lib/compile-wat.js`) and writes both tail-call and compatibility WASM builds.\n\n```bash\n# Build\nbash tools/build.sh\n```\n\nThe build checks the handler table, concatenates `src/*.wat` in filename order for inspection, then compiles `build/wine-assembly.wasm` and `build/wine-assembly.compat.wasm`.\n\n## Architecture\n\nThe entire interpreter is written in WAT (WebAssembly Text Format) — no C, no Rust, no compiler toolchain. The host environment (browser or Node.js) provides:\n\n- Canvas rendering (GDI operations)\n- File I/O (reading executables, help files, DLLs)\n- Input handling (keyboard, mouse, touch, and mobile software-keyboard proxy)\n- Timer management\n\nEverything else — x86 decoding, memory management, PE loading, Win32 API implementation, structured exception handling, sprintf — is implemented in ~48,000 lines of hand-written WAT, compiling to a ~230 KB `.wasm` module.\n\n## Project Structure\n\n```\nsrc/                WAT source files (compiled in filename order)\nsrc/api_table.json  Win32 API name -\u003e handler ID mapping\nlib/                JS libraries (renderer, resource parser, DLL loader)\nindex.html, host.js Browser frontend\nmanifest.webmanifest, icons/\n                    PWA/iOS Home Screen metadata and icons\ntest/               CLI test runner and test binaries\ntools/              Build scripts, code generators, debug tools\ndocs/               Memory map, design notes\napps/               Per-app reverse-engineering progress (pinball.md, screensavers.md, ...)\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgrichina%2Fwine-assembly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvgrichina%2Fwine-assembly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgrichina%2Fwine-assembly/lists"}