Skip to content

Latest commit

 

History

242 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sisyphus

A flash cartridge prototype for the Nintendo Entertainment System (NES) using FPGA-based hardware emulation. Sisyphus plugs into the NES cartridge slot and replaces a standard game cartridge, executing NES 2.0 ROM files loaded from an SD card.

Sisyphus physical assembly

The system runs on a Digilent ZedBoard (AMD Zynq-7000 SoC), which combines an ARM Cortex-A9 processor with an Artix-7 FPGA on a single chip. The ARM core (PS) handles all non-timing-critical tasks — mounting the SD card, parsing ROM headers, and loading game data — while the FPGA fabric (PL) handles all real-time cartridge emulation logic.

Mapper reconfigurability is achieved via Dynamic Function eXchange (DFX), which allows the PL to swap the active mapper partial bitstream at runtime without resetting the full design. Currently implemented mappers: NROM (mapper 0), UxROM (mapper 2), and SxROM/MMC1 (mapper 1). NROM has been validated on PAL hardware; UxROM and MMC1 are fully implemented but were not testable due to a hardware fault in the debug card.

Super Mario Bros. Ice Climber
Super Mario Bros. gameplay Ice Climber gameplay

Note: Both titles exhibit minor graphical glitches and consistently freeze or crash during gameplay. Small variations in the cartridge connector insertion angle frequently cause the CPU to halt immediately after reset via a JAM instruction — a known signal integrity limitation of the perfboard assembly. Donkey Kong (also NROM) runs more stably and rarely crashes.

See docs/bachelors-thesis.pdf for the full project report.

Prerequisites

The project uses the Xilinx Vivado and Vitis toolchains. See Digilent's installation guide for the ZedBoard here. Version 2025.2 is required. Manually add them to your path by running:

source /path/to/Xilinx/Vivado/2025.2/settings64.sh && source /path/to/Xilinx/Vitis/2025.2/settings64.sh

Additionally, other tools used for development are managed through the flake.nix flake. To utalize it, make sure to have the Nix package manager installed. In the repository root directory, run the flake via:

nix develop .

Build

The build is split between hardware and software. Both subdirectories have their own Makefile and README.md with detailed instructions. See which targets are available by running:

make -C hw/fpga help
make -C sw help

The software build pipline is fully automated by running make -C sw all. However, the hardware currently requires you to generate a Vivado project via make -C hw/fpga edit and manually generete the .XSA hardware handoff. This must be done before building the software.

See hw/README.md and sw/README.md for the full build flows.

Usage

If you want to run Sisyphus you're out of luck. It requires a converter board from the ZedBoard's FMC LPC connector to the NES cartridge connector. During development, this was achieved using an AMD FMC XM105 Debug Card together with a DIY perfboard (see image above). Naturally, developing a PCB is on the todo list.

Regardless, after building the software and hardware, the generated BOOT.BIN file together with all mapper partial bitstreams (exported as binary files) must be placed on an FAT32 formatted SD card and inserted into the ZedBoard. The mapper partial bitstreams must follow the naming convention <mapper_name>_p.bin. Alternatively, its possible to run over JTAG by execution make -C sw run. However, the mapper partial bitstreams must still be present on the SD card.

Your ROM must also be present on the SD card. Sisyphus currently does not support switching between games, it will simply use the first file encountered.

Project Structure

sisyphus/
├── .env                        # Shared build configuration 
├── scripts/
│   └── shared.tcl              # Shared Tcl utilities
├── hw/                         # FPGA PL design and physical hardware (see hw/README.md)
│   ├── fpga/                   # Vivado block design + RTL
│   ├── cic/                    # CIC lockout bypass firmware for ATtiny13A
│   ├── perfboard/              # Perfboard layout for SN74LVC245A level shifters
│   └── schematic/              # KiCad schematic for the interface board
├── sw/                         # ARM bare-metal software — Vitis (see sw/README.md)
├── docs/
│   └── bachelors-thesis.pdf    # Full project report
├── images/                     # Photos and screenshots
├── tests/
│   └── cc-validation/          # Cartridge connector signal integrity validation tests
└── flake.nix                   # Nix development environment

NOTE: The tests/cc-validation directory is a remnent of the development process and should be removed/reworked. Currently, it contains a custom hardware design based on the NROM mapper and a family of test ROMs for verifying the connection between the NES and ZedBaord.

Future Work

  • BRAM cache backed by PS DDR: The ZedBoard's 630 KiB of BRAM is a hard constraint that limits how much ROM/CHR data can be live in the PL at once. A cache hierarchy where the ARM core evicts and refills BRAM pages from PS-side DDR would lift this limit and enable games with larger PRG/CHR banks without architectural changes to the mapper logic.
  • Custom mezzanine PCB: Replace the current perfboard + FMC XM105 debug card with a dedicated PCB that integrates the ZedBoard FMC LPC connector breakout and the NES cartridge edge connector on a single board, eliminating the signal integrity issues that currently cause intermittent JAM-instruction crashes.
  • NES soft core for development and debugging: Integrate an FPGA-based NES implementation (e.g. FPGA NES or similar) alongside the cartridge emulation logic so the full system — CPU, PPU, APU, and cartridge — can be co-simulated and debugged without requiring physical NES hardware.
  • Save state support: Add hardware-assisted save states by snapshotting the relevant mapper and RAM state from the PL into PS-side DDR (or SD card) at any point during gameplay, and restoring it on demand, similar to what commercial flash cartridges provide.
  • Embedded Lua scripting: Bundle a lightweight Lua interpreter in the ARM firmware to allow users to write scripts that interact with the running system — reading/writing memory, triggering save states, injecting inputs, or automating testing — providing a highly extensible user-facing scripting interface without requiring firmware rebuilds.
  • 10NES soft core: Implement the 10NES CIC lockout chip in the FPGA fabric, eliminating the need for a dedicated ATtiny13A on the PCB.

About

A flash cartridge prototype for the Nintendo Entertainment System (NES) using FPGA-based hardware emulation. Built on the Digilent ZedBoard, Sisyphus enables developers and hobbyists to interact with original NES hardware in new ways.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages