Skip to content

A basic NES emulator written in C++ using GLFW and SDL2 audio.

Notifications You must be signed in to change notification settings

kevinbchen/nes-emu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

nes-emu

nes-emu is a basic NES emulator written in C++ for fun / learning. Features:

  • Support for Mappers 0 to 4. Games that I've tested include Donkey Kong, Super Mario Bros 1 & 3, Mega Man 1 & 2, Metroid, The Legend of Zelda.
  • Visualizations of the PPU nametables, PPU pattern tables, and APU audio waveforms (using Dear ImGui for the UI).
  • APU implementation with dynamic rate control for sampling to keep audio in sync with the v-sync'd graphics.
  • Buildable for the web via emscripten.

See the Accuracy and TODO sections for details about limitations.

nes-emu

Building

The project builds using cmake:

mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ../ 
make

The GLFW and SDL2 dependencies will be automatically downloaded via FetchContent and don't require separate setup.

To build for web using emscripten:

mkdir web_build && cd web_build
emcmake cmake -DCMAKE_BUILD_TYPE=Release ../
emmake make

The project should be cross-platform for linux and mac too, though I've personally only tested building for Windows and the web.

Usage

To load a rom, simply drag-and-drop the file into the window.

The controls can be remapped, but the defaults are:

NES Keyboard Gamepad
DPAD Arrow keys DPAD
A Z A
B X B
Start Enter Start
Select Space Back

Accuracy

nes-emu is definitely not 100% accurate, though I did try to emulate certain details to a reasonable level.

The CPU implementation has a degree of sub-instruction level simulation, and can step the PPU and APU (via ppu.tick() and apu.tick()) at points within a single CPU instruction (though I don't know if this matters in practice for any games). I have verified that the CPU cycle counts are correct for the nestest rom tests.

The PPU implementation is per-pixel, so the pixel outputs should happen at (roughly) the correct cycle timings.

Some known inaccuracies:

  • [CPU] Only official instructions supported
  • [CPU] IRQ timing is off
  • [PPU] Memory reads for bg and sprites are not perfectly cycle accurate (and not all dummy reads are implemented)
  • [PPU] Sprite evaluation pipeline happens all at once at specific stages each scanline
  • [PPU] Sprite overflow bug isn't emulated
  • [PPU] Mapper 4 relies on a hacky end-of-scanline signal for the interrupt, instead of the actual PPU A12 line.
  • [APU] DMC doesn't emulate CPU stall

TODO

  • More mappers
  • Unofficial CPU instructions
  • Fix accuracy issues to pass all Blargg's NES tests
  • Save state
  • Additional debug visualizations (e.g. hex view of CPU and PPU memory)
  • TAS videos

References

There's a lot of great info on NES emulation out there, but some sources I found particularly useful:

About

A basic NES emulator written in C++ using GLFW and SDL2 audio.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages