Posts: 7
Threads: 1
Joined: Feb 2017
Reputation:
0
Hello everybody,
Long time FF player. First time poster.
I'm trying to figure out the algorithm for generating the save game checksum for Final Fantasy II on SNES (or 4 however you look at it). I know the file is 8kB long and is divided into 4 equally spaced 2kB blocks. The checksum from what I gather is at the end of this block. I've tried sums of the words, XORs of the words, and I'm really sort of lost as to how it's computed. I found a tool by Lord J - FF4H version 3B that implements this. That's great, but I'd like to know the calculation behind it. From looking at his freely available source code for FF3H, it does look like it's more or less a simple sum of the words in each slot, XORd with all 1's at the end. Is FF4 the same?
Thanks for any help you can provide.
Posts: 7
Threads: 1
Joined: Feb 2017
Reputation:
0
Thanks Madsiur for the direction. I'll go take a look at Zyrthofar's tool and see if I can contact him on that forum.
Posts: 7
Threads: 1
Joined: Feb 2017
Reputation:
0
By changing one value at a time in Zyrthofar's tool (ie: Max HP from 1 to 2), I noticed that both bytes of the checksum independently increment by the same amount. For instance, if I increase Cecil's Max HP field by 1, then both checksum bytes increase by 1. If I increase another field by 2, then both checksum bytes increase by 2. They seem to be somewhat independent of each other.
I don't know what the final two bytes (or depending on endianness the 3rd and 4th bytes from the end) are 0xE4 and 0x1B. Interestingly these add up to 0xFF, which I could see factoring into some sort of checksum. They could also just as well be an 'end of slot' marker. The 5th byte from the end also changes - maybe as part of the checksum calculation. I haven't figured that out yet.
It'd be great if you could take a look at it. Maybe it's a really easy problem and I've just overlooked the obvious solution?
Posts: 7
Threads: 1
Joined: Feb 2017
Reputation:
0
Awesome! Thanks for the source assembly code. It's been a long time since I've dealt with assembly code (~17 years or so), so I'll need to brush up on it to get familiar with what these op codes and instructions do on the 65816.
If I understand what you said correctly, and from looking at the main loop (0x1cc7b to 0x1cc80) it treats the data as 16-bit (accumulator set to 16 bits at 0x1cc6d), but only increments the byte address by 1?
So if my 16-bit words are as follows,
0x1122
0x3344
0x5566
It would add 0x1122, 0x2233, 0x3344, 0x4455, 0x5566 and then set the accumulator to 8-bit mode (effectively dropping all higher bits) and return that as the 16(?)-bit checksum?
Am I kind of on the right track?
Posts: 127
Threads: 8
Joined: Jan 2012
Reputation:
13
Yep, you pretty much got it.
Nothing is dropped though. When the accumulator is set to 8-bit mode the checksum has already been transferred to X so all 16-bits are stored.
I'm not sure about all of this as I have not properly tested anything but I found the routines with breakpoints, disassembled them and commented by hand.
The checksum starts with RAM value $41, I have no idea what it contains but I hope it's zero. More breakpoints could figure this out though.
I think we're on the right track, you're understanding what I have very well. Let us know if you get something working.
Posts: 200
Threads: 1
Joined: Oct 2015
Reputation:
18
glad to see you're making short work of this. so it's essentially two separate 8-bit checksums, with the bottom one having all but the last data value, and the top one having all but the first?