An accuracy-first SEGA Saturn emulator in Rust.
The Saturn is one of the hardest 5th-gen consoles to emulate — eight processors with tightly-coupled timing (2× SH-2 SH7604, MC68EC000, VDP1, VDP2, SCU + SCU-DSP, SCSP M68k + SCSP-DSP, SH-1 CD-block) on a shared bus. Performance is explicitly subordinated to fidelity: this project will never include a JIT, dynarec, or any "approximate cycle" shortcut. Each chip is built up one milestone at a time so the foundation stays solid.
| Milestone | Goal | State |
|---|---|---|
| M1 | Cycle-accurate SH-2 (SH7604) core | ✅ complete |
| M2 | Saturn bus, dual SH-2, event-driven scheduler | ✅ complete |
| M3 | SCU, SMPC, VDP2 minimal, SCU-DSP, SDL window (scaffolding) | ✅ complete |
| M4 | BIOS splash on screen | ✅ complete |
| M5 | Chip-coverage build-out — VDP1, MC68EC000, full VDP2 | ✅ complete |
| M6 | SCSP audio — slot/FM engine + SCSP-DSP | ✅ complete |
| M7 | CD-block (HLE) + disc recognition + cartridge slot | ✅ complete |
| M8 | Save states + battery-backed backup RAM | ✅ complete |
| M9 | Frontend OSD (in-window menu) | ✅ complete |
| M10 | Live physical disc + CD audio | ✅ complete |
| M11 | Boot a commercial game to gameplay | ✅ complete |
| M12 | Whole-system cycle accuracy vs the reference emulator | ✅ complete |
| M13 | Hardware completeness & fidelity-gap backlog | 📋 in progress |
What works today: a real Saturn BIOS boots to its splash screen, and the following commercial games are fully playable on the real-BIOS LLE path:
- Virtua Fighter 2 — steady 60 fps, full 3D fights with CD music and sound effects.
- Doukyuusei
if— graphics, sound effects, and voices, including Shuttle Mouse support, at native 640×224 hi-res. - Sangokushi V (三國志V) — Koei's strategy title, from its per-scenario opening movie through to the in-game strategy map.
- Panzer Dragoon Zwei — from its opening Cinepak movie through the title and menus into the game, at native 704×448 hi-res.
- Greatest Nine '98 — the baseball game, at native 704×480 interlaced resolution (VDP1 field-weave).
- Super Robot Wars F and F Final (スーパーロボット大戦F / F完結編) — Banpresto's mecha tactical RPGs, from the scenario-intro movies through the strategy map into the combat animations with XA-ADPCM audio.
Games load from disc images (CUE/BIN, ISO, CloneCD) or straight from an original disc in a host optical drive; save states, the console's battery-backed save memory, expansion cartridges, and an in-window menu (Esc — save slots, controller rebinding, region/cartridge/BIOS switching, all persisted to a config file) are all in place.
Task-by-task technical status lives in doc/roadmap.md, and
the per-title compatibility list in
doc/compatible-game-titles.md.
v0.20.0 demo video — click the thumbnail to watch on YouTube.
5thPlanet v0.20.0 demo: Virtua Fighter 2 — click the thumbnail to watch on YouTube.
A few frames from the emulator running commercial games on the real-BIOS LLE
path. The full set — including the optional CRT shader and the in-window menu —
is in doc/screenshots/.
The screenshots show SEGA's and other rights holders' copyrighted material and are included solely to document the emulator's output — see Trademarks & copyrights.
# Build & test everything
cargo test --workspace
# Format + lint (both are gates; the workspace follows standard rustfmt)
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
# Coverage (~85% line, excluding the SDL3 frontend + FFI crate)
cargo llvm-cov --workspace --summary-only
# Run a single test
cargo test -p sh2 -- decoder::tests::decodes_branches
# SDL3 frontend (default-on `sdl-frontend` feature): opens a window and
# runs the supplied BIOS. Use --no-default-features for a headless run.
# --backend=opengl|metal|direct3d11|software (default: auto) picks how the
# frame is presented; the picture itself is always rendered in software.
cargo run -p jupiter -- "bios/Sega Saturn BIOS (USA).bin"
# Optional: an SDL_GPU/Vulkan presenter with a built-in CRT-filter shader
# (scanlines + aperture mask), behind a build feature + off by default. Enable
# with `--gpu=on` and pick it in the OSD (Settings -> Graphics -> Shaders -> CRT):
cargo run -p jupiter --features gpu-presenter -- --gpu=on "bios/Sega Saturn BIOS (USA).bin"
# Built-in self-diagnostics (no window): exits 0 if all checks pass.
# Add a BIOS (+ disc) to also run boot/compatibility checks.
cargo run -p jupiter -- doctor
# Optional: build a faster release binary with Profile-Guided Optimization.
# Same accuracy (it only changes code layout, not behaviour) but a markedly
# faster emulation core. Needs a BIOS + a game disc in roms/ to train on;
# without them it just falls back to a plain release build.
tools/pgo/build_release.sh # -> target/release/jupiterThe SDL3 frontend maps the host keyboard and any attached game controller to the two Saturn controller ports. Each port can be assigned a device — keyboard, a specific game controller (by identity, so two pads work side-by-side), or the Shuttle Mouse — from Esc → Settings → Controller (the default is the keyboard on port 1). The analog 3D Control Pad is emulated too: assign a controller as a 3D pad to feed its stick and analog triggers. Controllers hot-plug at any time (SDL's GameController layer — XInput on Windows, evdev on Linux — so Xbox-style pads just work) and can also navigate the menu (D-pad + A/B, Start toggles).
| Saturn button | Keyboard | Game controller |
|---|---|---|
| D-pad ↑ ↓ ← → | Arrow keys | D-pad or left stick |
| A / B / C | Z / X / C | X / A / B |
| X / Y / Z | A / S / D | Y / LB / RB |
| L / R | Q / W | LT / RT |
| Start | Enter | Start |
Both maps are fully rebindable from Settings → Controller (the keyboard map, and the per-button gamepad map via Gamepad Buttons…, press-to-bind); the bindings persist in the config file. The defaults above follow Sega's own layout from their Xbox Saturn ports.
Plug Sega's Saturn mouse into port 2 (--mouse, keeping the keyboard pad
on port 1) or port 1 (--mouse=1, replacing the pad) for games that
support it — e.g. Doukyuusei if. The host pointer is captured and hidden
while playing (the game draws its own cursor); host Left/Right/Middle clicks
map to the mouse buttons and Enter doubles as the mouse's Start button.
| Action | Key |
|---|---|
| Toggle pointer capture (free the cursor) | F10 |
| Release the pointer (menu open) | Esc |
| Action | Key |
|---|---|
| Open / close the on-screen menu | Esc |
| Quick save (to the quick slot) | F5 |
| Quick load (from the quick slot) | F9 |
| Toggle Shuttle Mouse capture | F10 (with --mouse) |
| Toggle fullscreen | F11 |
| Fullscreen aspect (keep ratio / fit screen) | F12 |
| Quit | Close the window, or Esc → Quit |
| Action | Key |
|---|---|
| Move selection | ↑ / ↓ |
| Select | Enter or Z |
| Back (closes the menu at top level) | Backspace or X |
| Close menu | Esc |
crates/sh2— cycle-accurate SH-2 (SH7604) CPU core.no_std+alloc, no I/O.crates/m68k— MC68EC000 core (the Saturn's SCSP sound CPU).no_std+alloc, library-shaped likesh2.crates/scu_dsp— SCU's embedded 32-bit DSP.crates/saturn— Saturn system glue: memory map, dual SH-2 scheduler, SMPC, SCU + DMA + interrupt aggregator, VDP1 (full sprite/polygon plotter), VDP2 (multi-layer NBG/RBG compositor with rotation + live raster timing), SCSP (slot/FM audio engine + hosted MC68EC000 + SCSP-DSP), the CD-block (HLE: disc image + TOC, buffer/filter/partition, read pump + transfer, ISO9660 FS, authentication), and the cartridge slot (Extension DRAM / backup-RAM / ROM carts).crates/physdisc— live optical-driveSectorSourcevia libcdio, feature-gated (libcdio); the only crate that usesunsafe(FFI). Default build is a stub.crates/debugger— interactive headless Saturn debugger (binsdbg): a gdb-style REPL over the core with breakpoints (incl. register-guarded), single-step, SH-2 and SCSP-68k disassembly + PC-trace, read/write watchpoints, memory search, CD-block + SCSP/68k state, command history, and save-state rewind.cargo run -p sdbg -- <bios.bin> [disc.cue].jupiter— SDL3 frontend binary (window + framebuffer upload + audio, or headless), behind a default-on feature. Includes the hand-rolled in-window OSD menu (src/osd/, Esc to open) and the persisted config file (src/config.rs) — ajupiter.tomlbeside the executable (portable install) takes precedence, else$XDG_CONFIG_HOME/5thplanet/jupiter.toml; seejupiter/jupiter.toml.example.cargo run -p jupiter -- <bios.bin> [disc.cue]. (The binary is namedjupiterfor Jupiter — the 5th planet, hence the project name 5thPlanet — the neighbour of Saturn: closest to it, but not identical.)
SEGA Saturn BIOS images go in bios/ and are never committed —
they're copyrighted by SEGA and each developer supplies their own
legally-obtained dump. See bios/README.md for the
expected filenames and rationale.
The repository ships with project-tailored Claude Code skills under
.claude/skills/ (code-review,
commit-and-push, docs-engineering, release-engineering,
security-audit). CLAUDE.md documents the architecture
in depth and the conventions a contributor needs to follow. The
Saturn-specific vocabulary used throughout the codebase and commits
is collected in doc/glossary.md, and significant
design decisions and their rationale are recorded as Architecture
Decision Records in doc/adr/. For how the Saturn hardware
maps onto this project's crates and modules, see
doc/system-architecture.md.
Three open-source emulators serve as behavioral references: local builds are run against the same BIOS and games so their behavior can be compared with ours, instruction by instruction where needed.
- Mednafen — the accuracy reference for game-level behavior, and the primary oracle for the game-boot and cycle-accuracy work.
- MAME — the low-level / early-boot reference for CPU, bus, and peripheral behavior.
- Yabause — the secondary reference, and the primary one during early development.
Each is set up as a local, never-committed build (gitignored
mednaref/, mameref/, yabref/). No emulator code is included in or
derived by this project — they serve purely as behavioral references for
cross-checking; each is GPL-licensed and remains entirely separate from
5thPlanet's MIT-licensed source.
5thPlanet is an independent, unofficial project and is not affiliated with, endorsed by, or sponsored by SEGA. "SEGA", "Sega Saturn", and the Sega Saturn logos are trademarks of their respective owners (SEGA Corporation and/or its affiliates). They are referenced here only for identification and interoperability — to describe the hardware this emulator targets.
The Sega Saturn BIOS, games, and any disc images are copyrighted by their
respective owners and are not distributed with this project (see
BIOS); supply your own legally-obtained copies. The screenshots in
doc/screenshots/ show SEGA's copyrighted boot logos and are
included solely to document the emulator's output.
No SEGA code, firmware, or assets are included in or derived by this project; it is a clean-room behavioral re-implementation cross-checked against the reference emulators. Only the original source in this repository is covered by the licence below.
MIT — see LICENSE. This licence applies to 5thPlanet's own source
code only, not to any third-party trademarks or copyrighted material referenced
above.











