A (reasonably) accurate NES emulator with support for NROM/MMC3 games. Only runs on Linux with Vulkan-supported hardware.
NOTE: Game compatibility remains low. Only mappers 0 and 4 are supported, and ROM parsing is limited to INES-1.0. As of writing, many of the more obscure INES-header flags are simply ignored (including the presence of a trainer). Conveniences like user interface or interactive debugging have also not been prioritized - the primary focus of the project has been on the emulator core itself. Stability has likewise been low-priority, with me pushing directly to master and breaking things every other commit. Hopefully, however, the project can still serve as guidance for people wishing to make similar programs in Rust.
- mapper 0 and 4 support
- simple save states
- nearly cycle accurate (but not cycle-steppable) CPU emulation, including dummy reads/writes
- almost 8-cycle accurate PPU emulation
- low level emulation of MMC3 IRQ counter behavior
- APU emulation
- cycle accurate CPU NMI/IRQ polling
- dummy PPU nametable fetches at dots 337-340
.. and tons more
- instr_test_v5
- 01-basics
- 02-implied
- 03-09 (unofficial opcodes aren't supported yet)
- 10-branches
- 11-stack
- 12-jmp_jsr
- 13-rts
- 14-rti
- 15-brk
- 16-special
- instr_misc
- 01-abs_x_wrap
- 02-branch_wrap
- 03-dummy_reads
- 04-dummy_reads_apu (no apu emulation)
- instr_timing
- 1-instr_timing (no apu emulation)
- 2-branch_timing (no apu emulation)
- cpu_timing_test6
- branch_timing_tests
- 1.Branch_Basics.nes
- 2.Backward_Branch.nes
- 3.Forward_Branch.nes
- ppu_vbl_nmi
- 01-vbl_basics
- 02-vbl_set_time
- 03-vbl_clear_time
- 04-nmi_control
- 05-nmi_timing (no cycle accurate nmi polling)
- 06-nmi_suppression
- 07-nmi_on_timing (fails for unknown reasons - many other emulators seem to struggle with this one)
- 08-nmi_off_timing
- 09-even_odd_frames
- 10-even_odd_timing (ppu cycle inaccuracies)
- ppu_sprite_overflow
- 01-basics
- 02-details
- 03-timing (fails for reasons i've yet to investigate)
- 04-obscure
- 05 (haven't investigated this either)
- mmc3_test_2
- 1-clocking
- 2-details
- 3-A12_clocking
- 4-scanline_timing (ppu cycle inaccuracies)
- 5-MMC3
- 6-MMC3 (only newer MMC3 revisions are supported - both test 5 and 6 cannot pass at once)
to install, simply:
cargo install --path emulator/
run with:
nees [rom]
optionally:
nees [rom] --save [path/to/save/file]
Up/down/left/right are bound to WASD, A is bound to space, B is Shift, Select is F, and Start is Tab. Emulation can be paused by pressing Esc, stopped by pressing Ctrl+Q and saved by pressing P. Keybinds are currently not configurable (short of editing the source code).
libxcb
libxcb-keysyms
xcb-util
Vulkan SDK
cargo
.. and related dev headers