Mega Memory Card

Discussion of programming and development for the original Game Boy and Game Boy Color.
Post Reply
skaman
Posts: 85
Joined: Fri Oct 24, 2014 1:56 am

Mega Memory Card

Post by skaman » Wed Nov 30, 2016 4:15 pm

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:

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
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: 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 
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: 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 
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: 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
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!

Post Reply