In case anyone is interested I am attaching an implementation of an emulator of the original 1980s Nintendo Entertainment System (NES) for the Hydra, running the original Pacman game.
This is an emulation - meaning that every original 6502 instruction is read in and interpreted by the Hydra in real-time. It's not yet perfect but I think it is somewhat amazing that it works at all. This project ran up against all the limitations of the Hydra - only 32 KB of memory to hold the original ROM code, the ROM Pattern Table information, the Name Table information, sprite data, pallettes, scratch memory, etc. In addition there is the constraint of only 512 longs per cog. Inevitably this means that you can't put everything you want in. In particular I wasn't able to include quite all of the original pattern table and unused 6502 instructions are not emulated. The program uses all the available cogs. If I could I would like one more cog to emulate the sound of the original NES. The Hydra appears fast enough at least for this game, but a few more CPU cycles would be nice.
Why was Pacman chosen for this NES emulation project? The answer is that Pacman is a relatively early game which uses only 16KB (out of the 32 KB available on the NES) and only vertical scrolling (no horizontal scrolling) and horizontal mirroring. Therefore it was potentially feasible. Many larger games simply will not be feasible without a major change in approach (such as the use of the Hydra 512K RAM extension card). My objective was to run the original Pacman ROM code. This was nearly achieved. The ROM code was altered slightly for a couple of reasons - one was to change the original pallette of colors (I haven't yet worked out how to do color mapping in real time), another was to take out one KB of unused space to give me just a little more room.
The program seems to run fine. It emulates all the sprites, name tables, scrolling etc. of the original NES, together with the ability to read the gamepad. It also emulates the PPU's non-maskable interrupt which occurs every time the screen is refreshed (during vertical blanking).
One of the nice features of running an emulator is that debugging on the Hydra is made a lot easier. The emulator allows you to step through one instruction at a time, observing changes to each register (including the stack and the status register), together with changes to any memory location you wish to observe. You can add a breakpoint at any instruction.
This code is not perfect. In particular there are some color artifacts of two kinds. First the colors on the title screen are not quite right due to some problems implementing the PPU's attribute table feature. Perhaps someone can figure out what I am doing wrong. The second problem is related to the sprites themselves. Each sprite somehow picks up the color set of another sprite on the same line. This is a subtle error which has proved hard to debug. I am putting the code up as it is. Still, the sprites are mostly the right colors. Also, as noted above, there is no emulation of sound, due to a lack of cogs and a lack of memory space.
This project uses Eric Ball's 6502 emulator which is clever and efficient. But there were a few "errors" in Eric's original code which I spent many hours trying to track down. Hopefully that is now done.
Having put in a lot of effort to get Pacman running I am hoping to move on to test the emulator on some other NES game. I figure that once I have tried this approach on a few different (simple) games I'll be in a better position to know just how much this emulation approach is feasible. Again, the amazing thing here is that it works at all. We are not quite yet in the position of having an NES-on-a-chip, but this comes close.
I am attaching the code as it is. This is my first attempt at distributing code in this way. If there are any concerns about copyright etc. I will, of course, take it down. I am happy to discuss...
Post Edited (Darryl) : 1/11/2010 11:23:50 AM GMT