I've been working on a standalone GB cart reader. I recently added support for the Mega Memory Card. The MMC is used to backup and restore save games. The MMC is made by Datel and looks like their Gameshark except for its clear yellow housing. Like the Gameshark, the MMC sits between the Gameboy and the cart.
The MMC uses a SST 28SF040 Flash EEPROM to store the save games. The Flash uses banks 0x80-0x9F. Access to the Flash banks is by writing the bank # to 0x2000. The save data sits in 0x4000-0x7FFF. Flash commands are written to 0x4000.
The save data is stored from 0x0000-0x7EFFF in the Flash. The save data is RLE compressed. The 1st byte of each stored save game is the RLE marker. The RLE marker changes based on the individual save game data. The MMC selects a byte not used by the individual save game. In the case where a save game uses all individual bytes (0x00-0xFF) then the MMC defaults to using 0x00 as the RLE marker. Bytes are stored as is if they don't repeat.
RLE compressed save data at 0x0000:
Code: Select all
EE EE 49 00 01 02 04 01 0B 01 05 05 0A 05 04 09
03 07 03 EE 04 00 01 02 00 04 01 01 EE 1C 00 B4
01 1F 3F F9 F5 F2 F7 F7 E6 F8 7C FA FF FE FC C0
13 0F 17 62 60 60 64 E1 C1 00 10 08 04 03 01 02
07 1F 3F 7F 7F 1F EE 10 00 02 01 81 80 40 04 24
A6 23 03 11 10 80 08 00 64 B2 38 79 F8 71 7B 77
E7 6B B7 17 0F 0F 07 0F FC 19 21 91 91 10 60 EE
12 00 03 81 C0 F0 78 7F 3F 3B BD BC BC EE 02 3E
3F 1F 1F 0F 83 C1 C2 E4 E0 F0 F0 F1 F2 EC F0 80
In the above data, the 2nd byte is the 0xEE marker followed by 0x49 (count) and 0x00 (byte). This means that the start of the save game consists of 0x4A (0x49 + 1) bytes of 0x00.
Decompressed save data:
Code: Select all
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 01 02 04 01 0B 01
There are two tables at the end of the Flash that store the save names and the save mapping:
1) The save name table starts at 0x7F800 (Bank 0x9F, Address 0x7800) and ends at 0x7FEFF. Each save name uses 0x10 bytes padded with trailing spaces (0x20). Empty entries are padded with spaces (0x20).
Code: Select all
50 4F 4B 45 4D 4F 4E 20 52 45 44 20 20 20 20 20 // POKEMON RED
50 4F 4B 45 4D 4F 4E 20 42 4C 55 45 20 20 20 20 // POKEMON BLUE
50 4F 4B 45 4D 4F 4E 20 59 45 4C 4C 4F 57 20 20 // POKEMON YELLOW
50 4F 4B 45 4D 4F 4E 20 52 45 44 32 20 20 20 20 // POKEMON RED2
59 45 4C 4C 20 20 20 20 20 20 20 20 20 20 20 20 // YELL
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
Code: Select all
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 // POKEMON RED
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 // POKEMON RED
01 01 01 01 01 01 01 01 01 01 01 01 01 02 02 02 // POKEMON RED - POKEMON BLUE
02 02 02 02 02 02 03 03 03 03 03 03 03 03 03 03 // POKEMON BLUE - POKEMON YELLOW
03 03 03 03 03 03 03 03 03 03 03 03 03 04 04 04 // POKEMON YELLOW - POKEMON RED2
04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 // POKEMON RED2
04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 // POKEMON RED2
04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 // POKEMON RED2
04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 // POKEMON RED2
04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 04 // POKEMON RED2
04 04 04 04 04 04 04 04 04 05 05 05 05 05 05 05 // POKEMON RED2 - YELL
05 05 05 00 00 00 00 00 00 00 00 00 00 00 00 00 // YELL
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Be mindful when crossing between banks in the compressed data. Watch also for instances when an RLE marker falls near the end of a block (< 3 bytes from the end) with the remaining count and/or byte items running into the next block.
A couple other Flash items:
1) The Flash ID is BF04. The ID is retrieved by writing command 0x90 to 0x4000 then reading back 0x4000 for the Manufacturer Code followed by writing command 0x90 to 0x4001 then reading back 0x4001 for the Device Code. After reading the Flash ID, write command 0xFF to 0x4000 to reset the flash.
2) To erase the Flash, write 0x80 to 0x2000 to switch the bank. The flash requires read sequences of 7 bytes to unprotect/protect the flash. To unprotect the flash, read 0x5823, 0x5820, 0x5822, 0x4418, 0x441B, 0x4419, 0x441A. Erase the flash by writing command 0x30 to 0x4000 twice. After the chip erase, protect the flash by reading 0x5823, 0x5820, 0x5822, 0x4418, 0x441B, 0x4419, 0x440A.
Hope this helps!