save
games/tbs/src/system/save on GitHub
atmel.c
games/tbs/src/system/save/atmel.c
Functions
EraseAtmelFlashChip
u16 EraseAtmelFlashChip(void)
Erases the Atmel chip and waits for completion with its configured timing. Returns 0, or 0xc003 when byte 0 has not read 0xff within the chip-erase time. Atmel's erase-chip routine (gFlash_Handler1); nothing in āļø calls through that cell.
EraseAtmelFlashSector
u16 EraseAtmelFlashSector(u16 sector)
Erases one small Atmel sector by programming every byte to 0xff: one of gFlash_ChipAtmelLayout's 512 sectors of 128 bytes, written with interrupts off. Returns 0, or the wait's error with its phase made 2, 0xc002, so that it reads as an erase error.
Used by EraseAtmelFlashBlock.
EraseAtmelFlashBlock
u16 EraseAtmelFlashBlock(u16 sector)
Erases thirty-two small sectors, trying each sector at most twice: the
4 KB of standard sector sector. Atmel's erase-sector routine
(gEraseFlashSector). Returns 0, 0x80ff for a sector above 15, or the error
of a small sector's second failed try, the sectors after it left as they
were.
ProgramAtmelFlashSector
u16 ProgramAtmelFlashSector(u32 sector, const u8 *source)
Programs a small Atmel sector with interrupts disabled, then polls its last
byte. Writes 128 bytes from source after one program command, with no
erase first. Returns 0, or 0xc001 when the last byte does not read back
in time.
Used by ProgramAtmelFlashBlock.
ProgramAtmelFlashBlock
u16 ProgramAtmelFlashBlock(u16 sector, u8 *source)
Programs an Atmel block in small sectors, trying each sector at most twice.
Writes standard sector sector (4 KB) from source 128 bytes at a time,
gFlashNumRemainingBytes counting what is left. Atmel's program routine
(gFlash_Handler0), which SaveState_WriteWorkspaceSlot calls. Returns 0,
0x80ff for a sector above 15, or the error of the small sector that failed
twice.
Globals, without a comment: gFlash_Handler3, gFlashNumRemainingBytes.
flash.c
games/tbs/src/system/save/flash.c
Functions
ReadFlashId
s32 ReadFlashId(void)
Enters flash ID mode, waits for the chip and reads its device and manufacturer IDs. Returns device << 8 | maker; the makers' codes in gFlash_Chips' records are 0xbf (SST), 0x1f (Atmel), 0xc2 (Macronix) and 0x32 (Panasonic). Called by IdentifyFlash.
Used by IdentifyFlash.
IdentifyFlash
s32 IdentifyFlash(void)
Selects matching chip handlers, falling back to the final table entry when unknown. Returns 0 when the chip's id is one of gFlash_Chips' SST, Atmel, Macronix and Panasonic records and 1 when not; either way it installs a record's routines, timings and type (gFlash), for an unknown chip gFlash_ChipUnknown's: SST's routines and timings. Called by SaveState_InitializeWorkspace, up to eight times a frame apart, before each use of the save. It rewrites three of the cells the credits borrow; graphics/credits/credits.c says why that borrowing is harmless.
Used by SaveState_InitializeWorkspace.
FlashTimerIntr
void FlashTimerIntr(void)
Counts down the active flash timeout and marks its expiration. The timer interrupt handler SetFlashTimerIntr hands out; it runs about once a millisecond while StartFlashTimer's timer runs, and sets gFlashTimeoutFlag when gFlashTimerCount reaches 0.
Used by SetFlashTimerIntr.
SetFlashTimerIntr
s32 SetFlashTimerIntr(u8 timerIndex, void (**callback)(void))
Selects a hardware timer and returns its timeout interrupt callback: FlashTimerIntr goes to *callback, for the caller to install as timer timerIndex's interrupt handler. Returns 0, or 1 for a timer above 3 and nothing changed. Called by SaveState_InitializeWorkspace with timer 2.
Used by SaveState_InitializeWorkspace.
StartFlashTimer
void StartFlashTimer(u8 timingIndex)
Starts the selected operation timeout, saving the interrupt-enable state. timingIndex is the operation's phase (WaitForFlashWrite). Interrupts are on while the timer runs, whatever REG_IME was; StopFlashTimer puts the saved value back.
Used by WaitForFlashWrite.
StopFlashTimer
void StopFlashTimer(void)
Stops the flash timer and restores the saved interrupt-enable state.
Used by WaitForFlashWrite.
ReadFlashByte
u8 ReadFlashByte(u8 *source)
Reads one byte; copied into RAM so the cartridge can be polled during a write.
Used by CopyFlashReadRoutineToRam.
CopyFlashReadRoutineToRam
void CopyFlashReadRoutineToRam(void *destination)
Copies the byte reader to RAM and installs its Thumb entry point.
destination takes the code from ReadFlashByte up to this function, and
gFlashReadRoutine points into it: the callers pass a buffer in their own
stack frame, so the reader is good only until that caller returns.
Used by EraseAtmelFlashBlock, EraseAtmelFlashChip, EraseFlashChip, EraseFlashSector, ProgramAtmelFlashBlock, ProgramFlashSector, ProgramFlashSectorWithEraseRetry, ReadFlashId.
WaitForFlashWrite
u16 WaitForFlashWrite(u8 timingIndex, volatile u8 *address, u8 expected)
Polls for the expected byte until success or timeout, returning an operation error. Every chip's wait routine (gFlash_Handler3). timingIndex is the phase, 1 programming, 2 a sector erase and 3 a chip erase: it picks the max-time row and is the error's low byte. Returns 0 once address reads expected, else 0xc000 | timingIndex. Reads through gFlashReadRoutine, which the caller must have copied to RAM (CopyFlashReadRoutineToRam).
ReadFlashCore
void ReadFlashCore(const u8 *source, u8 *destination, u32 size)
Copies flash bytes into RAM; this routine executes from a RAM copy.
Used by ReadFlash.
ReadFlash
void ReadFlash(u16 sector, u32 offset, u8 *destination, s32 size)
Copies the RAM reader and reads a range using the standard sector geometry.
Reads size bytes from offset in sector into destination, running
ReadFlashCore from a copy in a 128-byte local. Sectors are addressed with
gFlash_ChipUnknown's 4 KB geometry whatever the chip, which is the same:
every record gFlash can point to has 4 KB sectors. Called by the save code
for a sector's record and a file's summary (runtime/runtime/save.c).
Used by SaveState_LoadSummaryRecords, SaveState_ReadSlotAndCheckChecksum.
VerifyFlashCore
u8 *VerifyFlashCore(u8 *left, u8 *right, u16 size)
Returns the first differing byte in the right buffer, or NULL when all bytes match.
Used by Flash_VerifySector.
Flash_VerifySector
s32 Flash_VerifySector(u16 sector, s32 source)
Copies the verifier to RAM and compares a standard flash sector with source
data. Returns 0 when sector sector holds the 4 KB at source, else the
address of its first differing byte. Called by SaveState_WriteWorkspaceSlot
after each write.
Used by SaveState_WriteWorkspaceSlot.
Types, without a comment: FlashByteRead, FlashReadCore, FlashVerifyCore.
Globals, without a comment: gFlash_Chips, gFlash_Handler3, gFlash_Handler0, gFlash_Handler1, gEraseFlashSector, gFlash_Handler4, gFlashTimerCount, gFlashTimeoutFlag, gFlashTimerNum, gFlashTimerReg, gFlashSavedIme.
program_flash_sector.c
games/tbs/src/system/save/program_flash_sector.c
Functions
ProgramFlashSector
u16 ProgramFlashSector(u16 sector, u8 *source)
Erases a standard sector and programs bytes until completion or an error.
The program routine (gFlash_Handler0) of the Macronix and Panasonic chips,
which SaveState_WriteWorkspaceSlot calls with 4 KB at source. Returns 0,
0x80ff for a sector above 15, the erase's error, or 0xc001 for the first
byte that did not read back in time; gFlashNumRemainingBytes is left at
the bytes not written.
Globals, without a comment: gFlashNumRemainingBytes.
savedata.c
games/tbs/src/system/save/savedata.c
Globals
gSave_Signature
const u8 gSave_Signature[]
The signature that marks a save record: SaveState_InitializeWorkspace counts a sector as a save only when its first seven bytes match it.
Used by SaveState_InitializeWorkspace.
gSave_HeaderTemplate
const u8 gSave_HeaderTemplate[8]
The record header's first eight bytes, with no terminator. The writers copy it over a new header: the seven signature bytes, and a recordId byte ('T') they then replace.
Used by SaveState_InvalidateSlot, SaveState_WriteRecord.
gLink_TestWord
const u32 gLink_TestWord
Nothing in āļø reads it.
Also, globals without a comment: gLink_TestDataA, gLink_TestDataB.
sst.c
games/tbs/src/system/save/sst.c
Functions
EraseFlashChip
u16 EraseFlashChip(void)
Issues the chip-erase command and waits for an erased byte. Returns 0, or 0xc003 when byte 0 has not read 0xff within the chip-erase time. The erase-chip routine (gFlash_Handler1) of every chip but Atmel; nothing in āļø calls through that cell.
EraseFlashSector
u16 EraseFlashSector(u16 sector)
Erases one of sixteen sectors, restoring the cartridge wait setting afterward: the chip's own SRAM wait while erasing, 3 after. Returns 0, 0x80ff for a sector above 15, or 0xc002 when the sector's first byte has not read 0xff within the sector-erase time. The erase-sector routine (gEraseFlashSector) of every chip but Atmel, and the first step of ProgramFlashSector and ProgramFlashSectorWithEraseRetry.
Used by ProgramFlashSector, ProgramFlashSectorWithEraseRetry.
ProgramFlashByte
u16 ProgramFlashByte(u8 *source, u8 *destination)
Issues a byte-program command and waits for its destination to match. Returns 0, or 0xc001 when the byte does not read back in time. The caller sets the wait state and the RAM byte reader first.
Used by ProgramFlashSector, ProgramFlashSectorWithEraseRetry.
ProgramFlashSectorWithEraseRetry
u16 ProgramFlashSectorWithEraseRetry(u16 sector, u8 *source)
Erases and verifies a sector with retries, then programs its bytes. The
program routine (gFlash_Handler0) of the SST and unknown chips, which
SaveState_WriteWorkspaceSlot calls with 4 KB at source. Returns 0,
0x80ff for a sector above 15, the last erase or check error after 81
failed tries (0x8004 for a sector that would not read blank), or 0xc001
for the first byte that did not read back in time.
CountRemainingErasedFlashBytes
s32 CountRemainingErasedFlashBytes(u8 *cursor)
Returns how many bytes remain when the first non-erased byte is found: 0 when the sector at cursor reads 0xff throughout. Runs from a RAM copy (ProgramFlashSectorWithEraseRetry).
Used by ProgramFlashSectorWithEraseRetry.
RunFlashEraseVerifier
s32 RunFlashEraseVerifier(u8 *sector, s32 (*verify)(u8 *))
Converts a nonzero erased-byte remainder into the flash verification error:
returns 0 when verify finds the sector blank, else 0x8004.
Used by ProgramFlashSectorWithEraseRetry.
Globals, without a comment: gFlash_Handler3, gFlashNumRemainingBytes.