-
Notifications
You must be signed in to change notification settings - Fork 0
Cartridge and Coprocessors
References: docs/cart.md, docs/cartridge-format.md, docs/adr/0003 (the tiering honesty gate).
rustysnes-cart owns two jobs: the ROM/SRAM memory model (LoROM/HiROM/ExHiROM/ExLoROM) and the on-cart coprocessor families. Each coprocessor is a "mapper-equivalent" with its own bus window and (where the hardware has one) its own clock domain. Both are exposed through a Board trait with default-no-op hooks, so the CPU and PPU never special-case a specific cartridge.
| Model | $FFD5 |
Layout | Header offset | Max size |
|---|---|---|---|---|
| LoROM | $20 |
32 KiB windows in $8000-$FFFF of every bank |
$007FC0 |
4 MiB |
| HiROM | $21 |
64 KiB linear banks, full ROM at $C0-$FF
|
$00FFC0 |
4 MiB |
| ExHiROM | $25 |
>4 MiB: $80-$FF = first 4 MiB, $00-$7D = extra 4 MiB |
$40FFC0 |
~8 MiB |
| ExLoROM | — (unofficial) | LoROM extension for >4 MiB titles that keep the 32 KiB windowing | $407FC0 |
~8 MiB |
ExLoROM has no dedicated $FFD5 value — both ares and bsnes document it as unofficial, and real carts typically report plain LoROM's $20 there. RustySNES disambiguates it purely by header offset. Its decode formula was sourced directly from bsnes's own runtime board database rather than guessed, since no real ExLoROM ROM (commercial or homebrew) exists to validate against — see Architecture-Decision-Records and docs/cart.md §ExLoROM for the full provenance chain.
The single biggest economy in the coprocessor breadth is the shared µPD77C25 / µPD96050 engine (coproc::upd77c25): one clean-room LLE core, parameterized by chip revision, drives six different chips — DSP-1/1A/1B, DSP-2, DSP-3, DSP-4, and ST010/ST011.
| Chip | Core | Tier | Status |
|---|---|---|---|
| DSP-1/1A/1B | µPD77C25 | Core/Curated | Implemented — validated against real Super Mario Kart, Pilotwings, Super Bases Loaded 2, Aim for the Ace |
| Super FX / GSU-1/2 | Argonaut RISC | Core/Curated | Implemented — full RISC core, host-synced on the Go flag; validated by 58 Krom GSU test ROMs |
| SA-1 | second WDC 65C816 | Core/Curated | Implemented — validated against 18 commercial SA-1 carts (Super Mario RPG, both Kirby Super Star titles, PGA Tour 96, Power Rangers Zeo, and others) |
| DSP-2 / DSP-4 | µPD77C25 (shared) | BestEffort | Implemented — validated against real Dungeon Master (DSP-2) and Top Gear 3000 (DSP-4) |
| ST010 / ST011 | µPD96050 (shared) | BestEffort | Implemented — validated against real F1 ROC II |
| S-DD1 | Nintendo ASIC | BestEffort | Implemented — validated against real Star Ocean and Street Fighter Alpha 2 |
| CX4 | Hitachi HG51B169 | BestEffort/Curated | Implemented — validated against real Mega Man X2 and Mega Man X3 |
| OBC1 | simple ASIC | BestEffort | Implemented — validated against real Metal Combat: Falcon's Revenge |
| SPC7110 (+RTC-4513) | Hudson ASIC | BestEffort | Implemented, not yet booting to real content — the CPU runs into unmapped memory partway through boot on its one available commercial title; root cause not yet found |
| ST018 | ARMv3 | BestEffort | Not started |
| S-RTC (standalone) | Epson RTC | BestEffort | Not started (the underlying RTC-4513 core exists, wired only for SPC7110's paired chip so far) |
No chip-ROM dump is needed for Super FX, SA-1, S-DD1, SPC7110, or OBC1 — their programs live in the cartridge ROM itself, or (OBC1, S-DD1) the coprocessor has no program ROM at all. DSP-1/2/3/4, ST010/011, and CX4 need a user-supplied firmware dump (e.g. dsp1.rom, cx4.rom); the dump is never committed to the repository (docs/adr/0003), and without it the board is honestly non-functional rather than silently degraded.
Every board is tiered Core, Curated, or BestEffort (docs/adr/0003). A CI gate fails if any BestEffort board ever backs the accuracy oracle — a chip validated only against a single commercial title's boot screen, with no independent test-ROM corpus behind it, must never be presented as equivalent to a Core/Curated chip that clears a dedicated oracle suite. Nothing is silently degraded, and nothing under-validated is silently promoted either.
Real-time-clock coprocessors (S-RTC, SPC7110's paired RTC-4513) are the project's one deliberate determinism hazard — a live wall-clock read would break the "same seed + ROM + input → bit-identical output" contract (Architecture-Decision-Records, ADR 0004). Both are HLE, seeded to a frozen epoch, and never advance except by explicit register writes.
The internal header ($FFC0-$FFDF) is scored at each of the four candidate offsets above — checksum/complement summing to $FFFF is the strongest signal, followed by map-mode-byte plausibility, size/region plausibility, and reset-vector plausibility. See docs/cartridge-format.md for the full scoring rule and the copier-header (512-byte SMC prefix) handling.
- Testing-Strategy — how each board is validated, and what "BestEffort" actually means in practice.
-
Roadmap — which coprocessors are scheduled for
v0.4.0 "Completion"(the SPC7110 boot fix, ST018, standalone S-RTC). -
docs/cart.mdin the main repository — the authoritative spec this page summarizes, including the exact per-model ROM-offset formulas and the per-chip implementation notes.
RustySNES is a cycle-accurate Super Nintendo / Super Famicom emulator written in pure Rust. Licensed under MIT OR Apache-2.0. | GitHub Repository | Web Demo | API Docs