Remove EEPROM

This commit is contained in:
Agent-11 / Agent X 2021-12-24 13:12:46 -05:00
parent 93c0487f53
commit 0148ca818b
1 changed files with 0 additions and 251 deletions

View File

@ -17,8 +17,6 @@
#define MENU_DATA_MAGIC 0x4849
#define SAVE_FILE_MAGIC 0x4441
STATIC_ASSERT(sizeof(struct SaveBuffer) == EEPROM_SIZE, "eeprom buffer size must match");
extern struct SaveBuffer gSaveBuffer;
struct WarpCheckpoint gWarpCheckpoint;
@ -46,207 +44,6 @@ s8 gLevelToCourseNumTable[] = {
STATIC_ASSERT(ARRAY_COUNT(gLevelToCourseNumTable) == LEVEL_COUNT - 1,
"change this array if you are adding levels");
// This was probably used to set progress to 100% for debugging, but
// it was removed from the release ROM.
static void stub_save_file_1(void) {
UNUSED s32 pad;
}
/**
* Byteswap all multibyte fields in a SaveBlockSignature.
*/
static inline void bswap_signature(struct SaveBlockSignature *data) {
data->magic = BSWAP16(data->magic);
data->chksum = BSWAP16(data->chksum); // valid as long as the checksum is a literal sum
}
/**
* Byteswap all multibyte fields in a MainMenuSaveData.
*/
static inline void bswap_menudata(struct MainMenuSaveData *data) {
for (int i = 0; i < NUM_SAVE_FILES; ++i)
data->coinScoreAges[i] = BSWAP32(data->coinScoreAges[i]);
data->soundMode = BSWAP16(data->soundMode);
#ifdef VERSION_EU
data->language = BSWAP16(data->language);
#endif
bswap_signature(&data->signature);
}
/**
* Byteswap all multibyte fields in a SaveFile.
*/
static inline void bswap_savefile(struct SaveFile *data) {
data->capPos[0] = BSWAP16(data->capPos[0]);
data->capPos[1] = BSWAP16(data->capPos[1]);
data->capPos[2] = BSWAP16(data->capPos[2]);
data->flags = BSWAP32(data->flags);
bswap_signature(&data->signature);
}
/**
* Read from EEPROM to a given address.
* The EEPROM address is computed using the offset of the destination address from gSaveBuffer.
* Try at most 4 times, and return 0 on success. On failure, return the status returned from
* osEepromLongRead. It also returns 0 if EEPROM isn't loaded correctly in the system.
*/
static s32 read_eeprom_data(void *buffer, s32 size) {
s32 status = 0;
if (gEepromProbe != 0) {
s32 triesLeft = 4;
u32 offset = (u32)((u8 *) buffer - (u8 *) &gSaveBuffer) / 8;
do {
block_until_rumble_pak_free();
triesLeft--;
status = osEepromLongRead(&gSIEventMesgQueue, offset, buffer, size);
release_rumble_pak_control();
} while (triesLeft > 0 && status != 0);
}
return status;
}
/**
* Write data to EEPROM.
* The EEPROM address was originally computed using the offset of the source address from gSaveBuffer.
* Try at most 4 times, and return 0 on success. On failure, return the status returned from
* osEepromLongWrite. Unlike read_eeprom_data, return 1 if EEPROM isn't loaded.
*/
static s32 write_eeprom_data(void *buffer, s32 size, const uintptr_t baseofs) {
s32 status = 1;
if (gEepromProbe != 0) {
s32 triesLeft = 4;
u32 offset = (u32)baseofs >> 3;
do {
block_until_rumble_pak_free();
triesLeft--;
status = osEepromLongWrite(&gSIEventMesgQueue, offset, buffer, size);
release_rumble_pak_control();
} while (triesLeft > 0 && status != 0);
}
return status;
}
/**
* Wrappers that byteswap the data on LE platforms before writing it to 'EEPROM'
*/
static inline s32 write_eeprom_savefile(const u32 file, const u32 slot, const u32 num) {
// calculate the EEPROM address using the file number and slot
const uintptr_t ofs = (u8*)&gSaveBuffer.files[file][slot] - (u8*)&gSaveBuffer;
#if IS_BIG_ENDIAN
return write_eeprom_data(&gSaveBuffer.files[file][slot], num * sizeof(struct SaveFile), ofs);
#else
// byteswap the data and then write it
struct SaveFile sf[num];
bcopy(&gSaveBuffer.files[file][slot], sf, num * sizeof(sf[0]));
for (u32 i = 0; i < num; ++i) bswap_savefile(&sf[i]);
return write_eeprom_data(&sf, sizeof(sf), ofs);
#endif
}
static inline s32 write_eeprom_menudata(const u32 slot, const u32 num) {
// calculate the EEPROM address using the slot
const uintptr_t ofs = (u8*)&gSaveBuffer.menuData[slot] - (u8*)&gSaveBuffer;
#if IS_BIG_ENDIAN
return write_eeprom_data(&gSaveBuffer.menuData[slot], num * sizeof(struct MainMenuSaveData), ofs);
#else
// byteswap the data and then write it
struct MainMenuSaveData md[num];
bcopy(&gSaveBuffer.menuData[slot], md, num * sizeof(md[0]));
for (u32 i = 0; i < num; ++i) bswap_menudata(&md[i]);
return write_eeprom_data(&md, sizeof(md), ofs);
#endif
}
/**
* Sum the bytes in data to data + size - 2. The last two bytes are ignored
* because that is where the checksum is stored.
*/
static u16 calc_checksum(u8 *data, s32 size) {
u16 chksum = 0;
while (size-- > 2) {
chksum += *data++;
}
return chksum;
}
/**
* Verify the signature at the end of the block to check if the data is valid.
*/
static s32 verify_save_block_signature(void *buffer, s32 size, u16 magic) {
struct SaveBlockSignature *sig = (struct SaveBlockSignature *) ((size - 4) + (u8 *) buffer);
if (sig->magic != magic) {
return FALSE;
}
if (sig->chksum != calc_checksum(buffer, size)) {
return FALSE;
}
return TRUE;
}
/**
* Write a signature at the end of the block to make sure the data is valid
*/
static void add_save_block_signature(void *buffer, s32 size, u16 magic) {
struct SaveBlockSignature *sig = (struct SaveBlockSignature *) ((size - 4) + (u8 *) buffer);
sig->magic = magic;
sig->chksum = calc_checksum(buffer, size);
}
/**
* Copy main menu data from one backup slot to the other slot.
*/
static void restore_main_menu_data(s32 srcSlot) {
s32 destSlot = srcSlot ^ 1;
// Compute checksum on source data
add_save_block_signature(&gSaveBuffer.menuData[srcSlot], sizeof(gSaveBuffer.menuData[srcSlot]), MENU_DATA_MAGIC);
// Copy source data to destination
bcopy(&gSaveBuffer.menuData[srcSlot], &gSaveBuffer.menuData[destSlot], sizeof(gSaveBuffer.menuData[destSlot]));
// Write destination data to EEPROM
write_eeprom_menudata(destSlot, 1);
}
static void save_main_menu_data(void) {
if (gMainMenuDataModified) {
// Compute checksum
add_save_block_signature(&gSaveBuffer.menuData[0], sizeof(gSaveBuffer.menuData[0]), MENU_DATA_MAGIC);
// Back up data
bcopy(&gSaveBuffer.menuData[0], &gSaveBuffer.menuData[1], sizeof(gSaveBuffer.menuData[1]));
// Write to EEPROM
write_eeprom_menudata(0, 2);
gMainMenuDataModified = FALSE;
}
}
static void wipe_main_menu_data(void) {
bzero(&gSaveBuffer.menuData[0], sizeof(gSaveBuffer.menuData[0]));
// Set score ages for all courses to 3, 2, 1, and 0, respectively.
gSaveBuffer.menuData[0].coinScoreAges[0] = 0x3FFFFFFF;
gSaveBuffer.menuData[0].coinScoreAges[1] = 0x2AAAAAAA;
gSaveBuffer.menuData[0].coinScoreAges[2] = 0x15555555;
gMainMenuDataModified = TRUE;
save_main_menu_data();
}
static s32 get_coin_score_age(s32 fileIndex, s32 courseIndex) {
return (gSaveBuffer.menuData[0].coinScoreAges[fileIndex] >> (2 * courseIndex)) & 0x3;
}
@ -290,52 +87,6 @@ static void touch_high_score_ages(s32 fileIndex) {
}
}
/**
* Copy save file data from one backup slot to the other slot.
*/
static void restore_save_file_data(s32 fileIndex, s32 srcSlot) {
s32 destSlot = srcSlot ^ 1;
// Compute checksum on source data
add_save_block_signature(&gSaveBuffer.files[fileIndex][srcSlot],
sizeof(gSaveBuffer.files[fileIndex][srcSlot]), SAVE_FILE_MAGIC);
// Copy source data to destination slot
bcopy(&gSaveBuffer.files[fileIndex][srcSlot], &gSaveBuffer.files[fileIndex][destSlot],
sizeof(gSaveBuffer.files[fileIndex][destSlot]));
// Write destination data to EEPROM
write_eeprom_savefile(fileIndex, destSlot, 1);
}
/**
* Check if the 'EEPROM' save has different endianness (e.g. it's from an actual N64).
*/
static u8 save_file_need_bswap(const struct SaveBuffer *buf) {
// check all signatures just in case
for (int i = 0; i < 2; ++i) {
if (buf->menuData[i].signature.magic == BSWAP16(MENU_DATA_MAGIC))
return TRUE;
for (int j = 0; j < NUM_SAVE_FILES; ++j) {
if (buf->files[j][i].signature.magic == BSWAP16(SAVE_FILE_MAGIC))
return TRUE;
}
}
return FALSE;
}
/**
* Byteswap all multibyte fields in a SaveBuffer.
*/
static void save_file_bswap(struct SaveBuffer *buf) {
bswap_menudata(buf->menuData + 0);
bswap_menudata(buf->menuData + 1);
for (int i = 0; i < NUM_SAVE_FILES; ++i) {
bswap_savefile(buf->files[i] + 0);
bswap_savefile(buf->files[i] + 1);
}
}
void save_file_do_save(s32 fileIndex) {
if (fileIndex < 0 || fileIndex >= NUM_SAVE_FILES)
return;
@ -386,7 +137,6 @@ void save_file_load_all(void) {
}
gSaveFileModified = TRUE;
gMainMenuDataModified = TRUE;
stub_save_file_1();
}
/**
@ -614,7 +364,6 @@ void save_file_set_sound_mode(u16 mode) {
gSaveBuffer.menuData[0].soundMode = mode;
gMainMenuDataModified = TRUE;
save_main_menu_data();
}
u16 save_file_get_sound_mode(void) {