Alchemy

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.

Line 11

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.

Line 41

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.

Line 74

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.

Line 117

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.

Line 156

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.

Line 12

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.

Line 71

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.

Line 107

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.

Line 123

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.

Line 139

StopFlashTimer

void StopFlashTimer(void)

Stops the flash timer and restores the saved interrupt-enable state.

Used by WaitForFlashWrite.

Line 168

ReadFlashByte

u8 ReadFlashByte(u8 *source)

Reads one byte; copied into RAM so the cartridge can be polled during a write.

Used by CopyFlashReadRoutineToRam.

Line 186

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.

Line 192

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).

Line 216

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.

Line 237

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.

Line 255

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.

Line 279

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.

Line 302

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.

Line 13

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.

Line 6

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.

Line 10

const u32 gLink_TestWord

Nothing in ā˜€ļø reads it.

Line 13

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.

Line 16

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.

Line 46

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.

Line 90

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.

Line 109

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.

Line 201

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.

Line 213

Globals, without a comment: gFlash_Handler3, gFlashNumRemainingBytes.

On this page