This is an old revision of the document!
Blast Corps uses a 512 byte EEPROM in the cartridge to save game state of levels unlocked, record times, and tutorials given. A copy of the EEPROM data is stored at 80364A40 in RAM.
Offset | Length | Description |
---|---|---|
0x000 | 0x8 | Name (ASCII name entered during game start) |
0x008 | 0x1 | Selected Level |
0x009 | 0x1 | Unknown? |
0x00A | 0x2 | Points |
0x00C | 0x1 | Rank |
0x00D | 0x3 | Unknown? |
0x010 | 0x4 | Vehicles |
0x014 | 0x4 | Total Accumulated Money |
0x018 | 0x3C | Level Medals |
0x054 | 0x3C | Level Paths |
0x090 | 0x1 | Scientists |
0x091 | 0x1 | Event |
0x092 | 0x3C | Level Vehicles |
0x0CE | 0x12 | Tutorials |
0x0E0 | 0xE | Unknown? |
0x0EE | 0x1 | Cut Scenes |
0x0EF | 0x4 | Unknown? |
0x0F3 | 0x1 | Control Mode |
0x0F4 | 0x8 | Unknown? |
0x0FC | 0x4 | Checksum |
0x100 | 0xF0 | Level Times |
0x1F0 | 0x8 | Language 0x1982198219821982 = English 0x1945194519451945 = German |
0x1F8 | 0x8 | Footer |
There is a time recorded for each level as an 4-byte unsigned integer in big endian in units of 1/655360 of a second. To convert these values to seconds, divide the value by 655360. e.g., if the value is 0x00E4554E = 14964046, then 14964046/655360 = 22.8 seconds.
The 4-byte checksum at 0xFC is computed using functions that are stored in the hd_front_end_text.raw gzip file. The UpdateChecksum/801F2C84 function takes a pointer to the start of the EEPROM data in A0 and an offset to compute the checksum over and store result in A1. It uses helper function ComputeChecksumByte/80205760 to compute each round.
u8 ComputeChecksumByte(u8 *data) // 80205760 { u8 cksum = 0; u8 key; for (int i = 0; i < 33; i++) { // 80205760 for (int j = 7; j >= 0; j--) { // 80205760 if (cksum & 0x80) { key = 0x85; } else { key = 0x00; } cksum = cksum << 1; if (i == 0x20) { cksum = cksum & 0xFF; } else { // 80205760 u8 mask = data[i] & (1 << j); u8 bit = mask ? 1 : 0; cksum |= bit; } cksum = cksum ^ key; } } return cksum; } u8 UpdateChecksum(u8 *eeprom, int length) // 801F2C84 { u8 buf[4]; // sp28-sp2B int blocks = (length + 0x7F) >> 7; // zero out existing EEPROM checksum and local buffer for (int i = 0; i < 4; i++) { // .Lproc_801F2C84_28: 801F2CAC buf[i] = 0; eeprom[length + i - 4] = buf[i]; } // 801F2CE8 if (blocks > 0) { for (int i = 0; i < blocks; i++) { //.Lproc_801F2C84_78: for (int j = 0; j < 4; j++) { //.Lproc_801F2C84_7C: int offset = (i << 7) + (j << 5); if (offset < length) { u8 cksum = ComputeChecksumByte(eeprom + offset); buf[j] += (cksum & 0xFF); } } } } // copy the checksum into the EEPROM data for (int i = 0; i < 4; i++) { // .Lproc_801F2C84_F8: eeprom[length + i - 4] = buf[i]; } return 0; }
The EEPROM functions are all stored in the hd_front_end_text.raw gzip file. In the (U) (1.0) ROM, these are inflated to 0x801E7000.
RAM/offset | Function |
---|---|
801F1944/00A944 | int ManageEeprom(u8 block, u8 mode) |
801F2C84/00BC84 | u8 UpdateChecksum(u8 *eeprom, int length) |
80205760/01E760 | u8 ComputeChecksumByte(u8 *data) |
80202850/01B850 | s32 osEepromProbe(OSMesgQueue *mq) |
802042A0/01D2A0 | s32 osEepromLongWrite(OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) |
802043E0/01D3E0 | s32 osEepromLongRead(OSMesgQueue *mq, u8 address, u8 *buffer, int nbytes) |
80204BE0/01DBE0 | s32 osEepromWrite(OSMesgQueue *mq, u8 address, u8 *buffer) |
802050C0/01E0C0 | s32 osEepromRead(OSMesgQueue *mq, u8 address, u8 *buffer) |