tepples wrote:
Have you programmed any other emulator before?
Basic steps I think most people follow:
1. iNES/UNIF/etc file reading into memory arrays.
2. 6502 emulation. Start by implementing opcodes, RAM [and stack], and the registers, then move up to a step/execute function that keeps track of cycles. Add IRQ/NMI assertion support. Move up to trying to execute a NES ROM, and you will most likely note the ROM doesn't get very far before it gets stuck in a loop looking at memory address $2002 for a specific bit pattern. This comes from the PPU...
3. PPU emulation. Start by implementing the registers, PPU pixel clock, VBLANK flag, NMI assertion. Move up to frame-based PPU activity such as implementing VBLANK period, pre-render scanline, TV scanlines, etc. This will give your 6502 the input it needs to continue past the loop it previously got stuck at.
4. Tie the PPU to the 6502 via VBLANK and the PPU registers. Now when you run your NES ROM you should see the PPU being accessed at $2002 and other registers...your ROM is coming to life.
5. Implement a surface for the TV. Paint pixels to the TV based on the rendering rules that can be found in several very useful documents online.
6. Implement the main emulation loop which probably needs to know how to do things at 60Hz or 50Hz. This loop will tell the PPU to do a frame and possibly also the 6502 to execute some instructions...though for a cycle-accurate emulation you'll probably want the PPU rendering engine to tell the 6502 how many CPU clocks to run since the PPU can be adjusted mid-scanline by the 6502 in various ways to create neat effects.
6.5. Add input support!
7. Run Super Mario Bros or some other iNES mapper 0 ROM (32KB PRG, 8KB CHR-ROM) and marvel at your results. Debug away!
Then take it to the next level...in any order:
. Add APU (sound) emulation. This is where I am having the most trouble getting it just right and getting rid of the timing-jitter "cracks and pops".
. Add mapper 1 (MMC1) or other mapper support so you can play more complicated games like Zelda 1, Metroid.
. Start trying to run some of the homebrew stuff out there that REALLY stresses the NES to its limits! This will make you want to pull your hair out because the emulation of such things can be a challenge! There are several packages of test ROMs that will also help you figure out what you have left to do to get the 'perfect' emulator.
What I'm finding is that adding each new thing like MMC5 involves almost a complete rewrite of the underlying assumptions in some or all of my emulation pieces that worked just fine for other mappers but don't work at all with "higher level" mappers. An example would be the MMC5's ability to redirect the PPU nametable memory to on-cartridge RAM, or the MMC3's ability to generate cartridge-originated IRQs to the CPU.
Whichever path you take I have found that emulating something that I thoroughly enjoyed as a kid is a very rewarding and exciting process of learning and discovery.
Good luck!
EDIT: Added step 6.5 -- can't believe I forgot that one!