d0k3 / GodMode9

GodMode9 Explorer - A full access file browser for the Nintendo 3DS console :godmode:
GNU General Public License v3.0
2.15k stars 194 forks source link

Save management: Detect save size by the last byte of JEDEC id, if possible #670

Closed dratini0 closed 3 years ago

dratini0 commented 3 years ago

This makes progress on #553, but not complete closure. Not by a long way...

The long and short of this is that this commit now only compares the first two bytes of the JEDEC ID of the flash chip when looking it up. When looking up the size, if the lookup table has a size, it uses that, otherwise it checks the last byte of the JEDEC ID. Additionally, the auto-detection for type is now skipped for card1 3DS cards, and all the flash chips are handled the same way.

I have also tried another approach on the branch ctr-generic-flash, in which I read from the ExHeader instead. I think I prefer this approach, as this doesn't involve going deep into the cartridge header. Then again, that might be needed for card2 games. (Unless I can just assume the save area just stretches to the end of the cartridge?...)

@wwylele , Thank you again for the pointer! Would you mind trying this one out, especially the writing, if you feel brave enough? Reading is practically guaranteed to work, and if the datasheets are to be believed, the writing will be just fine, too. (It now uses the same parameters it uses for the Macronix chips)

d0k3 commented 3 years ago

Glad to see progress on this one! I had a look through the code, looks good to me. I guess I'll still wait with merging until @wwylele comments, as there may be more changes needed.

About the card2 save size - my cart reading code assumes the card2 save actually stretches until the end of the cart storage. For cart reading, that's a save assumption, as there can't be anything else but save data or padding there, and we don't want save data in cart dumps. That may not be the case for save writing, as I'm not sure about the size of the writable area. I don't know about any info inside the cart header that would specify the actual size of the header, but I may also have missed it.

dratini0 commented 3 years ago

I don't know about any info inside the cart header that would specify the actual size of the header, but I may also have missed it.

I will assume you mean "actual size of the save" here.

I have some code that parses the header for the save size on my other branch here: https://github.com/dratini0/GodMode9/blob/ctr-generic-flash/arm9/source/gamecart/gamecart.c#L96

It boils down to the following:

  1. Read the first two sectors of the first partition on the cartridge (NCCH and first sector of ExHeader)
  2. Decrypt the ExHeader using the NCCH
  3. Look up offset 0x1C0 in the ExHeader

It does seem to arrive at the right result, but it just seems like a very roundabout way to do it for SPI flash based saves.

profi200 commented 3 years ago

The only way to get the CARD2 save size (for 3DS cards) is via the exheader. The offset where the save is stored is in this header: https://www.3dbrew.org/wiki/NCSD#Card_Info_Header

d0k3 commented 3 years ago

@dratini0 - I assume this is ready to be merged (also in regards to the coming release, as mentioned in that other pr discussion)?

dratini0 commented 3 years ago

I am quite happy with it. That said I haven't tested it with any of the 0x6226XX games, because I don't have any and I am quite concerned that they don't keep the save chip consistent between production runs of the same cartridge. The best I can say that it still works with the 0xC222XX cartridges I have.

dratini0 commented 3 years ago

I got my hands on a bootleg copy of Pokemon Diamond, and it turns out that that has a previously unsupported type of flash chip. (ST M25PE40VP) So I added support for that too (not that bootlegs working/not working for any particular purpose isn't a bit of a crapshoot anyway). It does look pretty fast and versatile to me.

dratini0 commented 3 years ago

I have rebased this as per the discussion on #672

dratini0 commented 3 years ago

I pushed my changes to fix #690 here, as I don't feel like starting a zillion merge requests and rebasing them again.

d0k3 commented 3 years ago

Alright, that means it's good to merge now?

dratini0 commented 3 years ago

Thank you. Yes, that should be fine

d0k3 commented 3 years ago

Merged with current master. Thanks a lot, @dratini0 !