EarthBound/SRAM map: Difference between revisions

From Data Crystal
Jump to navigation Jump to search
(Remove stub template)
m (Add anchor)
 
(One intermediate revision by the same user not shown)
Line 34: Line 34:
* <tt>1ff0-1ff0 (0001)</tt>: [[#AntiPiracyCheckByte|Anti-Piracy Check Byte]]
* <tt>1ff0-1ff0 (0001)</tt>: [[#AntiPiracyCheckByte|Anti-Piracy Check Byte]]
* <tt>1ff1-1ffd (000d)</tt>: '''Unused'''
* <tt>1ff1-1ffd (000d)</tt>: '''Unused'''
* <tt>1ffe-1fff (0002)</tt>: Version
* <tt>1ffe-1fff (0002)</tt>: Version<span class="anchor" id="1ffe"></span>


==Save Format==
==Save Format==
Line 43: Line 43:
* A version number (<code>0x0493</code> for US-release ROMs) is stored at <tt>1ffe-1fff</tt>, and on game startup, all 8KB of SRAM is erased/reset if the version number does not match the expectation hard coded in the ROM. This is assumed to primarily be a development compatibility mechanism to ensure incompatible saves with different formats from earlier builds of the game cannot be accidentally loaded, but the mechanism has a secondary role in detecting corruption if the version number somehow changes in SRAM.
* A version number (<code>0x0493</code> for US-release ROMs) is stored at <tt>1ffe-1fff</tt>, and on game startup, all 8KB of SRAM is erased/reset if the version number does not match the expectation hard coded in the ROM. This is assumed to primarily be a development compatibility mechanism to ensure incompatible saves with different formats from earlier builds of the game cannot be accidentally loaded, but the mechanism has a secondary role in detecting corruption if the version number somehow changes in SRAM.
* The first 20 bytes of each <tt>0x500</tt> block of SRAM is set to a known signature ("HAL Laboratory, inc." in ascii). On game startup, all 6 signatures are validated against the expectation hard coded in the ROM. If any signature does not match the expectation, the respective <tt>0x500</tt> block of SRAM is erased and the signature is rewritten.
* The first 20 bytes of each <tt>0x500</tt> block of SRAM is set to a known signature ("HAL Laboratory, inc." in ascii). On game startup, all 6 signatures are validated against the expectation hard coded in the ROM. If any signature does not match the expectation, the respective <tt>0x500</tt> block of SRAM is erased and the signature is rewritten.
* Each <tt>0x500</tt> block of SRAM contains 2 checksum values of the block's respective data section, one derived from adding together all data bytes, and the other from XORing all the data.<p>On game startup, checksums are recalculated for all 6 SRAM blocks, and if the newly calculated checksums do not match the saved checksums for any SRAM block, the respective <tt>0x500</tt> block of SRAM is erased and the signature is rewritten. For every 2 blocks redundantly storing the same save file, if only 1 block is reset, the entire <tt>0x500</tt> good block (including signature and checksums) is copied over the bad block. If both blocks are invalid and reset, an error message is displayed to the user in the main save-selection menu.</p><p>On game save, when data is redundantly saved to 2 <tt>0x500</tt> block of SRAM, checksums for each block are calculated and written to that block. Then the checksum is calculated again for each block, and if that checksum does not match the value saved in the block, the entire save file process (for both blocks) starts over.</p>
* Each <tt>0x500</tt> block of SRAM contains 2 checksum values of the block's respective data section, one derived from adding together all data bytes, and the other from XORing all the data.<p>On game startup, checksums are recalculated for all 6 SRAM blocks, and if the newly calculated checksums do not match the saved checksums for any SRAM block, the respective <tt>0x500</tt> block of SRAM is erased and the signature is rewritten. For every 2 blocks redundantly storing the same save file, if only 1 block is reset, the entire <tt>0x500</tt> good block (including signature and checksums) is copied over the bad block. If both blocks are invalid and reset, an error message is displayed to the user in the main save-selection menu.</p><p>On game save, when data is saved to a <tt>0x500</tt> block of SRAM, checksums for the block are calculated and written to that block. Then the checksums are calculated again, and if either checksum does not match the value saved in the block, the entire save block process starts over.</p>


==Anti Piracy Check Byte<span class="anchor" id="AntiPiracyCheckByte"></span>==
==Anti Piracy Check Byte<span class="anchor" id="AntiPiracyCheckByte"></span>==
Byte <tt>1ff0</tt> is used to implement the infamous [http://media.earthboundcentral.com/2011/05/earthbounds-copy-protection/index.html EarthBound copy protection]. EarthBound first writes <code>30</code> to this byte via CPU address <tt>$307ff0</tt>, then writes <code>31</code> to this byte via CPU address <tt>$317ff0</tt>, and then checks that the first CPU address (<tt>$307ff0</tt>) matches the expected <code>31</code>. In a normal EarthBound cartridge with 8KB of SRAM, the SNES is expected to map both addresses to the same SRAM byte <tt>1ff0</tt>. If the game is being run with 16KB or more of SRAM (as would often be the case with pirated games of the era), the SNES would map the two addresses to separate bytes in SRAM (<tt>1ff0</tt> and <tt>3ff0</tt>), and the second write would not overwrite the first.
Byte <tt>1ff0</tt> is used to implement the infamous [http://media.earthboundcentral.com/2011/05/earthbounds-copy-protection/index.html EarthBound copy protection]. EarthBound first writes <code>30</code> to this byte via CPU address <tt>$307ff0</tt>, then writes <code>31</code> to this byte via CPU address <tt>$317ff0</tt>, and then checks that the first CPU address (<tt>$307ff0</tt>) matches the expected <code>31</code>. In a normal EarthBound cartridge with 8KB of SRAM, the SNES is expected to map both addresses to the same SRAM byte <tt>1ff0</tt>. If the game is being run with 16KB or more of SRAM (as would often be the case with pirated games of the era), the SNES would map the two addresses to separate bytes in SRAM (<tt>1ff0</tt> and <tt>3ff0</tt>), and the second write would not overwrite the first.

Latest revision as of 03:09, 12 June 2024

Chip tiny.png The following article is an SRAM map for EarthBound.

  • 0000-0013 (0014): Save 1A Signature
  • 0014-001b (0008): Unused
  • 001c-001d (0002): Save 1A Checksum 1
  • 001e-001f (0002): Save 1A Checksum 2
  • 0020-04ff (04df): Save 1A Data
  • 0500-0513 (0014): Save 1B Signature
  • 0514-051b (0008): Unused
  • 051c-051d (0002): Save 1B Checksum 1
  • 051e-051f (0002): Save 1B Checksum 2
  • 0520-09ff (04df): Save 1B Data
  • 0a00-0a13 (0014): Save 2A Signature
  • 0a14-0a1b (0008): Unused
  • 0a1c-0a1d (0002): Save 2A Checksum 1
  • 0a1e-0a1f (0002): Save 2A Checksum 2
  • 0a20-0eff (04df): Save 2A Data
  • 0f00-0f13 (0014): Save 2B Signature
  • 0f14-0f1b (0008): Unused
  • 0f1c-0f1d (0002): Save 2B Checksum 1
  • 0f1e-0f1f (0002): Save 2B Checksum 2
  • 0f20-12ff (04df): Save 2B Data
  • 1300-1313 (0014): Save 3A Signature
  • 1314-131b (0008): Unused
  • 131c-131d (0002): Save 3A Checksum 1
  • 131e-131f (0002): Save 3A Checksum 2
  • 1320-17ff (04df): Save 3A Data
  • 1800-1813 (0014): Save 3B Signature
  • 1814-181b (0008): Unused
  • 181c-181d (0002): Save 3B Checksum 1
  • 181e-181f (0002): Save 3B Checksum 2
  • 1820-1cff (04df): Save 3B Data
  • 1d00-1fef (02f0): Unused
  • 1ff0-1ff0 (0001): Anti-Piracy Check Byte
  • 1ff1-1ffd (000d): Unused
  • 1ffe-1fff (0002): Version

Save Format

EarthBound SRAM contains 3 save files or slots, corresponding with the 3 save games from the main menu. The data of a save file is a copy of the WRAM Persistent Data in the same order and format. For redundancy, each save file is repeated in two separate exact-mirror copies.

Data Integrity

EarthBound employs multiple mechanisms to validate and fix save files against data corruption:

  • A version number (0x0493 for US-release ROMs) is stored at 1ffe-1fff, and on game startup, all 8KB of SRAM is erased/reset if the version number does not match the expectation hard coded in the ROM. This is assumed to primarily be a development compatibility mechanism to ensure incompatible saves with different formats from earlier builds of the game cannot be accidentally loaded, but the mechanism has a secondary role in detecting corruption if the version number somehow changes in SRAM.
  • The first 20 bytes of each 0x500 block of SRAM is set to a known signature ("HAL Laboratory, inc." in ascii). On game startup, all 6 signatures are validated against the expectation hard coded in the ROM. If any signature does not match the expectation, the respective 0x500 block of SRAM is erased and the signature is rewritten.
  • Each 0x500 block of SRAM contains 2 checksum values of the block's respective data section, one derived from adding together all data bytes, and the other from XORing all the data.

    On game startup, checksums are recalculated for all 6 SRAM blocks, and if the newly calculated checksums do not match the saved checksums for any SRAM block, the respective 0x500 block of SRAM is erased and the signature is rewritten. For every 2 blocks redundantly storing the same save file, if only 1 block is reset, the entire 0x500 good block (including signature and checksums) is copied over the bad block. If both blocks are invalid and reset, an error message is displayed to the user in the main save-selection menu.

    On game save, when data is saved to a 0x500 block of SRAM, checksums for the block are calculated and written to that block. Then the checksums are calculated again, and if either checksum does not match the value saved in the block, the entire save block process starts over.

Anti Piracy Check Byte

Byte 1ff0 is used to implement the infamous EarthBound copy protection. EarthBound first writes 30 to this byte via CPU address $307ff0, then writes 31 to this byte via CPU address $317ff0, and then checks that the first CPU address ($307ff0) matches the expected 31. In a normal EarthBound cartridge with 8KB of SRAM, the SNES is expected to map both addresses to the same SRAM byte 1ff0. If the game is being run with 16KB or more of SRAM (as would often be the case with pirated games of the era), the SNES would map the two addresses to separate bytes in SRAM (1ff0 and 3ff0), and the second write would not overwrite the first.