NES Emulator

Jeff Longo & Boning Dong - ECE 153B Winter 2018

Update 1 (2/21/19)

We have always wanted to write an NES emulator, so we decided on this for our project. We are designing a PCB to house the controller alongside with extra memory, an LCD display, a microSD card slot, and controller ports. In the future, we plan to revise the board to be a full handheld console, but that is out of the scope of the class.

I spent a week reading through the abundant MOS6502 CPU documentation and starting writing the CPU emulator in Python as a proof-of-concept. I tested the CPU on a custom .nes file which tests for correctness and after much debugging my emulator is successful for the majority of the tests. I did my best to document every addressing and mode and instruction, making each operation cycle-correct. Tests involving illegal opcodes I didn't worry about since they are only used by a few games and time is limited. After this success, I ported the code to C which will be put on the MCU.

Meanwhile, Boning has been hard at work designing the PCB in Altium. Mapping a 144 pin microcontroller and impedance matching traces to the external memory is an arduous task. We hope to finish and order the board this weekend.

The next steps will be implementing memory mappers, finishing and ordering the PCB, and spending more time researching the PPU (Picture Processing Unit).

The code is on Boning's GitHub. https://github.com/boningdong/Gamedude-Emulator


Update 2 (2/28/19)

We spent the majority of last week designing the PCBs necessary for the project. 4 layers later and many days of routing, we finished and ordered all the PCBs. We expect to have our boards by next weekend, after which we will populate and test the boards. Meanwhile, I have been working on writing mappers. A mapper essentially maps the NES address space to the external hardware inside a game cartridge. Game cartridges often store extra memory to essentially expand the RAM of the console, so mapping also involves handling bank switching. Different games use different mappers, which are defined in the header part of the game ROM. I implemented one of the simple but popular mappers to test later.

Boning has been researching the LCD that we bought and is learning the parallel interface to write a driver for it. I plan to research implementing the SD card reading using SPI. We hope to finish learning SD card interfacing and LCD drawing before the PCBs arrive.

Update 3 (3/7/19)

We received our PCBs today and started assembling them. After some troubleshooting, we got the MCU to accept code, meaning that the circuit works! We tested enabling the charge LED via GPIO to ensure we can execute code. We will assemble the rest of the board next, including the external memory, LCD, SD card slot, and controller modules.

The SD card driver has seen limited success. After reading all the documentation and implementing the low-level driver for FATFS, we are still encountering issues initializing the SD card. However, now that the board is working we are going to invest more time into solving this problem.

After we finish getting the SD card reading working, the final two things to do are to implement the PPU on our LCD and the controller via SPI. Boning wrote the extremely difficult driver for the LCD parallel interface and is able to draw to the screen. We just need to translate the ROM CHR data to the LCD's interface. As for the controller, our PCB has a shift register built in which will send the status of the buttons over a serial SPI connection.

Update 4 (3/15/19)

We are nearing the finish line with this project. The SD card driver is finally complete, and the remaining PCBs have been assembled. The CPU and mappers have been ported to the MCU. Currently I am working on using SPI and our on-board shift register to retrieve the button states for the game controller. Boning is implementing the PPU and translating ROM video data to the display driver.

Update 5 (3/20/19)

After a grueling all nighter, we have reached the end of our project. All the hardware and low level drivers successfully work on our board, however we spent hours debugging the emulator without success. The CPU executes the correct instructions, but the translation of the graphics data to the display has not worked properly. We intend to fix it during the break. The unfortunate effect of all the low level code working is that there is a huge amount of success under the hood but nothing directly visible to the end user. To showcase our hardware, we decided to write our own game to run on the system. This game involves moving a paddle to bounce a ball. The difficulty scales over time. The game utilizes our integrated SPI controller, draws to the screen using our 16-bit parallel interface, and runs off microUSB with our newly added power management system.

We are disappointed we couldn't finish the emulator in time, but we knew from the start this is a years' worth of work to do in 3 months on top of other classes. However we are satisfied that our hardware and drivers work well and give us platform to develop on in the future. In the end we have:

  • A fully functional development board
  • Multiple SPI interfaces working simultaneously
  • 16-bit parallel interface for driving a screen
  • SD card FATFS driver
  • External SDRAM
  • Power regulation circuit
  • A flawless NES CPU emulator
  • A fun game we were able to bring to our system

All in all that is a success to us!