Net de Get GB Mobile Adapter Server Technical Documentation 0.2
September 23, 2018
Shonumi aka D.S. Baxter

***************************************************
1. Introduction
***************************************************

Net de Get is a Game Boy Color game published by Konami and released on June 12, 2001. In addition to being one of the select few GBC games to support the GB Mobile Adapter, it is the only known game to use the MBC6. This special cartridge allowed the Game Boy to download minigames from the internet and save them locally to flash memory for offline play. Players could browse an online list of available software and purchase them. 


***************************************************
2. Server Structure
***************************************************

Net de Get is currently known to access the following URLs:

* http://gameboy.datacenter.ne.jp/cgb/download?name=/A4/CGB-BMVJ/h0000.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/A4/CGB-BMVJ/RomList.cgb
* http://gameboy.datacenter.ne.jp/cgb/download?name=/A4/CGB-BMVJ/*

Although a few other URLs are present within the ROM, the above are the only ones observed in actual use.


***************************************************
3. h0000.cgb
***************************************************

Once some of the default minigames have been played, the "セーバ" or "Server" option in the main menu unlocks. After the user's password is given, this file is then downloaded via HTTP GET. The purpose of h0000.cgb is simply to display the text "ミニゲームリスト" or "Minigame List". Selecting this downloads RomList.cgb via HTTP GET. The format of h0000.cgb is described below:

----------------------------------
Header - 4 bytes
----------------------------------
0x0000 - "M"			::	0x4D
0x0001 - "N"			::	0x4E
0x0002 - "G"			::	0x47
0x0003 - "L"			::	0x4C

----------------------------------
Text offset - 6 bytes
----------------------------------
0x0004 - Offset			::	Offset to text string. Calculated as 10 + (Offset * 5).
0x0005 - ???			:: 	0x0005 through 0x0009 seem to be ignored.
0x0006 - ???			::
0x0007 - ???			::
0x0008 - ???			::
0x0009 - ???			::

As far as anyone knows, this file only had one menu item, and the "ミニゲームリスト" text itself did not change. The game code appears to only process one offset to whatever text it wants to print. Additionally, the game manual shows only one menu item in a screenshot.


***************************************************
4. RomList.cgb
***************************************************

After downloading h0000.cgb, the next file is RomList.cgb. This file contains a list of all available minigames the server has to offer. It also displays how many 8KB blocks of flash memory are required for the  download, as well as the type of minigame being downloaded.

----------------------------------
Entry Count - 1 byte
----------------------------------
0x00 - Number of entries	::	(1 - ?) Maximum not currently known.

----------------------------------
Data Offsets - 2 bytes each
----------------------------------
0x01				::	Low byte of 16-bit internal offset to RomsList.cgb data structure.
0x02				::	High byte of 16-bit internal offset to RomsList.cgb data structure. 
...				::	Repeat offsets as needed.

----------------------------------
Data Structure
----------------------------------
0x00	 			::	Number of memory blocks necessary for the download (modulus 100). Should be 0x00 - 0x63 ideally.
0x01				::	Mini-game icon type. See Icon Type below for details.
0x02 - 0x05			::	Game ID, simply in the format "Gxyz" where "xyz" are three numbers. E.g. the first minigame ID in the Net de Get ROM is "G000"
0x08 - 0x0A			::	Disables download (grayed out text). All 3 must be zero, otherwise download is disabled.
0x0C - 0x0F			::	Disables menu item completely (no text, item not selectable). All 4 must be zero, otherwise menu item is disabled.
0x10				::	String Length 1. Each menu item should ideally be 12 characters or less (font is fixed width). Used for minigame name.
0x11 - ...			::	Menu Item Text (see String Format below).
0x11 + String Length 1		::	String Length 2. Each menu item draws additional text to a small on-screen textbox. Used brief explanations about minigame. Ideal max is 0xF.
0x11 + 1 + String Length 1 	::	Additional textbox string.
0x11 + 2 + String Length 1 & 2	::	The price of the minigame download in yen. 4 digits max.
0x11 + 6 + String Length 1 & 2	::	Unique ID for download. 8 characters max.


The offset to the data structure is technically (ADDRESS - 0x4). If the data structure is located at 0x44, the offset is written as 0x40.

Minigames have their own categories and can be assigned their own specific icons. The following bytes dictate what icon is drawn:

----------------------------------
Icon Type
----------------------------------
0x00				::	Question Mark		不定その他	Unspecified other aka misc.
0x01				::	Boxing Glove		アクション	Action
0x02				::	Green Head		パズル		Puzzle
0x03				::	Running Person		オーソドックス	Orthodox aka Platformer?
0x04				::	Sword			アールピージー	RPG
0x05				::	Green Sheet		シミュレーション 	Simulation
0x06				::	Fighter Jet		シューティング	Shooter/Shooting game 
0x07				::	Red Square		アドベンチャー	Adventure 
0x08				::	Blue Square (P)		プログラム	Program i.e. a full minigame, as opposed to additional data.
0x09				::	Green Square (D)	???		???
0x0A				::	Red Square (A)		アペンド		Additional minigame data.
0x0B				::	Brown Square (S)	???		???

Each mini game has two icons. The first describes the main type, "Program" for the main minigame, or "Append" for additional data or content. The 2nd icon describes the sub-type for the minigame. Apparently for minigame downloads, the main type is forcibly set to "Program". Byte 0x01 of the data structure controls only the 2nd icon, the sub-type. In that regard, only values of 0x00 through 0x07 are contextually correct. It should also be noted that two other main types seem to exist (the Green and Brown squares), but they are unused, or at least have no mention whatsoever in the game manual.


***************************************************
5. cgb/download?name=/A4/CGB-BMVJ/*
***************************************************

The GB Mobile Adapter attempts to access this URL for downloading minigames. The file containing the minigame is appended to the base URL. The appended part should be 12 characters, 4 for the price in yen, followed by 8 characters for rest of the unique ID. Although it is unknown if this really was the case, it would make sense to use the minigame ID (e.g. "G000") along with ".cgb". Thus a full URL would be something like:

	http://gameboy.datacenter.ne.jp/cgb/download?name=/A4/CGB-BMVJ/1234G000.cgb

Note that the filename of the minigame should start with numbers (the price) since this indicates a service fee for the download. The server responds with the required binary data. Net de Get will blindly receive data, regardless of what it is. That is to say, no error checking of the minigame itself is done during the download phase.


***************************************************
6. Download Wrapper
***************************************************

Rather than simply downloading the minigame data as-is, Net de Get expects minigames to have come in a sort of wrapper file. This consists of a brief header followed by the actual minigame data as described in the next section below. The wrapper header is as follows:

0x00:				::	Offset to the rest of the wrapper data. This is the 1-byte value + 1, so 1-256.
Offset + 0x00			::	???
Offset + 0x01			::	For most minigame downloads, this should be 0x00. When set to 0x05, it seems to do a block-fill operation on the MBC6 flash ROM.
Offset + 0x02			::	???
Offset + 0x03			::	???
Offset + 0x04			::	Minigame size (low-byte).
Offset + 0x05			::	Minigame size (high-byte). Should not be zero.
Offset + 0x06			::	???
Offset + 0x07			::	???
Offset + 0x08 ...		::	Minigame data (as described below in Minigame Format).

The minigame is copied to various RAM locations (SRAM and WRAM) until it is finally written to flash. A maximum of 0x200 bytes is copied at a time. The wrapper, however, expects a 0x100 "footer" to be inserted after each of the 0x200 chunks. This is only necessary if the minigame size is greater than 0x200 bytes. For example, if a minigame is only 0x100 bytes, then the footer can be ignored, although such a small size is rather impractical. Additionally, only the last footer technically needs to be correctly formatted. The default footer is as follows:

0x00, 0x00, 0x01, 0x00,
0x02, 0x00, 0x03, 0x00,
0x04, 0x00, 0x05, 0x00,
0x06, 0x00, 0x07, 0x00,
0x08, 0x00, 0x09, 0x00,
0x0A, 0x00, 0x0B, 0x00,
0x0C, 0x00, 0x0D, 0x00,
0x0E, 0x00, 0xFF, 0x00,
... (the remaining 224 bytes should be 0x00).

So in summary, the wrapper effectively looks like this:

Wrapper Header ->
	Minigame Data Chunk (0x200 max)
		Footer (0x100)
	Minigame Data Chunk (0x200 max)
		Footer (0x100)
	...

Note that the footer is written to SRAM later on, not flash. Improperly formatted footers may crash the game when booting or trying to access the minigame menu. There are other valid footers, but the default above is the only one tested extensively. It is currently unknown exactly how this data should be formatted.


***************************************************
7. Minigame Format
***************************************************

The minigame format is essentially the same as that found on the MBC6 ROM. Using the base address of the flash ROM bank, minigames look like so:

0x00 - 0x02			::	Typically contains a JR or JP instuction.
0x05 				::	Number of memory blocks used by the minigame.
0x06				::	Primary minigame icon.
0x07				::	Secondary minigame icon.
0x09 - 0x0C			::	Game ID, simply in the format "Gxyz" where "xyz" are three numbers. E.g. the first minigame ID in the Net de Get ROM is "G000"
0x0F - ...			::	Text for game title. Null terminated, but nothing stops it from being too long. Text can technically spill over multiple lines.
0x24 - ...			::	Text for dialog box. Null terminated.
0x44				::	If this is 0xFF, it prints the game title, otherwise the title is blank. Oddly enough, the dialog box is unaffected and always printed.
0x6D - 0x6E			::	Always 0x3B, 0xB3. Acts like a watermark for valid minigames. Net de Get checks this specifically to tell if a game is on flash ROM.
0x6F - ...			::	Code + Data.

Generally, the jump instruction goes right to Byte 0x6F, but not always. When the minigame is selected from the menu and the play (あそぶ) option is selected, the MBC6 switches Bank 0 (0x4000 - 0x5FFF) with flash ROM, then performs a CALL 0x4000, which in turn executes the jump instruction and starts the minigame. It should also be noted that the downloaded minigame code is actually executed from flash ROM rather than copying it somewhere else first like WRAM.

Unlike the previous icons from RomList.cgb, each minigame's primary icon can be specified. The secondary minigame icon is nearly identical to the format in RomList.cgb, but contains some variations:

----------------------------------
Primary Minigame Icon Type
----------------------------------
0x00				::	Gray Square (P)		プログラム	Program i.e. a full minigame, as opposed to additional data. Might be "disabled" since it's gray.
0x01				::	Blue Square (P)		プログラム	Program i.e. a full minigame, as opposed to additional data.
0x02				::	Green Square (D)	???		???
0x03				::	Green Square (D)	???		???
0x04				::	Red Square (A)		アペンド		Additional minigame data.
0x05				::	Gray Square (A)		アペンド		Additional minigame data (disabled?).
0x06				::	Gray Square (A)		アペンド		Additional minigame data (disabled?).
0x07				::	Gray Square (A)		アペンド		Additional minigame data (disabled?).
0x08				::	Brown Square (S)	???		???

----------------------------------
Secondary Minigame Icon Type
----------------------------------
0x00				::	Question Mark		不定その他	Unspecified other aka misc.
0x01				::	Boxing Glove		アクション	Action
0x02				::	Green Head		パズル		Puzzle
0x03				::	Running Person		オーソドックス	Orthodox aka Platformer?
0x04				::	Sword			アールピージー	RPG
0x05				::	Green Sheet		シミュレーション 	Simulation
0x06				::	Fighter Jet		シューティング	Shooter/Shooting game 
0x07				::	Green Square		アドベンチャー	Adventure

For the secondary icon, everything above 0x08 results in garbage tile data being drawn on-screen. 0x07 is the same icon as in RomList.cgb, except the color is now green instead of Red. Strangely enough, the game manual only shows the red version of that icon. 


***************************************************
8. String Format
***************************************************

Blank entries represent values that are not used and can effectively be treated as spaces.

        0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
0x00
0x10         !    "    #    $    %    &    '    (    )    *    +    ‘    -    .    /
0x20    0    1    2    3    4    5    6    7    8    9    :    ;    <    =    >    ?
0x30    [    ¥    ]    x    ÷    {    |    }    ˜    @    ⌜    ⌟    —    ~    、    。
0x40         A    B    C    D    E    F    G    H    I    J    K    L    M    N    O
0x50    P    Q    R    S    T    U    V    W    X    Y    Z    ✜    ‥    ^    _    ’
0x60         a    b    c    d    e    f    g    h    i    j    k    l    m    n    o
0x70    p    q    r    s    t    u    v    w    x    y    z    Ⓐ    Ⓑ


0x80    ぁ    あ    ぃ    い    ぅ    う    ぇ    え    ぉ    お    か    き    く    け    こ    さ        
0x90    し    す    せ    そ    た    ち    っ    つ    て    と    な    に    ぬ    ね    の    は
0xA0    ひ    ふ    へ    ほ    ま    み    む    め    も    ゃ    や    ゅ    ゆ    ょ    よ    ら
0xB0    り    る    れ    ろ    ゎ    わ    を    ん    →    ←    ↑    ↓    •
0xC0    ァ    ア    ィ    イ    ゥ    ウ    ェ    エ    ォ    オ    カ    キ    ク    ケ    コ    サ
0xD0    シ    ス    セ    ン    タ    チ    ッ    ツ    テ    ト    ナ    ニ    ヌ    ネ    ノ    ハ      
0xE0    ヒ    フ    ヘ    ホ    マ    ミ    ム    メ    モ    ャ    ヤ    ュ    ユ    ョ    ヨ    ラ 
0xF0    リ    ル 	   レ    ロ    ヮ    ワ    ヲ    ン    ☎    ♪    ☺    ☺    ★    ❤     ﾟ     ﾞ

A couple of things to note, since some characters listed are not quite the same in Unicode as they are on Net de Get:

* 0x33 is supposed to be the multiplication sign (not X).
* 0x5B is supposed to be the GBC's d-pad.
* 0x7B and 0x7C are actually inverted color-wise (black circle with white "A" or "B" in the center). These are presumably the GBC's A and B buttons.
* 0xF8 is actually inverted color-wise (black outlines, white on the inside).
* 0xFB is a "smiley face" like 0xFA, but it's kind of lumpy and missing an eye.


***************************************************
9. MBC6 flash Operation
***************************************************

The MBC6 writes games to flash ROM for long-time data storage. Although technically it has a limited number of lifetime writes, it does not rely on a battery unlike cartridge SRAM for DMG/GBC games. The MBC6 uses the MX29F008TC-14. While no specific documentation about the MX29F008TC-14 is available, the following information has been reverse-engineered based on how Net de Get's code expects flash ROM to work.

* Net de Get never appears to check the chip ID for flash ROM. Instead of issuing the 0x90 command, it immediately accesses flash. Given that the MX29F008TC-14 was likely a variant of other existing Macronix flash chips but specialized exclusively for the Game Boy Color, it's entirely possible that Net de Get was all but gauranteed to use one flash chip. In that sense, the developers had no need to identity other flash hardware.

* Net de Get makes extensive use of the 0x30 command to erase sectors, particularly before a minigame is downloaded. After the 0x30 command is issued, Net de Get issues a 0xF0 command, which forcibly terminates the previous erase command. During this time (until another flash command is issued), any reads to flash return the current status of the previous erase command. The status is a single byte. Bit 7 determines if the erase command has indeed finished (1 = Done, 0 = In Progress). Bit 4 seems to indicate a timeout (1 = Timeout, 0 = OK). Net de Get actively checks both bits.

* Net de Get only writes to flash ROM in portions of 128 bytes at a time. At the end of each 128 byte section (e.g. 0x407F, 0x40FF, etc), it writes a 0x00 at the very last byte. This seems to indicate that the flash chip should return the status byte from any reads, much like the 0x30 commands. Again, Bit 7 and 4 are checked. Afterwards, the game will use the 0xF0 command to terminate writing.

* Net de Get actually saves the downloaded minigame to SRAM initially, then portions are copied to WRAM, and eventually flash ROM. Net de Get also actively verifies whether the data written to flash is correct by comparing current flash memory to the original RAM data. Any discrepancy triggers an error message and aborts.

* The exact way in which the MBC6 handles flash ROM banking is not entirely understood, however, there is some evidence of how it should work. After issuing command 0x30 (sector erase), the current bank is taken from whatever bank ID was written to in 0x2000 (for flash ROM mapped to 0x4000 - 0x5FFF) or 0x3000 (for flash ROM mapped to 0x6000 - 0x7FFF). The flash bank used for all further IO operations is essentially "remembered" after the 0x30 command. Reads and writes to flash ROM will use that "remembered" bank instead of the one specified at 0x2000 or 0x3000 until another command is issued. The other 8KB area of flash memory can use the bank ID in 0x2000 or 0x3000 for reading normally.