NeoGeo Pocket SaveGame Backups

Today a new owner of the NGPC Flash Masta & Linkmasta bundle emailed me with a question about backing up Neo Geo Pocket savegame data. In particular, he was asking why the software won’t backup only the save-game data when you are using a flash cartridge. If you’ve never tried it, the Linkmasta software will allow you to backup the savegame data from an official cartridge, but it won’t do it when it detects a flash cartridge. To backup the savegame data on a NGPC flash cart, you need to backup the entire (usually 32mbit) cartridge.

To understand this, first of all, it’s important to understand that the NGPC does not have separate savegame “SRAM” and game data “ROM” memory. This is a common misconception, because many systems had this architecture. What the NGPC has is flash memory that is used to store both game and savegame data.

In official games, the game data is protected so the NGPC can not write over the actual game ROM. However, you can write to every official NGPC cartridge. To do it, you’d have to write to an unprotected area of the cartridge memory, and this is typically where the savegame data would live.

What happens when you want to backup the savegame data from an official cartridge is that the Linkmasta uses some low-level routines to talk directly to the flash memory chip and ask about the protection status of each block. Whenever it encounters an unprotected block, it assumes that is where savegame data lives (or could possibly live) and backs it up. It saves this in the NeoPop savegame format which is the closest thing we have to a standard for this.

The problem arises when you try to employ this technique on a flash cart. The flash cart is 100% unprotected. The Linkmasta has no way to know which blocks contain savegame data and which ones contain game code/data. It could make guesses, but they would not be 100% accurate. The only way to be sure that you backup all of the savegame data is to backup ALL of the data on the cart (savegame plus game data).

I have thought about this before, and there is another way that the Linkmasta could (most likely) determine what data is savegame related. There could be another function to backup changes in the cart. This would probably be slightly different than the NeoPop savegame format. What you would do is to write a ROM file to the Neo Geo Pocket Flash Masta cart. Then, you would play it and save your progress. If you wanted to backup changes, you would (in theory) hit the “save changes” button. The software would then ask you to supply the ROM file used to create the cartridge. Then, it would compare, byte by byte, the contents of the file against the contents of the cartridge. Whenever it encountered a mismatch, it would save this to a savegame backup file. It would be like using the verify feature and saving a “diff”.

So, now that I’ve laid this out, I wonder if anyone is interested in implementing it. I am spending most of my time lately working on building bundles and researching and designing a WonderSwan cartridge. In the past, I have talked about making the NeoLinkmasta software open-source. I would be interested in hearing from anyone that would want to work on adding features like this. Do you have other ideas? If so, contact me. I just haven’t gotten around to “opening” the source, but I’m definitely interested in discussing this with coders.

9 comments on “NeoGeo Pocket SaveGame Backups
  1. jrronimo says:

    Excellent explanation — even I understood it! heh.

    I think it’d be troublesome to have to supply a ROM file every time to create this diff. What might be a cool feature would be if the NeoLinkmasta software also acted as sort of a… ROM library — think iTunes but for ROMs. I don’t know if there’d be a way to auto-identify the ROM flashed to the cartridge and then auto-create the diff, but that would take a lot of the tedium of supplying a ROM images every time.

    Of course, this would also create huge burden on the programmer(s) to create since it would probably significantly change the software itself.

    I’m all for open sourcing things, but my opinion shouldn’t really be counted — the last programming I did net me a C+ in a C++ class about a decade ago. Unless, of course, NeoLinkmasta is secretly written in QBasic. Then I am *so* in. 😉

    • Flavor says:

      The iTunes idea sounds cool, but it also sounds like an entirely new scope for the project requiring databases and stuff.

      It’s definitely not QBasic. The base code (for the command-line version) is all C. Then, when Mr. Spiv worked on the multi-OS GUI, he used FLTK. It’s still C, but it’s wrapped in this FLTK GUI builder sort of environment.

  2. loïc says:

    The other way to handle savegame could by via a small database.

    I think that each game (more precisely NEOPxxxxx) have the same unprotected block.

    So if NeoLinkmasta software can rewrite only a specified block, we could build a database with game_id (neop# + name), cart size, unprotected block list for each known official game (homebrew will depend on their developer technical data. To be compatible, they shouldn’t use any official neop# – or 9999 – and could be identified by their string name.)

    This way, we could have this kind of savegame format :
    header (‘NLM’ string, neop#, “game name” as in the cartridge, number of block) + data (block #, data).

    If I remember right, block size being fixed, no need to worry about their size.
    Last part is to zip the resulting file to .NLM (NeoLinkMasta)

    This way, NeoLinkMasta software can check if you’re applying savegame on the right game, and where to patch. I should be ok on dev cards and official games…

    I don’t remember how neopop savegame format is, but it should be possible to convert neopop to NeoLinkMasta.

    Correct me if I’m wrong or if I forget something !

    • NoonKnight says:

      I like the database idea. We could even have an option that diffs two cart saves and creates a DB entry for it.

    • Flavor says:

      Actually, I’ve thought many times in the past that the NGP dumps didn’t actually dump all the cart info. It would have been very nice to dump this protection info (and manufacturer/device IDs) along with the ROM data. I’m sure that the people making the dumps back then never even considered it.

      Way back when I made PocketSend (and the NGPC MultiROM Menu), I added a hidden feature to dump some of this info. A couple guys (SweaterFish and Fuz) actually submitted a lot of them to me. Unfortunately, it wasn’t coded well, and the info is a bit incomplete (not to mention that they weren’t able to scan ALL the carts).

      But, I do have a basis for a start on such a database. It looks like the SweaterFish file has 36 entries, and the Fuz data includes 7 entries. I don’t know how much overlap there is.

      Just for fun, here’s a couple example entries. Just keep in mind that this wasn’t meant to be used for anything in particular, so the format isn’t great and some of the data is still missing in some cases.

      =========================
      Manufacturer ID = 0x98
      Device ID = 0x2c
      Cart Name = CRUSH ROLLER
      i=0x0 protected=0x1
      i=0x10000 protected=0x1
      i=0x20000 protected=0x1
      i=0x30000 protected=0x1
      i=0x40000 protected=0x1
      i=0x50000 protected=0x1
      i=0x60000 protected=0x1
      i=0x70000 protected=0x1
      i=0x80000 protected=0x1
      i=0x90000 protected=0x1
      i=0xa0000 protected=0x1
      i=0xb0000 protected=0x1
      i=0xc0000 protected=0x1
      i=0xd0000 protected=0x1
      i=0xe0000 protected=0x1
      i=0xf0000 protected=0x1
      i=0xf8000 protected=0x0
      i=0xfa000 protected=0x0
      i=0xfc000 protected=0x0

      Manufacturer ID = 0x98
      Device ID = 0x2c
      Cart Name = PUZZLE-B-USA
      i=0x0 protected=0x1
      i=0x10000 protected=0x1
      i=0x20000 protected=0x1
      i=0x30000 protected=0x1
      i=0x40000 protected=0x1
      i=0x50000 protected=0x1
      i=0x60000 protected=0x0
      i=0x70000 protected=0x0
      i=0x80000 protected=0x1
      i=0x90000 protected=0x1
      i=0xa0000 protected=0x1
      i=0xb0000 protected=0x1
      i=0xc0000 protected=0x1
      i=0xd0000 protected=0x1
      i=0xe0000 protected=0x1
      i=0xf0000 protected=0x1
      i=0xf8000 protected=0x1
      i=0xfa000 protected=0x1
      i=0xfc000 protected=0x0
      =========================

      By system specs, the last block has to be open and unused. The NGP itself can use this space for storage. The game shouldn’t.

      Crush roller is pretty typical, and it has its unprotected savegame blocks all right at the end.

      Puzzle Bobble, however, is an example of the odd ones that open the last block (for the system) and then some other (seemingly random) blocks in the middle (for savegame).

  3. loïc says:

    If we can add the neop# to this dump data (maybe useless) I can dump those informations from most of the games.

    • Flavor says:

      The ROM header contains:
      unsigned short GameNum;
      unsigned char Version;
      unsigned char Type;
      char Title[12];

      In theory, this should be sufficient to uniquely define each one. All this info should probably be in there along with everything from /i and /p (from the command-line version of the NeoLinkmasta software).

Leave a Reply

Your email address will not be published. Required fields are marked *

*