Home | Forums | What's new | Resources | |
Action Replay Save Format? |
slinga - Jan 22, 2021 |
slinga | Jan 26, 2021 | |||
Thanks. I'm thinking maybe I should just add notes on how to dump the raw Action Replay cartridge and tell them to use ss-save-parser. |
hitomi2500 | Jan 26, 2021 | |||
Oh, did you mean getting saves off the raw cartridge image? I thought it was about AR export tool for PC via DB25 connector (i had one AR like this, but it was lost sadly). I don't know if the tool like this ever existed, but how did i got this file anyway? For raw cartridge, ss-save-parser can import it, but not export, and the feature is experimental. If you need the code, look at ProbeActionReplay() and ImportActionReplay() functions in import.cpp ... Another option is inserting raw image into emulator and copying everything manually to internal backup, it's less convenient, but more reliable i guess. |
slinga | Jan 27, 2021 | |||
I wanted to add support for copying\writing\deleting saves from the Action Replay same as internal memory works now within SGC. It looks like a pain so... |
slinga | Apr 8, 2021 | ||||
@Jameson..., I had some time to review your code as well as reverse engineer the the Action Replay firmware. I understand the RLE01 algorithm and my results match what I see when I check via the Yabause debugger. I'm stumped on what format the uncompressed data is. In your code you setup a huge ram data field which I don't follow:
Code:
Looking at the uncompressed data I can make out the save. The only issue I see is that there seems to be extraneous 0x00s in certain places. Do you know if these are unescaped at some point? So any advice on how to go from this RLE format to parsing out saves would be appreciated. |
hitomi2500 | Apr 8, 2021 | |||
@slinga... , the code you mentioned simply adds 4 "BackUpRam Format" lines to the beggining of the image. The replace() function is a member of QByteArray class, it replaces a part of array with something else without changing the array size. Extra 0x00s should not be there after RLE decompressing. Are you sure you followed both RLE01 sequences thru? The first one is 0xKK 0xXX 0xYY and it transforrms into 0xXX copies of the 0xYY, and the second one is 0xKK 0x00, and it transformes to 0xKK. Maybe you missed the second one? |
hitomi2500 | Apr 9, 2021 | |||
"BackupRam Format" is a signature sequence that allows BIOS to detect if the media is formatted or not. If there are at least 4 copies of this sequence at the start, the media is considered as formatted. The number of these sequences determines the cluste size (4 = 64 bytes, 16=256 bytes, etc). Thus, the first cluster is always completely filled with these sequences. The second cluster is always unused. Following clusters can be save start clusters (start with 0x8x), save continue or unused (start with 0x0x). The save start cluster includes what i call SAT (analogue to FAT), a table that enumerates all save continue clusters for this save. If the table is big enough, it can extend into the next continue cluster. So, saves can be very fragmented, and the only way to know if the cluster that starts with 0x00 is unused or continue is to parse the entire image. |
slinga | Apr 10, 2021 | |||
Thank you, I'm beginning to understand now. The additional 0x00s I'm seeing are most likely save continue headers. |
slinga | Apr 15, 2021 | |||||
Is the SAT guaranteed to be contiguous? Or do I need to look a the SAT while parsing the SAT? |
hitomi2500 | Apr 15, 2021 | |||||
I can't remember the exact cases of SAT being non-contiguous, but i remember fragmented saves with the second cluster being away from the first one. They were relatively small, so SAT was probably completely in first cluster, but i think nothing prevents SAT from being fragmented. And even if the cluster chain that stores SAT is contiguous, the SAT itself is interrupted by save continue headers in every new cluster. To be on a safe side, you should look at the SAT while parsing SAT. SimCity2000 saves use 461 blocks , using entire internal backup, they are a good research material for the case. There are even bigger ones, like well-known Tamagotchi park save or Sega Rally ghosts, they can only fit into backup cart. |
rorirub | Apr 16, 2021 | ||||
From what I recall when writing my own extractor, the allocation table definitely spans multiple blocks and suffers from fragmentation if the save file is large enough. Here's a comment from my code:
This refers to extracting data from memory cards where a sector size is 256 bytes (252 = sector size - sector header size). On internal memory you have smaller sectors but I forgot the exact number (64 bytes?) |
slinga | Apr 17, 2021 | |||||
On the Action Replay, after uncompressing the RLE01 compression, the uncompressed data is stored in 64-byte sectors. 60 bytes of data storage after subtracting the 4-byte sector header\tag. The first two sectors are all 0x00 whereas they should normally save "BackupRAM Format". Other then that I believe the uncompressed data should be identical to the internal\cartridge backup memory. I'm close to finishing (reading, not writing the save), will document my code. |
slinga | Apr 24, 2021 | |||
I have basic read-only support working: Release Beta Read-Only Action Replay Support · sl.... Needs more testing as always. |