Since there is no documentation on the Mega Memory Card, I thought I'd write some notes on retrieving save games directly off the MMC.
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:
From the above data, the RLE marker is 0xEE. Each 0xEE (except the 1st one) in the save game data designates a run length encoded item consisting of 3 bytes. Following the RLE marker, the 2nd byte is the count (number of times to repeat) and the 3rd byte is the byte that repeats.
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:
Within the flash, the number of save games is stored at 0x7FF00 (Bank 0x9F, Address 0x7F00).
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).
2) The save mapping table starts at 0x7F000 (Bank 0x9F, Address 0x7000) and ends at 0x7F7EF. Each byte in the mapping table represents 0x100 (256) bytes. The mapping byte represents the save game from the save name table (starting with 01). The 1st byte in the mapping table corresponds to 0x0000-0x00FF in the flash, the 2nd byte corresponds to 0x0100-0x01FF, and so on.
To retrieve a save, start by checking the number of save games at 0x7FF00 (Bank 0x9F, Address 0x7F00). Read the save name table at 0x7F800 (Bank 0x9F, Address 0x7800) to get the first save name. Scan the mapping table at 0x7F000 (Bank 0x9F, Address 0x7000) to find the "01" blocks. Convert the position within the mapping table to the actual Flash address and start reading the compressed data. The 1st byte in the compressed data is stored as the RLE marker and read the rest of the bytes in the associated blocks decompressing as needed. Repeat the steps until all the save games are processed.
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!
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:
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
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
From the above data, the RLE marker is 0xEE. Each 0xEE (except the 1st one) in the save game data designates a run length encoded item consisting of 3 bytes. Following the RLE marker, the 2nd byte is the count (number of times to repeat) and the 3rd byte is the byte that repeats.
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:
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
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
Within the flash, the number of save games is stored at 0x7FF00 (Bank 0x9F, Address 0x7F00).
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:
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
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
2) The save mapping table starts at 0x7F000 (Bank 0x9F, Address 0x7000) and ends at 0x7F7EF. Each byte in the mapping table represents 0x100 (256) bytes. The mapping byte represents the save game from the save name table (starting with 01). The 1st byte in the mapping table corresponds to 0x0000-0x00FF in the flash, the 2nd byte corresponds to 0x0100-0x01FF, and so on.
Code:
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
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
To retrieve a save, start by checking the number of save games at 0x7FF00 (Bank 0x9F, Address 0x7F00). Read the save name table at 0x7F800 (Bank 0x9F, Address 0x7800) to get the first save name. Scan the mapping table at 0x7F000 (Bank 0x9F, Address 0x7000) to find the "01" blocks. Convert the position within the mapping table to the actual Flash address and start reading the compressed data. The 1st byte in the compressed data is stored as the RLE marker and read the rest of the bytes in the associated blocks decompressing as needed. Repeat the steps until all the save games are processed.
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!