I spent a little time decoupling the NES FPGA system from the computer recently. Instead of needing a program running on the computer to upload games, I really wanted to have the ability to upload games via an SD card on the board itself.
The way this worked previously was you would open a program on the computer to navigate to an NES rom file, and select it. The rom would be sent via the serial USB link to the FPGA. To facilitate this same functionality, I would need to replicate how the computer program was sending packets, and in what sequence on a microcontroller connected to an SD card loaded with roms.
I chose to use the Parallax Propeller microcontroller to do the heavy lifting between the SD card and the FPGA. The Propeller has a somewhat different architecture than the traditional micro. It has essentially 8 cores, or what Parallax calls cogs, running on the chip. Each of these cogs can run tasks independently of the other cogs. So, for my application I'm using one cog to access the SD card, one cog to provide a serial link to display the file contents, one cog to provide a serial link for streaming the rom packets, and one cog that runs the main program loop. I used the FLiP module Parallax sells to provide easy access to the Propeller on the breadboard.
To duplicate the serial packets that the software was using involved looking through the source code and analyzing how it was sending the data. The program started out by sending commands to tell the FPGA to disable the PPU (picture processing unit) of the NES, then it would send over the iNES header of the rom. The iNES header basically holds information on which mapper to use for the game, as well as the size of the program and PPU rom. After sending this data, it would send a command letting the FPGA know that it would start receiving the actual game packets. Next it would send the address to start writing the data to, as well as the size of the packet (in this case the packets were 1KB). Finally, when the last packet was received, the program retrieved the reset vector from the rom and issued a command to the cpu to let it know where to start executing the code.
In order to make sure the Propeller sent the correct data exactly as the original software had done, I used this program called Advanced Serial Port Monitor to spy on the usb serial port and log the bytes that were being sent. This way I could step through the code and see which bytes were being sent in relation to which commands and that the packets were being sent correctly.
In order to facilitate displaying the menu on the FPGA, I setup an 80 column by 30 row tile map. Each tile was made up of an 8x16 pixel grid. I also setup a rom image to store the font of each individual character type that would be displayed as it was received from the serial port. I added a menu toggle button on the controller to facilitate toggling from the menu display back to the game display. The menu is pretty basic for now, it displays the game title, the size of the rom, as well as the total number of games, and current page. By using the up/down/right/left and select buttons on the controller while in menu mode you're able to scroll up and down and forward and backward to different pages in order to select the game you want.
Next, I need to figure out how to get the FPGA to load the bit file via the attached SPI flash so I no longer need to load it via the USB to JTAG link. Then, who knows, maybe I could cobble together some perfboard and make a proper handheld prototype.