Skip to content

Latest commit

 

History

History
159 lines (132 loc) · 4.4 KB

README.md

File metadata and controls

159 lines (132 loc) · 4.4 KB

NesDev Nintendo Entertainment System (NES) Developing Toolkits

License: GPL v3

Screenshot of Donkey Kong

Notice

This project is STILL EXPERIMENTAL and WIP. There are LOTS OF BUGS(01/24/2021).

Summary

Modern C++ NES developing toolkits for My Own Learning Porpose. The implementation is NOT fully faithfull to the original NES hardware though, but CPU instruction implementations are cycle accurate.

Things NOT faithfull to the original NES hardware so far (01/24/2021)

  1. PPU Foregound/Sprites Rendering In original NES hardware archetecture, sprite gathering, sprite clearing and sprite evaluation for the next scanline, natural on the digital circuit, these things are distributed in parallel, but in my implementation, these are embedded in the PPU cycle along with the background rendering. This may limit compatibility with some games.

Roadmap

The following is a checklist of features and their progress:

  • Console
    • NTSC
    • PAL
    • Dendy
    • Headless mode
  • CPU
    • Official Instructions
    • Unofficial Instructions
    • Interrupts
  • PPU
    • VRAM
    • Background
    • Sprites
    • NTSC TV Artifact Effects
    • Emphasize RGB/Grayscale
  • APU
    • Pulse Channels
    • Triangle Channels
    • Noise Channels
    • Delta Mulation Channel
  • Inputs
  • Memory
  • Cartridge
    • Battery-backed Save RAM
    • iNES Format
    • NES 2.0 Format
    • Mappers
      • NROM (Mapper 0)
      • SxROM/MMC1 (Mapper 1)
      • UxROM (Mapper 2)
      • CNROM (Mapper 3)
      • TxROM/MMC3 (Mapper 4)
      • ExROM/MMC5 (Mapper 5)
      • AxROM (Mapper 7)
      • PxROM/MMC2 (Mapper 9)
  • Testing/Debugging/Documentation
    • Unit/Integration tests
    • Test ROMs
    • Logging

Generating + Compiling

NesDev builds with CMake

On macOS / Linux

# in NesDev root
mkdir build
cd build
cmake ..
make
make install

Usage

NesDev library (libnesdev) is a static library for developing NES emulators, so libnesdev it self does NOT contain any media layer implementations. All you have to do is implememnt media backends with your favorite library, such as SDL2 and hook the NesDev's Framebuffer API for PPU and Sampling API for APU respectively.

#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <SDL.h>
#include <SDL_ttf.h>
#include <nesdev/core.h>
#include "backend.h"
#include "cli.h"
#include "utility.h"

namespace nc = nesdev::core;

int main(int argc, char** argv) {
  Utility::Init();
  CLI cli(argc, argv);

  std::string rom;
  if ((rom = std::filesystem::absolute(cli.Get("--rom"))).empty()) {
    std::cerr << "iNES file must be specified" << std::endl;
    exit(1);
  }

  try {
    std::ifstream ifs(rom, std::ifstream::binary);
    nc::NES nes(nc::ROMFactory::NROM(ifs));
    ifs.close();
    Utility::ShowHeader(nes);

    Backend sdl(nes, nes.controller_1.get(), nes.controller_2.get());
    nes.ppu->Framebuffer([&sdl](std::int16_t x, std::int16_t y, nc::ARGB rgba) {
      sdl.Pixel(x, y, rgba);
    });
    //nes->apu->Sampling([&sdl]() {
    //  /* This is a placeholder for APU API. */
    //});

    if (cli.Defined("--chr_rom")) {
      while (sdl.IsRunning()) {
	Utility::RenderCHRRom(nes, sdl);
	sdl.Update();
      }
    } else {
      while (sdl.IsRunning()) {
	nes.Tick();
	if (/*nes.cpu->IsIdle() &&*/ (nes.cycle % 3 == 0))
	  Utility::Trace(nes);
	if (nes.ppu->IsPostRenderLine() && nes.ppu->Cycle() == 0) {
	  sdl.Update();
	}
      }
    }
  } catch (const std::exception& e) {
    Utility::ShowStackTrace();
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

References

  1. NesDev
  2. Bisqwit's implementation
  3. Javidx9's series of NES emulator

Contributing

Contributions are more than welcome! Everything from code to examples and documentation are all equally valuable so please don't feel you can't contribute. To contribute please fork the project make your changes and submit a pull request. We will do our best to work through any issues with you and get your code merged into the main branch.