Research-quality static recompilation framework for the Super Nintendo / Super Famicom.
Input: a standard .sfc SNES ROM
Output: a portable C11 project whose generated code executes the game on the host CPU
Byte-identical output is not a goal. 100% functional compatibility is.
- True static recompilation — not a JIT, not a dynamic translator, not an interpreter for game CPUs
- Every instruction-stream processor becomes native C in the end (65816, SPC700, coprocessors)
- PPU, DSP mix path, DMA/HDMA, carts, and the scheduler remain hardware implementations
- CPU interpreters exist only as temporary verify-build oracles, never in release architecture
- Correctness first, maintainability second, performance third
Beyond accurate single-player execution, desktop builds aim to:
- Import user-owned
.sfc/.smcfiles (ROMs are never redistributed) - Invite Steam friends (lobbies / overlay), using SpaceWar (App ID 480) during development
- Offer Steam Remote Play for streamed sessions
- Offer synced P2P netplay where peers run the game locally and stay aligned via input lockstep plus WRAM/state checksums and occasional snapshot resync (SNES state is small enough for low-latency recovery)
Steam code stays in platform/steam/; the runtime only exposes snapshot/checksum APIs. See ADR-005.
Support agent-assisted game-specific patches and mods via a live connection to a running session:
- Optional runtime debug bridge (pause, frame-step, memory/register R/W, snapshots)
- MCP server (host-side) so Cursor and other agents can drive that bridge
- Patch apply at safe boundaries; reuse traces/snapshots from the verification ladder
Runtime stays free of MCP dependencies. See ADR-006.
| Path | Role |
|---|---|
frontend/ |
Python: ROM loading, mapping, symbols |
analysis/ |
Python: CFG, M/X, jump tables, data/code |
recompiler/ |
Python: translation and C emission |
runtime/ |
C11: scheduler, bus, DMA, PPU, SPC hardware, IRQ, snapshots |
platform/ |
SDL3 desktop, Steam (stub), RP2040 (later) |
generated/ |
Emitted C (local; usually gitignored) |
tools/verify/ |
Trace diff, frame/audio compare harnesses |
tools/extract_spc/ |
ARAM / SPC image capture for static SPC recomp |
docs/ |
ADRs, hardware notes, verification docs |
Generated code depends on the runtime. The runtime never depends on generated code.
# Python host tools
python -m venv .venv
# Windows: .venv\Scripts\activate
pip install -r requirements.txt
# Disassemble / emit a tiny C stub from a local ROM
python -m recompiler --rom path/to/game.sfc --out generated/
# Load .sfc/.smc → recompile → run N frames → JSONL + report
python tools/run_rom.py --rom path/to/game.sfc --frames 2
# Community 65816 test ROM (gilyon/snes-tests cputest-basic)
python tools/run_cputest.py --frames 2
# Playable MVP (SDL3 window + keyboard/gamepad → $4218)
python tools/run_play.py
# Kirby Super Star local gate (ROM in tests/roms/local/, gitignored)
python tools/run_kirby.py
# Build runtime (CMake 3.20+)
cmake -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build buildOptional verify (shadow lockstep) build:
cmake -B build -DSNESN_VERIFY_SHADOW=ON
cmake --build buildStart here:
- ADR-001 Timing / scheduler
- ADR-002 Toolchain split
- ADR-003 Native CPUs and oracles
- ADR-004 Verification ladder
- ADR-005 Steam networking
- ADR-006 Live debug MCP
- Credits / accuracy hierarchy — bsnes primary, MiSTer secondary gold
- MiSTer RTL contract bridge (
python -m tools.verify.mister check) - Control flow and M/X
Phase 2 — system silicon. DMA/HDMA, BG1 renderer, frame hashes, SPC image recomp emitter, Layer 1 trace export/diff.
python tools/regen_cpu_smoke.py
cmake -B build -DSNESN_BUILD_TESTS=ON
cmake --build build --config Debug
ctest --test-dir build -C Debug --output-on-failureSee LICENSE (to be chosen by the project owner). Copyrighted ROMs and commercial game assets must not be committed to this repository.