This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
mario_kart_64:eeprom_map [2016/06/27 04:26] shygoo [Record Format] |
mario_kart_64:eeprom_map [2017/06/23 10:49] (current) shygoo ↷ Links adapted because of a move operation |
||
---|---|---|---|
Line 5: | Line 5: | ||
===== Top level structure ===== | ===== Top level structure ===== | ||
^ Offset ^ Length ^ Description ^ | ^ Offset ^ Length ^ Description ^ | ||
- | | 0x000 | 24 | Luigi raceway record set | | + | | 0x000 | 24 | Luigi raceway [[#record_format|record set]] | |
| 0x018 | 24 | Moo Moo Farm record set | | | 0x018 | 24 | Moo Moo Farm record set | | ||
| 0x030 | 24 | Koopa Troopa Beach record set | | | 0x030 | 24 | Koopa Troopa Beach record set | | ||
Line 21: | Line 21: | ||
| 0x150 | 24 | Banshee Boardwalk record set | | | 0x150 | 24 | Banshee Boardwalk record set | | ||
| 0x168 | 24 | Rainbow Road record set | | | 0x168 | 24 | Rainbow Road record set | | ||
- | | 0x180 | 4 | Unknown (Unused padding?) | | + | | 0x180 | 4 | 50cc trophy information | |
+ | | 0x181 | 4 | 100cc trophy information | | ||
+ | | 0x182 | 4 | 150cc trophy information | | ||
+ | | 0x183 | 4 | Extra trophy information | | ||
| 0x184 | 1 | Audio setting | | | 0x184 | 1 | Audio setting | | ||
- | | 0x185 | 1 | Unknown (Unused padding?) | | + | | 0x185 | 1 | Unused, padding | |
- | | 0x186 | 2 | Unknown (Checksum?) | | + | | 0x186 | 2 | [[#x186|Checksum of 0x180-0x184]] | |
- | | 0x188 | 48 | Copies of all 1st records | | + | | 0x188 | 12 | Copies of Mushroom Cup 1st Record Times | |
+ | | 0x194 | 12 | Copies of Flower Cup 1st Record Times | | ||
+ | | 0x1A0 | 12 | Copies of Mushroom Cup Lap Record Times | | ||
+ | | 0x1AC | 12 | Copies of Flower Cup Lap Record Times | | ||
| 0x1B8 | 6 | Unknown (Padding?) | | | 0x1B8 | 6 | Unknown (Padding?) | | ||
- | | 0x1BE | 2 | Unknown (Checksum?) | | + | | 0x1BE | 2 | [[[#x1BE_and_0x1F6|Checksum of 0x188-0x1BD]] | |
- | | 0x1C0 | 48 | Another 16 records (What for?) | | + | | 0x1C0 | 12 | Copies of Star Cup 1st Record Times | |
+ | | 0x1CC | 12 | Copies of Special Cup 1st Record Times | | ||
+ | | 0x1D8 | 12 | Copies of Star Cup Lap Record Times | | ||
+ | | 0x1E4 | 12 | Copies of Special Cup Lap Record Times | | ||
| 0x1F0 | 6 | Unknown (Padding?) | | | 0x1F0 | 6 | Unknown (Padding?) | | ||
- | | 0x1F6 | 2 | Unknown (Checksum?) | | + | | 0x1F6 | 2 | [[#x1BE_and_0x1F6|Checksum of 0x1C0-0x1F5]] | |
| 0x1FC | 1 | Copy of audio setting (0x184) | | | 0x1FC | 1 | Copy of audio setting (0x184) | | ||
- | | 0x1FD | 1 | Copy of Unknown (Unused padding?) (0x185) | | + | | 0x1FD | 1 | Copy of Unused, padding? (0x185) | |
- | | 0x1FE | 2 | Copy of Unknown (Checksum?) (0x186) | | + | | 0x1FE | 2 | Copy of [[#x186|Checksum of 0x180-0x184]] | |
===== Course record set ===== | ===== Course record set ===== | ||
Line 47: | Line 56: | ||
| 0x012 | 1 | Records exist (00 or 01) | | | 0x012 | 1 | Records exist (00 or 01) | | ||
| 0x013 | 4 | Unknown (Unused?) | | | 0x013 | 4 | Unknown (Unused?) | | ||
- | | 0x017 | 1 | Unknown (Checksum?) | | + | | 0x017 | 1 | [[#record_checksum|Record Checksum]] | |
- | {{:mk64:yjuty.png?200}} | + | {{mario_kart_64:yjuty.png?200}} |
===== Record Format ===== | ===== Record Format ===== | ||
Line 69: | Line 78: | ||
| 6 | PEACH | | | 6 | PEACH | | ||
| 7 | BOWSER | | | 7 | BOWSER | | ||
- | | 8 | (none) | | ||
The default value applied to record entries is ''0xC02709'', which is 100 minutes and Mario as the character selection. | The default value applied to record entries is ''0xC02709'', which is 100 minutes and Mario as the character selection. | ||
+ | |||
+ | ===== Checksums ===== | ||
+ | |||
+ | ==== Record Checksum ==== | ||
+ | Each record contains a 1-byte checksum at offset 0x17 and is computed as follows: | ||
+ | <code c> | ||
+ | unsigned char RecordChecksum(unsigned char data[], int offset) | ||
+ | { | ||
+ | int checksum = 0; | ||
+ | for (int rec = 0; rec < 7; rec++) { | ||
+ | for (int i = 0; i < 3; i++) { | ||
+ | unsigned char val = data[offset + rec * 3 + i]; | ||
+ | checksum += (val * (i + 1)) + rec; | ||
+ | } | ||
+ | } | ||
+ | return (unsigned char)(checksum & 0xFF); | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | ==== 0x186 ==== | ||
+ | 0x186 is a checksum of offsets 0x180-0x184 and is computed by procedure at 800B492C and 0x187 is computed by procedure at 800B49E4 | ||
+ | |||
+ | <code c>eeprom[0x186] = (eeprom[0x180] + 1 + ((eeprom[0x181] + 1) * 2) + 1 + ((eeprom[0x182] + 1) * 3) + 2 + ((eeprom[0x183] + 1) * 4) + 3 + ((eeprom[0x184] + 1) * 5) + 4) & 0xFF | ||
+ | eeprom[0x187] = (eeprom[0x186] + 0x5A) & 0xFF</code> | ||
+ | |||
+ | ==== 0x1BE and 0x1F6 ==== | ||
+ | |||
+ | <code c> | ||
+ | // eeprom: base of EEPROM data | ||
+ | // offset: offset in eeprom to checksum (either 0x188 or 0x1C0) | ||
+ | void Checksum1BEand1F6(unsigned char eeprom[], int offset) | ||
+ | { | ||
+ | int checksum = 0; | ||
+ | int blockOffset = offset; | ||
+ | for (int block = 0; block < 3; block++) { | ||
+ | int loopOffset = blockOffset + 1; | ||
+ | checksum += (eeprom[blockOffset] + 1) * (block + 1); | ||
+ | for (int byteOff = 1; byteOff < 0x11; byteOff += 0x4) { | ||
+ | int mult2 = (eeprom[loopOffset] + 1) * (block + 1); | ||
+ | checksum += mult2 + byteOff; | ||
+ | int mult3 = (eeprom[loopOffset + 1] + 1) * (block + 1); | ||
+ | checksum += mult3 + byteOff + 1; | ||
+ | int mult4 = (eeprom[loopOffset + 2] + 1) * (block + 1); | ||
+ | checksum += mult4 + byteOff + 2; | ||
+ | int mult5 = (eeprom[loopOffset + 3] + 1) * (block + 1); | ||
+ | checksum += mult5 + byteOff + 3; | ||
+ | loopOffset += 4; | ||
+ | } | ||
+ | blockOffset += 0x11; | ||
+ | } | ||
+ | eeprom[offset + 0x36] = (unsigned char)(checksum & 0xFF); | ||
+ | eeprom[offset + 0x37] = (unsigned char)((data[offset + 0x36] + 0x5A) & 0xFF); | ||
+ | } | ||
+ | </code> | ||
===== References ===== | ===== References ===== | ||
* http://origami64.net/showthread.php?tid=47&pid=2936#pid2936 | * http://origami64.net/showthread.php?tid=47&pid=2936#pid2936 |