Hardware and Accessories


About Dan Docs


Barcode Boy

Barcode Taisen Bardigun Scanner

DMG-07 4-Player Adapter

Zok Zok Heroes Full Changer

GBC Infrared Communication

Gyogun Tanchiki: Pocket Sonar

Power Antenna + Bug Sensor

Turbo File GB

Sewing Machines


GBA Screen Stretch

Soul Doll Adapter

Battle Chip Gate

Multi Plust On System

Turbo File Advance



Ubisoft Thrustmaster Pedometer


Magic Reader

Mobile Adapter GB

Hardware Documentation

Mobile Adapter GB

Game and Server Documentation

Game Boy Wars 3

Hello Kitty no Happy House

Mobile Trainer

Net de Get: Minigame @ 100

About Dan Docs

For the longest time, a technical document called Pan Docs formed the basis of nearly all known documentation about the Nintendo Game Boy. To this day, Pan Docs (or an updated version such as the GBDev wiki) continues to be the go-to source of general Game Boy information. However, while Pan Docs covers the basics well enough, it does not touch upon more obscure Game Boy hardware. Dan Docs, on the other hand, aims to fill this gap. Dan Docs is basically everything else you wanted to know about the Game Boy, but no one dared to ask.

All of the data here either comes from my research for the GBE+ project or from others studying Game Boy hardware and software. Much of this information is copied+pasted from the text files I've made over the years. For ease of use and access, however, it's been converted to a single HTML document. As more items are reverse-engineered and studied, they will be added to Dan Docs as well as GBE+.

Consider all information within this document to be Public Domain. Copy and share as you please.


Billy - Mobile Adapter GB documentation

ClawGrip - Scans of all known Barcode Boy cards

endrift - MBC6 documentation. Collaboration on Battle Chip Gate documentation (especially Progress Chip Gate) + testing + verification of results.

Háčky - Mobile Adapter GB documentation

pfero - Mobile Adapter GB documentation

Robert Abel (Tauwasser) - Net de Get translation help

Barcode Boy

General Hardware Information

Compatible Games

Barcode Boy to DMG Communication

Barcode Format

Card Dumping + Emulation

Barcode Errors


[Barcode Boy] : General Hardware Information

Appearing around 1992, the Barcode Boy is the earliest form of card-scanning on Nintendo's Game Boy line of handhelds, predating both the e-Reader and the Bardigun Taisen Reader by a number of years. Only a limited set of games made by Namcot were compatible with (or rather absolutely required) the Barcode Boy. All of the games and the Barcode Boy itself were only released in Japan.

[Barcode Boy] : Compatible Games

Only 5 Barcode Boy games are known to exist:

Barcode Boy titles come in two types: those that absolutely require the Barcode Boy for any gameplay at all (専用カートリッジ) and those that merely support the Barcode Boy as an accessory for additional content (対応カートリッジ). These games are differentiated with red and blue "B.B." logos respectively. Only Battle Space and Monster Maker: Barcode Saga fall into the first group.

[Barcode Boy] : Barcode Boy to DMG Communication

Each game will first try to detect if the Barcode Boy is plugged in and turned on. The Game Boy will send the bytes [0x10, 0x07, 0x10, 0x07] as part of a handshake. A properly functioning Barcode Boy will return the bytes [0xFF, 0xFF, 0x10, 0x07]. Barcode Boy games will still successfully detect the Barcode Boy scanner even if the first two bytes in the reply to the handshake aren't 0xFF, probably to simplify the game code. As a result, the first two bytes of the handshake are useless and ignored, but the last two bytes *MUST* be [0x10, 0x07]. If the Barcode Boy is plugged in but not turned on, it responds with 0x00 for the entire handshake, and the game produces an error message.

After detection passes, the Game Boy will sit and wait for a response. The Game Boy, unlike how it works with other SIO devices, takes on a passive role with the Barcode Boy by switching to an external clock. The Game Boy actually requires the Barcode Boy to take the initiative when scanning. Therefore, it is assumed that the Barcode Boy uses an internal clock and drives serial communications while scanning a barcode.

Nitty-gritty bits:

  1. The game logic pings the Barcode Boy with [0x10, 0x07, 0x10, 0x07]. The Barcode Boy is expected to reply; the first two bytes are not important (real hardware returns 0xFF), but the second two bytes must be [0x10, 0x07].
  2. Afterwards, the Game Boy waits for input using an external clock. What follows are two strings of numbers representing the barcode data. The "numbers" are represented as ASCII instead of hex.
  3. Both strings are 13-digits long and are the EAN-13 number corresponding to the barcode.
  4. Before sending each string, the Barcode Boy sends a 0x02 byte.
  5. After sending each string, the Barcode Boy sends a 0x03 byte.
  6. Altogether, the Barcode Boy transmits 30 bytes to the Game Boy.

Overall known communication protocol:

Standard communication flow:

[DMG] [BCB] Handshake ---> <--- Handshake <--- 0x2 <--- EAN-13 <--- 0x3 <--- 0x2 <--- EAN-13 <--- 0x3

Since the Barcode Boy acts as master (after the handshake at least), the Game Boy never initiates a transfer during barcode transmission. When sending barcode data, the Barcode Boy doesn't seem to care what value the Game Boy writes to SB, although no Barcode Boy games write to SB at that time anyway. Ultimately unknown if the Barcode Boy accepts input beyond the handshake, but no evidence has been observed to suggest otherwise.

Once the Barcode Boy sends the handshake [0x10, 0x07] back to the Game Boy, the scanner returns 0xFF anytime the Game Boy tries to send additional data while the handheld is still on its own internal clock. After the Barcode Boy finishes sending back the barcode data to the Game Boy, it requires the handshake again. It appears the handshake can fail for unknown reasons (probably related to the hardware). For example, the Barcode Boy at times may send back [0x90, 0x07], which seems to indicate an error of some sort.

[Barcode Boy] : Barcode Format

The two strings are the actual barcode data in numerical form. The barcode format itself is EAN-13, and a few games use JAN-13 specifically. Older JAN-13 barcodes start off with the flag code 49. Interestingly enough, the newer JAN-13 flag code is 45 and was introduced in 1992, the same year the Barcode Boy was released. Probably due to timing or convenience, the JAN-13 barcodes on the cards stuck to the older flag code. Some Barcode Boy barcodes are technically "coupons/vouchers" types, as they use the flag code 99 instead of 45 or 49. Family Jockey 2 and Famista 3 don't use JAN-13 specifically; instead they use random EAN-13 barcodes with varying flag codes.

Using scans of the barcode @ 600 DPI, the smallest bar width is approximately 7 pixels (give or take). With that information, it's possible to recreate the EAN-13 number with a sufficient image and barcode scanning software. It should be noted that the Barcode Boy appears to do away with the center guard, however, it maintains left and right guards.

[Barcode Boy] : Card Dumping + Emulation

Amazingly simple in comparison to something like Barcode Taisen Bardigun, chiefly because such a small amount of bytes need to be sent to the Game Boy. Basically, all you need to do is convert the barcode to EAN-13. Anything capable of reading standard barcodes found on most products should be sufficient to grab the numerical form of each card.

As far as emulation goes, simply convert the EAN-13 ASCII string to hex and transmit it accordingly.

[Barcode Boy] : Barcode Errors

Interestingly enough, a vast majority of the barcodes for Family Jockey 2 are completely incorrect. Only 3 out of the 8 barcodes actually generate horses with the stats listed on the cards. Barcodes A1, B1, and A4 work fine; the rest give stats that do not match up with the card's. Some, such as A2, even generate horses that are totally unfit for competition (A2 produces stats with 2s and 0s, and the max is supposed to be 9 in each category). It's not clear if this was a programming glitch or a mistake Namcot made when printing the cards, or some combination of the two. All other Barcode Boy games came packaged with cards that have no issues whatsoever.

[Barcode Boy] : Barcodes

Below are the full 13 digit barcodes for all known Barcode Boy cards along with any names, other identifying information found on the card, or important notes.

Battle Space

* バーサーカー (Berserker) * 4907981000301 * バルキリー (Valkyrie) * 4908052808369 * グリズリー (Grizzly Bear) * 4916911302309 * マホウセンシ (Magic Soldier aka Rune Knight) * 4902776809367 * ナイト (Knight) * 4905672306367 * レイス (Wraith) * 4912713004366 * シャーマン (Shaman) * 4913508504399 * シーフ (Thief) * 4918156001351 * ソーサラー (Sorcerer) * 4911826551347 * ウォリアー (Warrior) * 4909062206350

Family Jockey 2

* A1 * 5893713522816 * A2 (Erroneous Barcode) * 2378649896765 * A4 * 9845554422318 * B1 * 1509843019075 * B2 (Erroneous Barcode) * 4232978865152 * B4 (Erroneous Barcode) * 3572821107673 * C3 (Erroneous Barcode) * 7164625542390 * C5 (Erroneous Barcode) * 6319537443513

Famista 3

* ホームランバッター (Home-Run Batter) * 8357933639923 * 高打者バッター (Senior Batter) * 7814374127798 * 駿打者バッター (Swift Batter) * 9880692151263 * ピッチャー (Pitcher) * 1414213562177

Kattobi Road

* フォワールド (Truck) * 4902105002063 * ガウディ (Sedan) * 4901121110004 * ナイト 2000 (Racecar) * 4903301160625 * ミイラターボ (Japanese Street Car) * 4902888119101 * リイスラックス (4x4 Jeep) * 4901780161157 * ロクタスヨンート (F1-style racecar) * 4987084410924

Monster Maker: Barcode Saga

* 弓使いロリエーン (Archer Lorian) * 9998017308336 * 弓使いエリサイス (Archer Elysice) * 9447410810323 * 騎士ローラン (Knight Lauren) * 9052091324955 * 竜騎士ハーグン (Dragon Knight Haagun) * 9322158686716 * 戦士ディアーネ (Warrior Diane) * 9752412234900 * 戦士タムローン (Warrior Tamron) * 9362462085911

Barcode Taisen Bardigun Scanner

General Hardware Information

Card Reader to GBC Communication

Barcode Format

Card Dumping

ROM Revision


[Barcode Taisen Bardigun] : General Hardware Information

Barcode Taisen Bardigun is a Japanese Game Boy game released December 11, 1998, made by TAM. It doesn't seem like a very interesting or noteworthy game in and of itself (yet another monster breeding/raising/fighting/collecting game). However, this game featured exclusive hardware, a card reader that scanned various barcodes

[Barcode Taisen Bardigun] : Card Reader to GBC Communication

Game Boy will initialize a transfer with an internal clock; much like every other Serial I/O device (GB Printer, GB Mobile Adapter), Game Boy sends initial data, then the reader responds. Transfer rate is 1KB/s, the slowest speed, so there is no difference between DMG and GBC transfers. To begin, the Game Boy constantly sends 0xFF to the reader. The game logic times out after a few seconds if no proper response is established.

To scan a card, hold it face down (barcode facing the ground and towards the reader), press the reader's button, and swipe. The scanner only seems to activate once the button is pushed (otherwise it'd waste battery if it were constantly on, or constantly on and trying to receieve commands from the Game Boy). Without pressing the button, the game logic times out the scanning process after a few seconds (about 9 seconds). If an error is detected during the scan process, the reader seems to acknowledge this pretty quickly.

Nitty-gritty bits

  1. When connected, the reader responds with 0x00 until it is prepared to send the barcode data.
  2. Afterwards, it begins processing barcode data. Data is represented serially. A bit reading "1" indicates that the card reader is detecting whitespace. A bit reading "0" indicates the card reader is detecting a black segment (black bar).
  3. The barcode sequence itself is nothing more than a continuous stream of zeroes and ones. That is to say, groups of ones and zeroes are always packed together, but the length of each group determines the length of any given bar.
  4. There doesn't appear to be a fixed number of bytes that the Game Boy seems to expect when scanning. Different scans seem to produce different amounts of data transferred to the Game Boy. This could be due to numerous reasons in the hardware (swipe speed, how clean the scanner is, some other variance within the scanner's light sensitivity). Overall, however, the most important thing seems to be the length and sequence of the bars encoded as groups of ones and zeroes.
  5. The Game Boy doesn't ever seem to send any interesting data, just 0xFF. No commands are sent. The Game Boy simply sends a byte and expects a result to come from the reader; the results are what matter and are interpreted later on.

[Barcode Taisen Bardigun] : Barcode Format

Because the incoming barcode data is not consistent byte-for-byte, the patterns are what matters most. To illustrate this idea, below are two sets of data extracted after scanning a card (using a hacked version of Barcode Taisen Bardigun and saving all SIO communications to Cart RAM).

SET_1 SET_2 00 00 00 03 7F FE FF F8 00 01 00 03 FF FF FF FF FF FF FF FF FF C0 FF E0 00 3F 00 0F FF 00 FF 80 00 00 00 00 07 FF 00 FF 00 00 FC 00 FF FF 03 FF FF C0 FF FF 00 00 C0 00

Each set is actually a bitstream of 0s and 1s like so:

Set 1 [16:0] [14:1] [15:0] [43:1] ... Set 2 [14:0] [15:1] [14:0] [45:1] ...

The patterns in the sets are roughly the same. They switch between 0s, 1s, and 0s (black, white, black) fairly quickly followed by a long segment of 1s (white) which is roughly the general pattern seen at the beginning/ends of the barcodes. Based on this information, the thinest bars are about 0.0133 inches (8 pixels when scanning at 600dpi). Some further calculations based on this information:

Bar Width (in pixels @ 600dpi) -> Estimated bit-count sent to Game Boy 8 -> ~14-16 16 -> ~27-29 24 -> ~43-45

Every 8 pixels should be approximately 15 bits worth of data sent to the Game Boy, so:

Number of Pixels @ 600dpi * 1.875 = Approximate bit count

The physical barcode format on the actual cards is EAN-13.

[Barcode Taisen Bardigun] : Card Dumping

With the above guideline, it is possible to dump the cards by scanning them, then creating a binary file containing barcodes as alternating bitstreams of 0s and 1s. With this method, no homebrew techniques are needed, and only an image file is necessary to actually preserve the card.

The second method involves using a hacked version of the Barcode Taisen Bardigun ROM on a flashcart to save incoming Serial I/O data as a card is scanned. The binary can be pulled from a save file. Both binary files could be used an input to feed back to an emulator.

[Barcode Taisen Bardigun] : ROM Revision

Barcode Taisen Bardigun has two known ROMs, DMG-ABEJ-JPN and DMG-ABEJ-JPN-1. The later version polishes many rough edges found in the first release (e.g. including a text box when barcode scanning fails). Currently, both games appear to be largely the same besides these UI and UX enhancements. Barcode scanning is exactly the same in each.

[Barcode Taisen Bardigun] : Barcodes

* ラルフ "Ralph" * 4900758340136 * タマッピ "Tamapi" * 4900269429252 * チビッシー "Chibisshii" * 4900287167419

DMG-07 4-Player Adapter

General Hardware Information

Compatible Games

Link Cable Protocol

Ping Phase

Transmission Phase

Restarting Ping Phase

[DMG-07] : General Hardware Information

The DMG-07 is an accessory that allows 4 Game Boys to connect for multiplayer. In the West, it first appeared with the game F-1 Race as bundle in 1990. Only a few other games took advantage of the DMG-07 (namely Wave Race and Faceball 2000, Yoshi's Cookie) and it did not see widespread support at all.

[DMG-07] : Compatible Games

F1 Pole Position is the localization of the Japanese game Nakajima Satoru F-1 Hero GB '92: The Graded Driver. Both versions support the DMG-07. The prequel, Nakajima Satoru F-1 Hero GB World Championship '91, was however a Japanese exclusive.

Several games are claimed to be compatible but actual support for the DMG-07 remains dubious at best for those titles. Gauntlet II advertises 4-player action via the Link Cable, but this may simply refer to 2-player mode with each Game Boy controlling 2 characters (and switching among friends when appropiate).

Micro Machines 1 claims to support the DMG-07 in its instruction manual, but it does not appear to work; it may have been a planned but unfinished feature. Although the game initially tries to handle the DMG-07 Ping Phase, the acknowledgement signal is malformed. Based on hardware tests the game does not properly follow the DMG-07 protocol. If a DMG-07 is plugged in while booting the game, the software may ignore all input from Player 1 if the title screen runs for a few seconds. Unplugging the DMG-07 restores input from Player 1. The main game can be accessed by pressing buttons quickly on the title screen, however, various glitches occur with the DMG-07 plugged in. Most immediately return to the title screen after choosing a race course.

Micro Machines 2 has no indication of 4-player support outside of other versions, such as the PC edition.

[DMG-07] : Link Cable Protocol

The DMG-07 protocol can be divided into 2 sections, the "ping" phase, and the "transmission" phase. The initial ping phase involves sending packets back and forth between connected Game Boys probing for their current connection status. Afterwards, the DMG-07 enters into transmission mode where the Game Boys exchange data across the network.

A very important thing to note is that all Game Boys transfer data across the DMG-07 via an external clock source. Apparently, the clock source is provided by the DMG-07 itself. Trying to send data via an internal clock results in garbage data.

[DMG-07] : Ping Phase

When a "master" Game Boy (Player 1) is first connected to the DMG-07, setting Bit 7 of 0xFF02 to 1 and setting Bit 0 of 0xFF02 to 0 causes the accessory to send out "ping" packets periodically. All connected Game Boys will receive 4 bytes as part of the ping packet, at a rate of about 2048 bits-per-second, or about 256 bytes-per-second. Essentially, the ping seems to run 1/4 as fast as the clock used for normal serial transfers on the DMG (1KB/s). The ping data looks like this:

0xFE ID Byte 0x?? STAT1 0x?? STAT2 0x?? STAT3

3 "STAT" bytes are sent indicating the current connection status of the other Game Boys. Each byte is usually the same, however, sometimes the status can change mid-way through a ping, typically on STAT2 or STAT3. Each STAT byte looks like such:

Bit 0-2: Player ID Bit 4: Player 1 Connected Bit 5: Player 2 Connected Bit 6: Player 3 Connected Bit 7: Player 4 Connected

The Player ID is simply a value of 1-4. Its value is determined by whichever port a Game Boy is connected to. As more Game Boys connect, the upper bits of the STAT bytes are turned on.

When talking about Game Boys and the "connection", this refers to a Game Boy properly responding to STAT1 and STAT2 bytes when receiving a ping packet from the DMG-07. In this way, the Game Boy broadcasts across the Link Cable network that it is an active participant in communications. It also acts as a sort of acknowledgement signal, where software can drop a Game Boy if the DMG-07 detects an improper response during a ping, or a Game Boy simply quits the network. The proper response is to send 0x88 *after* receiving the ID Byte and STAT1, in which case the upper-half of STAT1, STAT2, and STAT3 are updated to show that a Game Boy is "connected". If for whatever reason, the acknowledgement codes are not sent, the above bits are unset.

Some examples of ping packets are shown below:

0xFE 0x01 0x01 0x01 -> Ping packet received by Player 1 with no other Game Boys connected 0xFE 0x11 0x11 0x11 -> Ping packet received by Player 1 when Player 1 has connected 0xFE 0x31 0x31 0x31 -> Ping packet received by Player 1 when Players 1 & 2 have connected 0xFE 0x71 0x71 0x71 -> Ping packet received by Player 1 when Players 1, 2, & 3 have connected 0xFE 0x62 0x62 0x62 -> Ping packet received by Player 2 when Players 2 & 3 are connected (but not Player 1)

It's possible to have situations where some players are connected but others are not; the gaps don't matter. For example, Player 1 and Player 4 can be connected, while Player 2 and Player 3 can be disconnected (or non-existant, same thing); most games do not care so long as Player 1 is active, as that Game Boy acts as master and orchestrates the multiplayer session from a software point of view. Because of the way the DMG-07 hardcodes player IDs based on which port a Game Boy is physically connected to, in the above situation Player 4 wouldn't suddenly become Player 2 in a game like F-1 Race.

During the ping phase, the master Game Boy is capable of setting up two parameters that will be used during the transmission phase. The clock rate for the transmission phase can be adjusted, as well as the packet size each Game Boy will use. The master Game Boy needs to respond with one byte for STAT2 and STAT3 respectively. The chart below illustrates how a master Game Boy should respond to all bytes in a ping packet:

---------------------------- DMG-07 Game Boy ---------------------------- 0xFE <--> (ACK1) = 0x88 STAT1 <--> (ACK2) = 0x88 STAT2 <--> (RATE) = Link Cable Speed STAT3 <--> (SIZE) = Packet Size

The new clock rate is only applied when entering the transmission phase; the ping phase runs at a constant 2048 bits-per-second. The formula for the new clock rate is as follows:

DMG-07 Bits-Per-Second --> 4194304 / ((6 * RATE) + 512)

The lowest setting (RATE = 0) runs the DMG-07 at the normal speed DMGs usually transfer data (1KB/s), while setting it to 0xFF runs its close to the slowest speed (2042 bits-per-second).

SIZE sets the length of packets exchanged between all Game Boys. Nothing fancy, just the number of bytes in each packet. It probably shouldn't be set to zero.

[DMG-07] : Transmission Phase

When the master Game Boy (Player 1) is ready, it should send 4 bytes (0xAA 0xAA 0xAA 0xAA). Some games only send 3 bytes however (0xAA 0xAA 0xAA and 0x00). This alerts the DMG-07 to start the transmission phase. The RATE and SIZE parameters are applied at this point. The protocol is simple: Each Game Boy sends a packet to the DMG-07 simultaneously, then the DMG-07 outputs each packet to all connected Game Boys. All data is buffered, so there is a 4 packet delay after each Game Boy submits their data (the delay is still 4 packets long even if some Game Boys are not connected). For example, say the packet size is 4 bytes; the flow of data would look like this when sending:

-------------------------------------------------------------------------------------------- P1 send P2 send P3 send P4 send Transfer count -------------------------------------------------------------------------------------------- P1_byte_1 P2_byte_1 P3_byte_1 P4_byte_1 0 P1_byte_2 P2_byte_2 P3_byte_2 P4_byte_2 1 P1_byte_3 P2_byte_3 P3_byte_3 P4_byte_3 2 P1_byte_4 P2_byte_4 P3_byte_4 P4_byte_4 3 0 0 0 0 4 (Typically supposed to be zero, but DMG-07 ignores anything here) 0 0 0 0 5 0 0 0 0 6 0 0 0 0 7 0 0 0 0 8 0 0 0 0 9 0 0 0 0 10 0 0 0 0 11 0 0 0 0 12 0 0 0 0 13 0 0 0 0 14 0 0 0 0 15

And when receiving, the flow of data would look like this:

-------------------------------------------------------------------------------------------- P1 recv P2 recv P3 recv P4 recv Transfer count -------------------------------------------------------------------------------------------- P1_byte_1 P1_byte_1 P1_byte_1 P1_byte_1 16 P1_byte_2 P1_byte_2 P1_byte_2 P1_byte_2 17 P1_byte_3 P1_byte_3 P1_byte_3 P1_byte_3 18 P1_byte_4 P1_byte_4 P1_byte_4 P1_byte_4 19 P2_byte_1 P2_byte_1 P2_byte_1 P2_byte_1 20 P2_byte_2 P2_byte_2 P2_byte_2 P2_byte_2 21 P2_byte_3 P2_byte_3 P2_byte_3 P2_byte_3 22 P2_byte_4 P2_byte_4 P2_byte_4 P2_byte_4 23 P3_byte_1 P3_byte_1 P3_byte_1 P3_byte_1 24 P3_byte_2 P3_byte_2 P3_byte_2 P3_byte_2 25 P3_byte_3 P3_byte_3 P3_byte_3 P3_byte_3 26 P3_byte_4 P3_byte_4 P3_byte_4 P3_byte_4 27 P4_byte_1 P4_byte_1 P4_byte_1 P4_byte_1 28 P4_byte_2 P4_byte_2 P4_byte_2 P4_byte_2 29 P4_byte_3 P4_byte_3 P4_byte_3 P4_byte_3 30 P4_byte_4 P4_byte_4 P4_byte_4 P4_byte_4 31

Again, due to buffering, data output to the DMG-07 is actually delayed by several transfers according to the size of the packets. All connected Game Boys should send their data into the buffer during the first few transfers. Here, the packet size is 4 bytes, so each Game Boy should submit their data during the first 4 transfers. The other 12 transfers don't care what the Game Boys send; it won't enter into the buffer. The next 16 transfers return the packets each Game Boy previously sent (if no Game Boy exists for player, that slot is filled with zeroes).

With the buffering system, Game Boys would normally be reading data from previous packets during transfers 0-15, in addition to sending new packets. Likewise, during transfers 16-19 each Game Boy is sending new packets. In effect, while receiving old data, Game Boys are supposed to pump new data into the network.

When the DMG-07 enters the transmission phase, the buffer is initially filled with garbage data that is based on output the master Game Boy had sent during the ping phase. At this time, it is recommended to ignore the earliest packets received, however, it is safe to start putting new, relevant data into the buffer.

[DMG-07] : Restarting Ping Phase

It's possible to restart the ping phase while operating in the transmission phase. To do so, the master Game Boy should send 4 or more bytes (0xFF 0xFF 0xFF 0xFF). Again, some games send less (0xFF 0xFF 0xFF and 0x00). It's possible only 1 or 2 0xFF bytes need to be sent, but this has not been extensively investigated yet. At any rate, the bytes alert the DMG-07 that the ping phase should begin again. Most games use this to end the multiplayer session and return to the title screen. For example, in F-1 Race, the game automatically jumps back to the title screen after all races have been completed, while Wave Race has a menu to continue playing or end the session. In either case, the games send 0xFF bytes and the DMG-07 sends ping packets after a brief delay. During this delay, the transmission protocol is still working as intended until the switch happens.

Zok Zok Heroes Full Changer

General Hardware Information


IR Communication

Capturing IR Data


Cosmic Characters

[Full Changer] : General Hardware Information

Zok Zok Heroes was a GBC JRPG released on August 4, 2000, made by Media Factory when they still produced video games. It used a special accessory called the "Full Changer", a device that looks like a toy, but acts as an IR transmitter. It sent signals to the GBC once players moved it through the air to "draw" certain patterns. Once the GBC gets the IR light pulses, it allows players to transform into different "Bright Heroes" to do battle against evil bad guys. It never sold outside of Japan. After a specific point early in the game, it becomes impossible to progress further in emulators without cheat codes/hacks or by properly emulating the Full Changer.

[Full Changer] : Operation

  1. Grab the Full Changer firmly, holding it by the strap
  2. Press and release the top button. It should beep and the 3 lights should flash for approximately 5 seconds.
  3. During those 5 seconds, move the Full Changer to draw the pattern of a "Cosmic Character" e.g. for "Z" start left, move right, stop, move downward and leftward, stop, move right, stop.
  4. Make sure the Full Changer is always held upright while drawing.
  5. For each successful movement, the Full Changer will activate another light and beep. Once all three at lit, it beeps a little tune and the data is ready to be sent to the GBC.
  6. Put the bottom of the Full Changer on top of the GBC, making sure to cover the IR port. The Full Changer has a little plastic guide to make sure everything fits and faces the right direction.

[Full Changer] : IR Communication

The Full Changer sends a total of 18 IR pulses (ON then OFF periods) when transmitting data. The length of these pulses varies and determines what values the Full Changer is trying to send. Zok Zok Heroes runs in a couple of loops while the pulse takes place. Each iteration, it increments a counter to get an idea of the overall "delay" it takes for the IR light to turn on then turn off. That counter is then placed in WRAM as a single byte (anything greater than 0xFF causes a timeout) and verified later. In this way, Zok Zok Heroes can view data from the Full Changer as a series of bytes rather than light pulses. These 18 bytes do not have especially strict values, rather they are expected to fall within a certain range to indicate long or short pulses.

[Full Changer] : Capturing IR Data

Below is psuedo-code representing how Zok Zok Heroes grabs the 18 bytes:

================================== LABEL CHECK_ON_LOOP: ================================== //Use an 8-bit CPU register as a Time-Out Counter, initially set to 0xFF, exit if it hits zero TIMEOUT_COUNTER-- IF(TIMEOUT_COUNTER == 0) { RETURN } //Load A from 16-bit immediate address for RP register A = [0xFF56] //Wait for IR light to come on (Bit 1 of 0xFF46 goes to zero) IF(A AND 0x1) { GOTO CHECK_ON_LOOP } //Use another 8-bit CPU register to act as a counter for total number of bytes processed from Full Changer TOTAL_BYTES = 0x12 //Set a 16-bit CPU register pair as the destination address (0xD005+) to write IR data DEST_ADDR = 0xD005 ================================== LABEL GRAB_IR_BYTES: ================================== //Wait for IR light to go off (Bit 1 of 0xFF46 goes to one) //Set an 8-bit CPU register to act as an IR pulse length counter, initialized to 0x00 PULSE_LENGTH = 0x00 CALL WAIT_FOR_OFF CALL WAIT_FOR_ON //Save pulse length results to 0xD005 - 0xD017 [DEST_ADDR] = PULSE_LENGTH DEST_ADDR++ TOTAL_BYTES-- IF(TOTAL_BYTES != 0) { GOTO GRAB_IR_BYTES } ... //IR handling code ends here ================================== FUNCTION WAIT_FOR_OFF: ================================== PULSE_LENGTH++ IF(PULSE_LENGTH == 0) { RETURN } //Load A from 16-bit immediate address for RP register A = [0xFF56] //Wait for IR light to come on (Bit 1 of 0xFF46 goes to one) IF((A AND 0x1) == 0x00) { GOTO WAIT_FOR_OFF } RETURN ================================== FUNCTION WAIT_FOR_ON: ================================== PULSE_LENGTH++ IF(PULSE_LENGTH == 0) { RETURN } //Load A from 16-bit immediate address for RP register A = [0xFF56] //Wait for IR light to come on (Bit 1 of 0xFF46 goes to zero) IF(A AND 0x1) { GOTO WAIT_FOR_ON } RETURN

Once all 18 bytes have been stored in WRAM, it's possible to read them and save them using a ROM hack. Alternatively, homebrew software can use code with the same timing to accurately capture IR data from the Full Changer.

[Full Changer] : Emulation

The Full Changer can be successfully emulated by setting Bit 1 of RP register (located at 0xFF56) to 0 or 1 at the appropiate times. To do so requires accurate timing and knowing the amount of cycles it takes to generate the delays represented by those 18 bytes in WRAM. When activating the Full Changer, GBE+ always fires the 1st "ON" IR signal at a specific time to get consistent timings:

TIMEOUT_COUNTER-- IF(TIMEOUT_COUNTER == 0) { RETURN } A = [0xFF56] <---- After the CPU reads 0xFF56 and the user activates the Full Changer, IR light is turned on here <---- This happens after the actual read instruction is executed, so the loop runs once more IF(A AND 0x1) { GOTO CHECK_ON_LOOP }

Afterwards, the timings for ON and OFF pulses can be calculated as such (ALL TIMING IS IN DOUBLE SPEED):

1st ON pulse length 74 + (20 * (LENGTH-2)) Every other ON pulse length 78 + (20 * (LENGTH-2)) OFF pulse length 38 + (20 * (LENGTH-2))

The LENGTH is number of times the 8-bit CPU register is incremented in the WAIT_FOR_OFF or WAIT_FOR_ON functions. The sum of two LENGTHs from one ON pulse and one OFF pulse must be equal to the delay data in WRAM. For example, say the delay data contains 0x20. This means that the TOTAL amount of times the 8-bit register was incremented is 0x20. In a perfect world, the Full Changer would probably turn on the IR light so that this 8-bit register is incremented 0x10 times, then turn off the IR light so that D is incremented again 0x10 times. In reality, however, the length of the ON/OFF pulses could run a bit longer or shorter. As far as Zok Zok Heroes is concerned, the total amount of time the IR light is ON then OFF is what matters, so the ON/OFF pulse timings ultimately have to add up

The current database GBE+ uses recreates ON/OFF pulses that generally run for the same amount of cycles. However, based on hardware tests, the ON pulses have variable lengths, while the OFF pulses are typically constant. Again, Zok Zok Heroes won't care, as long as the total time of the ON/OFF pulses meets whatever value it expects.

[Full Changer] : Cosmic Characters

There are a total of 70 "Cosmic Characters" available in Zok Zok Heroes, and by extension, there are 70 unique transformations. This Cosmic Character is simply an 8-bit ID generated from the ON and OFF pulses from the Full Changer. Using the delays stored in the 18 WRAM bytes, the game software uses the following logic to determine an ID.

The first pulse is checked to ensure that it has a delay greater than 0x20, signaling a long pulse, otherwise processing for the Cosmic Character does not continue. Afterwards, the next 16 pulses are examined to build two separate 8-bit values. These values are constructed LSB. A short pulse (any value from 0x00 to 0x13) translates into a "0", and a long pulse (any value from 0x14 to 0x20) translates into a "1". The 1st 8-bit value built from these pulses is used for a checksum of a sort, and the 2nd 8-bit value is complemented to form an ID. IDs range from 0x01 to 0x46 and correspond to the 70 Cosmic Characters. Note that while the 18th IR pulse is required by the software, it isn't used for the ID or checksum.

Checksum Calculation: Pulse Byte 1 + Pulse Byte 2 = 0xFF Cosmic Character ID Calculation: ~Pulse Byte 2 = Cosmic Character ID Pulse Byte 1 Calculation (using an arbitrary ID of one's choosing): Pulse Byte 1 = 0xFF - (~Cosmic Character ID) Pulse Byte 2 Calculation (using an arbitrary ID of one's choosing): Pulse Byte 2 = ~Cosmic Character ID -------------------------------------------------------------------------------------------- ID | Japanese Name | Translated Name | Cosmic Character Movements -------------------------------------------------------------------------------------------- 01 (あ) | アルカリパワード | Alkaline Powered | Up, Down, Up 02 (い) | イン ウォーター | In Water | Right, Left, Right 03 (う) | ウルトランナー | Ultra Runner | Down, Up, Down 04 (え) | エアロ パワー | Aero Power | Left, Right, Left 05 (お) | オチャッパ | Ochaapa | Down+Left, Right, Left 06 (か) | カイザーエッジ | Kaizer Edge | Up, Right, Down 07 (き) | キングバッター | King Batter | Right, Down, Left 08 (く) | クラッシッカー | Crash Car | Down, Left, Up 09 (け) | ケイタイがー | Cellphone Tiger | Left, Up, Right 10 (こ) | コップエース | Cup Ace | Down+Left, Up, Right 11 (さ) | サカナード | Sakanard | Up, Left, Down 12 (し) | シンデルター | Thin Delta | Right, Up, Left 13 (す) | スケボーライダー | Skateboard Rider | Down, Right, Up 14 (せ) | セロリスター | Celery Star | Left, Down, Right 15 (そ) | ソウジキラー | Cleaning Killer | Down+Left, Short Down, Right 16 (た) | タコアキッド | Takoyaki Kid | Short Up, Right, Short Up 17 (ち) | チンコーマン | Chinkoman | Short Right, Down, Short Right 18 (つ) | ツカイステイター | Tsukai Stater | Short Down, Left, Short Down 19 (て) | テッパンガー | Teppangar | Short Left, Up, Short Left 20 (と) | トンガラリン | Tongararin | Short Down+Left, Up, Short Left 21 (な) | ナガシマン | Nagashiman | Short Up, Right, Left 22 (に) | ニンジャーノン | Ninja | Short Right, Down, Up 23 (ぬ) | ぬいぬいちゃん | Plushy-chan | Short Down, Left, Right 24 (ね) | ネジレイザー | Screw Razor | Short Left, Up, Down 25 (の) | ノーベルブレイン | Nobel Brain | Short Down+Left, Up, Down 26 (は) | ハードハンマー | Hard Hammer | Short Up, Left, Short Up 27 (ひ) | ヒートマン | Heat Man | Short Right, Up, Short Right 28 (ふ) | フレイムグルメ | Flame Gourmet | Short Down, Right, Short Down 29 (へ) | ヘラクレスアーミー | Hercules Army | Short Left, Down, Short Left 30 (ほ) | ホットカード | Hot Card | Short Down+Left, Short Down, Short Left 31 (ま) | マッスルさん | Mr. Muscle | Short Up, Left, Right 32 (み) | ミストウォーター | Mist Water | Short Right, Up, Down 33 (む) | ムシムシマン | Mushimushi Man | Short Down, Right, Left 34 (め) | メガーテン | Megaaten | Short Left, Down, Up 35 (も) | モビルロボX | Mobile Robot X | Down+Left, Down, Up 36 (や) | ヤキバード | Yaki Bird | Up, Down, Left 37 (ゆ) | ユートロン | Utron | Down, Up, Right 38 (よ) | ヨーヨーマスク | Yo-Yo Mask | Down+Left, Right, Down 39 (ら) | ラジアルロード | Radial Road | Up, Down, Right 40 (り) | リモコンマン | Remote-Control Man | Right, Left, Down 41 (る) | ルビーフック | Ruby Hook | Down, Up, Left 42 (れ) | レトロサウンダー | Retro Sounder | Left, Right, Up 43 (ろ) | ロケットやろう | Rocket | Down+Left, Right, Short Up 44 (わ) | ワイルドソード | Wild Sword | Up, Down, Up+Left 45 (が) | ガッツラゴー | Guts Lago | Up, Down+Right, Short Left 46 (ぎ) | ギーニウン | Giniun | Right, Down+Left, Short Up 47 (ぐ) | グレートファイヤー | Great Fire | Down, Up+Left, Short Right 48 (げ) | ゲーマルク | Gamemark | Left, Up+Right, Short Down 49 (ご) | ゴウリキラー | Gorilla Killa | Down+Left, Up+Right, Short Down 50 (ざ) | ザ・クライマー | The Climber | Up, Down+Right, Short Right 51 (じ) | Gシャーク | G Shark | Right, Up+Left, Short Down 52 (ず) | ズームレーザー | Zoom Laser | Down, Up+Right, Short Left 53 (ぜ) | ゼンマイン | Zenmai | Left, Down+right, Short Up 54 (ぞ) | ゾウシャワー | Elephant Shower | Short Down+Left, Short Down+Right, Short Up 55 (だ) | ダイヤモール | Diamond Mall | Up, Down+Right, Up 56 (ぢ) | ヂグロニャン | Digronyan | Right, Down+Left, Right 57 (づ) | ヅィザーワン | Ziza One | Down, Up+Left, Down 58 (で) | デンジャレッド | Danger Red | Left, Up+Right, Left 59 (ど) | ドハツテン | Dohatsuten | Down+Left, Up+Right, Left 60 (ば) | バルバルーン | Balloon | Up, Down+Left, Up 61 (び) | ビデオージャ | Videoja | Right, Up+Left, Right 62 (ぶ) | ブーブーウー | Boo Boo | Down, Up+Right, Down 63 (べ) | ベルトジャイン | Belt Jain | Left, Down+Right, Left 64 (ぼ) | ボートロン | Boat Ron | Short Down+Left, Down+Right, Left 65 (ぱ) | パーフェクトサン | Perfect Sun | Up, Down+Left, Up+Left 66 (ぴ) | ピンスポーン | Pinspawn | Right, Up+Left, Up+Right 67 (ぷ) | プレスアーム | Press Arm | Down, Up+Right, Down+Right 68 (ぺ) | ペガサスボーイ | Pegasus Boy | Left, Down+Right, Down+Left 69 (ぽ) | ポップサンダー | Pop Thunder | Short Down+Left, Short Down+Right, Short Down+Left 70 (ん) | ンジャメナス | Ndjamenas | Right, Down+Left, Down+Right

GBC Infrared Communication

General Hardware Information

Compatible Games

Communication Types

Communication Protocol

RP Register

Signal Fade

Obscure Behavior

Pokemon Pikachu 2

Pocket Sakura

[GBC Infrared] : General Hardware Information

The Game Boy Color came with an infrared port on the very top of the handheld. Previously, where IR communications had to be done with special cartridges (like the HuC-1 variants), the Game Boy itself now had the hardware built-in. Unfortunately, the feature was never popular outside of a few games and accessories. The IR port essentially sends out signals and is also capable of receiving them, allowing for fast, wireless, line-of-sight transmission.

[GBC Infrared] : Compatible Games

This list represents all the games that have been verified to use the IR port. While exhaustive, this list is probably not complete. There are likely more Japanese exclusives that need to be added. It's dubious whether or not Animorphs actually is a "Ubi Key" game. The back boxart doesn't have the "IR Compatible" logo, and the manual makes no mention of IR communication.

The North American version of Disney's Aladdin claims to have infrared support on the box, supposedly for Ubi Key functionality, however, no such option is accessible in the game. Additionally, European variants omit the GBC IR logo from their boxes. It's possible that like Animorphs, Aladdin had its IR features stripped.

It should be noted that a few games that use HuC-3 MBC are not in fact "GB KISS" games. Instead, they use the GBC's built-in IR hardware. Robopon Sun Version (US version only) and Pocket Family GB 2 are such examples. While the other Robopon games use the HuC-3's IR capabilities, these were lost when the game went overseas. A similar phenomenon can be seen with the Japanese release of Pokemon TCG (which used the HuC-1) versus releases for any other region (which use the GBC's native IR). Pocket Family GB 2 abandons the IR diodes on the HuC-3 PCB. At this point in time, Hudson may have finally decided to abandon GB KISS and the HuC-1 and HuC-3's IR features as they were redundant, especially for games designed to run exclusively on the GBC.

[GBC Infrared] : Communication Types

While a number of games may use similar formats for their IR communications, there is no "standard" protocol that all games use. IR communication is entirely determined by the game's code, hence it can vary wildly depending on needs. However, all communications fall into one of several general categories as described below:

[GBC Infrared] : Communication Protocol

Again, there is no set or established infrared protocol that games must follow. Many games vary in their approach. For example, the 2nd Generation Pokemon games use the GBC's hardware timers, while others have hardcoded values that count cycles to check timing. The simplest form is a barebones communication protocol, i.e. something like a binary Morse code where a "0" is a long ON-OFF pulse and "1" is a short ON-OFF pulse or vice versa. Properly done, data could have been short, compact, and easily converted into bytes in RAM. Sakura Taisen GB seems to follow this model in its communications with the Pocket Sakura. Not all games do this, however, and appear to be doing who knows that, opting instead for customized and specialized communications unique to each title. To illustrate this idea, it would be possible to use a table of given lengths of IR ON-OFF pulses so that individual bytes could be sent all at once instead of in a binary, bit-by-bit manner. A number of games try to send a few pulses when pressing input like the A button and wait for another GBC to echo that in response, but after the handshake, most of the IR pulses are impossible to understand without disassembling the code.

One thing to note is that 4 games in particular do share somewhat similar IR protocols, at least in regards to the initial handshake between 2 GBCs. They are Pokemon TCG 1 & 2 and Bombermax Red & Blue, all from the "2-Player Init" category above. Typically, IR capable GBC games will continually wait for an IR signal on both sides, i.e. the "1-Player Init" category. When one player presses certain input, that GBC takes the initiative and sends out a few IR pulses. That is to say, for most IR games, it only takes *just one* player to start the entire process.

The handshake for the 4 games previously mentioned, however, requires *both* players to input at almost the same time. One has to be slightly faster or slower than the other. Each side continually sends a few IR pulses, then reads the sensor to see if anything was received. If so, the GBCs begin to sync. The idea is that one side should be sending while the other is checking, and then the handshake completes. This is why one side needs to be faster or slower to input; if they are sending IR signals at the same time, they don't see anything when reading the sensor. As a result, both GBCs cannot input at exactly the same time. Practically speaking, this is unlikely to happen under normal circumstances, since most humans can't synchronize their actions down to a handful of microseconds, so the handshake will normally succeed.

The following is just theory. This handshake is possibly an artifact of the HuC-1. Consider that the Japanese version of Pokemon TCG 1 used the HuC-1 for its IR communications, and the developers may have borrowed the "best practices" used by other HuC-1/"GB KISS" games. When bringing Pokemon TCG 1 overseas, the IR handling code was likely minimally adapted to use the GBC's IR port, with the underlying protocol remaining unchanged in most regards. Pokemon TCG 2 ditched the HuC-1 in favor of the GBC IR port, so the IR code from non-Japanese versions of Pokemon TCG 1 was copy+pasted. The Bomberman games were made by Hudson Soft, literally the same people who created the HuC-1 in the first place. They too probably used the same protocol that had worked forever in their "GB KISS" games, so they used the same handshake method as before, just on the GBC IR port now. More research into the HuC-1 itself and the games needs to be done to confirm any of this.

[GBC Infrared] : RP Register

On the GBC, the MMIO register located at 0xFF56 controls infrared communication. Simply known as "RP" (Radiation Port? Reception Port? Red Port???), it is responsible for sending and receiving IR signals. Below is a diagram of the 8-bit register:

Bit 0: Turn IR light ON (1) or OFF (0) (R/W) Bit 1: IR signal (0 = Receiving signal) (1 = Normal/No signal) (R) Bits 2-5: Unused Bits 6-7: Signal Read Enable (0 = Disable) (3 = Enable) (R/W)

Turning on the IR light is as simple as writing to Bit 0 of RP. Reading is a bit more complicated. Bits 6 and 7 must both be set (0xC0), to read Bit 1, otherwise Bit 1 returns 1, acting as if no signal is detected, except in edge cases detailed below in "Obscure Behavior". With signal reading enabled, Bit 1 will determine the status of any incoming IR signals. Like other Game Boy MMIO registers, unused bits read high (set to 1).

[GBC Infrared] : Signal Fade

The IR sensor in the GBC adapts to the current level of IR light. That is to say, if the GBC receives a sustained IR signal beyond a certain amount of time, eventually the sensor treats this as a new "normal" level of IR light, and Bit 1 of RP goes back to 1. This is called the signal "fade" because it may appear as if the signal disappears.

Signal fade time is dependent on length and has an inverse relationship with the distance between a GBC and the IR light. The closer a GBC is to the IR source, the longer the fade time. The farther away a GBC is to the IR source, the shorter the fade time. One possible explanation for everything is that the IR signal is weaker on the receiving end, so the signal is prone to get "lost" to surrounding noise. The GBC IR sensor is probably good at sending IR signals (evidenced by the Mission Impossible cheat to turn a GBC into a TV remote) but not so good at picking up signals (evidenced by Chee Chai Aliens plastic add-on to enhance IR reception).

At about 3.0 to 3.5 inches (7.62 to 8.89cm) signal fade time appears to be around 3ms. Optimal distance seems to be 2.5 to 4.0 inches (6.35 to 10.16cm) to maintain a fade time close to 3ms and avoid potential miscommunication. One oddity of note is that putting two GBCs very close together (physically touching) produced unusually short fade times, far shorter than 3ms. There may be some sort of interference at that range.

[GBC Infrared] : Obscure Behavior

The RP register has one very strange quirk. Disabling Bits 6 and 7 and then subsequently re-enabling them causes Bit 1 to go to zero under certain conditions. In other words, the IR sensor will act as if it is detecting a signal if reading the signal is disabled then enabled. It seems this behavior happens in the presence of any light; covering up the sensor during the read signal disable/enable causes the sensor to act normally. It's possible that the sensor resets itself (to its lowest level of detection???) and immediately detects any infrared sources, even from ambient/environmental light. The presence of any noise may temporarily trick the sensor into "seeing" IR light. By abusing this behavior, the GBC has some rudimentary ability to gauge the type of nearby lighting:

-------------------------------------------------------------------------------------------- Result of 1st RP Write (0x00) Result of 2nd RP Write (0xC0) Type of Lighting -------------------------------------------------------------------------------------------- Bit 1 = 1 Bit 1 = 1 Dark Bit 1 = 0 Bit 1 = 1 Ambient Bit 1 = 0 (sometimes 1) Bit 1 = 0 Bright

Writing 0x00 to RP, followed by 0xC0 will trigger these results listed above. One very important thing to note is that when enabling Bits 6 and 7 (writing 0xC0), it does take some time for the sensor to register legitimate IR light coming into the sensor. I.e. if you want to use this method to detect what kind of light a GBC is looking at, the software needs to loop for a bit until Bit 1 of RP changes. Generally a few hundred cycles in double-speed mode will suffice. If Bit 1 of RP remains 1 after the loop, it's safe to assume the lighting is either ambient or dark. This delay doesn't seem to happen when Bits 6 and 7 are never disabled (which is what most official GBC software does). Games typically write either 0xC0 or 0xC1 to RP, with a small handful setting it to 0x00 initially when setting up other MMIO registers (Pokemon G/S/C does this).

The downside to this method is that when detecting a bright IR source, the sensor quickly adjusts to this new level, and the next attempt at writing 0x00 followed by 0xC0 to RP will result in readings of dark or ambient (typically dark though). Essentially the bright result only appears briefly when transitioning from lower levels of light, then it "disappears" thanks to the short time it takes for IR signal fade. Designing a game mechanic (darkness and light) around this quirk is still possible, although it would require careful thought and planning to properly work around the observed limitations.

One suggested method: once the Bright setting is detected, switch to writing only 0xC0 to RP so that the IR sensor works normally. If IR light stops being detected, switch to alternating 0x00 and 0xC0 writes as described above to determine Dark or Ambient settings. Whether it's practical or not to do this in a game remains theoretical at this point.

[GBC Infrared] : Pokemon Pikachu 2

The Pokemon Pikachu 2 (PP2) is a virtual pet device similar in concept to Tamagotchis. The PP2 is the successor to the original Pokemon Pikachu with a number of notable changes, largely the new color screen and the ability to communicate with Pokemon Gold, Silver, and Crystal via IR signals. These signals are used for the Mystery Gift functionality. Unlike normal Mystery Gifts between two GBCs, which produce random items, the PP2 gives out consistent items based on the number of "watts" transferred. The "watts" are the PP2's form of currency generated by the unit's pedometer (via walking, or more commonly, just shaking). Players either give Pikachu watts to make it happy, or send them to another PP2, or use them to Mystery Gift with Pokemon G/S/C.

In addition to giving out predictable items via Mystery Gift, the PP2 can also Mystery Gift without time limits. Normally, when two GBCs Mystery Gift 5 times in Pokemon G/S/C, players have to wait until the following day to try again. No such restriction applies when a GBC communicates with the PP2. The two can Mystery Gift endlessly, as long as the PP2 has watts to transfer. Below is a table of watts and the items they generate:

0 - 99 Watts Eon Mail 100 - 199 Watts Berry 200 - 299 Watts Bitter Berry 300 - 399 Watts Great Ball 400 - 499 Watts Max Repel 500 - 599 Watts Ether 600 - 699 Watts Miracle Berry 700 - 799 Watts Gold Berry 800 - 899 Watts Elixir 900 - 998 Watts Revive 999 Watts Rare Candy

Current analysis of the IR communications between a GBC and a PP2 indicates that the PP2 interacts with Pokemon Crystal differently in comparison to Pokemon Gold and Silver. Each transfer appears to be 2007 ON-OFF transitions long.

[GBC Infrared] : Pocket Sakura

The Pocket Sakura is another virtual pet device similar to the Pokemon Pikachu 2. Design-wise, it is a copy+paste version of the PP2, except it's pink. Interestingly enough, the Pocket Sakura was made by Media Factory, the same people behind Zok Zok Heroes and the Full Changer device. The Pocket Sakura uses a pedometer to make Sakura travel to various locations and meet other Sakura Taisen-based characters. When resting at a location, the pedometer turns steps into "points" (10 steps = 1 point), which can then be sent to a GBC running Sakura Taisen GB or another Pocket Sakura.

Each transfer appears to be 1607 ON-OFF transitions long.

Gyogun Tanchiki: Pocket Sonar

General Hardware Information


Sonar Format

Fish Finder

Game Boy Incompatibilities

Further Research

[Pocket Sonar] : General Hardware Information

Gyogun Tanchiki: Pocket Sonar (shortened to just Pocket Sonar) was a combination "game" and accessory released by Bandai on July 24, 1998 exclusively in Japan. The cart and attached sonar device act as a fish finder, capable of probing water depths of up to 20 meters. It was the first video-game based sonar hardware, but not the last (Bandai released the WonderSwan Handy Sonar the following year). Apparently, Bandai worked with Honda Electronics for this product.

[Pocket Sonar] : MBC1S

The MBC1S is a specialized variant of the standard MBC1. The key difference here is that the ability to control sonar hardware was added. Aside from that, the MBC1S appears largely identical to the MBC1 from a high-level view. Below are the MBC registers:

0x0000 - 0x1FFF (W) : Unknown. Not used in the Pocket Sonar. Pocket Sonar has no cart RAM. 0x2000 - 0x3FFF (W) : ROM Bank Number. Same as MBC1. 0x4000 - 0x5FFF (W) : Sonar Pulse. Apparently activates the sonar when writing "1", turns it off when writing "0". Must be in "sonar mode" 0x6000 - 0x7FFF (W) : Sonar Mode Enable/Disable. Activates "sonar mode" when writing "1". Pocket Sonar never seems to write "0" here though. 0xA000 (R) : Sonar Data. Data comes in byte-by-byte and the software uses that information to build an image of what's in the water.

The Pocket Sonar doesn't have cartridge-based RAM, so it repurposes most MBC1 registers dealing with RAM to instead handle sonar.

[Pocket Sonar] : Sonar Format

The Pocket Sonar displays a 160x96 image on screen based on sonar data. This "frame" is constantly updated, albeit quite slowly. The next frame slides in from the right to replace the old one. Each frame is generated using the responses that come from reading 0xA000. The byte held in this register determines what color the software should draw on-screen, and the colors ultimately represent either open water or soil, sediment, rocks, and other solid flooring. The Pocket Sonar interprets two different "sets" of colors, one for before solid flooring is detected, and one for after. With Shade 0 being the lightest DMG pixel color and Shade 3 being the darkest DMG pixel color, the following values held in 0xA000 determine the corresponding colors:

--------------------------------------------------------- VAL = 0xA000 AND 0x7 : Before solid flooring detected (0xA000 reads 0x00) --------------------------------------------------------- 1 SHADE 3 Solid object or debris (the top-most exterior) 2, 3 SHADE 2 Solid object or debris (inner layers) 4, 5, 6, 7 SHADE 0 Open water --------------------------------------------------------- VAL = 0xA000 AND 0x7 : After solid flooring detected (0xA000 reads 0x00) --------------------------------------------------------- 0, 1, 2, 3 SHADE 3 Solid floor (the top-most exterior) 4, 5, 6, 7 SHADE 1 Solid floor (inner layers)

Solid floor detections appears to happen after the Pocket Sonar returns a single 0x00 byte for each section of the frame. Every frame is internally divided into 1x96 strips by the software. Depending on the depth the Pocket Sonar is trying to probe (e.g. 2m, 5m, 10m, etc), the device reads 0xA000 more frequently.

--------------------------------------------------------- Depth 1x96 Reads Total Frame Reads --------------------------------------------------------- 2 meters 188 30080 5 meters 196 31360 10 meters 198 31680 15 meters 199.4 31904 20 meters 199 31840 30 meters 200 32000

The first 96 reads correspond directly to a 1x96 strip that's part of the larger 160x96 frame. That is to say, 1 read = 1 pixel drawn on-screen (after the waterline). The additional reads from 0xA000 are not drawn unless the magnification feature is used. With magnification, instead of displaying the sonar image from the waterline to the probing depth (e.g. 0-2m, 0-5m, 0-10m), the Pocket Sonar will start drawing at halfway to the probing depth (e.g. 1-2m, 2.5-5m, 5-10m). It effectively drops viewport of the sonar image, and in doing so displays some of the other reads beyond the first 96. Consequently, using the magnification feature changes the above chart to this:

----------------------------------------------------------------- Depth 1x96 Reads Total Frame Reads ----------------------------------------------------------------- 1.0 - 2.0 meters 176 28160 2.5 - 5.0 meters 192 30720 5.0 - 10.0 meters 196 31360 7.5 - 15.0 meters 198 31680 10.0 - 20.0 meters 198 31680 20.0 - 30.0 meters 199 31840

The Pocket Sonar represents the waterline as all black and forcibly draws a certain number of pixels for it depending on the depth the device is checking. The waterline is not applicable when using magnification. Apparently the Pocket Sonar internally divides the 160x96 frame into a 80x96 "sub-frame". It isn't clear what the purpose of this is, but it appears to be some sort of mid-frame reset if necessary, perhaps if garbage values are detected (e.g. sonar data that doesn't realistically make sense?)

To collect the above sonar data, the MBC1S must first send out a sonar pulse by writing "1" then "0" to the memory regions 0x4000 - 0x5FFF. Afterwards, 0xA000 will hold a single byte representing part of the sonar image. The process of reading back the sonar image appears to take some time, however. It doesn't seem to be immediate, as the Pocket Sonar's software reads 0xA000 across several screen refreshes. Below are charts detailing the number of 0xA000 reads per-screen refresh on the Game Boy LCD:

------------------------------------------------------------- 2 Meters Magnification OFF Magnification ON ------------------------------------------------------------- Refresh_0 188 reads 176 reads Refresh_1 0 reads 0 reads Refresh_2 0 reads 0 reads Refresh_3 0 reads 0 reads Refresh_4 0 reads 0 reads Refresh_5 0 reads 0 reads Refresh_6 0 reads 0 reads Refresh_7 0 reads 0 reads ------------------------------------------------------------- 5 Meters Magnification OFF Magnification ON ------------------------------------------------------------- Refresh_0 153 or 154 reads 192 reads Refresh_1 42 or 43 reads 0 reads Refresh_2 0 reads 0 reads Refresh_3 0 reads 0 reads Refresh_4 0 reads 0 reads Refresh_5 0 reads 0 reads Refresh_6 0 reads 0 reads Refresh_7 0 reads 0 reads Refresh_8 0 reads ------------------------------------------------------------- 10 Meters Magnification OFF Magnification ON ------------------------------------------------------------- Refresh_0 76 reads 135 or 137 reads Refresh_1 121 reads 59 or 61 reads Refresh_2 1 read 0 reads Refresh_3 0 reads 0 reads Refresh_4 0 reads 0 reads Refresh_5 0 reads 0 reads Refresh_6 0 reads 0 reads Refresh_7 0 reads 0 reads Refresh_8 0 reads 0 reads Refresh_9 0 reads ------------------------------------------------------------- 15 Meters Magnification OFF Magnification ON ------------------------------------------------------------- Refresh_0 50 reads 90 or 92 reads Refresh_1 81 reads 106 or 108 reads Refresh_2 68 reads 0 reads Refresh_3 0 reads 0 reads Refresh_4 0 reads 0 reads Refresh_5 0 reads 0 reads Refresh_6 0 reads 0 reads Refresh_7 0 reads 0 reads Refresh_8 0 reads 0 reads Refresh_9 0 reads ------------------------------------------------------------- 20 Meters Magnification OFF Magnification ON ------------------------------------------------------------- Refresh_0 37 reads 68 or 69 reads Refresh_1 60 reads 109 reads Refresh_2 59 or 60 reads 20 or 21 reads Refresh_3 42 or 43 reads 0 reads Refresh_4 0 reads 0 reads Refresh_5 0 reads 0 reads Refresh_6 0 reads 0 reads Refresh_7 0 reads 0 reads Refresh_8 0 reads 0 reads Refresh_9 0 reads 0 reads Refresh_10 0 reads ------------------------------------------------------------- 30 Meters Magnification OFF Magnification ON ------------------------------------------------------------- Refresh_0 24 reads 45 or 46 reads Refresh_1 40 reads 73 reads Refresh_2 41 reads 73 reads Refresh_3 40 reads 7 or 8 reads Refresh_4 40 reads 0 reads Refresh_5 15 reads 0 reads Refresh_6 0 reads 0 reads Refresh_7 0 reads 0 reads Refresh_8 0 reads 0 reads Refresh_8 0 reads 0 reads Refresh_10 0 reads 0 reads Refresh_11 0 reads Refresh_12 0 reads

The values above should be considered approximate. When changing between different depths, the above numbers get slightly messed up for a short time (usually just for 1 sonar pulse) before they normalize. During the transition, the totals still add up (e.g. 10m still reads 0xA000 198 times per 1x96 segment of the frame, with magnification off), however, the spacing between reads shifts a bit. Trying to change 30m to the next depth (pressing A on the depth change menu item) sometimes causes an elongated pause between sonar pulses (31 LCD refreshes, so more than 1/2 a second) but since 30m is the max, the Pocket Sonar keeps reading 0xA000 at 200 times per 1x96 frame segment. The numbers briefly fluctuate across screen refreshes until returning to the chart above.

[Pocket Sonar] : Fish Finder

The usefulness of the Pocket Sonar, aside from bathymetry, is largely its fish finding capabilities. The Pocket Sonar has a toggable option for displaying any fish it believes it has detected. The fish are represented by simple 8x8 graphics. Strangely enough, the fish are aligned to a slightly different grid than the 160x96 sonar image. If using the 160x96 sonar image divided into 8x8 cells as a reference, the fish are drawn over this image with a Y offset of -1. This "fish grid" also determines when the Pocket Sonar software thinks it has located a fish.

Fish tiles are always aligned on the X-axis by 8 pixels of the "fish grid", so they are always locked into columns, however, they seem to shift freely on the Y-axis. Obviously, fish are only detected in open water; once solid flooring (and not just debris or other objects) has been detected, no fish appear below the floor. As such, fish detection only happens when using the first "set" of colors for drawing the frame. To detect fish, an 8x8 section of the "fish grid" needs to have only 1 value of 0x00 or 0x01 within the first column. If not, the Pocket Sonar will treat it as a miscellaneous object. Even if the second column (or every other one) has multiple 0x00 or 0x01 values, the Pocket Sonar only cares about first column. The first occurence of a 0x00 or 0x01 value in the first column of any 8x8 cell on the "fish grid" appears to determine where the fish tile is aligned vertically.

Oddly enough, several options change the X offset of the "fish grid". Enabling or disabling the option for displaying fish seems to reposition the "fish grid" according to whatever 1x96 segment of the frame is rendered. Additionally, toggling magnifcation or the "auto" (オート) mode resets the "fish grid".

[Pocket Sonar] : Game Boy Incompatibilities

For some reason, Game Boy Color and Game Boy Advance units do not work with the Pocket Sonar. These handhelds seem to return 0x00 when reading 0xA000 for the sonar. When the sonar is turned on, this results in a pure black screen. When the sonar is turned off, some other value (probably 0xFF) is read, resulting in a pure white screen. DMG and MGB Game Boys have no apparent trouble properly reading sonar data from 0xA000 though.

[Pocket Sonar] : Further Research

There are a couple of discrepancies that require further clarification. The Pocket Sonar displays a brief "demo" mode if players wait around the title screen. It shows an example sonar image scrolling across the screen, however it uses 3 shades to represent the ground (SHADE 3, SHADE 2, and SHADE 1 in that order). It doesn't seem possible to recreate this type of image when actually using the Pocket Sonar, as the ground only uses 2 shades (SHADE 3 and SHADE 1). Additionally, on the box and in the manual, all pictures of the Pocket Sonar in action only show these 2 shades. Extensive testing using various values for the sonar image data at 0xA000 could not reproduce the "demo" mode either. While the "demo" mode may be impossible on real hardware, as actual tests in real bodies of water have not reproduced it.

Additionally, while the Pocket Sonar clearly states it can probe a depth of 20m, the software has settings for 30m. Furthermore, there is photographic evidence of at least one individual successfully using the 30m option. It isn't clear if the Pocket Sonar is capable of handling 30m without issue or if it can do 30m with some degree of inaccuracy. Again, real world testing would have to be done to determine the exact nature of the 30m setting.

GBA Screen Stretch

GBA hardware has the ability to stretch the final image drawn on-screen when running DMG or GBC games. On applicable hardware (e.g. not the Micro, original NDS, or NDS Lite models), the L and R triggers toggle this feature on and off respectively. The default mode is to display the DMG/GBC image in the middle of the GBA screen with black borders. The dimensions are as follows:

Top and bottom borders (240x8 pixels, or 30x1 tiles) Left and right borders (40x160 pixels, or 5x20 tiles) DMG/GBC screen (160x144 pixels, or 20x18 tiles)

Technically, the original DMG/GBC screen has an offset of (40, 8). Once the player toggles stretching, the above dimensions change:

Top and bottom borders (240x8 pixels, or 30x1 tiles) Left and right borders (Not Applicable) DMG/GBC screen (240x144 pixels, or 30x18 tiles)

The DMG/GBC screen completely stretches to the left and right ends of the screen. No vertical stretching occurs; the black bars still exist at the top and the bottom. Horizontal stretching follows a simple formula. For every 2 pixels from the original 160x144 image, a third pixel is generated by blending them together. This third pixel is then placed between the two original pixels. For example, imagine Pixel A and Pixel B represent original pixels from the 160x144 image. Pixel C is the result of blending the two of them. The GBA will produce A-C-B when stretching DMG and GBC games.

This method of stretching acts on the present 160x144 image generated by the DMG/GBC game, that is to say, scrolling the background, window, or OBJs can produce minor inconsistencies depending on where a tile is rendered to the screen. Generally, these inconsistencies affect the blending seen around edges. For example, in the first level of Super Mario Land, the trunks of the trees in the background are only 1 pixel wide. When stretching, the blended edge will switch from the left to the right depending on its current position due to scrolling. However, these inconsistencies are barely visible under the best circumstances, and almost impossible to detect during actual gameplay.

The blending comes straight from the GBA's affine transformations. That is to say, after the final DMG/GBC screen is rendered, the GBA controls all output via BG2. Even in the GBA's DMG/GBC backward compatibility mode, GBA video hardware is still being used to display graphics. Currently, the exact formula for determining colors remains unknown, however, something as simple as averaging Pixel A and Pixel B gives quick, adequately believable results. One thing that is known about the blending: if A and B are the same color, they will not produce a different color.

Power Antenna + Bug Sensor

General Hardware Information

Game Boy Color Operation

Game Boy Advance Operation

Misc. Notes

[Power Antenna + Bug Sensor] : General Hardware Information

The Power Antenna are accessories bundled with the Keitai Denjuu Telefang Telefang games for the Game Boy Color and Game Boy Advance. An identical accessory, called the Bug Sensor, was also bundled with the Network Adventure Bugsite games on the GBC. Primarily cosmetic, these devices were essentially LEDs that were programmed to light up depending on certain events in the games.

* The 2nd version of the Power Antenna, the one that came with Telefang 2, is physically only compatible with the GBA's link port. However, it can be used with the GBC games.

[Power Antenna + Bug Sensor] : Game Boy Color Operation

To communicate with the Power Antenna + Bug Sensor, the GBC must run on an internal clock. A single byte is then transmitted via serial communications. The chart below describe what input will affect the LED:

----------------------------------------------------- Value Sent | LED Result ----------------------------------------------------- 0x00 | Turns LED off Bit 0 == 1 | Turns LED on (Strong Light) Bit 0 == 0 | Turns LED on (Weak Light) -----------------------------------------------------

"Strong Light" refers to the LED turning on and sustaining its brightest output; it will not turn off until a value of 0x00 is sent. "Weak Light" refers to the LED turning on temporarily and rapidly fading on its own. Weak Light is very dim (not noticable under certain lighting conditions) and is extremely short-lived. This mode does not appear to be used by the games. Instead, only Strong Light is turned on. Weak Light can be emitted constantly and indefinitely if multiple and repeated serial transfers occur. Sending such a transfer around 60Hz is enough to get weak light turned on for as long as desired.

It is possible to cause flickering by turning the LED on and off at given intervals. For Strong Light, this involves alternate transfers of 0x00 and some other value with Bit 0 set high. For Weak Light, simply send a value with Bit 0 set low and increase the gaps between transmission (e.g. delay transmission by 2 frames or 3 frames).

When the Power Antenna + Bug Sensor are emitting any kind of light, the device returns 0xF3 to the GBC. This is true even after Weak Light has fully faded. When no light is being emitted, the device returns 0xF2.

[Power Antenna + Bug Sensor] : Game Boy Advance Operation

Communications with the Power Antenna + Bug Sensor are a bit different when operating in GBA mode (i.e. running GBA software, not using a GBA to run GBC software). The GBA must use NORMAL_8BIT or NORMAL_32BIT mode; either one is fine. The following values of SIOCNT will affect the LED:

----------------------------------------------------- Value Written | LED Result ----------------------------------------------------- 0x0080 | Turns LED off 0x0089 | Turns LED on (Strong Light) 0x0081 | Turns LED on (Weak Light) -----------------------------------------------------

To turn off the LED, simply set Bit 3 of SIOCNT low and start a serial transfer. It does not matter whether an internal or external clock is set. For Strong and Weak Light, the 8-bit or 32-bit data sent is ignored. Instead, high or low values of Bit 3 of SIOCNT respectively dictate whether Strong or Weak Light is produced.

In NORMAL_8BIT mode, Strong and Weak Light return an 8-bit value of 0xFF instead of 0xF3 as on the GBC. In NORMAL_32BIT mode, the returned 32-bit value is 0x00.

[Power Antenna + Bug Sensor] : Misc. Notes

Since all Power Antenna + Bug Sensors rely on the presence or absence of a single bit, it is possible for other software to inadvertedly turn it on. For example, the GBA BIOS performs a few NORMAL_32BIT transfers on an internal clock, therefore turning on the LED for the duration of the boot logo (and indefinitely if the game does not change SIOCNT). Even software written specifically for these devices may turn them on at odd moments. Telefang triggers the LED on when attempting to use multiplayer via the Link Cable, although in this case, there is a reasonable expectation that the Power Antenna would be unplugged first.

Turbo File GB

General Hardware Information

Compatible Games

Communication Protocol


File Structure

Memory Card

Unused Space

[Turbo File GB] : General Hardware Information

Developed by ASCII Corporation and released in March of 2000, the Turbo File GB is an external storage device designed to hold large amounts of save data. Having already made several similar devices for the Famicom and Super Famicom, the company brought a new unit over to the Game Boy Color. Only select games specifically programmed to take advantage of the Turbo File GB were compatible. The accessory made use of memory cards as well, a first for the Game Boy.

[Turbo File GB] : Compatible Games

Only 2 games were officially compatible with the Turbo File GB, both RPG Maker titles. Despite the Turbo File GB technically being compatible with older Game Boys, the only compatible software was all GBC-exclusive.

It should also be noted that these games are RPG "Tskuru" as in the Japanese verb "To Make". A number of resources mistakenly translate this as "School" perhaps given the katakana used on the boxart, title screens, and other media.

[Turbo File GB] : Communication Protocol

The GBC communicates with the Turbo File on an external clock. It starts off with a sync signal, waiting for the Turbo File to begin. Once the first sync signal has been acknowledged, a packet is transferred from the GBC to the Turbo File, followed by a second sync signal. The packet consists of the following parts:

------------------------------------------------- Packet Format ------------------------------------------------- Sync Signal 1 | 1 Byte (0x6C) Packet Body | Length varies Checksum | 1 Byte Sync Signal 2 | 2 Bytes (0xF1, 0x7E) -------------------------------------------------

For the first sync signal, the GBC sets 0xFF01 to 0x6C and waits until the Turbo File sends 0xC6. After the packet body and checksum have been transferred, a second sync signal is sent. For this signal the GBC sets 0xFF01 to 0xF1, then 0x7E. The Turbo File should send 0xE7 and 0xA5 respectively.

The packet body consists of the following parts:

------------------------------------------------- Packet Body Format ------------------------------------------------- Magic Byte | 1 Byte (0x5A) Command | 1 Byte Parameters | Length varies -------------------------------------------------

Not every command has parameters, therefore, that section of the packet is not always present.

The checksum is calculated as such: 0x100 - (Sum of Packet Body Bytes)

After the entire packet has been sent, the GBC will wait with the value 0xF2 for several transfers, the length of which depends on the given command. During that time, the Turbo File responds with the appropiate data. This data is formatted as a packet as well, however, it does not use sync signals.

The basic flow of commands goes something like this:

1. Command 0x10 Get status (called often in-between other commands) 2. Command 0x20 Begin session 3. Command 0x23 or 0x22 Switch bank for read/write mode 4. Command 0x40 or 0x30 Read/write 64 bytes from/to memory 5. ... Repeat 3 and 4 as needed 6. Command 0x24 End session

[Turbo File GB] : Commands

Command 0x10 - Get Status

Parameters: None

Response Data: 9 bytes detailing the status of the Turbo File GB.

Returns various bits of information about the Turbo File GB. Called frequently before and after many other commands. The response packet for this command follows this format:

------------------------------------------------- Command 0x10 Response Packet Bytes ------------------------------------------------- 0x00 - Command | 0x10 0x01 - Unknown | 0x00 0x02 - Device Status | See below 0x03 - Card Status | 0x01 = No memory card, 0x05 = Card present 0x04 - Current Bank MSB | 0x00 through 0x01 0x05 - Current Bank LSB | 0x00 through 0x7F 0x06 - Unknown | 0x00 0x07 - Unknown | 0x00 0x08 - Checksum | 0x100 - 0xA5 - (Sum of Bytes 0 through 7) -------------------------------------------------

The device status byte uses the following bits to represent several states:

------------------------------------------------- Device Status Bits ------------------------------------------------- Bit 0 | Device Ready = 1 Bit 1 | Unknown Bit 3 | Initialized ??? Bit 7 | Read-Only Physical Switch On/Off -------------------------------------------------

Command 0x20 - Begin Session

Parameters: 1 byte of unknown significance

Response Data: 4 byte echo packet

Appears to be called before reading or writing operations take place. The response packet for this command is an echo of the previous packet from the GBC.

------------------------------------------------- Command 0x20 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x20 Byte 0x01 | 0x00 Byte 0x02 | Device Status Byte 0x03 | Checksum = 0x100 - 0xA5 - (Sum of Bytes 0 through 2) -------------------------------------------------

Command 0x22 - Set Write Bank

Parameters: 2 bytes forming an 8-bit bank number (MSB first)

Response Data: 4 byte echo packet

This command sets the bank for write operations. The 1st parameter is Bit 7 and the 2nd parameter is Bit 0-6. This command also sets Bit 3 of the Device Status flag for all future Get Status commands. The response packet for this command is an echo of the previous packet from the GBC.

------------------------------------------------- Command 0x22 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x22 Byte 0x01 | 0x00 Byte 0x02 | Device Status (Bit 3 set) Byte 0x03 | Checksum = 0x100 - 0xA5 - (Sum of Bytes 0 through 2) -------------------------------------------------

Command 0x23 - Set Read Bank

Parameters: 2 bytes forming an 8-bit bank number (MSB first)

Response Data: 4 byte echo packet

This command sets the bank for read operations. The 1st parameter is Bit 7 and the 2nd parameter is Bit 0-6. This command also sets Bit 3 of the Device Status flag for all future Get Status commands. The response packet for this command is an echo of the previous packet from the GBC.

------------------------------------------------- Command 0x23 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x23 Byte 0x01 | 0x00 Byte 0x02 | Device Status (Bit 3 set) Byte 0x03 | Checksum = 0x100 - 0xA5 - (Sum of Bytes 0 through 2) -------------------------------------------------

Command 0x24 - End Session

Parameters: None

Response Data: 4 byte echo packet

This command is called after the game has finished reading or writing all necessary data. The response packet is like all of the echo packets for other commands, however, it technically isn't a copy of the original packet (which is only 2 bytes: a command and a checksum).

------------------------------------------------- Command 0x24 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x24 Byte 0x01 | 0x00 Byte 0x02 | Device Status Byte 0x03 | Checksum = 0x100 - 0xA5 - 0x24 -------------------------------------------------

Command 0x30 - Write Data

Parameters: 2 bytes forming a 13-bit offset (MSB first) and 64 bytes of data to write

Response Data: 4 byte echo packet

The two parameters are the 13-bit offset where to write data. The 1st parameter is Bit 8-12 and the 2nd parameter is Bit 0-7. Data will be written to the bank specified by Command 0x22. Only 64 bytes can be written at a time. The response packet for this command is an echo of the previous packet from the GBC.

------------------------------------------------- Command 0x30 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x30 Byte 0x01 | 0x00 Byte 0x02 | Device Status Byte 0x03 | Checksum = 0x100 - 0xA5 - (Sum of Bytes 0 through 2) -------------------------------------------------

Command 0x40 - Read Data

Parameters: 2 bytes forming a 13-bit offset (MSB first)

Response Data: 69 bytes for a data packet

The two parameters are the 13-bit offset to read data from. The 1st parameter is Bit 8-12 and the 2nd parameter is Bit 0-7. Data will be read from the bank specified by Command 0x23. Only 64 bytes can be read at a time. The response packet follows this format:

------------------------------------------------- Command 0x40 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x40 Byte 0x01 | 0x00 Byte 0x02 | Device Status Byte 0x03 - 0x42 | Data Byte 0x43 | Checksum = 0x100 - 0xA5 - (Sum of Bytes 0x00 through 0x42) -------------------------------------------------

Even though the Turbo File GB uses flash memory, these commands do not correspond to ones generally used by other devices. The Turbo File GB may be using an additional microprocessor (an M38034M4 by Mitsubishi) to handle and translate the GBC's packets into valid flash commands.

Although the flash memory inside the Turbo File GB supports block erase commands, the Turbo File GB has not been verified to process such a command from the Game Boy. Whereas the Turbo File Advance uses the 0x34 command to erase blocks, no GBC games make use of such a command, nor have limited hardware tests succeeded in executing that command. If the Turbo File GB's microprocessor does translate input from the Game Boy, it may not have been programmed to handle command 0x34 at all.

[Turbo File GB] : File Structure

Bank 0x7F (for internal storage) and Bank 0xFF (for memory card storage) contain the file headers for each file. These identify the name of the file and how many blocks it occupies. With this information, games can know where each file is within the lower banks and correctly access them. Each header occupies 64 bytes. The format is described below:

------------------------------------------------- File Header ------------------------------------------------- Byte 0x00 | 0x5A Byte 0x01 - 0x04 | Game ID Byte 0x05 - 0x10 | ASCII String for filename (12 characters max) Byte 0x11 - 0x15 | Should all be 0x20 Byte 0x16 | Current block ranging from 0 to (Total - 1) Byte 0x17 | Total number of blocks for save Byte 0x18 - 0x3F | Should all be 0x00 -------------------------------------------------

Each 8KB block a file occupies is given its own header, hence the need for a byte detailing the current block. The smallest file saved by games is 4 blocks, thus it has 4 separate headers. Since the very last 32KB on both internal storage and the memory card are reserved for these file headers, the maximum number of available blocks on either will be 120 (displayed as 119 in compatible games), enough for 30 different files.

Bytes 0x01 through 0x04 act as IDs. They are the same bytes found in the game's ROM header, specifically right after the ASCII-encoded title (bytes 0x13F through 0x142). Interestingly enough, these header bytes are supposed to be the new manufacturer code Nintendo specified for GBC games. As both RPG Tsukuru GB and Uchuu Nin Tanaka Tarou De RPG Tsukuru GB2 can save to the Turbo File GB, using an ID prevents incompatibilities when trying to load a file. Each game ignores reading files from the other, however, both can freely erase any file on the device.

[Turbo File GB] : Memory Card

The Turbo File GB's memory cards can be accessed by setting Bit 0 of the 1st parameter byte for commands 0x22 and 0x23. The memory cards effectively act as expanded storage, and thus the parameters from commands 0x22 and 0x23 form an 8-bit bank number. Banks 0x00 through 0x7F represent data stored internally on the Turbo File. Banks 0x80 through 0xFF represent data stored on the memory card.

To detect whether a memory card is present, games must check Bit 2 of Byte 3 of the 0x10 command. If that is set, a memory card has been inserted, otherwise, nothing has been slotted in.

[Turbo File GB] : Unused Space

While the last block of internal storage or the memory card is reserved for file headers, a number of blocks before that are deemed off-limits by game software. This empty space acts as a buffer against any errant writes, with the idea being the last 8 blocks should not be touched for anything but file header access. Thus the maximum usable space on the Turbo File GB should be 120 blocks, as advertized on the product's box.

Unfortunately, due to a programming error in RPG Tsukuru GB and Uchuu Nin Tanaka Tarou De RPG Tsukuru GB2, an additional 4 blocks are rendered inaccessible. Instead of having 1 block for file headers and 7 blocks as padding, they use 1 block for file headers and 8 blocks as padding. This results in 119 blocks as the maximum usable space. After filling up 116 blocks (for 29 saves), only 3 blocks remain, which is too small for one last save. This off-by-one counting error does not exist in Derby Stallion Advance or RPG Tsukuru Advance when using the Turbo File Advance.

Sewing Machines

General Hardware Information

Compatible Software

Transmission Protocol

Packet Format

Stitching Logic - Regular Stitching

Stitching Logic - Embroidery

Sewing Machine Status

[Sewing Machines] : General Hardware Information

In 2000, 3 different sewing machines were released that featured connectivity with the Nintendo Game Boy. The Jaguar JN-100 and later the Jaguar JN-2000 were released in Japan, while the Singer IZEK-1500 was released in the US later. Jaguar JN-100 models were also released in Europe. Each machine comes with a built-in Link Cable that allows a Game Boy running specialty software to send various stitching commands. With this, the Game Boy dictates sewing for patterns, buttonholes, and embroidery. Aside from their novelty, these devices mark one of the first attempts at pushing affordable programmable sewing machines to average consumers.

Singer IZEK-1500

Jaguar JN-100

Jaguar JN-2000

[Sewing Machines] : Compatible Software

System Compatibility

[#] = DMG and GBC compatible

[*] = GBC only

Sewing Machine Compatibility

[-] = Not compatible

[x] = Compatible

[!] = Compatible ONLY with an embroidery arm

[#] Sewing Machine Operation Software

[#] Raku x Raku Mishin

[*] Raku x Raku Moji

[*] Raku x Raku Cut Shuu

[*] Jaguar Mishin Sashi Senyou Soft: Mario Family

[*] Kanji Shishuu

[*] Kirby Family

A majority of the software was released exclusively to take advantage of the EM-2000 embroidery arm. Sewing Machine Operation Software and Raku x Raku Mishin are functionally identical, save for some cosmetic differences and offering Latin character stitching instead of kana. Otherwise, an IZEK-1500 can use the Japanese version of the software without issue and vice versa. The IZEK-1500 and the JN-100 cannot use Moji, Cut Shuu, Kanji Shishuu, Mario Family, or Kirby Family as they have no slot to accept an embroidery arm. The JN-2000 is the ONLY sewing machine that can do embroidery. The general functionality of each piece of software is detailed below:

Sewing Machine Operation Software

Raku x Raku Mishin

Raku x Raku Moji

Raku x Raku Cut Shuu

Jaguar Mishin Sashi Senyou Soft: Mario Family

Kanji Shishuu

Kirby Family

Kanji Shishuu and Kirby Family were never commercially released, thus out of the 7 known compatible titles, only 5 were sold to the public. Kanji Shishuu is very similar to Moji except it has a vastly larger pool of available kanji. Kirby Family is very similar to Cut Shuu and Mario Family, with embroidery patterns that appear largely inspired by Kirby 64.

[Sewing Machines] : Transmission Protocol

All communication between the sewing machines and the Game Boy happens via the attached Link Cable. The Game Boy and the sewing machine, however, alternate between which side uses an internal clock or an external clock. The general pattern is 2 external transfers followed by 1 internal transfer. On the first external transfer, the Game Boy sends a value of 0x00. Presumably before such a transfer can complete (literally a few CPU instuctions later), the Game Boy sends another external transfer, this time with actual data for the sewing machine. This transfer does finish, however, the clock rate provided by the sewing machine is currently unknown. On this transfer, the sewing machine sends back a single byte reporting its status. Finally the last transfer is sent by the Game Boy via an internal clock. The Game Boy sends 0x00 and the sewing machine responds with 0xFF.

------------------------------------------------- Transfer Flow ------------------------------------------------- External Transfer 1 | Short "dummy" transfer with 0x00. Quickly cancelled by next transfer External Transfer 2 | Payload data sent to sewing machine. Machine status may be returned Internal Transfer 1 | Send 0x00, receive 0xFF. Signals end of transfer for 1 byte -------------------------------------------------

When transferring a pattern to the sewing machine, the first few bytes of payload data are as follows: [0x80, 0x80, 0x80, 0x86]. This acts as a start signal, after which the Game Boy starts trasmitting packets. After all packets for a pattern have been sent to the machine, the Game Boy sends 0x80 endlessly until the next pattern is submitted. During that time, it's possible for the Game Boy to check the current status of machine.

[Sewing Machines] : Packet Format

For regular stitching and embroidery, data is transferred to each sewing machine in 128-byte packets containing stitch coordinate data. The format is described below:

------------------------------------------------- Packet Format ------------------------------------------------- Header | 1st packet = 8 or 9 bytes, Other packets = 0 Bytes Real Coordinate Data | 1st packet = 118 bytes, Other packets = 126 Bytes Checksum | 2 Bytes -------------------------------------------------

Headers only appear on the first packet sent to the machine when defining what to sew. Until the operating software finishes that definition, subsequent packets are headerless. Regular stitching and embroidery use two different headers. Each format is as follows:

------------------------------------------------- Packet Header Bytes - Regular Stitching ------------------------------------------------- 0x00 - New Packet Control Code | 0xB9 0x01 - Checksum Seed LSB | 0x00 - 0xFF 0x02 - Checksum Seed MSB | 0x00 - 0xFF 0x03 - N/A | 0x00 0x04 - Virtual X Coordinate | 0x00 - 0x20 0x05 - N/A | 0x00 0x06 - Virtual Y Coordinate | 0x00 - 0x20 0x07 - N/A | 0x00 ------------------------------------------------- ------------------------------------------------- Packet Header Bytes - Embroidery ------------------------------------------------- 0x00 - New Packet Control Code | 0xB9 0x01 - Checksum Seed LSB | 0x00 - 0xFF 0x02 - Checksum Seed MSB | 0x00 - 0xFF 0x03 - N/A | 0x00 0x04 - N/A | 0x00 0x05 - X Offset LSB | 0x00 - 0xFF 0x06 - X Offset MSB | 0x00 - 0xFF 0x07 - Y Offset LSB | 0x00 - 0xFF 0x08 - Y Offset MSB | 0x00 - 0xFF -------------------------------------------------

The checksum is a 16-bit sum of all the previous packet bytes, including the header. The header appears to contain seeds as a means to influence the checksum.

For regular stitching, the header contains two bytes that determine starting coordinates for stitching. The machines treat these as virtual coordinates that determine how to move towards the first pair of real coordinates where stitching actually begins. When repeating a pattern, the virtual coordinate data is ignored, and instead the machines begin processing at the start of real coordinate data.

For embroidery, the header contains two 16-bit values that determine the initial offset where the machine will begin the pattern. The effective stitching area for embroidery ranges from 0xFED0 to 0xFFFF horizontally and from 0xFFFF to 0xFE30 vertically:

0xFFFF = Right boundary 0xFED0 = Left boundary 0xFFFF = Top boundary 0xFE30 = Bottom boundary

Real coordinate data always comes in XY pairs. The values represent how far left/right or up/down the machine needs to shift the material when sewing. The format differs between regular stitching and embroidery. Both formats are as follows:

------------------------------------------------- Real Coordinate Data - Regular Stitching ------------------------------------------------- X Coordinate | 0x00 - 0x1F Y Coordinate | 0x00 - 0x20 ------------------------------------------------- ------------------------------------------------- Real Coordinate Data - Embroidery ------------------------------------------------- X Coordinate | 0x00 - 0x10 and 0x40 - 0x50 Y Coordinate | 0x00 - 0x10 and 0x40 - 0x50 -------------------------------------------------

Each format's data has its own meaning and needs to be interpreted separately; the logic for both are described later in the sections below. Real coordinate data contains a few bytes in between these pairs that signal what type of data the sewing machine can next expect from the Game Boy. These control codes are as follows:

------------------------------------------------- Packet Control Codes ------------------------------------------------- 0xC1 | 1st byte after header. Signals start of a path. 0xC2 | 1st byte after header. Signals start of a path. 0xC3 | 1st byte after header. Signals start of a path. 0xC4 | 1st byte after header. Signals start of a path. 0xC7 | Signals a path end after next 4 bytes. 0xB9 | Signals start of a new packet. 0xBA | Signals end of session (no more data, no more packets). Generally appears right before the checksum. 0xBB | Signals end of one packet in a multi-packet session. Appears right before the checksum 0xBC | Signals Real Coordinate Data has ended. The rest of the packet data is zero-filled. 0xBE | Signals start of Shift Coordinate Data for moving EM-2000 to new positions. 0xBD | Signals end of Shift Coordinate Data for moving EM-2000 to new positions. 0xBF | Signals end of session (no more data, no more packets). Generally appears right before the checksum. 0xE7 | Signals a path end after next 4 bytes. 0xF7 | Signals a path end after next 4 bytes. -------------------------------------------------

A typical single-session packet might look like this:

------------------------ Header 0xC1 X Data Y Data ... 0xBC Zero-filled 0xBF Checksum ------------------------

A typical multi-session might look like this:

------------------------ Header 0xC1 X Data Y Data ... 0xBB Checksum 0xB9 X Data Y Data ... 0xBC Zero-filled 0xBF Checksum ------------------------

[Sewing Machines] : Stitching Logic - Regular Stitching

X coordinates range from 0x00 (farthest point left) to 0x1F (farthest point right). Whenever the X coordinate changes, the machine will adjust the needle accordindly. Y coordinates are more complicated however, with regards to shifting up or down. The below chart details what values will shift the actual fabric (not the needle) vertically and how far:

------------------------------------------------- 0x00 Shift Down 1.25mm 0x01 Shift Down 1.1875mm 0x02 Shift Down 1.125mm 0x03 Shift Down 1.0625mm 0x04 Shift Down 1.0mm 0x05 Shift Down 0.9375mm 0x06 Shift Down 0.875mm 0x07 Shift Down 0.8125mm 0x08 Shift Down 0.75mm 0x09 Shift Down 0.6875mm 0x0A Shift Down 0.625mm 0x0B Shift Down 0.5625mm 0x0C Shift Down 0.5mm 0x0D Shift Down 0.4375mm 0x0E Shift Down 0.375mm 0x0F Shift Down 0.3125mm 0x10 Shift Down 0.25mm 0x11 Shift Down 0.1875mm 0x12 Shift Down 0.125mm 0x13 Shift Down 0.0625mm 0x14 No Change 0x15 Shift Up 0.0625mm 0x16 Shift Up 0.125mm 0x17 Shift Up 0.1875mm 0x18 Shift Up 0.25mm 0x19 Shift Up 0.3125mm 0x1A Shift Up 0.375mm 0x1B Shift Up 0.4375mm 0x1C Shift Up 0.5mm 0x1D Shift Up 0.5625mm 0x1E Shift Up 0.625mm 0x1F Shift Up 0.6875mm 0x20 Shift Up 0.75mm -------------------------------------------------

Ultimately, the sewing machines can program stitching to move vertically in 0.0625mm increments and horizontally in 0.25mm increments. Horizontal movement is limited to a set "window", e.g. setting multiple X coordinates to 0x1F keeps the stitching at farthest point right. Vertical movement is unlimited, as the machines will move the fabric up or down like a feed.

While the X and Y coordinates come in pair, it is important to note how each affects the movement of the needle and fabric. The below example demonstrates how X and Y coordinates actually dictate movement, assuming there are only 4 sets of Real Coordinate data.

---------------------------------------------------------------------------------------------------------------------------------------------------- Data | Location | X movement | Y movement ---------------------------------------------------------------------------------------------------------------------------------------------------- X0, Y0 | Virtual Coordinates from header | Start at X0, move to X1 | IF Y1 >= 0x1A THEN Move fabric by Y1, ELSE Move fabric by Y0 X1, Y1 | 1st set of Real Coordinates in packet | Move needle from X1 to X2 | Move fabric by Y1 X2, Y2 | 2nd set of Real Coordinates in packet | Move needle from X2 to X3 | Move fabric by Y2 X3, Y3 | 3rd set of Real Coordinates in packet | Move needle from X3 to X4 | Move fabric by Y3 X4, Y4 | 4th set of Real Coordinates in packet | Move needle from X4 to X1 | Move fabric by Y4 ---------------------------------------------------------------------------------------------------------------------------------------------------- If the control codes 0xC7, 0xE7, or 0xF7 are not sent in one of the packets, the pattern continually loops as such: ---------------------------------------------------------------------------------------------------------------------------------------------------- X1, Y1 | 1st set of Real Coordinates in packet | Move needle from X1 to X2 | Move fabric by Y1 X2, Y2 | 2nd set of Real Coordinates in packet | Move needle from X2 to X3 | Move fabric by Y2 X3, Y3 | 3rd set of Real Coordinates in packet | Move needle from X3 to X4 | Move fabric by Y3 X4, Y4 | 4th set of Real Coordinates in packet | Move needle from X4 to X1 | Move fabric by Y4 ----------------------------------------------------------------------------------------------------------------------------------------------------

Ideally, repeating patterns would have the same data for the Virtual Coordinates and the very last Real Coordinate pair. When the pattern begins looping, the Virtual Coordinates are ignored.

[Sewing Machines] : Stitching Logic - Embroidery

X and Y coordinates use Bit 6 to determine whether the embroidery arm must move in a positive or negative direction, after which the machine will stitch once. The distance of each movement can be calculated as such:


At certain point during embroidery, the embroidery arm must shift to a different area. The designs themselves are broken into multiple parts that are stitched continuously. When a new section that is not continuous with the current one must be stitched, the machine receives Shift Coordinate Data that dictate where to move next. This data always begins with the control code 0xBE and ends with the control code 0xBD. Typically, the path also ends (control code 0xE7 or 0xC7) right before the Shift Coordinate Data is sent. Shift Coordinate Data has the following format:

------------------------------------------------- Shift Coordinate Data ------------------------------------------------- 0xBE | Data Start X Shift LSB | 0x00 - 0xFF X Shift MSB | 0x00 - 0xFF Y Shift LSB | 0x00 - 0xFF Y Shift MSB | 0x00 - 0xFF 0xFF | Signals additional 16-bit XY shifts if applicable ... | Additional XY shifts | ... | 0xBD | Data End -------------------------------------------------

The distance shifted horizontally or vertically comes in 16-bit XY pairs. Note that these These values are very different from 16-bit offsets found in the header. While the 16-bit XY pair in the header represents an absolute position, the Shift Coordinate Data operates on relative positioning. That is to say, the embroidery arm will shift up/down/left/right from the last position that was previously stitched. The 16-bit XY pairs for Shift Coordinate Data are calculated as such:

IF X SHIFT >= 0xFF00 THEN X -= (0x10000 - X SHIFT) ELSE X += (X SHIFT & 0xFF) IF Y SHIFT >= 0xFF00 THEN Y += (0x10000 - Y SHIFT) ELSE Y -= (Y SHIFT & 0xFF)

Multiple, additional shifts can be made. In that case, after each 16-bit XY pair, a 0xFF byte must follow along with the next 16-bit XY pair. The final XY pair, however, is simply terminated by the 0xBD control code.

Note that sometimes the software sends shifts that result in no movement. These appear to be dummy shifts, perhaps for the sake of consistency when everything was programmed. These dummy shifts are often the last shifts to be made (and at times the only ones made).

[Sewing Machines] : Sewing Machine Status

The sewing machines report their status whenever the Game Boy sends the value 0x80 via external transfer. This byte describes various aspect of the machine during operation.

------------------------------------------------- Status Byte ------------------------------------------------- Bit 0 - Large Embroidery Hoop | Used for EM-2000. If set, Bit 2 must also be set. Bit 1 - EM-2000 Attached | 0 = Not attached, 1 = Attached, Bit 2 - Small Embroidery Hoop | Must be set to use EM-2000 at all. If Bit 0 not set, defaults to small embroidery hoop. Bit 3 - N/A | Bit 4 - N/A | Bit 5 - "SW" Button | Used for EM-2000. Alerts software to advance to next segment of embroidery. Bit 6 - Foot Pedal | 0 = Foot pedal is up, 1 = Foot pedal is pressed down. Bit 7 - Pause Operation | Alerts software when sewing operations are immediately paused. -------------------------------------------------

Soul Doll Adapter

General Hardware Information

Communication Protocol - Start Signal

Communication Protocol - Read Operations

Communication Protocol - Write Operations

Soul Doll Data Format

[Soul Doll Adapter] : General Hardware Information

The Soul Doll Adapter is a GBA accessory for the Legendz franchise, designed to allow data from plastic figurines to transfer over the games. The hardware came bundled with special editions of Legendz: Yomigaeru Shiren no Shima (released July 29th, 2004) and its sequel, Legendz: Sign of Necrom (released February 17th, 2005). The figurines, called "Soul Dollz" contain powerful monsters that players can use in battle. The Soul Dollz are "reborn" in the games, and from there they can level up and transfer that data back to the figurine.

*Ones made after Yomigaeru Shiren no Shima was released may not be "recognized" in that game. If the data sent to the adapter is correct but the Soul Doll is not in the game's internal database, it is categorized as "unknown".

[Soul Doll Adapter] : Communication Protocol - Start Signal

The GBA and the Soul Doll Adapter communicate via the serial port using General Purpose Mode. The protocol is essentially bit-banging. For most of the protocol, the GBA sets both SC and SI high. To begin any communications with the Soul Doll Adapter, the GBA writes to following "device start signal" to RCNT:

Device Start Signal: -------------------- 0x8020 0x8025 --------------------

The device start signal basically takes the Soul Doll Adapter out of standby-mode. The Soul Doll Adapter then accepts read or write commands to the EEPROM controller inside the Soul Dollz. When sending any commands or performing write operations, the start signal is always identified with Bit 7 of RCNT set to 0. When receiving data from commands through read operations, the start signal is always identified with Bit 7 of RCNT set to 1. For example, the least significant byte of RCNT may be the following for the start signals:

Start signal when issuing commands or performing writes: -------------------- 0x25 0x27 0x27 0x25 --------------------

Start signal when receiving data through read operations: -------------------- 0xA5 0xA7 0xA7 0xA5 --------------------

These signals determine when one command ends and another begins or when data is read or written.

[Soul Doll Adapter] : Communication Protocol - Read Operations

The 24LC08 allows for random access at any given address. To do so, the EEPROM controller must receive the following 3 pieces of information:

  1. Start Signal + Slave Address + Dummy Write Command
  2. Start Signal + Word Address
  3. Start Signal + Slave Address + Read Command

The slave address is 1 byte, with the Bits 4-7 being the device identifier (in the case of the 24LC08, this is 0b1010). Bits 1-3 are the device address. They effectively form the two MSBs of the final address (Bit 3 is ignored on the 24LC08, only use Bits 1-2). Bit 0 is the command; 0 = Write and 1 = Read.

The GBA uses 4 transfers per bits, with Bit 3 of RCNT determining whether the value is a "0" or a "1". A typical slave address sent via the GBA might look like this:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Device ID - 0b1010 | Ignored | 2 MSB of final address | EEPROM command ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Data is received MSB first. The 1st and 4th transfers for each bit are probably irrelevant, however, the 2nd and 3rd transfers contain the actual data for the bit. So:

0xAD 0xAF 0xAF 0xAD = Bit 3 is HIGH = 1 0xA5 0xA7 0xA7 0xA5 = Bit 3 is LOW = 0

The first slave address sent is basically ignored, as if the write command. This, however, prompts the 24LC08 to expect a word address next. The word address is the same format; 4 transfers per bit, with the 2nd and 3rd Bit 3 values determining whether it's a "0" or a "1". The word address forms the lower 8 bits of the final address to read from.

After the word address is sent, a final slave address is sent along with Bit 0 being set to 1 to indicate a read command. This final slave address forms the real two MSBs of the final address. Once this slave address and the read command are sent, EEPROM can be read from by sending a start signal followed by 32 transfers. The EEPROM controller doesn't seem to care what is sent during reading, so long as it's not another start signal. Once a full byte has been read, the internal pointer for the EEPROM address is incremented, and another read can be done simply by sending another start signal followed by 32 more transfers. The data format for reading looks something like this:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 | 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 | 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 | 0x2D 0x2F 0x2F 0x2D | 0x25 0x27 0x27 0x25 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Again, 2nd and 3rd transfers use Bit 3 to determine a "0" or a "1". The above example would be 0b10101010 or 0xAA. Once another command is detected, reading stops. One important thing to note, after sending the final slave address, the very first start signal still looks something like:

-------------------- 0x25 0x27 0x27 0x25 --------------------

But after the 1st byte has been read, the start signal shifts to something like:

-------------------- 0xA5 0xA7 0xA7 0xA5 --------------------

It isn't until another command is issued that the start signals swap. Generally, both Isle of Trial and Sign of Nekrom tend to read EEPROM in chunks of 128 bytes of 256 bytes. If the internal pointer for the EEPROM address is incremented past 0x3FF, it rolls over to 0x000. Apparently, when this happens, another device start signal must be issued.

[Soul Doll Adapter] : Communication Protocol - Write Operations

Writing shares many of the same conventions as reading. The EEPROM controller needs 2 pieces of information:

  1. Start Signal + Slave Address + Write Command
  2. Start Signal + Word Address

It's exactly like reading, except no secondary slave address is issued, therefore what would normally be the dummy write command is actually acknowledged. Additionally, there is no need to shift to a different start signal; only [0x25 0x27 0x27 0x25] is used. Once the slave address, write command, and word address are sent, data is written using a start signal plus 32 transfers for the byte. Once again, the format of the byte looks something like this:

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Again, 2nd and 3rd transfers use Bit 3 to determine a "0" or a "1". The above example would be 0b10101010 or 0xAA. Unlike reads, which can continue on updating the internal EEPROM address, writes are done in 16-byte pages. Up to 16-bytes can be written sequentially; anymore and the writes loop around. E.g. if writing to 0x100 a page write has a range of 0x100 to 0x10F. Attempting to write a 17th byte will overwrite 0x100 instead of 0x110. In order to write 0x110 to 0x11F, another write slave address, write command, and word address need to be sent to the 24LC08.

[Soul Doll Adapter] : Soul Doll Data Format

Most of the 1KB data contained on the 24LC08 appears to be related to the Talispod or Talisdam accessories, e.g. such data as the Legend's preferred humidity and tempurature, and their stats. For the games, however, only bytes 0x300 - 0x3FF are relevant. This area of memory specifies the nickname, the owner's name, and various other flags related to auto-training mode. Most importantly, these bytes determine what kind of Legend is generated from the Soul Doll. Byte 0x302 acts as this ID:

0x01 = Windragon (A)? 0x03 = Windragon (B)? 0x04 = Mermaid 0x05 = Werewolf 0x06 = Will 'o' Wisp 0x07 = Tornado Kingdragon 0x08 = Blaze Dragon (A)? 0x09 = Goblin 0x0A = Yeti 0x0B = Hell Hound 0x0C = Volcano Kingdragon 0x0D = Windragon Berserker Mode 0x0E = Blazedragon Berserker Mode 0x0F = Fire Giant 0x10 = Undine 0x11 = Peryton 0x12 = Troll 0x13 = Command Windragon 0x14 = Manticore 0x15 = Carbuncle 0x16 = Command Blazedragon 0x17 = Dwarf 0x18 = Skeleton 0x19 = Earthquake Kingdragon 0x1A = Storm Kingdragon 0x1B = Wyvern 0x1E = Ranshiin (A)? 0x1F = Ranshiin (B)? 0x20 = Chibi Shiron 0x21 = Command Windragon Break Armed 0x22 = Command Blazedragon Volk Armed 0x23 = Chimaera 0x24 = Triton 0x25 = Gargoyle 0x26 = Cloud Giant 0x27 = Command Windragon 0x28 = Command Blazedragon 0x2B = Spiritual Windragon 0x2C = Hexadragon 0x2D = Windragon Berserker Mode (Growing)? 0x2E = Blazedradon Berserker Mode (Growing)? 0x31 = Devour Crocodile (Dandy) 0x32 = Harpy 0x33 = Cait Sith 0x34 = Command Blazedragon Volk Armed 0x35 = Devour Crocodile 0x36 = Vampire 0x37 = Spiritual Kingdragon 0x38 = Ogre 0x39 = Spriggan 0x3A = Command Windragon Break Armed 0x3B = Bicorn 0x3C = Centaur 0x3D = Nekrom Kingdragon 0x3E = Golem 0x3F = Ifrit 0x41 = Gorgon 0x42 = Kraken 0x43 = Minotauros 0x44 = Oberon 0x45 = Lich 0x48 = Colonel Windragon Tornado Soul 0x49 = Pheonix 0x4A = Behemoth 0x4B = Jabberwock 0x4C = Leviathan 0x4D = Fenrir 0x4E = Colonel Blazedragon Volcano Soul 0x4F = Sphinx 0x50 = Cyclops 0x54 = Syclla 0x55 = Titan 0x56 = Echidna 0x59 = Ranshiin (B)? 0x5A = Chibi Shiron (Manga Version)? 0x5B = Blazedragon (B)? 0x5C = Windragon (Manga Version) 0x5D = Griffin 0x5E = Bigfoot 0x5F = Tiamat 0x66 = Wyvern 0x67 = Storm Kingdragon 0x68 = Carbuncle 0x6D = Giant Crab 0x71 = Hydra 0x72 = Iron Golem 0x73 = Valkyrie 0x74 = Cerberus

Several IDs appear to be mapped to the same Legend. This may be explained by the fact that some Soul Dollz were released in A, B, and sometimes C variants. The plastic figurine is different, but the GBA games generate the same sprite and default name for the Soul Doll. All of the potential duplicates are marked with "?" in the list above. Although there are 103 Soul Dollz, the list remains incomplete. The gaps between entries do not generate valid Legendz, which suggests other bytes in EEPROM are also responsible for the ID.

Battle Chip Gate

General Hardware Information

Compatible Games


Multiplayer Setup

Starting with Mega Man Battle Network 4, Capcom along with Takara introduced GBA accessories known as Battle Chip Gates. These devices allowed players to insert physical Battle Chips into a slot, which in turn executed attacks or activated special moves during combat. Effectively, these Battle Chip Gates simulated the act of being a real "Net Navi operator" as depicted in the games and anime. Three hardware revisions exist for each numbered Battle Network game released after 2003 (4, 5, 6). Among those revisions are several variants that differ only in color and design. Each revision additionally uses its own collection of Battle Chips.

[Battle Chip Gate] : General Hardware Information

[Battle Chip Gate] : Compatible Games

Battle Chip Gate

Mega Man Battle Network 4: Enables Operation Battles + using real chips in that same mode Mega Man Zero 3 Unlocks Guardian minigames based on chip ID Rockman EXE 4.5: Real Operation Enables using real chips in ever battle

Progress Chip Gate

Mega Man Battle Network 5 Enables Navi Change and Operation Battles + using real chips in that same mode

Beast Link Gate

Rockman EXE 6 Enables infinite BeastOut, Link Navi System, and using real chips in any battle

4.5 Real Operation was never released outside of Japan. Supposedly these accessories were deemed unpopular in the west, therefore English versions of Battle Network 6 had features relating to the Beast Link Gate disabled or removed. The bulk of content, such as BeastOut and loading Battle Chips during fights still works. The English version, however, merely alters the detection code so that it fails to recognize the Beast Link Gate even when properly plugged in.

For Mega Man Zero 3, chips with odd IDs unlock the Phantom minigame, while chips with even IDs unlock the Harpuia minigame. The RedSun chip (#304) unlocks the Fefnir minigame, while the BlueMoon chip (#309) unlocks the Leviathan minigame.

[Battle Chip Gate] : Protocol

Each Battle Chip Gate uses mostly the same protocol with only very slight changes. They are largely the same hardware in different shells and different physical arrangements. From a software point of view, however, they behave nearly identically.

The Battle Chip Gates communicate via the GBA's Multi16 mode with a baud rate of 115200bps. The GBA acts as the parent, and the device is Child 1. The Chip Gates begin in a sort of "stand-by" mode where they continually respond with their "Gate ID". This ID is the only thing the Chip Gates send until the GBA transmits a start signal. The Gate IDs are as follows:

Battle Chip Gate 0xFFC6 Progress Chip Gate 0xFFC7 Beast Link Gate 0xFFC4

The English release of Battle Network 6 checks for a Gate ID of 0xFF00 instead of 0xFFC4, thus causing the rest of the detection code to fail and preventing players from using the Beast Link Gate via normal means.

The start signal looks something like this sequence of transmissions:

  1. 0x0000
  2. 0xA---
  3. 0xA---
  4. 0xA---
  5. 0x8FFF
  6. 0xA---
  7. 0x0000

Typically, the 0xA--- values will be 0xA380 (used for Mega Man Zero 3), 0xA3D0 (used for 4.5 Real Operations), or 0xA6C0 (used for Battle Network 6). The purpose and function or lower 12-bits are unknown, but they may arbitrary, or simply any value OR'ed with 0x280. At any rate, the games use them as a means to keep track of the protocol by examining the last value sent (which would be stored in the halfword at 0x4000120).

On the transmission of the 6th value for the above start signal, the protocol is already switching over to the next phase, a repeating series of 9 transfers that contains the Battle Chip ID. The 9-stage transfer session looks something like this:

  1. Chip Gate ID (e.g. 0xFFC6)
  2. 0xFFFF
  3. 0xFFFF
  4. 0x--00
  5. 0xFF--
  6. Battle Chip ID
  7. 0x0000
  8. 0x0000
  9. 0x0000

The 4th and 5th transfer contains seeds that increment and decrement respectively on each transfer. The two seeds together add up to 255, however, it appears all compatible game software simply ignore this data. 6th transfer is the Battle Chip ID as determined by the DIP switch. A value of zero indicates no chip is inserted, while a non-zero value indicates a chip is currently slotted. This 9-stage transfer loops endlessly until the GBA sends another start signal. Once any 0xA--- value of the start signal is received, the Battle Chip Gate responds with its Gate ID (just like in stand-by mode) until the start signal terminates. Afterwards, the 9-stage transfers begin once again.

Mega Man Battle Network 6 sends an indeterminate number of transfers via Normal32 mode before the first start signal, and oddly enough before the any first battle after loading a save. The Battle Chip Gates simply return zero for these transfers.

It appears that some of the bytes set high (such as transfers 2, 3, and 5) occasionally do hold other values ranging from 0x00, 0x80, or 0xC0, however the conditions under which this occurs remains unknown. Needless to say, on the software side those changes are irrelevant.

[Battle Chip Gate] : Multiplayer Setup

It's possible to link together 2 GBAs, each with their own Battle Chip Gate, for multiplayer battles in all of the compatible Battle Network games. The model for this multiplayer appears to work as follows:

Player 1 Parent Player 1 Battle Chip Gate Child 1 Player 2 Child 2 Player 2 Battle Chip Gate Child 3

With this setup, Player 1 and Player 2 can technically ignore any output the opponent's Battle Chip Gate and focus on their own, despite essentially being able to see exactly what's happening on the other side. It also indicates that the Battle Chip Gates are capable of operating as Child 1 or Child 3.

Multi Plust On System

General Hardware Information

Compatible Games

Communication Protocol

Pluster IDs

[Multi Plust On System] : General Hardware Information

The Multi Plust On System (MPOS) is an accessory for the Bouken Yuuki Pluster World franchise from Takara. Designed as a "toys-to-life" device, it allows plastic figurines to transfer characters known as "Plusters" into the games. Bouken Yuuki Pluster World: Densetsu no Plust Gate and the EX version are RPGs, while Bouken Yuuki Pluster World: Pluston GP is a racing game. All 3 were released in 2003 and came with special sets featuring the the MPOS and a bundled Pluster figurine.

[Multi Plust On System] : Compatible Games

All 3 games are more or less unplayable without the MPOS. A few minigames can be played in Densetsu no Plust Gate EX, but in both that game and the regular Densetsu no Plust Gate, starting the main RPG requires the MPOS be attached with a Pluster Figure inserted. In Pluston GP, many of the menus can be navigated, but beginning a race also requires the accessory and an inserted figurine.

[Multi Plust On System] : Communication Protocol

Communication between the MPOS and the GBA is very simple. The role of the MPOS is to provide a single 16-bit number. Depending on which spokes the plastic model uses to put on the MPOS' array of pressure pads, a different number is sent to the GBA. The number effectively acts as an ID for the Pluster figurine. Using General Purpose Mode, both sides send a total of 37 transfers. At the beginning, of a session, the games will set all lines (SC, SD, SI, SO) as output with the RCNT value 0x80F0. Afterwards the 37 transfers keep looping indefinitely. The first 4 transfer appear to act as a start signal. The start signal is the following:

---------------------------------------------- RCNT |SC | SD | SI | SO ---------------------------------------------- 0x80BD | 1 | 0 | 1 | 1 0x80B5 | 1 | 0 | 1 | 0 0x80BF | 1 | 1 | 1 | 1 0x80BF | 1 | 1 | 1 | 1

Although the games' code ignores the results of the start signal, the MPOS returns these values:

---------------------------------------------- RCNT |SC | SD | SI | SO ---------------------------------------------- 0x80B9 | 1 | 0 | 0 | 1 0x80B1 | 1 | 0 | 0 | 0 0x80BB | 1 | 1 | 0 | 1 0x80BB | 1 | 1 | 0 | 1

The next 33 transfers are used for the 16-bit ID, 1 bit for every 2 transfers. The last transfer appears to dangle. This may simply be necessary to complete the transfer of the ID and begin the process over again. The GBA sends the following over and over again until it sends another start signal:

---------------------------------------------- RCNT |SC | SD | SI | SO ---------------------------------------------- 0x80BE | 0 | 1 | 1 | 1 0x80BC | 0 | 0 | 1 | 1

In response, the MPOS toggles SI every odd transfer (when receiving 0x80BE from the GBA) to send the the bit. For example, for the Pluster Wyburst (PF002), it produces the ID 0x16A0. The values sent back to the GBA look like this:

------------------------------------------------------ RCNT |SC | SD | SI | SO | Bit ------------------------------------------------------ 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BE | 0 | 1 | 1 | 1 | 1 0x80BC | 0 | 0 | 1 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BE | 0 | 1 | 1 | 1 | 1 0x80BC | 0 | 0 | 1 | 1 | 0x80BE | 0 | 1 | 1 | 1 | 1 0x80BC | 0 | 0 | 1 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BE | 0 | 1 | 1 | 1 | 1 0x80BC | 0 | 0 | 1 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BE | 0 | 1 | 1 | 1 | 1 0x80BC | 0 | 0 | 1 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 | 0 0x80B8 | 0 | 0 | 0 | 1 | 0x80BA | 0 | 1 | 0 | 1 |

The ID is received serially, MSB first. Essentially, a "1" bit is transferred whenever both SD and SI go high, and a "0" bit is transferred whenever SD is high, but SI is low.

[Multi Plust On System] : Pluster IDs

Currently, there are 22 identified Pluster figurines along with some 16-bit IDs that will generate that character in the games. There are multiple variants of figurines, therefore Plusters have multiple valid IDs, since the configuration of their spokes is different. The electronic toys may treat them differently, yet the GBA games do not.

IMPORTANT: These IDs were generated artificially by testing them against the games, so with the exception of Wyburst (0x16A0) none of these represent actual IDs captured from a MPOS. They are, however, sufficient for the purposes of emulation or using homebrew on a second GBA to fake a connected MPOS.

PF001 :: Beetma * 0x16C0 * 0x1682 * 0x1642 PF002 :: Wyburst * 0x16A0 * 0x1660 * 0x1622 PF003 :: Gabrian * 0x1650 * 0x1630 PF004 :: Molly * 0x16D8 * 0x16B2 * 0x1672 PF005 :: Hania * 0x1688 * 0x1648 * 0x1628 PF006 :: Zagarian * 0x1614 PF007 :: Tan Q * 0x16D4 PF008 :: Warrion * 0x16F0 * 0x1612 PF009 :: Doryuun * 0x16B8 * 0x1678 PF010 :: Fezard * 0x16D2 * 0x1618 PF011 :: Mashanta * 0x1684 * 0x1644 * 0x1624 PF012 :: Gingardo * 0x16B4 * 0x1674 PF013 :: Torastorm * 0x16CC PF014 :: Gongoragon * 0x16AC PF015 :: Mighty V * 0x169C PF016 :: Dorastorm * 0x16FC PF-EX001 :: Beetma EX * 0x1666 PF-EX002 :: Varouze * 0x1636 PF-EX003 :: Gigajoule * 0x164E PF-EX004 :: Badnick * 0x161E PF-EX005 :: Poseihorn * 0x167E PF-EX006 :: Tera * 0x1621

When the MPOS is connected to the GBA but has no Pluster figurine inserted, the device returns the ID 0x1400.

Turbo File Advance

General Hardware Information

Compatible Games

Communication Protocol


File Structure

[Turbo File Advance] : General Hardware Information

Developed by Sammy Corporation and released in April of 2002, the Turbo File Advance is an external storage device designed to hold large amounts of save data. Following in the footsteps of ASCII Corporarions Turbo File GB, the Turbo File Advance came out two years later, with the key difference between the two being support for GBA software. Only select games specifically programmed to take advantage of the Turbo File Advance were compatible. The accessory made use of memory cards as well, one of only two instances where this happened on the Game Boy.

The Turbo File Advance is pretty much an exact copy of the Turbo File GB. The PCB even still has "TURBO FILE GB" printed on it, and one microprocessor still says "ASCII".

[Turbo File Advance] : Compatible Games

Although the manual explicitly claims that the previous Turbo File GB games are not compatible, it is actually unknown if that is the case. In theory, the Link Cable on the Turbo File Advance would be capable of handling 3.3v instead of the 5v used on the Turbo File GB, which would be one source of incompatibility. Whether or not the Turbo File Advance would function when using the GBA's backward compatibility or if the Turbo File Advance itself was just a marketing ploy to sell more hardware remains uncertain.

[Turbo File Advance] : Communication Protocol

The Turbo File Advance has exactly the same protocol as the Turbo File GB. The GBA communicates over an external clock in 8-bit Normal mode, mirroring how a GBC would generally work with the device. The sync signal, packet format, banking, use of memory cards, and commands have not been changed in the Turbo File Advance. Reference existing Turbo File GB documentation for further information.

[Turbo File Advance] : Commands

Only one new command is used by the Turbo File Advance (and only one game, Derby Stallion, executes it). The other commands are the exact same as the previous Turbo File GB commands.

Command 0x34 - Block Write

Parameters: 2 bytes forming a 13-bit offset (MSB first) and 1 byte with value to fill block with

Response Data: 4 byte echo packet

The two parameters are the 13-bit offset to read data from. The 1st parameter is Bit 8-12 and the 2nd parameter is Bit 0-7. The 3rd parameter is the value to write into the next 64 bytes of the block. The response packet is like all of the echo packets for other commands, however, it technically isn't a copy of the original packet.

------------------------------------------------- Command 0x34 Response Packet Bytes ------------------------------------------------- Byte 0x00 | 0x34 Byte 0x01 | 0x00 Byte 0x02 | Device Status Byte 0x43 | Checksum = 0x100 - 0xA5 - (Sum of Bytes 0x00 through 0x02) -------------------------------------------------

[Turbo File Advance] : File Structure

The banking in the Turbo File Advance is the same as the Turbo File GB. Bank 0x7F (for internal storage) and Bank 0xFF (for memory card storage) contain the file headers for each file; these headers identify the name of the file and how many blocks it occupies. The format is described below:

------------------------------------------------- File Header ------------------------------------------------- Byte 0x00 | 0x5A Byte 0x01 - 0x04 | Game ID Byte 0x05 - 0x13 | ASCII String for filename (16 characters max) Byte 0x14 - 0x15 | Should all be 0x20 Byte 0x16 | Current block ranging from 0 to (Total - 1) Byte 0x17 | Total number of blocks for save Byte 0x18 - 0x3F | Should all be 0xFF -------------------------------------------------

Games generally write in 8 blocks (meaning 15 saves total for internal storage or the memory card). However, Derby Stallion can write 1 or 7 blocks of data. Even so, without expanding the memory capacity from the Turbo File GB, the Turbo File Advance generally ends up holding fewer saves.

Bytes 0x01 through 0x04 act as IDs. They are the same bytes found in the game's ROM header, specifically the ASCII-encoded "Game Code" (bytes 0xAC through 0xAF). Once again, the use of IDs prevents incompatibilities between games when reading data.


General Hardware Information

Device Detection

IR Operation

Comparison to GBC IR

Zoid Commands

Prototype IR Port

[AGB-006] : General Hardware Information

The AGB-006 is an accessory released in conjunction with Cyber Drive Zoids: Kiju no Senshi Hyuu on July 18, 2003. It serves as an infrared adapter, coming as a bundle with each game. Using IR signals, players can turn their GBAs into remote controls to pilot three toy model Zoids. Although the GBA removed the GBC's IR port, the AGB-006 officially restored that functionality as an add-on. Unfortunately Cyber Drive Zoids was the only game to take adavantage of the AGB-006.

[AGB-006] : Device Detection

The AGB-006 can be detected in software by generating an interrupt request in General Purpose mode whenever sending an OFF/ON pulse. When no AGB-006 is plugged in, no interrupts are triggered, so checking Bit 7 of the Interrupt Request Flags is sufficient to verify whether or not the adapter is present. At a minimum, two writes are necessary. The first sets the SO line LOW (turning the IR signal off). The second sets the SO line HIGH (turning the IR signal on) and enables interrupts. The following RCNT values are sent by Cyber Drive Zoids to trigger an interrupt request:

0x80B2 //Turn IR light off 0x81BA //Turn IR light on and enable Serial I/O interrupts

For this example, after the interrupt is generated, RCNT should hold the value 0x2004 at that time.

[AGB-006] : IR Operation

The following values of RCNT can be used for various IR-related functions:

---------------------------------------- Value | Usage ---------------------------------------- 0x80BA | Turns IR signal on 0x80B2 | Turns IR signal off 0x8190 | Receive IR signal

For turning the IR signal on, set the SO line HIGH. For turning the IR light off, set the SO line LOW.

For receiving IR signals, set SI's direction as input. An interrupt will be requested once the signal arrives. This interrupt is only generated when the IR sensor begins detecting light when it previously detected none. Essentially it comes when transitioning from a "no light" to "light" state. There doesn't appear to be a way to get an interrupt once the signal goes off. It should be noted that Cyberdrive Zoids, the only officially supported game for the AGB-006, is not programmed to receive IR signals. This feature was thus never used in commercial software.

Both sending and receiving signals can trigger an interrupt if Bit 8 of RCNT is set. For receiving IR signals, interrupts are the most effective method of detecting an incoming signal, as simply waiting for RCNT to change its read value is unreliable (unlike the device detection phase). Writing the value 0x8190 to RCNT, for example, instantly changes its read value to 0x8196, even when no AGB-006 is connected. For this reason, interrupts are all but required for properly receiving IR signals. Requesting interrupts while sending IR signals is optional but of limited use.

When receiving an IR signal, software should in theory measure the delay until the next IR signal to get the total ON/OFF pulse duration. Once RCNT is set, IR interrupts are continuously generated whenever a new IR signal is detected, as long as Bit 7 of the Interrupt Request Flags is cleared after each pulse. The so-called "signal fade" present in GBC IR hardware is not evident in the AGB-006, so the accessory will not automatically stop receiving an IR signal after a set amount of time. Software should set a cut-off threshold for pulse durations to decide when one side has stopped sending, especially as the AGB-006 does not have any apparent feedback to manually check.

[AGB-006] : Comparison to GBC IR

The biggest difference between the AGB-006 and the GBC's native IR hardware are interrupts. While prototype GBAs originally were designed to have IR ports with their own associated interrupts, the AGB-006 repurposes the existing serial interrupt. Interrupts potentially simplify the task of detecting IR light. Depending on the communication protocol, however, actually servicing an interrupt may be too slow for rapid data transfer. In such cases, a tight loop that merely continuously reads the Interrupt Request Flags may be more effecient. The AGB-006's interrupts excel in convenience over the GBC when detecting the next IR signal, as they eliminate the need to check any OFF status of the IR signal. The only thing a program needs to do is maintain a maximum allowed duration for pulses to see when communications should stop (something GBC software does anyway to check for errors mid-transmission).

Physically speaking, the AGB-006 has a far wider range of reception. It is capable of receiving signals at a maximum distance roughly between 1.7 and 1.8 meters. Furthermore, it can receive signals approximately within 150 degrees horizontally, and approximately 165 degrees vertically (IR light is only undetectable from very extreme angles beneath the unit). This stands in contrast to the GBC, which mostly needs line-of-sight to communicate via IR, or even detect IR sources.

Finally, while the GBC IR hardware is receptive to incandescent light sources, the AGB-006 largely ignores them.

[AGB-006] : Zoid Commands

Officially, the AGB-006 is exclusively used to control motorized minature models from the Zoids franchise. This communication is always one-way, with the GBA blasting IR signals repeatedly once a button is pressed. The protocol is fairly simple. A number of IR pulses (total ON and OFF time) are sent with only a few specific lengths. Their exact timing seems to vary and may not be entirely consistent, so relative duration must be used. The ON phase of the pulse accounts for a very miniscule amount time, while the OFF phase accounts for the majority of the delay.

Mini Pulse Smallest pulse. Very short and very numerous Short Pulse Roughly 16x the length of a Mini Pulse Medium Pulse Roughly 40x the length of a Mini Pulse Long Pulse The longest pulse. Easily around 6000x the length of a Mini Pulse

Mini Pulses appear to last anywhere from 18.1us to 20us. There are dozens of them in between every other type of pulse, and they seem to act as a sort of "keep-alive" for IR transmission. Below are the specific transfers used to manipulate the Zoids. There are two separate "channels" for ID1 and ID2. The goal was to have two players compete against each other, so two distinct versions of each command exist to avoid interference.

When omitting Mini Pulses, each IR command is 12 Short or Medium Pulses followed by 1 Long Pulse. The order of Short and Medium Pulses determines the exact command, while the Long Pulse functions as a stop signal. Each command can be converted into binary by treating a Medium Pulse as "1", and a Short Pulse as a "0". Commands can then be parsed by examining every 4-bit segment. Below describes how each segment affects the command. Note that the values use the first pulse as the MSB and the last pulse as the LSB.

----------------------------------------------------------- Bits 8-11 - Channel + Action Category ----------------------------------------------------------- 0x8 Perform "Main Actions" for ID1 0x9 Perform "Misc. Actions" for ID1 0xA Perform "Main Actions" for ID2 0xB Perform "Misc. Actions" for ID2 -----------------------------------------------------------

Bits 8-11 determine which channel the command belongs to, as well as the overall category of action the CDZ model should perform. Main Actions describe things such as moving forward/backward, firing the cannon, and turning. Misc. Actions describe a variety of things such as syncing/initializing the GBA and CDZ model, roaring, and retreating. It is also used for some actions during the "boost" mode. A number of these actions are not listed in the game's manual.

----------------------------------------------------------- Bits 4-7 - Motion Type ----------------------------------------------------------- For Main Actions 0x2 Boost Backward 0x3 Boost Backward 0x4 Backward Speed 2 0x6 Backward Speed 1 0x8 Backward Speed 0 0xA Forward Speed 0 0xC Forward Speed 1 0xE Forward Speed 2 For Misc. Actions 0x0 Boost Forward 0x1 Boost Forward + Fire (optionally) 0x3 Sync Signal/Hidden Moves 0x5 Hidden Moves -----------------------------------------------------------

The Cyber Drive Zoids game can use the save data from the single-player mode to enhance the actions performed by the CDZ model, chiefly in regards to speed, HP, and the ability to boost. Once sufficient progress is made in the single-player mode, the CDZ model can shift gears up and down to alter speed. The regular IR controller that comes packaged by default with CDZ models does not offer these advantages. The sync signal is used on startup to activate the CDZ model for a match.

----------------------------------------------------------- Bits 0-3 - Action Type ----------------------------------------------------------- For Main Actions 0x0 Walk OR Fire if Motion Type == 1 or 3 0x1 Walk OR Fire if Motion Type == 1 or 3 0x2 Jump (typically for Boost Mode) 0x3 Jump (typically for Boost Mode) 0x4 Jump 0x5 Jump 0x6 Jump 0x7 Jump 0x8 Jump 0x9 Jump 0xA Fire 0xB Fire 0xC Fire 0xD Fire For Misc. Actions 0x0 If Motion Type == 1 -> Fire 0x1 If Motion Type == 1 -> Fire 0x2 If Motion Type == 0 -> Jump If Motion Type == 3 -> Sync ID1, Boost Level 0 If Motion Type == 5 -> Intimidate 0x3 If Motion Type == 0 -> Jump If Motion Type == 3 -> Sync ID2, Boost Level 0 If Motion Type == 5 -> Intimidate 0x4 If Motion Type == 3 -> Sync ID1, Boost Level 1 If Motion Type == 5 -> Swing Hips 0x5 If Motion Type == 3 -> Sync ID2, Boost Level 1 If Motion Type == 5 -> Swing Hips 0xA War Cry 0xB War Cry 0xE Escape 0xF Escape -----------------------------------------------------------

For Main Actions, if the Motion Type is not one of the above specified values (e.g. a 0), and the Action Type is jumping or firing, then the Zoid will move not forward or backward. Instead, it will remain stationary while performing that action. In this same manner, it's possible to simultaneously combine jumping or firing with moving by properly setting the Motion Type. Walking should always specify one of the listed Motion Types, however.

The CDZ model has a boost mode where the toy is temporarily invulnerable to damage and shifts into the highest gear. This mode lasts for 10 seconds. The sync signals specify how many boosts are available per match for that CDZ model. The boost mode commands are spread across Main Actions and Misc. Operations such as firing and jumping are often conditional, requiring the Motion Type to be Boost Forward or Boost Backward.

[AGB-006] : Prototype IR Port

Cyber Drive Zoids appears to frequently read from the memory location 0x4000136 which was supposed to have been the MMIO register for the IR port on prototype GBAs. The AGB-006 does not cause the 16-bit value of that location to change at all, however, and all reads do in fact return zero. The purpose of that bit of code is currently unclear. It may be a remnant of earlier code long made before the AGB-006 was fully realized.

Ubisoft Thrustmaster Pedometer

General Hardware Information

Device Detection

Reading Steps

[Ubisoft Thrustmaster Pedometer] : General Hardware Information

The Ubisoft Thrustmaster Pedometer is a Slot-2 NDS device that came bundled with My Weight Loss Coach / My Health Coach: Manage Your Weight. It simply counts the user's steps and transfers that number to the software.

[Ubisoft Thrustmaster Pedometer] : Device Detection

The software will read some values from the GBA cart space between 0x8000000 and 0x801FFFF. Those values are somewhat difficult to accurately and consistently map out byte-by-byte; one explanation is that open bus behavior may affect reading. However, the following psuedo-code will allow the software to properly detect the presence of the pedometer:

//Read individual bytes from GBA cart space if address AND 1 return 0xF7 else return 0xF0 OR ((address AND 0x1F) SHIFT RIGHT 1)

[Ubisoft Thrustmaster Pedometer] : Reading Steps

Steps are stored in the area where the DS would normally access SRAM/FRAM/Flash in GBA carts. 5 bytes are used, one for each displayable digit:

0xA000000 Ones 0xA000001 Tens 0xA000002 Hundreds 0xA000003 Thousands 0xA000004 Ten Thousands

The values range from 0xF0 to 0xF9, with only the lower half of the byte being relevant. The maximum number of steps the pedometer can track is 99999. To properly access each value, the memory location should be read at least 4 times with a brief delay in between, such as one frame (~16ms). If the delays are not used, the pedometer returns 0xF0. These locations appear to be read-only, so software cannot manually set the pedometer's step count.

However, if the memory location 0xA00000C is read, the pedometer resets the step count. The supported software does this whenever it records data from the pedometer.


General Hardware Information

Compatible Games

Device Detection

I/O Registers


[HCV-1000] : General Hardware Information

The HCV-1000 is a Slot-2 NDS device designed to read barcodes from cards. Produced by Sega and released in 2006, it came bundled with Oshare Majo Love and Berry: DS Collection, Kouchuu Ouja Mushiking Super Collection, Card de Asobu! Hajimete no DS. By scanning various cards, certain items/characters were unlocked in each of the games.

[HCV-1000] : Compatible Games

Card de Asobu! is the only title that absolutely requires the HCV-1000 to play. Without the device, the game will not reach the main screen and will stall with an error message/animation. The other two games are still playable without the HCV-1000 and without the bonuses it provides, thereby limiting some aspects of gameplay.

[HCV-1000] : Device Detection

The software will read some values from the GBA cart space between 0x8000000 and 0x801FFFF. The following psuedo-code will allow software to properly detect the presence of the HCV-1000:

//Read individual bytes from GBA cart space if address AND 1 return 0xFD else return 0xF0 OR ((address AND 0x1F) SHIFT RIGHT 1)

[HCV-1000] : I/O Registers

------------------------------------- HCV_CNT (R/W) 0xA000000 ------------------------------------- Bit 0 (R) Camera status, 1 = On, 0 = Off (W) Turn camera on = 1, Turn camera off = 0 Bit 1 (R) Current barcode strip, 1 = Gap, 0 = Bar (W) ??? Bit 2 N/A Bit 3 N/A Bit 4 (R) Barcode processing flag (W) 0 = Clear flag Bit 5 (R) Barcode orientation flag (W) 0 = Clear flag Bit 6 (R) Scan error flag (W) 0 = Clear flag Bit 7 (R) Scanning status, 1 = In progess, 0 = Done (W) Start scanning = 1, Stop scanning = 0 -------------------------------------

Camera Status: When scanning cards, this must be set high. Doing this turns on the red light and the camera. If needed, this bit can be read to determine whether the camera is on or off.

Current Barcode Strip: A "1" indicates a gap, while a "0" indicates a bar. Although this data is exposed to software, reading Bit 1 is not necessary to obtain barcode data. The HCV-1000 automatically outputs that information to HCV_DATA. It's possible to write to this bit, but its affect is unknown.

Barcode Processing Flag: This flag is set to "1" whenever the HCV-1000 begins processing barcode data for HCV_DATA. It is not set to "0" when all of the data is finished. Reading Bit 7 should be used to determine if scanning is complete.

Barcode Orientation Flag: Describes the format of the data in HCV_DATA. If this flag is "0" this means the barcode data is meant to be read in ascending order (0xA000010, 0xA000011, 0xA000012, etc). If this flag is "1", that means the barcode data is meant to be read in descending order (0xA00001F, 0xA00001E, 0xA00001D, etc).

Scan Error Flag: If this flag is "1", it indicates a problem occurred at some point while a card was scanned. Any bytes in HCV_DATA may be unreliable.

Scanning Status: It must be set high to start the scanning process. It will remain high until the HCV-1000 has finished processing the barcode. At that point, Bit 7 is automatically set low and the bytes in HCV_DATA will represent barcode data.

Bits 2 and 3 are not used. While all of the other bits are writable, Bits 4-6 may not be set high by NDS software. Writing "0" to those bits will set them low, however, in effect clearing them.

------------------------------------- HCV_DATA (R) 0xA000010 - 0xA00001F ------------------------------------- 0xA000010 ... 0xA00001F 1 byte of processed barcode data -------------------------------------

16 bytes are set at this location for incoming barcode data in the form of an ASCII encoded string. Once Bit 0 and Bit 7 in HCV_CNT are both set high, the HCV-1000 continually attempts to grab any barcode data on its own and puts the results here.

All barcodes must be in Code39 with a maximum length of 16 characters. The ASCII string in HCV_DATA is the human-readable form of the barcode, e.g. *12345-ABCDEFG*. If a barcode has less than 16 characters, HCV_DATA appends the value 0x5F to the string for the rest of the length.

The barcode data may come in "reversed" depending on which direction the card was swiped, therefore Bit 5 of HCV_CNT can be referenced to read the bytes in the correct order. Alternatively, NDS software can simply read the bytes in any order and check for both barcodes. Whether or not the barcode data is reversed, any 0x5F values in HCV_DATA will always appear at the end (0xA00001F, 0xA00001E, 0xA00001D, ... for example).

[HCV-1000] : Operation

The NDS must use proper memory timings in order to correctly access the HCV-1000. Compatible games set EXMEMCNT to 0xE877. When using incorrect timings, the I/O registers become inaccessible (reading zero constantly).

While it is possible to continually read Bit 1 of HCV_CNT and measure the delays between each transition and manually calculate barcode values, the HCV-1000 provides built-in decoding. NDS software need only perform the following steps:

  1. Set HCV_CNT to 0x81 (turn on camera + start scanning).
  2. Read HCV_CNT and wait for the HCV-1000 to clear Bit 7 of that register.
  3. Check Bit 6 of HCV_CNT for errors and abort if any detected.
  4. Read 16 bytes from HCV_DATA.
  5. Set HCV_CNT to 0x00 (turn off camera + clear flags).
  6. Repeat as necessary.

Magic Reader

General Hardware Information

Device Detection

I/O Registers

Two-Wire Interface: Reading

Two-Wire Interface: Writing

Control Flow

Card List and Index Values

[Magic Reader] : General Hardware Information

Beast Shinden: Ultimate Beast Battlers for the NDS used a special Slot-2 device called the "Magic Reader", which allowed players to scan collectible trading cards to battle opponents. Released in 2007 by Konami, the game makes heavy use of the scanning functionality, and the accessory is required for the software. While the card game itself is yet another monster fighting TCG, the scanning process itself was unique. Whereas all previous card reading devices on the DMG, GBC, GBA, and NDS involved swiping a card through a slot, the Magic Reader detects the card when hovered over its sensor.

[Magic Reader] : Device Detection

The software will read some values from the GBA cart space between 0x8000000 and 0x801FFFF. The following psuedo-code will allow software to properly detect the presence of the Magic Reader:

//Read individual bytes from GBA cart space if address AND 1 return 0xFB else return 0xFF

[Magic Reader] : I/O Registers

------------------------------------- MR_CNT (R/W) 0xA000000 ------------------------------------- Bit 0 (W) Serial Clock aka SCK Bit 1 (R/W) Serial Data IO aka SDIO Bit 2 (W) NDS Read (1) or Write (0) Flag Bit 3 N/A Bit 4 N/A Bit 5 N/A Bit 6 (W) Power On Optical ID? Bit 7 N/A

SCK and SDIO are used for the so-called "two-wire interface" between the NDS and the Optical ID decoder. Using those two bits, the NDS communicates with the Magic Reader to send commands as well as retrieve image data. SCK must be pulsed from LOW to HIGH (0 to 1) by the NDS to start or continue receiving or sending data. The Magic Reader can signal to the NDS that it has data available to read by setting SDIO LOW, however.

Although the two-wire interface's protocol makes read and write operations explicitly different, MR_CNT appears to use Bit 2 to indicate the direction I/O direction. For reads, this bit is set HIGH, but for writes it is set LOW. Oddly enough, this is the inverse of SDIO when sending the Read/Write bit used for the two-wire interface.

Bit 6 appears to be set by the NDS before powering on the Optical ID decoder, effectively waking it from sleep mode. In that case, the Magic Reader should set SDIO low to indicate it has data for the NDS to read (the OIDCmd_PowerOn value).

It is important to note that when reading MR_CNT, all bits except for Bit 1 are always set HIGH. In effect, when reading MR_CNT, only two values are ever returned: 0xFB or 0xFF.

[Magic Reader] : Two-Wire Interface: Reading

The Magic Reader must set SDIO LOW to indicate to the NDS that data is available to read. This is often in response to a command sent by the NDS, or in some cases by setting Bit 6 of MR_CNT. Once the NDS recognizes that the Magic Reader is requesting a read, the following happens:

  1. NDS sets SCK and SDIO LOW and sets Bit 2 of MR_CNT HIGH for the duration of the transfer.
  2. NDS sets SCK HIGH and sets SDIO LOW to indicate a read operation for the two-wire interface.
  3. NDS sets SCK and SDIO LOW to begin data transmission.
  4. NDS sets SCK and SDIO HIGH, then reads MR_CNT. The SDIO bit indicates incoming data from the Magic Reader arriving MSB first.
  5. NDS sets SCK LOW and SDIO HIGH. Steps 5-6 are done a total of 23 times to receive a 23-bit value from the Magic Reader.
  6. NDS sets SCK LOW and SDIO HIGH and sets Bit 2 of MR_CNT LOW to indicate that the transfer is complete.

Below is an example of how the NDS would read data from the Magic Reader:

------------------------------------- INIT TRANSFER ------------------------------------- READ -> 0xFB //SDIO = LOW, Magic Reader has data to send WRITE -> 0x04 //SCK = LOW, SDIO = LOW, Bit 2 set HIGH for duration of transfer WRITE -> 0x05 //SCK = HIGH, SDIO = LOW, sets R/W bit WRITE -> 0x04 //SCK = LOW, SDIO = LOW, transfer data now ------------------------------------- TRANSFER DATA ------------------------------------- WRITE -> 0x07 //SCK = HIGH, SDIO = HIGH, data is available now READ -> xxxx //SDIO = Bit 22 WRITE -> 0x06 //SCK = LOW, SDIO = HIGH WRITE -> 0x07 //SCK = HIGH, SDIO = HIGH, data is available now READ -> xxxx //SDIO = Bit 21 WRITE -> 0x06 //SCK = LOW, SDIO = HIGH ... WRITE -> 0x07 //SCK = HIGH, SDIO = HIGH, data is available now READ -> xxxx //SDIO = Bit 1 WRITE -> 0x06 //SCK = LOW, SDIO = HIGH WRITE -> 0x07 //SCK = HIGH, SDIO = HIGH, data is available now READ -> xxxx //SDIO = Bit 0 WRITE -> 0x06 //SCK = LOW, SDIO = HIGH ------------------------------------- END TRANSFER ------------------------------------- Write -> 0x02 //SCK = LOW, SDIO = HIGH, end communications -------------------------------------

The data for each bit is available after clocking SCK HIGH. The value of SDIO is valid until SCK is set HIGH again. Even after setting SCK LOW, MR_CNT can still be read and SDIO will reflect the serial 23-bit data. Juushinden, the only official software that uses the Magic Reader, reads MR_CNT after setting SCK LOW, for example.

Switching SCK from LOW to HIGH has several timing conditions. SCK should be set LOW for a minimum of 2μs during the transfer and should ideally not exceed 64μs. Going further than 64μs stops the transfer. SCK should be set HIGH for a minimum of 2μs. The 23-bit data format is described below:

------------------------------------- Magic Reader Data ------------------------------------- Bit 0 - Bit 17 Optical ID Index Bit 18 - Bit 19 Reserved (Always 0) Bit 20 Battery Status Bit 21 Data Type (Command/Index) Bit 22 Reserved (Always 1) -------------------------------------

Bits 0 through 17 represent the Optical ID Index. The SN9P701FG-005 automatically takes image data from the SN9S102C and converts it into a binary number. The image data is similar to e-Reader dot-code or QR codes, so they can be reduced to a single value. Different models of the SN9P701-00X support different amounts of indices. The SN9P701FG-005 supports a total of 65536 indices with a range of 0x0000 to 0xFFFF. There are extra indices up to 0x3FFEF reserved for future use. Indices above 0x3FFEF have special usages:

------------------------------------- Extended Index Usage ------------------------------------- 0x3FFF0 - 0x3FFFA Reserved for internal use 0x3FFFB Null response when no usable data is returned to NDS 0x3FFFC - 0x3FFFF Captured image not recognized -------------------------------------

The battery status is a single bit that describes whether the SN9P701 has a high or low battery (1 or 0, respectively).

The data type describes what the NDS is receiving. If Bit 21 is set LOW, then the Magic Reader is returning a regular index after having processed an image. If Bit 21 is set HIGH, the Magic Reader is responding to a command with pre-set data:

------------------------------------- Command Responses ------------------------------------- 0x60FFF8 OIDCmd_PowerOn 0x60FFF7 OIDCmd_PowerDown 0x60FFF1 OIDCmd_SystemReset -------------------------------------

[Magic Reader] : Two-Wire Interface: Writing

The NDS can transfer a command to the Magic Reader like such:

  1. NDS sets SCK and SDIO LOW and sets Bit 2 of MR_CNT LOW for the duration of the transfer.
  2. NDS sets SCK and SDIO HIGH to indicate a write operation for the two-wire interface.
  3. NDS sets SCK LOW and sets SDIO HIGH to begin data transmission.
  4. NDS sets SCK HIGH and sets SDIO accordindly to trasmit 1 bit of the command MSB first.
  5. NDS sets SCK LOW and maintains the same SDIO level from Step 4. Steps 4-5 are done a total of 8 times to send an 8-bit command to the Magic Reader.
  6. NDS sets SCK LOW and SDIO HIGH and sets Bit 2 of MR_CNT LOW to indicate that the transfer is complete.

Below is an example of how the NDS would send the 0xA3 command:

------------------------------------- INIT TRANSFER ------------------------------------- Write -> 0x00 //SCK = LOW, SDIO = LOW, signals start of operation Write -> 0x03 //SCK = HIGH, SDIO = HIGH, sets R/W bit Write -> 0x02 //SCK = LOW, SDIO = HIGH, transfer data now ------------------------------------- TRANSFER DATA ------------------------------------- Write -> 0x03 //SCK = HIGH, SDIO = Bit 7 (1) Write -> 0x02 //SCK = LOW Write -> 0x01 //SCK = HIGH, SDIO = Bit 6 (0) Write -> 0x00 //SCK = LOW Write -> 0x03 //SCK = HIGH, SDIO = Bit 5 (1) Write -> 0x02 //SCK = LOW Write -> 0x01 //SCK = HIGH, SDIO = Bit 4 (0) Write -> 0x00 //SCK = LOW Write -> 0x01 //SCK = HIGH, SDIO = Bit 3 (0) Write -> 0x00 //SCK = LOW Write -> 0x01 //SCK = HIGH, SDIO = Bit 2 (0) Write -> 0x00 //SCK = LOW Write -> 0x03 //SCK = HIGH, SDIO = Bit 1 (1) Write -> 0x02 //SCK = LOW Write -> 0x03 //SCK = HIGH, SDIO = Bit 0 (1) Write -> 0x02 //SCK = LOW ------------------------------------- END TRANSFER ------------------------------------- Write -> 0x02 //SCK = LOW, SDIO = HIGH, end communications -------------------------------------

Like reading on the two-wire interface, switching SCK from LOW to HIGH while writing has several timing conditions. SCK should be set LOW for a minimum of 2μs during the transfer and should ideally not exceed 64μs. Going further than 64μs stops the transfer. SCK should be set HIGH for a minimum of 2μs.

Depending on the command sent, the Magic Reader may immediately reply with its own data (setting SDIO LOW to indicate a read request). Below are the supported commands for the Magic Reader:

Command 0x24 - Unknown Command

This appears after UserCMD_AutoSleepFunDisable (0xA3). It does not appear to expect a response from the Magic Reader.

Command 0x30 - UserCmd_CheckOIDStatus

Instructs the Optical ID to return its status. Magic Reader will typically reply with OIDCmd_PowerOn, OIDCmd_PowerDown, OIDCmd_SystemReset, a valid index, or a null response.

Command 0x50 - UserCmd_NonClearAutoSleepTimerIfOIDDetect

Instructs the Optical ID to not clear the auto-sleep timer when reading an index.

Command 0x56 - UserCMD_PowerDownOID

Instructs the Optical ID to enter sleep mode.

Command 0xA0 - UserCMD_AutoSleepFunEnable

Instructs the Optical ID to enable the auto-sleep timer.

Command 0xA3 - UserCMD_AutoSleepFunDisable

Instructs the Optical ID to disable the auto-sleep timer.

Command 0xA6 - UserCMD_TriggerToClearAutoSleepTimer

Manually clears the auto-sleep timer.

Command 0xAC - UserCMD_ClearAutoSleepTimerIfOIDDetect

Instructs the Optical ID to clear the auto-sleep timer when reading and index.

[Magic Reader] : Control Flow

Below is the general control flow used for Juushinden. Note that the full functionality of the SN9P701FG-005 is not necessarily used. There are generally 2 phases: 1 for the initial startup (shortly after the game boots) and the other used when reading cards.

Initial Startup Sequence

  1. NDS writes 0x42 to MR_CNT to force Power On. For this step, EXMEMCNT is set to 0xE003. For all subsequent steps, Bits 0-1 of EXMEMCNT are set LOW.
  2. Magic Reader sets SDIO LOW to indicate a read request. NDS reads OIDCmd_PowerOn from Magic Reader.
  3. NDS sends UserCMD_AutoSleepFunDisable and unknown command 0x24.
  4. NDS continually sends UserCMD_PowerDownOID and waits for Magic Reader to respond with OIDCmd_PowerDown.

Card Reading Sequence

  1. NDS writes 0x42 to MR_CNT to force Power On. For this step, EXMEMCNT is set to 0xE003. For all subsequent steps, Bits 0-1 of EXMEMCNT are set LOW.
  2. Magic Reader sets SDIO LOW to indicate a read request. NDS reads OIDCmd_PowerOn from Magic Reader.
  3. NDS sends UserCMD_AutoSleepFunDisable and unknown command 0x24.
  4. NDS continually reads MR_CNT for incoming read requests from the Magic Reader. A 23-bit index value is then read.
  5. NDS should compare the last index from the last read request and validate the value.

[Magic Reader] : Card List and Index Values

There are total of 240 cards for Juushinden released in 4 sets of 60. There are also an unknown amount promotional cards. For the regular sets, the index values returned by the Magic Reader roughly matches the number printed on the card itself.

------------------------------------- Set 1 - 第一弾「大いなる覚醒の時」 ------------------------------------- Card # | Name | Index ------------------------------------- JS1-06 | イカレコング | 0005 JS1-07 | タコ力士 | 0006 JS1-09 | イーグルカンフー | 0008 JS1-12 | ブラックドーベル | 000B JS1-13 | ガオー | 000C JS1-14 | 剛力獣神ガオー | 000D JS1-18 | ダイバクハーン | 0011 JS1-20 | ソードザック | 0013 JS1-23 | カワ・ウソン | 0016 JS1-25 | クワガイアス | 0018 JS1-26 | スカルドレイン | 0019 JS1-28 | ヨロイガエル | 001B JS1-32 | ザバット | 001F JS1-37 | シールドブレイク | 0024 JS1-38 | ソードブレイク | 0025 JS1-39 | 聖なる闘技場 | 0026 JS1-41 | ポメ剣士 | 0028 JS1-42 | シロクマックス | 0029 JS1-43 | アチョーモンキー | 002A JS1-47 | ハイエナガード | 002E JS1-49 | ブルドクター | 0030 JS1-52 | 怪力エレファン | 0033 JS1-53 | タイガ | 0034 JS1-57 | いでよ鋼の盾 | 0038

The cards themselves use tiny carbon dots to produce an index value. According to the OID specification, carbon ink can replace K when using CMYK. Black colors would need to be reproduced by merging CMY dots in close proximity to one another. At any rate, these dots are meant to absorb light rather than reflect it. The CMOS inside the Magic Reader can't detect these dots, so these "empty" spots form a pattern that can be recognized and converted into a number. These dots are not completely invisible to the human eye, however. Ordinary cameras are capable of capturing them. The dots occupy the entire face of the card with the exception of the borders and likely the silver text of some cards.

Mobile Adapter GB

General Hardware Information

Compatible Games

Protocol - Packet Format

Protocol - Flow of Communication

Protocol - Commands

Configuration Data

[Mobile Adapter GB] : General Hardware Information

The Mobile Adapter GB was an accessory designed to allow the Game Boy Color, and later the Game Boy Advance, to connect online via cellular networks in Japan. Released on January 27, 2001, it supported a limited number of games before service was shutdown on December 14, 2002. Many of the compatible games supported features such on mail clients, downloadable bonus content, player-versus-player modes, and even online tournaments. It represented Nintendo's first official attempt at online gaming for its handhelds.

Below, the Mobile Adapter variants are explained in further detail:

Blue -> Used to connect PDC phones. Yellow -> Used to connect cdmaOne phones. Red -> Used to connect DDI phones. Green -> Would have been used to connect PHS phones, but this version was never released.

[Mobile Adapter GB] : Compatible Games

There are currently 22 known games that are compatible with the Mobile Adapter:

Game Boy Color : 6 Total

Game Boy Advance : 16 Total

Two games were planned but later cancelled: beatmaniaGB Net Jam for the GBC and Horse Racing Creating Derby for the GBA.

The GBA game Yu-Gi-Oh! Duel Monsters 5 Expert 1 contains code for the Mobile Adapter, but despite being built with the library it does not appear to use it. This functionality may have been planned and later abandoned.

[Mobile Adapter GB] : Protocol - Packet Format

On the GBC, the Mobile Adapter operates using the fastest available setting (64KB/s) by setting Bits 0 and 1 of the SC register (0xFF02) high. It also uses an internal clock for all transfers. Communication is comparable to that of the Game Boy Printer, where the Game Boy sends packets with header, data, command, and checksum sections. On the GBA, the Mobile Adapter operates in NORMAL8 mode using a shift clock of 256KHz. Below is a chart breaking down the Mobile Adapter packet format used by the Game Boy or Mobile Adapter when acting as the sender. For response data sent by the receiver, refer to the next section.

------------------------------------------------- Section | Length ------------------------------------------------- Magic Bytes : 0x99 0x66 | 2 bytes Packet Header | 4 bytes Packet Data | 0-254 bytes Packet Checksum | 2 bytes Acknowledgement Signal | 2 bytes ------------------------------------------------- ------------------------------------------------- Packet Header ------------------------------------------------- Byte 1 | Command ID Byte 2 | Unknown/Unused (0x00) Byte 3 | Unknown/Unused (0x00) Byte 4 | Length of Packet Data ------------------------------------------------- ------------------------------------------------- Packet Data ------------------------------------------------- Bytes 0-254 | Arbitrary data ------------------------------------------------- ------------------------------------------------- Packet Checksum ------------------------------------------------- Byte 1 | High byte of 16-bit sum Byte 2 | Low byte of 16-bit sum ------------------------------------------------- ------------------------------------------------- Acknowledgement Signal ------------------------------------------------- Byte 1 | Device ID Byte 2 | Command ID -------------------------------------------------

The magic bytes are simply a pair of bytes used to identify the start of a Mobile Adapter packet.

Packet Data is arbitrary data and varies in length and content. On the Game Boy Color, it has a maximum size of 254 bytes. This restriction may be applied via software and appears to come from the fact that the Packet Data and Packet Checksum are lumped together, thus their total lengths must not exceed 256 bytes. Attempting to send more than 254 bytes of packet data causes communications errors in all supported GBC games. Evidence suggests GBA games can use Bytes 3 and 4 of the Packet Header to specify Packet Data size (possibly up to 64KB).

On the GBC, data greater than 254 bytes may be broken up into multiple packets, however. For example, when sending a large binary file such as an image or executable code, multiple packets are transferred from the Mobile Adapter to the Game Boy while the TCP transfer is ongoing.

The Packet Checksum is simply the 16-bit sum of all previous header bytes and all previous packet data bytes. It does not include the magic bytes. The checksum is transmitted big-endian.

After the checksum, a simple 2-byte Acknowledgement Signal is sent. The first byte is the Device ID OR'ed with the value 0x80. The second byte is 0x00 for the sender. The receiver transfers the Command ID from the Packet Header XOR'ed by 0x80. This essentially confirms what role the Game Boy is acting in. If it is the receiver, it is expecting to read information from the Packet Data from the Mobile Adapter. If it is the sender, it is pushing information from its own Packet Data to the Mobile Adapter. For example, with Command 0x19, the Game Boy is explicitly requesting data from the adapter, and with Command 0x1A the Game Boy is explicitly sending data to the adapter.

If the checksum fails, the receiving side typically immediately sends 0xF1 to indicate an error. 0xF0, and 0xF2 also appear to be failure codes, however, their meaning is currently unknown. 0xEE indicates a specific error from a previously issued command.

The device ID determines what kind of hardware each side is communicating with. Below are the possible values and their meaning:

------------------------------------------------- Device ID | OR Value | Device Type ------------------------------------------------- 0x00 | 0x80 | Game Boy Color 0x01 | 0x81 | Game Boy Advance 0x08 | 0x88 | PDC Mobile Adapter (Blue) 0x09 | 0x89 | cdmaOne Mobile Adapter (Yellow) 0x0A | 0x8A | PHS Mobile Adapter (Green) 0x0B | 0x8B | DDI Mobile Adapter (Red) -------------------------------------------------

[Mobile Adapter GB] : Protocol - Flow of Communication

Even though the protocol effectively enables 2-way communication between the Game Boy and a remote server, the handheld is expected to oversee all transmissions to the adapter itself. That is to say, the typical "master-slave" model often used for Game Boy serial I/O still applies in some sense. Once the server starts responding, the Game Boy has to continually initiate another transfer to the adapter (setting Bit 7 of 0xFF02 high) to keep reading any additional bytes that were sent.

It is up to the game software itself to handle secondary protocols (such as HTTP, POP3, or SMTP) which involve one side specifically acting as the sender or receiver. For example, after opening a TCP connection to an HTTP server and issuing the 0x15 command (Data Transfer), the software will determine whether the Game Boy is acting as a sender (making an HTTP request) or a receiver (receiving an HTTP response). Generally, this goes back and forth. The Game Boy sends information via its Packet Data, while the Mobile Adapter responds with 0xD2 "wait" bytes until the Game Boy finishes its TCP transfer. When the Game Boy's TCP transfer is done, the adapter sends any information from the server in its Packet Data while the Game Boy responds with 0x4B "wait" bytes. The chart below illustrates this concept and details what bytes are transferred by each side depending on their current role:

------------------------------------------------------------------------------------------------------------------------------------------------- Device | Role | Magic Bytes | Packet Header | Packet Checksum | Packet Data | Acknowledgement Signal ------------------------------------------------------------------------------------------------------------------------------------------------- Game Boy | Sender | 0x96 0x66 | Arbitrary | Arbitrary | Arbitrary | Device ID OR 0x80 + 0x00 Mobile Adapter | Receiver | 0xD2 0xD2 | 0xD2 0xD2 ... | 0xD2 0xD2 ... ... ... | 0xD2 0xD2 ... | Device ID OR 0x80 + Command ID XOR 0x80 ------------------------------------------------------------------------------------------------------------------------------------------------- Game Boy | Receiver | 0x4B 0x4B | 0x4B 0x4B ... | 0x4B 0x4B ... ... ... | 0x4B 0x4B ... | Device ID OR 0x80 + Command ID XOR 0x80 Mobile Adapter | Sender | 0x96 0x66 | Arbitrary | Arbitrary | Arbitrary | Device ID OR 0x80 + 0x00 -------------------------------------------------------------------------------------------------------------------------------------------------

When beginning communications with the Mobile Adapter, the Game Boy typically assumes the role of sender first.

Many games appear to follow a certain order of commands initially. This may have been part of some kind of standard library available to developers in order to connect to an ISP. The commands most commonly look like this:

------------ Command 0x10 Begin Session. First is perhaps to test the presence of the Mobile Adapter Command 0x11 Close Session. Command 0x10 Begin Session. Open session for configuration data ------------ Command 0x19 Read Configuration Data. Grab first 96 bytes Command 0x19 Read Configuration Data. Grab second 96 bytes Command 0x11 Close Session. Command 0x10 Begin Session. Open session to read configuration data again Command 0x19 Read Configuration Data. Grab first 96 bytes Command 0x19 Read Configuration Data. Grab second 96 bytes ------------ Command 0x17 Check Telephone Status if not busy Command 0x12 Dial Telephone. Should be the ISP's number stored in configuration data Command 0x21 ISP Login Command 0x28 DNS Query ------------

From there, the software decides what next (if anything) needs to be done after successfully connecting to the internet.

[Mobile Adapter GB] : Protocol - Commands

Command 0x10 - Begin Session

Data Sent: "NINTENDO" ASCII string. 8 bytes only, not null-terminated

Data Received: "NINTENDO" ASCII string. 8 bytes only, not null-terminated

Sent to the adapter at the beginning of a session. The Game Boy sends an ASCII string containing "NINTENDO" and the adapter replies with a packet containing the same data. It must be noted that the adapter will not respond to other commands until it receives this command. If this command is sent twice, it returns an error.

Command 0x11 - End Session

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

Sent to the adapter at the end of a session. The Packet Data is empty, and the length is zero bytes.

Command 0x12 - Dial Telephone

Data Sent: 1 unknown byte + telephone number

Data Received: N/A. Empty Packet Data

Instructs the adapter to dial a telephone number. The first byte's purpose is unknown. The second byte is "#" in ASCII, and following data is the telephone number represented in ASCII values.

Command 0x13 - Hang Up Telephone

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

Instructs the adapter to close a telephone connection. The Packet Data is empty, and the length is zero bytes.

Command 0x14 - Wait For Telephone Call

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

Instructs the adapter to wait for a telephone call. The Packet Data is empty, and the length is zero bytes.

Command 0x15 - Transfer Data

Data Sent: 1 unknown byte + Arbitrary Data (optional)

Data Received: 1 unknown byte + Arbitrary Data (optional)

Used to transfer data over TCP after the command 0x23 (Open TCP Connection) has been called. This command can communicate with a remote server or another Mobile Adapter. The Packet Data is a minimum length of 1 byte. That first byte's purpose is unknown. Generally, additional data is appended, although it is not required, such as when closing a connection. Large chunks of data greater than 254 bytes must be broken down into separate packets. While a connection is active (e.g. an HTTP request/response is in progress), the Command ID in the Acknowledgement Signal is 0x15 for the sender and 0x95 for the receiver. When a connection is closed (e.g. when an HTTP response has finished), the Command ID in the Acknowledgement Signal becomes 0x1F for the sender and 0x9F for the receiver.

Command 0x17 - Telephone Status

Data Sent: N/A. Empty Packet Data

Data Received: 1 byte for current telephone status + 2 unknown bytes

Typically sent to the adapter before dialing. Also used to test the telephone status before opening a TCP connection, or to constantly ping the phone to make sure it's still active. The reply is 1 byte. 0x00 means the phone is ready to make a call or connection. 0xFF indicates a disconnected phone. 0x04 and 0x05 indicate that the line is busy (presumably set after a command like 0x12). The difference between the two line-busy values is unknown. Most software does not seem to care which one is sent, but Net de Get: Mini Game @ 100 refuses to work with 0x05.

Additionally, the Game Boy seem to set Bits 0 - 4 high for the Command ID in the Acknowledgement Signal, thus sending 0x1F to the Mobile Adapter.

Command 0x18 - Unknown Command

Data Sent: 1 unknown byte

Data Received: N/A. Empty Packet Data

This command is generally sent after Command 0x10. Only GBA games have been known to use this command. The GBA sends 1 unknown byte. The response Packet Data is empty, and the length is zero bytes.

Command 0x19 - Read Configuration Data

Data Sent: 1 byte offset + 1 byte read length

Data Received: 1 unknown byte + Requested Configuration Data

Requests data from the adapter's 192-byte configuration memory. The first byte sent to the adapter is the offset. The second byte sent is the length of data to read. The adapter responds with 1 unknown byte followed by configuration data from the adapter's internal memory. Although it should be possible to read the entire configuration data with one packet, most software send 2 of these commands to read 96-byte chunks.

Command 0x1A - Write Configuration Data

Data Sent: 1 unknown + Configuration Data to Write

Data Received: N/A. Empty Packet Data

Writes data to the adapter's 192-byte configuration memory. The first byte sent to the adapter unknown. The following bytes are the data to be written in the adapters internal memory.

Command 0x21 - ISP Login

Data Sent: 1 byte Login ID Length + Login ID + 1 byte Password Length + Password + 4 bytes DNS Address #1 + 4 bytes DNS Address #2

Data Received: 4 bytes possibly representing IP address assigned to adapter

Logs into the DION service, which in turn connects to an internet server. Both the Login ID and Password are prefixed with bytes declaring their lengths. The IPv4 DNS addresses are 4 bytes each, with a single byte representing one octet.

Command 0x22 - ISP Logout

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

Logs out of the DION service.

Command 0x23 - Open TCP Connection

Data Sent: 4 bytes for IP Address + 2 Bytes for Port Number

Data Received: 1 unknown byte

Opens a TCP connection at the given IP address on the given port. The IPv4 IP address is 4 bytes, with a single byte representing one octet. The port number is big-endian. Depending on which port the TCP connection opens (25, 80, 110), different protocols can be accessed on a server (SMTP, HTTP, and POP respectively). Handling the details of the protocol itself depends on software. The Mobile Adapter is merely responsible for opening the connection and handling TCP transfers such as when using Command 0x15.

Command 0x24 - Close TCP Connection

Data Sent: 1 unknown byte

Data Received: 1 unknown byte

Closes an active TCP connection.

Command 0x28 - DNS Query

Data Sent: Domain Name

Data Received: 4 bytes for IP Address

Looks up the IP address for a domain name, presumably using the DNS server addresses sent in Command 0x21

Command 0x6E - Error Status

Data Sent: N/A. Adapter sends this in response to a failed command

Data Received: 1 byte for command that failed + 1 byte for error status

If a previously sent command fails, the adapter will respond with this instead, indicating the command that failed as well as a brief status code. The error statuses for one command do not indicate the same error for another command, so context matters when parsing the codes. The following commands and their known error status codes are listed below:

0x10: Error Code 0x01 - Sent twice 0x10: Error Code 0x02 - Invalid contents 0x12: Error Code 0x03 - Dial telephone with telephone disconnected 0x14: Error Code 0x00 - Wait for call with telephone disconnected 0x15: Error Code 0x01 - Transfer data without being connected 0x19: Error Code 0x02 - Read outside of config area 0x1A: Error Code 0x02 - Write outside of config area 0x21: Error Code 0x01 - ISP login with disconnected phone

[Mobile Adapter GB] : Protocol - Configuration Data

The Mobile Adapter has small area of built-in memory designed to store various settings for its configuration. It only uses 192 bytes but data is readable and writable via the Commands 0x19 and 0x1A respectively. These fields are filled out when running the initial setup on Mobile Trainer. The memory is laid out as describe below:

-------------------------- 0x00 - 0x01 :: "MA" in ASCII. The "Mobile Adapter" header. 0x02 :: Set to 0x1 during Mobile Trainer registration and 0x81 when registration is complete 0x04 - 0x07 :: Primary DNS server ( 0x08 - 0x0B :: Secondary DNS server ( 0x0C - 0x15 :: Login ID in the format gXXXXXXXXX. Mobile Trainer only allows 9 editable characters 0x2C - 0x43 :: User email address in the format XXXXXXXX@YYYY.dion.ne.jp 0x4A - 0x5D :: SMTP server in the format mail.XXXX.dion.ne.jp 0x5E - 0x70 :: POP server in the format pop.XXXX.dion.ne.jp 0x76 - 0x8D :: Configuration Slot #1 0x8E - 0xA5 :: Configuration Slot #2 0xA6 - 0xBD :: Configuration Slot #3 0xBE - 0xBF :: 16-bit big-endian checksum --------------------------

Each configuration slot may contain an 8-byte telephone number to be used to connect to the ISP and a 16-byte ID string. The telephone number is stored in a variant of binary-coded decimal, where 0x0A represents the "#" key, 0x0B represents the "*" key, and 0x0F marks the end of the telephone number. These slots may have been intended to allow users to connect online using ISPs besides DION at some point, however, Nintendo never implemented any such plans.

If the Mobile Adapter is connected to a PDC or CDMA device, the telephone number defaults to #9677 with an ID string of "DION PDC/CDMAONE". If the Mobile Adapter is connected to a PHS or DDI device, the telephone number defaults to 0077487751 with an ID string of "DION DDI-POCKET". Only the first slot is configured by Mobile Trainer; it fills the rest with 0xFF and 0x00 bytes. An unidentified device (as reported by the Device ID in the Acknowledgement Signal of a packet) causes the Mobile Adapter to overwrite all configuration data with garbage values.

The checksum is simply the 16-bit sum of bytes 0x00 - 0xBD.

All software compatible with the Mobile Adapter appears to read the configuration data first and foremost. If the data cannot be read or if there is a problem with the data, they will refuse to even attempt making an online connection. Generally, they return the error code 25-000 in that situation.

If any compatible software attempts to read or write configuration data outside the allotted 192 bytes via commands 0x19 and 0x1A, the entire I/O operation is cancelled. No data is written even if the initial offset is within the 192 bytes. No data is returned either, as both commands respond with Error Status packets.

Game Boy Wars 3

General Information

Server Structure







[Game Boy Wars 3] : General Information

Game Boy Wars 3 is a turn-based war strategy game for the GBC, similar in gameplay to Nectaris. The online capabilities of the software consist of downloading custom maps, viewing messages and news from the developers, and unlocking premium mercenary units in battle.

[Game Boy Wars 3] : Server Structure

Game Boy Wars 3 is currently known to access the following URLS (asterisks indicate variable characters):

[Game Boy Wars 3] : 0.map_menu.txt

This file dictates the price in yen for maps. Although every map should have cost 10 yen, the game allows for different prices to exist for any map. The file is simply text with the following format:

[Minimum Map #] [Maximum Map #] [Price in yen]

Each line defines a minimum and maximum map number to create a range of maps and the price that will apply to all of them. All values are 4-digits written in ASCII, and whitespace may be tabs or spaces. Before downloading a map, players must specify a 4 digit ID corresponding to the number of the map they want. If 0.map_menu.txt does not specify a range that includes that ID, that map is unavailble for download.

This file specifies that no service charge should apply, as the filename is prefixed with "0".

[Game Boy Wars 3] : map/map_****.cgb

This is the binary data for a downloadable map. The 4 digit ID previously specified by a player prior to download determines the full filename that the game will request. For example, if the ID 1337 is used, map_1337.cgb will be requested. The format is exactly the same as the custom maps that players can create themselves.

---------------------------------- Map Structure ---------------------------------- 0x00 - 0x01 :: 0x20, 0x00. Seems to be an identifier, but the game does not care what values these bytes are. 0x02 - 0x03 :: 16-bit sum of map size. LSB first. Calculated as 0x19F + (400 - (map width * map height)) 0x04 :: 8-bit sum of all data until EOF. Calculated as 0xFE - (a, b, c, ...) 0x20 - 0x2B :: String for map name 0x2C :: Map width (Min: 20, Max: 50) 0x2D :: Map height (Min: 20, Max: 50) 0x2E ... :: Map tiles ... :: Unit tiles (if any) EOF :: The last byte is 0xFF

The map tiles are 8-bit numbers that determine what type of terrain or buildings are placed on the grid (e.g. plains, mountains, forest, main base, factory, etc).

---------------------------------- Map Tiles ---------------------------------- 0x00 :: Null space. Black tile that is "out of bounds". 0x01 :: Red Star base 0x02 :: Red Star city 0x03 :: Red Star ruined city 0x04 :: Red Star factory 0x05 :: Red Star ruined factory 0x06 :: Red Star airport 0x07 :: Red Star ruined airport 0x08 :: Red Star simple airport 0x09 :: Red Star harbor 0x0A :: Red Star ruined harbor 0x0B :: Red Star Transmission Tower 0x0C :: White Moon base 0x0D :: White Moon city 0x0E :: White Moon ruined city 0x0F :: White Moon factory 0x10 :: White Moon ruined factory 0x11 :: White Moon airport 0x12 :: White Moon ruined airport 0x13 :: White Moon simple airport 0x14 :: White Moon harbor 0x15 :: White Moon ruined harbor 0x16 :: White Moon Transmission Tower 0x17 :: Neutral city 0x18 :: Neutral ruined city 0x19 :: Neutral factory 0x1A :: Neutral ruined factory 0x1B :: Neutral airport 0x1C :: Neutral ruined airport 0x1D :: Neutral harbor 0x1E :: Neutral ruined harbor 0x1F :: Neutral Transmission Tower 0x20 :: Plains 0x21 :: Highway 0x22 :: Bridge 0x23 :: Bridge 0x24 :: Mountains 0x25 :: Forest 0x26 :: Wasteland 0x27 :: Desert 0x28 :: River 0x29 :: Sea 0x2A :: Shoal 0x2B - 0xFF :: These appears to be invalid, glitchy, or null tiles

The game does not do any error-checking on the maps besides checking the 16-bit map size sum and the 8-bit data sum. If those are valid, the game will run it. Maps that would typically be impossible to create through the normal editor (maps lacking a Red Star/White Moon base, maps with null spaces, maps with Transmission Towers) can be downloaded and played.

If the 16-bit map size sum and 8-bit data sum are invalid, the game will complain when first booting. The actual map data is not deleted from SRAM, rather it simply becomes inaccessible from any in-game menus. Making a new map for that map slot will overwrite it, however.

Units can be placed on a map, but they are separate from the actual map data. After the map tile data is finished, unit tile data comes next. Each unit tile consists of 3 bytes:

---------------------------------- Unit Tile Bytes ---------------------------------- 0x00 :: X position on map 0x01 :: Y position on map 0x02 :: Unit ID

The IDs are as follows:

---------------------------------- Unit IDs ---------------------------------- 0x00 :: N/A. No unit appears 0x01 :: Invalid (DEL tile) 0x02 :: Red Star Infantry 0x03 :: White Moon Infantry 0x04 :: Red Star Missile Infantry 0x05 :: White Moon Missle Infantry 0x06 :: Red Star Merc Infantry 0x07 :: White Moon Merc Infantry 0x08 :: Red Star Construction Vehicle 0x09 :: White Moon Construction Vehicle 0x0A :: Red Star Supply Vehicle 0x0B :: White Moon Supply Vehicle 0x0C :: Red Star Supply Vehicle S 0x0D :: White Moon Supply Vehicle S 0x0E :: Red Star Transport Truck 0x0F :: White Moon Transport Truck 0x10 :: Red Star Transport Truck S 0x11 :: White Moon Transport Truck S 0x12 :: Red Star Combat Buggy 0x13 :: White Moon Combat Buggy 0x14 :: Red Star Combat Buggy S 0x15 :: White Moon Combat Buggy S 0x16 :: Red Star Combat Vehicle 0x17 :: White Moon Combat Vehicle 0x18 :: Red Star Combat Vehicle S 0x19 :: White Moon Combat Vehicle S 0x1A :: Red Star Armored Transport Truck 0x1B :: White Moon Armored Transport Truck 0x1C :: Red Star Armored Transport Truck S 0x1D :: White Moon Armored Transport Truck S 0x1E :: Red Star Rocket Launcher 0x1F :: White Moon Rocket Launcher 0x20 :: Red Star Rocket Launcher S 0x21 :: White Moon Rocket Launcher S 0x22 :: Red Star Anti-Air Tank 0x23 :: White Moon Anti-Air Tank 0x24 :: Red Star Merc Anti-Air Tank 0x25 :: White Moon Merc Anti-Air Tank 0x26 :: Red Star Anti-Air Missile 0x27 :: White Moon Anti-Air Missile 0x28 :: Red Star Anti-Air Missile S 0x29 :: White Moon Anti-Air Missile S 0x2A :: Red Star Artillery 0x2B :: White Moon Artillery 0x2C :: Red Star Artillery S 0x2D :: White Moon Artillery S 0x2E :: Red Star Anti-Infantry Tank 0x2F :: White Moon Anti-Infantry Tank 0x30 :: Red Star Anti-Infantry Tank S 0x31 :: White Moon Anti-Infantry Tank S 0x32 :: Red Star Tank Destroyer 0x33 :: White Moon Tank Destroyer 0x34 :: Red Star Tank Destroyer S 0x35 :: White Moon Tank Destroyer S 0x36 :: Red Star Tank 0x37 :: White Moon Tank 0x38 :: Red Star Merc Tank 0x39 :: White Moon Merc Tank 0x3A :: Red Star Fighter Jet A 0x3B :: White Moon Fighter Jet A 0x3C :: Red Star Fighter Jet B 0x3D :: White Moon Fighter Jet B 0x3E :: Red Star Fighter Jet S 0x3F :: White Moon Fighter Jet S 0x40 :: Red Star Attack Aircraft A 0x41 :: White Moon Attack Aircraft A 0x42 :: Red Star Attack Aircraft B 0x43 :: White Moon Attack Aircraft B 0x44 :: Red Star Attack Aircraft S 0x45 :: White Moon Attack Aircraft S 0x46 :: Red Star Bomber 0x47 :: White Moon Bomber 0x48 :: Red Star Merc Bomber 0x49 :: White Moon Merc Bomber 0x4A :: Red Star Transport Aircraft 0x4B :: White Moon Transport Aircraft 0x4C :: Red Star Aerial Tanker 0x4D :: White Moon Aerial Tanker 0x4E :: Red Star Attack Helicopter 0x4F :: White Moon Attack Helicopter 0x50 :: Red Star Attack Helicopter S 0x51 :: White Moon Attack Helicopter S 0x52 :: Red Star Anti-Sub Helicopter 0x53 :: White Moon Anti-Sub Helicopter 0x54 :: Red Star Transport Helicopter 0x55 :: White Moon Transport Helicopter 0x56 :: Red Star Transport Helicopter S 0x57 :: White Moon Transport Helicopter S 0x58 :: Red Star Aegis Warship 0x59 :: White Moon Aegis Warship 0x5A :: Red Star Merc Frigate 0x5B :: White Moon Merc Frigate 0x5C :: Red Star Large Aircraft Carrier 0x5D :: White Moon Large Aircraft Carrier 0x5E :: Red Star Small Aircraft Carrier 0x5F :: White Moon Small Aircraft Carrier 0x60 :: Red Star Transport Warship 0x61 :: White Moon Transport Warship 0x62 :: Red Star Supply Tanker 0x63 :: White Moon Supply Tanker 0x64 :: Red Star Submarine 0x65 :: White Moon Submarine 0x66 :: Red Star Submarine S 0x67 :: White Moon Submarine S 0x68 :: Red Star "Dummy" unit 0x69 :: White Star "Dummy" unit 0x6A :: Invalid (DEL tile) 0x6B - 0xFF :: Invalid (glitchy tiles)

Again, besides the basic additive checksumming, the game does not validate whether some units logically make sense when placed on a map (e.g. submarines on top of a mountain or in a forest). The in-game editor prevents such things from happening, however, downloaded maps can essentially do whatever they want. This includes populating the battlefield with the DLC mercenary units that would normally be available exclusively via the Transmission Tower. Mercenary units are not available through the in-game editor, however, downloaded maps can be freely edited, so such units can be deleted.

[Game Boy Wars 3] : charge/****.cgb

This file is requested after a map has sucessfully been downloaded or a mercenary unit has been unlocked. The filename is the price of the service in yen. This price is specified in either 0.map_menu.txt or 0.youhei.txt. The game largely appears to ignore the contents of the file and instead merely wants to confirm an HTTP 200 response from the server. Requesting that file incurs a service charge and is the mechanism behind Game Boy Wars 3's paid DLC. Neither 0.map_menu.txt or 0.youhei.txt check to make sure the 4-digit prices are valid ASCII numbers such as "30" or "10" and will blindly send whatever characters are written in those files.

[Game Boy Wars 3] : mbox/mbox_serial.txt

This file contains a list of strings when accessing the Message Center. mbox_serial.txt points the game to a mailbox file to download. It appears every string should be a number, e.g. ASCII characters 0x30 - 0x39. A total of 16 lines are parsed. If the contents of the strings have changed since the last time the player has downloaded from the Message Center, this indicates that a new message should be downloaded from that mailbox. The simplest method of managing mbox_serial.txt would be to set all lines at a baseline number (e.g. 0000) and increment each line when that mailbox features a new message (e.g. change line 0 from 0000 to 0001). If multiple lines are changed, multiple messages will be downloaded.

The previous strings (if any) are stored locally on the Game Boy Wars 3 cartridge RAM, and the game uses that to determine if anything should be downloaded at all. If no strings have been updated, Game Boy Wars 3 will not attempt to download any of the mailboxes.

Evidently, these mbox_serial.txt may need some formatting to correctly display the date for a mailbox's message, however, this information is currently unknown.

[Game Boy Wars 3] : mbox/mbox_**.cgb

This file contains the message to display from a mailbox. The exact url is determined by mbox_serial.txt. If the first line's string in mbox_serial.txt is updated, the game downloads mbox_00.cgb. If the second line's string in mbox_serial.txt is updated, the game downloads mbox_01.cgb, and so on. There are only 16 mailboxes available: mbox_00.cgb to mbox_15.cgb.

The format appears to be pure text, except that the first 7 characters are ignored. Messages can be displayed in ASCII. Hiragana and katakana are available as well, however, their format is currently unknown. The mbox_**.cgb file MUST end CRLF, otherwise the game does not know to stop parsing data and starts overwriting all kinds of RAM.

[Game Boy Wars 3] : 0.youhei_menu.txt

This file is requested when players use the Transmission Tower during a battle. It's merely a list that details the price in yen for each mercenary unit. The format is as follows:

[Price for Merc Infantry] [Price for Merc AA Tank] [Price for Merc Tank] [Price for Merc Bomber] [Price for Merc Frigate]

This file specifies that no service charge should apply, as the filename is prefixed with "0".

Hello Kitty no Happy House

General Information

Server Structure


[Hello Kitty no Happy House] : General Information

Hello Kitty no Happy House is a Game Boy Color title featuring furniture collection, minigames, and online communication. The game revolves around interacting with Hello Kitty, gaining new furniture, and decorating the "Happy House". As it concerns the Mobile Adapter GB, Hello Kitty no Happy House boasts basic email capabilities. Through the email service, users could share different furniture as presents.

[Hello Kitty no Happy House] : Server Structure

Hello Kitty no Happy House is not known to access any resource via HTTP. Instead, it simply communicates with a SMTP server and POP3 server for sending and receiving email respectively.

[Hello Kitty no Happy House] : Email

Email can be sent and received in Hello Kitty no Happy House, much like Mobile Trainer. The game offers similar tools to write the email, helping users fill out subjects, addresses, and content, and viewing the mailbox for received items. The game also sends "presents" to another user via email. The standard email format looks something like this (note that xxxx, yyyy, and zzzz parts are not exact lengths, consider them as variables):

From: =?ISO-2022-JP?xxxxxxxxxxxxxxxxxxxxxxxx <yyyy@zzzz.dion.ne.jp> To: =?ISO-2022-JP?xxxxxxxxxxxxxxxxxxxxxxxx <yyyyyyyyy> Subject: =?ISO-2022-JP?xxxxxxxxxxxxxxxxxxxxxxxx MIME-Version: 1.0 Content-Type: text/plain; charset="ISO-2022-JP" Content-Transfer-Encoding: 7bit X-Mailer: Hello Kitty Happy House X-Game-title: HKITTY_HH X-Game-code: CGB-BK7J-00 [content of email]

The game uses two additional custom SMTP email headers to send furniture to another player. These headers are parsed for a 3-letter ASCII code which determines the item received. After the "X-Game-code" header, the following would be inserted before the content of the email:

X-GBmail-type: exclusive X-HKH-HOUSE: [3-letter code]

The codes appear to be simple, e.g. "AAE" for a framed picture and "AIG" for a green rug.

Mobile Trainer

General Information

Server Structure


Web Browser


[Mobile Trainer] : General Information

Mobile Trainer is utility software designed as a configuration tool for the Mobile Adapter GB. It also served as a basic web-browser and email client when connected to the Mobile System GB network. The cartridge came bundled with every Mobile Adapter and was released on January 27, 2001.

[Mobile Trainer] : Server Structure

Mobile Trainer is currently known to access the following URL:

Although a few other URLs are present within the ROM, the above is the only ones observed in actual use. Additionally, Mobile Trainer is currently known to access POP3 mail servers on port 110 and SMTP servers on port 25.

[Mobile Trainer] - index.html

This is the "Home Page" for the Mobile Adapter. News and updates published by Nintendo would appear here periodically. Other pages could be accessed if the Home Page had links. Beyond a few screenshots, not much else has been recorded about the content and structure of the Home Page.

[Mobile Trainer] - Web Browser

Mobile Trainer features a barebones web-browser supported a limited subset of HTML. The following HTML elements are known to render:

Manual URL input is not possible from the browser. As such, it is restricted to the Home Page and whatever links appear in the index.html file. Bookmarks can be saved, however, and accessed without having to go through the Home Page. Manually editing the save file would allow bookmarks to point to arbitrary URLs.

Accessing the Home Page and associated links is timed, as the Mobile Adapter keeps an active connection to the server, thus a service charge (from the wireless provider) would be applied for the total time spent browsing. Handily enough, there is an option within the browser to cut the connection and freeze the timer.

<img> tags will only work with 1BPP BMP files. There are several additional restrictions:

Just about everything else in the BMP file and image header is ignored. Most image editors will produce a BMP that works fine with the Mobile Trainer web-browser. Some BMPs may need minor alterations. For example, GIMP may set the number of color maps but otherwise typically produce a valid BMP for Mobile Trainer (in which case, the incorrect bytes can be manually changed in a hex editor).

[Mobile Trainer] : Email

Email could be sent and received by Mobile Trainer. Users would have to register a DION account and would receive their information (email address, password, etc). Other game servers on the Mobile System GB network could send email to this account for various reasons. Pokemon Crystal, for example would send an email if a deposited Pokemon had been traded with another player. The email server itself is essentially a standard POP3 and SMTP server for receiving and sending email. The email format sent follows this format roughly (keep in mind the xxxx and yyyy and zzzz parts are not exactly lengths, consider them variable).

MIME-Version: 1.0 From: xxxx@yyyy.dion.ne.jp (=?ISO-2022-JP?zzzzzzzzzzzzzzzz) To: [email_address] Subject: =?ISO-2022-JP?xxxx X-Game-title: MOBILE TRAINER X-Game-code: CGB-B9AJ-00 Content-Type: text/plain; charset=iso-2022-jp [content_of_email]

As the above makes clear, emails are sent using ISO-2022 character encodings. The recepient's email address is not checked or verified by Mobile Trainer. It will blindly hand over the mail to the SMTP server, only showing the user and error if the server reports a problem. It is unknown if there were restrictions on which email addresses the Mobile System GB would service (only other DION email for Mobile Adapter customers, or anyone anywhere?) Email can be sent and received from the same menu. A small animation appears of the player walking to a digital post office and sending mail and receiving any new mail afterwards.

Also of note: there is absolutely no encryption done and any POP or SMTP transfer. While the limited nature, obscurity, and short lifespan of the Mobile System GB network probably prevented any major security concerns from appearing, by modern standards it is a security nightmare. For example, when retrieving mail via the POP3 server, both user ID and password are transmitted in plaintext. Those two pieces of information would be enough to impersonate another user for any other Mobile Adapter compatible game.

Net de Get: Mini Game @ 100

General Information

Server Structure




Download Wrapper

Minigame Format

String Format

MBC6 Flash Operation

[Net de Get] : General Information

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 online and save them locally to Flash memory for offline play. Players earn points based on their performance in minigames. Once enough points have been accumulated, they can be exchanged for downloadable minigames.

[Net de Get] : Server Structure

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

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

[Net de Get] : h0000.cgb

After some points are earned through the base set of minigames, players unlock the "セーバ" or "Server" option from the main menu. 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 - ??? ::

[Net de Get] : RomList.cgb

After h0000.cgb is downloaded, next comes RomList.cgb. This file contains a list of all available minigames the server has to offer. It also displays how many points it costs to 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 points necessary for download (modulus 100). Should be 0x00 - 0x63 ideally. 0x01 :: Mini-game icon type. See Icon Type below for details. 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 + 6 + String Length 1 & 2 :: Unique ID for download. 8 characters max.

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.

[Net de Get] : 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:


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.

[Net de Get] : 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.

[Net de Get] : 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 :: Points required to play 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.

[Net de Get] : 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:

[Net de Get] : 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.