Users browsing this thread: 1 Guest(s)
FF4 SNES SRM Checksum
02-12-2017, 03:05 PM
I checked this out since I'm also curious.
The two bytes at the end $07FE and $07FF are set to #$1BE4 if the save slot is in use.
The checksum is calculated word by word but each word will overlap as the checksum counter is only increased by one byte. This is why both bytes of the checksum increase when one byte is increased.
Partial disassembly
Note: CPU bank 01 is at 00 in the ROM because FFIV is LoROM.
Good luck and happy hacking!
The two bytes at the end $07FE and $07FF are set to #$1BE4 if the save slot is in use.
The checksum is calculated word by word but each word will overlap as the checksum counter is only increased by one byte. This is why both bytes of the checksum increase when one byte is increased.
Partial disassembly
Code:
Transfer A to X through $43
0187B4 85 43 STA $43
0187B6 A6 43 LDX $43
0187B8 60 RTS
Sanity check a save slot
01995D BF FE 07 70 LDA $7007FE.l,x ; SRAM $07FE for save slot X
019961 A8 TAY ; A to Y
019962 E2 20 SEP #$20 ; 8-bit A
019964 C0 E4 1B CPY #$1BE4 ; Is save slot in use?
019967 F0 04 BEQ $996D ; if so get checksum
019969 E2 20 SEP #$20 ; 8-bit A
01996B 18 CLC ; Carry clear, no save file
01996C 60 RTS ; Return
Checksum check a save slot
01996D A5 51 LDA $51
01996F 1A INC a
019970 20 5F CC JSR $CC5F ; Calculate checksum to X
019973 C2 20 REP #$20 ; 16-bit A
019975 8A TXA ; Checksum to A
019976 A6 45 LDX $45
019978 DF FC 07 70 CMP $7007FC.l,x ; SRAM checksum for save slot
01997C D0 EB BNE $9969 ; exit if no match, with carry clear
01997E E2 20 SEP #$20 ; 8-bit A
019980 38 SEC ; Carry set, save file is ok
019981 60 RTS ; Return
Calculate checksum for save slot
01CC5F 85 4E STA $4E ; Save slot index
01CC61 0A ASL a ; Multiply by 2
01CC62 65 4E ADC $4E ; Multiply by 3
01CC64 20 B4 87 JSR $87B4 ; TAX through $43
01CC67 BF 86 CC 01 LDA $01CC86.l,x ; High byte of pointer to save slot
01CC6B 85 4E STA $4E ; store it
01CC6D C2 20 REP #$20 ; 16-bit A
01CC6F BF 87 CC 01 LDA $01CC87.l,x ; Low 2 bytes of pointer
01CC73 85 4F STA $4F ; store it
01CC75 A5 41 LDA $41
01CC77 A0 FA 07 LDY #$07FA ; Size of save slot
01CC7A 18 CLC ; Carry clear
01CC7B 67 4E ADC [$4E] ; Add next byte and carry
01CC7D E6 4E INC $4E ; next byte
01CC7F 88 DEY ; decrease size left
01CC80 D0 F9 BNE $CC7B ; Loop for all bytes
01CC82 AA TAX ; Set checksum to X
01CC83 E2 20 SEP #$20 ; 8-bit A
01CC85 60 RTS ; Return
Pointers to save slots
01CC86 00 10 7E
00 00 70 ; Slot 1 at $700000
00 08 70 ; Slot 2 at $700800
00 10 70 ; Slot 3 at $701000
00 18 70 ; Slot 4 at $701800
Good luck and happy hacking!
« Next Oldest | Next Newest »
|
||||
Users browsing this thread: 1 Guest(s)