Skip to content

NES emulator written in C and targeted for Linux. Support for other OSes via CMake.

License

Notifications You must be signed in to change notification settings

jc-SpaceXp/cNES

Repository files navigation

What is cNES

cNES is the result of me wanting to get more experience with C and to work on some sort of computer architecture project. I settled on the NES due to the extensive documentation, especially that of the CPU and the meduim article by fogleman. There is already a plethora of NES projects online, so I wanted to make this project mine. I didn’t want to abandon the project or copy code, like many other NES emulators hosted online. It’s been a challenge so far, the result is an emulator that isn’t perfect but one that I’m proud of!

Screenshots

screens/donkey_kong.png screens/zelda_1.png screens/super_mario_bros.png screens/megaman2.png

Building cNES

cNES supports multiple OSes via CMake or can be built using Make on Linux. I primarily develop on Linux however cNES can be ported over to other platforms via CMake.

Prerequisites:

  • CMake (or Make for older builds) (with CMake SDL and libcheck can be downloaded and built from source if not present on your machine)
  • gcc or clang compilers (or any compiler supported by CMake)
    • gcc versions >= 4.8 or clang versions >= 3.1 are required to use the address sanitizer compile option (ASan)
  • libcheck (currently unit tests are always run when compiling cNES)
  • SDL2

With the prerequisites satisfied, it is as simple as:

# New cmake preset builds (see CMakePresets.json)
$ cmake --preset release

$ cmake --build --preset release

# OLD MAKE BUILDS
# Build cnes
$ make

# Build cnes (option 2)
$ make all

# Build cnes and clean previous build
$ make clean all

# For developers:
# Build cnes debug version, contains debug symbols (useful for GDB)
$ make DEBUG=1

# Build cnes with ASan enabled
$ make DEBUG=1 ASAN=1

# Build cnes using a specific compiler (gcc by default)
$ make CC=gcc

# Build cnes using a specific compiler (clang)
$ make CC=clang

# Can also enable debug and ASan options with a compiler option too
$ make CC=clang DEBUG=1 ASAN=1

For CMake: the compiled binary will end up in ./build/<PRESET_NAME>

For Make: the compiled binary will either end up in ./build/release/bin/ or ./build/debug/bin/

Running cNES

# Most common use case, opening a nes game/file with the correct build path
$ ./build/release/bin/cnes -o FILE

# Simplifying the path to the cnes binary, future examples will use this shortened notation (real path is likely above)
$ ./cnes -o FILE

# cnes usage, listing all the command-line options available to cnes
$ ./cnes -h

USAGE: cnes [options]
OPTIONS:
        -h
        Shows all the possible command-line options

        -l
        Enable logging to a file

        -s
        Suppress logging to file or terminal

        -o FILE
        Open the provided file

        -c CYCLES
        Run the CPU up to the specified number of cycles

        -u UI_SCALE_FACTOR
        Scaling factor (integer) to be applied to the displayed output

Controls:

Player 1

KeyboardNES
MA
NB
QSelect
EStart
WUp
SDown
ALeft
DRight

Supported mappers

  • NROM (mapper 0)
  • MMC1 (mapper 1)

Test ROMS

Here is a place to find a source of legal (test) ROMS: https://wiki.nesdev.com/w/index.php/Emulator_tests

Missing Features

  • No controller support for player 2
  • No audio
  • Only supports the NTSC region so far (no PAL)
  • Limited mapper support, see above

License

cNES is zlib licensed, as found in the LICENSE file.

Acknowledgments

https://github.com/mwpenny/pureNES

http://emulator101.com/

https://medium.com/@fogleman/i-made-an-nes-emulator-here-s-what-i-learned-about-the-original-nintendo-2e078c9b28fe

http://www.dustmop.io/blog/2015/04/28/nes-graphics-part-1/

https://opcode-defined.quora.com/

http://www.fceux.com/web/help/fceux.html?PPU.html

https://www.dwheeler.com/6502/oneelkruns/asm1step.html

https://github.com/paramsingh/gameboi

At a certain point I understood how the NES PPU worked but I was unable to put this thinking into code (in terms of how to use SDL2 to display the PPU output). This project massively helped me because it served as a readable reference on how to add SDL2 into my project.

https://github.com/mwillsey/NES

Again, this project was crucial in generating my first iteration of my PPU rendering. I understood how the background was rendered. For an easy first attempt at rendering I tried to implement the drawing of a fixed nametable (no scrolling) i.e. starting from $2000, like what the title screen of Donkey Kong does. An important landmark for cNES as this guided me in generating my first visual output.

https://github.com/SourMesen/Mesen

I wouldn’t of made so much progress on my PPU and CPU without the amazing debugging qualities of Mesen. It is a great emulator! Several times I’ve consulted their source code to better my understanding of how to successfully emulate the NES.

About

NES emulator written in C and targeted for Linux. Support for other OSes via CMake.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages