Skip to content

NES emulator written in C and targeted for Linux.

License

Notifications You must be signed in to change notification settings

jc-SpaceXp/cNES

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 is built using make on Linux. It could also be built using the Windows Subsytem for Linux (WSL) on newer builds of Windows (10 and above).

Prerequisites:

  • make
  • gcc or clang compilers
    • 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:

# 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

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.