Ryan,
You don't start small for your initial project, do you? Are you looking to have a single "save slot", a.k.a. "continue" feature such as in Final Fantasy (the first one) or Dungeon Magic, or multiple slots such as in Zelda, Crystalis, Super Mario World, and so on? Do you know approximately how much data you need to save in each slot? Do you know which parts of the "SRAM area" are unused by the game already? Do you want the game state to be saved implicitly whenever returning to the map, or explicitly under player control from the world map? Or even just to have the option when completing a fortress or boss battle (as in Super Mario World, again)? Do you really need to save the number of coins, lives, the score, and your item inventory, or is it sufficient to simply save the world map state? If you're using multiple save slots, do you select a single slot for the duration of the "game" (Zelda / Super Mario World model) or do you choose a slot each time you save (later Final Fantasy, Crystalis model)?
To begin with, I'd focus on analysis. SMB3 is apparently 16 PRG pages and 16 CHR pages, and uses MMC3. Figure out which areas of the ROM are graphics, which are level data, which is music, which are code, and so on. Once you know where the code is, disassemble it. Or just disassemble the entire ROM, look for sequences that could be code vs. sequences which are obviously not code, and use that to narrow down what is in each part of the ROM. Be aware that you may need to re-do your disassembly once you figure out more about the memory model that the game uses. Read NES programming tutorials, information about the obscure details of the hardware (some of which would have been Really Useful back when I was writing my NES emulator), and so on. Keep notes. If you can work out what parts of RAM are used for what data, that will help, and you might be able to do that by taking successive emulator save states and comparing them if you know the save state format. As a simple example, the in-level clock is monotonic-decreasing at a known rate. Take a few save states at successive seconds and compare them, one of the differences will be the clock, and the fact that you know its value will help to track it down. Do something similar in terms of before/after snapshots at the toad house on the first level to try and find the item inventory. Alter the save states to see if you can increase and decrease the amount of time remaining in the current level, or to stuff your inventory with various items. Look to see if someone else has already published an analysis of this ROM.
When working with the disassembled code, look for "leaf" routines, which don't call anything. Look for routines which access the PPU, the APU, the MMC3, and RAM. Try to build a dictionary of known RAM locations, known data areas, and known and unknown routines. Try to figure out what the RESET, NMI (PPU vblank interrupt) and IRQ (MMC3 scanline interrupt) routines do. If you know what certain areas of the ROM or RAM contain, watch for code that accesses those areas, even if you don't understand the code you'll know more-or-less what it does, which will help you to figure out what it's doing.
Find a game that you like that has a save feature that works the way that you want your save feature to work and analyze that game, with a focus on finding access to the save memory and figuring out how it works and what things it does that you might or might not have expected. Expect to be surprised.
If you don't know how to program yet (anything, not just the 6502), start learning about that, too. A 6502 system is a great place to start learning to program, as the programming model is fairly simple and yet still powerful enough to do an amazing amount of work. Start working through 6502 (and even NES-specific) programming tutorials. Find existing programs with source and read them. There will be a huge variation in quality and readability when it comes to program source code, so think about the differences and how they affect your ability to understand and possibly modify the code.
You are at the beginning of an amazing journey, one that will be a lot of hard work, but if you stay with it you will see some truly wonderful things, and the skills and understanding that you build in your explorations will serve you well for your hobby, and possibly your professional career, and you will be able to look upon some of your projects with pride and be able to say "I did that".
As a side note, my entry into NES hacking was in '97 or '98, and I was hoping to translate FF3j to english (I never did). I had prior experience with the 6502, Marat's NES document, and a small number of ROMs. I started by writing my own disassembler (not at all difficult), but once I reached the limits of my understanding that way I ended up building the start of a CPU simulator (capable of simulating a small handful of instructions), then RAM, bankswitch controls, and the bare minimum of a PPU status port, all under single-step control. That eventually spawned a full NES emulator, which got me my first real programming job, working on 6502-based modem firmware. I knew another NES emulator developer who at one point was using his reverse-engineering skills to work out a performance model for the graphics hardware in some game console for his day job at a game development company. Even if you never apply the specific skills for working with the NES and 6502, the more general skills and approaches to problems that you develop will prove useful again and again over your lifetime.
-- Alastair
|