The current URL is datacrystal.tcrf.net.
EarthBound/ASM/SRAM Routines: Difference between revisions
m (→$ef0683-$ef06a1: Validate All SRAM Block Signature: Grammar fix) |
(Finish documenting routines) |
||
Line 96: | Line 96: | ||
==<tt>$ef0b9e-$ef0bf9</tt>: Validate SRAM<span class="anchor" id="$ef0b9e"></span>== | ==<tt>$ef0b9e-$ef0bf9</tt>: Validate SRAM<span class="anchor" id="$ef0b9e"></span>== | ||
Validates the integrity of all of [[EarthBound/SRAM_map|SRAM]]. Always runs on EarthBound startup. | |||
First checks that the SRAM version tag at SRAM [[EarthBound/SRAM_map#1ffe|<tt>$1ffe</tt>]] matches a hardcoded expectation (<code>0493</code>), and on mismatch, zeroes all <tt>0x2000</tt> bytes of SRAM using <tt>memset</tt> ([[EarthBound/ASM/Memory_And_String_Util_Routines#$c08f15|<tt>$c08f15</tt>]]). Then validates all block signatures via a call to [[#$ef0683|<tt>$ef0683</tt>]]. Then validates checksums for all 3 save slots via calls to [[#$ef0825|<tt>$ef0825</tt>]]. Finally, sets the SRAM version tag to the correct value (<code>0493</code>). | |||
==<tt>$ef0bfa-$ef0c14</tt>: Erase Save Slot<span class="anchor" id="$ef0bfa"></span>== | ==<tt>$ef0bfa-$ef0c14</tt>: Erase Save Slot<span class="anchor" id="$ef0bfa"></span>== | ||
Erases and resets all data in two <tt>0x500</tt> blocks of [[EarthBound/SRAM_map|SRAM]], redundantly storing a single save game slot. Implemented via two calls to [[#$ef05a9|<tt>$ef05a9</tt>]]. | |||
===Inputs=== | |||
* <tt>accumulator</tt>: Save slot idx (<tt>0-2</tt>) | |||
==<tt>$ef0c15-$ef0c3c</tt>: Copy Save Slot<span class="anchor" id="$ef0c15"></span>== | ==<tt>$ef0c15-$ef0c3c</tt>: Copy Save Slot<span class="anchor" id="$ef0c15"></span>== | ||
Copies all data from two <tt>0x500</tt> blocks of [[EarthBound/SRAM_map|SRAM]], redundantly storing a single save game slot, overwriting two <tt>0x500</tt> blocks for a different save slot. Implemented via two calls to [[#$ef06a2|<tt>$ef06a2</tt>]]. | |||
===Inputs=== | |||
* <tt>accumulator</tt>: Destination save slot idx (<tt>0-2</tt>) | |||
* <tt>x</tt>: Source save slot idx (<tt>0-2</tt>) | |||
[[Category:EarthBound:ASM|SRAM Routines]] |
Latest revision as of 03:25, 12 June 2024
SRAM Routines | |
Game | EarthBound |
Start Address | 0x2F07A9 |
End Address | 0x2F0E3C |
Total Length | 1684 bytes (0x0694) |
Back to the ROM map |
$ef05a9-$ef062f: Reset SRAM Block
Zeroes out an entire 0x500 block of SRAM and then rewrites the block signature ("HAL Laboratory, inc.", loaded from ROM at address $ef0591).
Inputs
- accumulator: SRAM block idx (0-5)
$ef0630-$ef0682: Validate SRAM Block Signature
Checks if the 0x500 block of SRAM begins with the expected block signature ("HAL Laboratory, inc.", loaded from ROM at address $ef0591). If the signature does not match the expectation, the block is reset via a call to $ef05a9.
Inputs
- accumulator: SRAM block idx (0-5)
Outputs
- accumulator:
0001
if the block was reset. Otherwise0000
.
$ef0683-$ef06a1: Validate All SRAM Block Signatures
Checks all 0x500 blocks of SRAM to confirm they each begin with the expected block signature ("HAL Laboratory, inc.", loaded from ROM at address $ef0591), resetting any blocks as needed. Implemented via a trivial for loop and calls to $ef0630.
$ef06a2-$ef0733: Copy SRAM Block
Copies the entire contents of one 0x500 block of SRAM, overwriting another block. Implemented via a simple call to memcpy ($c08eed).
Inputs
- accumulator: Destination SRAM block idx (0-5)
- x: Source SRAM block idx (0-5)
$ef0734-$ef077a: Calculate SRAM Block Checksum 1
Calculates a checksum for the data contents of one 0x500 block of SRAM. (The checksum does not cover the block signature or checksums.)
Checksum 1 is calculated by adding together all bytes of the data contents.
Inputs
- accumulator: SRAM block idx (0-5)
Outputs
- accumulator: Checksum value
$ef077b-$ef07bf: Calculate SRAM Block Checksum 2
Calculates a checksum for the data contents of one 0x500 block of SRAM. (The checksum does not cover the block signature or checksums.)
Checksum 2 is calculated by XORing every 2-byte short of the data contents.
Inputs
- accumulator: SRAM block idx (0-5)
Outputs
- accumulator: Checksum value
$ef07c0-$ef0824: Validate SRAM Block Checksums
Checks if the checksums stored in one 0x500 block of SRAM are consistent with the data contents of the block. Calculates the expected checksums via calls to $ef0734 and $ef077b.
Inputs
- accumulator: SRAM block idx (0-5)
Outputs
- accumulator:
0000
on consistent checksums.ffff
if inconsistent.
$ef0825-$ef088e: Validate Save Slot Checksums
Validates the checksums stored in two 0x500 blocks of SRAM, redundantly storing a single save game slot, via calls to $ef07c0. Inconsistent blocks are reset via a call to $ef05a9, and if an inconsistency is found in only one block, the good block is copied over the bad block via a call to $ef06a2.
If both blocks of the save slot fail validation, a bit flag of the save slot is merged into WRAM $7e9f79. The EarthBound main file select menu will subsequently display an error message to apologize for losing a saved game.
Inputs
- accumulator: Save slot idx (0-2)
$ef088f-$ef0a4c: Save Persistent WRAM to SRAM Block
Copies all WRAM Persistent Data to the data section of one 0x500 block of SRAM. Implemented via 3 separate calls to memcpy ($c08eed) for each of the 3 sections of persistent WRAM (general game data, the Character Stats Table, and the Flag Value Table) even though all 3 sections are contiguous in both WRAM and SRAM.
After saving data, the checksum is calculated (via $ef0734 and $ef077b) and written to the block. Both checksums are then calculated again, and if either recalculated checksum does not match the checksum in SRAM, the entire process of saving persistent WRAM to the SRAM block starts over, potentially looping forever if SRAM continues to malfunction.
Possible Bug: This scheme of calculating checksums twice seems to be for the purpose of ensuring data is correctly written to SRAM, but since EarthBound only calculates the checksums from data directly read from SRAM, not from the original WRAM data, the extra check wouldn't catch anything wrong unless a checksum itself fails to write correctly or if SRAM is malfunctioning so badly that data is changing between reads.
Inputs
- accumulator: SRAM block idx (0-5)
$ef0a4d-$ef0a67: Save Persistent WRAM to Save Slot
Copies all WRAM Persistent Data to the data section of two 0x500 blocks of SRAM, creating two redundant copies in SRAM. Implemented via calls to $ef088f.
Inputs
- accumulator: Save slot idx (0-2)
$ef0a68-$ef0b9d: Load Save Slot to Persistent WRAM
Reloads WRAM Persistent Data from the data section of a 0x500 block of SRAM. Implemented via 3 separate calls to memcpy ($c08eed) for each of the 3 sections of persistent WRAM (general game data, the Character Stats Table, and the Flag Value Table) even though all 3 sections are contiguous in both WRAM and SRAM.
Always copies from the first of two SRAM blocks redundantly storing data for the save slot without any attempt to validate the integrity of the data or consistency with the second block.
Inputs
- accumulator: Save slot idx (0-2)
$ef0b9e-$ef0bf9: Validate SRAM
Validates the integrity of all of SRAM. Always runs on EarthBound startup.
First checks that the SRAM version tag at SRAM $1ffe matches a hardcoded expectation (0493
), and on mismatch, zeroes all 0x2000 bytes of SRAM using memset ($c08f15). Then validates all block signatures via a call to $ef0683. Then validates checksums for all 3 save slots via calls to $ef0825. Finally, sets the SRAM version tag to the correct value (0493
).
$ef0bfa-$ef0c14: Erase Save Slot
Erases and resets all data in two 0x500 blocks of SRAM, redundantly storing a single save game slot. Implemented via two calls to $ef05a9.
Inputs
- accumulator: Save slot idx (0-2)
$ef0c15-$ef0c3c: Copy Save Slot
Copies all data from two 0x500 blocks of SRAM, redundantly storing a single save game slot, overwriting two 0x500 blocks for a different save slot. Implemented via two calls to $ef06a2.
Inputs
- accumulator: Destination save slot idx (0-2)
- x: Source save slot idx (0-2)