Hardware and Accessories

Overview

About Dan Docs

DMG and GBC

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

GBA Screen Stretch

Soul Doll Adapter

Battle Chip Gate

Multi Plust On System

Turbo File Advance

AGB-006

Virtureal Racing System

Magical Watch

Joy Carry Cartridge

Advance Movie Adapter

Music Recorder

Play-Yan

NDS

Ubisoft Thrustmaster Pedometer

HCV-1000

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

Zen Nihon GT Senshuken

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.

Credits

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

mid-kid - 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

Barcodes

[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.

It should be noted that the barcode data itself is encapsulated by ASCII control codes, where 0x02 represents the Start of Text (STX) and 0x03 represents the End of Text (ETX).

[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

Barcodes

[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

Below is a chart with barcodes verified to work with the game. Each barcode will produce a single Bardigun when scanning to hatch an egg. The barcode can also be used to give Bardigun unique attacks when scanned before a battle begins. The names of each are listed in kana as well as Romanji or English when translatable.

------------------------------------------------------------------------------------------------ Bardigun Name | Attack Name | Barcode ------------------------------------------------------------------------------------------------ Chakanan" | "High Hearing" | 4580245316402 チャカナン | ハイヒーリング | ------------------------------------------------------------------------------------------------ "Chibisshii" | "Sword" | 4900287167419 チビッシー | ソード | ------------------------------------------------------------------------------------------------ "Chibisshii" | "Eye Beam" | 4901330547479 チビッシー | めからベーム | ------------------------------------------------------------------------------------------------ "Chip" | "Lullaby" | 4983164730678 チップ | こもりうた | ------------------------------------------------------------------------------------------------ "Noise" | "Ikikaeeru" | 4900753335663 ノイヅー | イキカエール | ------------------------------------------------------------------------------------------------ "Nyaari" | "Kaenhoushaki" | 4900363432103 ニャーリー | かえんほうしゃき | ------------------------------------------------------------------------------------------------ "Ralph" | "Ikikaeeru" | 4900758340136 ラルフ | イキカエール | ------------------------------------------------------------------------------------------------ "Takora" | "Fire Bolt" | 4902370501445 タコラ | ファイアーボルト | ------------------------------------------------------------------------------------------------ "Tamappi" | "Nandemonaooru" | 4900269429252 タマッピ | ナンデモナオール | ------------------------------------------------------------------------------------------------

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

Operation

IR Communication

Capturing IR Data

Emulation

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. Contrary to many misconceptions, this feature was used in a number of 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 games like Animorphs, Aladdin had its IR features stripped.

It should be noted that at least one game that uses the HuC-3 MBC, Pocket Family GB 2, is not in fact a "GB KISS" game. Instead, it uses the GBC's built-in IR hardware. 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 what, 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

MBC1S

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. Although the first versions of Gachasta! Dino Device did not come with any peripherals, they were nonetheless compatible with both the Power Antenna and Bug Sensor. 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

Commands

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:

IF X COORDINATE AND 0x40 THEN X -= (X COORDINATE - 0x40) ELSE X += X COORDINATE IF Y COORDINATE AND 0x40 THEN Y -= (Y COORDINATE - 0x40) ELSE Y += Y COORDINATE

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 Data Stats

Soul Doll Data Obfuscation

[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 and attached items. Most importantly, these bytes determine what kind of Legend is generated from the Soul Doll.

The layout of this memory varies depending on which Legendz game is being played. Data for Legendz: Yomigaeru Shiren no Shima and Legendz: Sign of Necrom change the location of the fields. While Sign of Necrom can recognize the format of Yomigaeru Shiren no Shima, data from Sign of Nekrom is incompatible with Yomigaeru Shiren no Shima.

For Yomigaeru Shiren no Shima, EEPROM data is arranged as follows:

----------------------------------------------------------- Address | Data Description ----------------------------------------------------------- 0x302 | Legend ID 0x398 - 0x39C | Owner Name 0x3A1 - 0x3B0 | Message 0x3B1 - 0x3B9 | Legend Name 0x3D4 | Legend Level 0x3D5 - 0x3DE | Legend Stats 0x3EE | Auto Adventure Flag 0x3F0 | Attached Item Flag 0x3F1 - 0x3F2 | Attached Item Type & Quantity 0x3FE - 0x3FF | Checksum -----------------------------------------------------------

For Sign of Nekrom, EEPROM data is arranged as follows:

----------------------------------------------------------- Address | Data Description ----------------------------------------------------------- 0x302 | Legend ID 0x390 - 0x394 | Owner Name 0x3A1 - 0x3B0 | Message 0x399 - 0x3A0 | Legend Name 0x3BD | Legend Level 0x3BE - 0x3C7 | Legend Stats 0x3CC | Auto Adventure Flag 0x3CE - 0x3CF | Attached Item Type & Quantity 0x3FC | Attached Item Flag 0x3FE - 0x3FF | Checksum -----------------------------------------------------------

Byte 0x302 acts as the Legend ID. Depending on the value of this, the games will produce a different Legend. Their values are listed below:

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

1 byte represents the so called "Training Bonus" granted to a Legend when it is reborn. This adds a certain amount of points to its various base stats, such as HP, Strength, Defense, etc. The larger the value of this byte, the greater the stat boost will be. It has a limited range of valid values (1 = Minimum, 6 = Maximum).

2 bytes represent the quantity and type of attached items for a Soul Doll. A Legend can temporarily hold onto items from the player's inventory. Only 1 type of item can be given to a Legend at a time, but its quanitity can vary (1 = Minimum, 9 = Maximum).

5 bytes are used to store the owner's name. During the Soul Doll Initialization process, the player's name is registered to the Soul Doll. The games use this to lock the Soul Doll to a particular player. If the owner name written to EEPROM doesn't match the current one from the game's save file, EEPROM must be erased and the Soul Doll reset in order to use it. Each byte in EEPROM represents one character. The exact string format is currently unknown.

16 bytes are used to store a brief message inside the Soul Doll. This message can be checked during the Reborn process on a Soul Doll that was previously initialized for a given player. Each byte in EEPROM represents one character. The exact string format is unknown.

8 bytes are used to store the Legend's name. Each byte in EEPROM represents one character. The exact string format is currently unknown.

1 byte represents the level of the Legend. Its value ranges from 1 to 99.

10 bytes represent the various stats about the player's Legend inside the Soul Doll (HP, Strength, Defense, Magic Power, Magic Defense, and Speed). The size of each value varies in terms of bits, and the same value is usually spread over multiple bytes. See the next section for more information.

1 byte represents the Auto Adventure flag. When the Legend goes on an Auto Adventure, this byte is set to a non-zero value, otherwise it is set to 0x00. For Yomigaeru Shiren no Shima, this flag is always 0x01 when set. For Sign of Nekrom, it varies depending on the type of Auto Adventure, acting as a sort of ID.

Bytes 0x3FE through 0x3FF are a 16-bit checksum the data 0x380 through 0x3FD. The checksum is computed by adding up every byte within that range. If the checksum is incorrect, both Legendz games will treat the entire Soul Doll data as invalid, which will require it to be reinitialized. After calculating the initial checksum, it must be XOR'ed with a separate 16-bit value. Yomigaeru Shiren no Shima uses 0x4832, while Sign of Nekrom uses 0x4C32. Sign of Nekrom can detect both types of checksums and uses this to determine which game last modified EEPROM data.

[Soul Doll Adapter] : Soul Doll Data Stats

Use the following psuedocode to obtain the values for each attribute of the Soul Doll's Legend. Assume that ADDRESS the specified the EEPROM address 0x3D5 (for Yomigaeru Shiren no Shima) or 0x3BE (for Sign of Nekrom).

----------------------------------------------------------- HP ----------------------------------------------------------- VAL1 = READ 16 BITS FROM (ADDRESS) VAL2 = READ 08 BITS FROM (ADDRESS + 2) HP = (VAL_1 >> 6) | ((VAL & 0x0F) << 10) ----------------------------------------------------------- STRENGTH ----------------------------------------------------------- VAL1 = READ 16 BITS FROM (ADDRESS + 2) STRENGTH = ((VAL1 << 18) >> 22) ----------------------------------------------------------- DEFENSE ----------------------------------------------------------- VAL1 = READ 16 BITS FROM (ADDRESS + 6) DEFENSE = ((VAL1 << 20) >> 22) ----------------------------------------------------------- MAGIC POWER ----------------------------------------------------------- VAL1 = READ 32 BITS FROM (ADDRESS + 2) MAGIC POWER = ((VAL1 << 8) >> 22) ----------------------------------------------------------- MAGIC DEFENSE ----------------------------------------------------------- VAL1 = READ 32 BITS FROM (ADDRESS + 6) MAGIC DEFENSE = ((VAL1 << 10) >> 22) ----------------------------------------------------------- SPEED ----------------------------------------------------------- VAL1 = READ 08 BITS FROM (ADDRESS + 6) VAL2 = READ 08 BITS FROM (ADDRESS + 5) SPEED = ((VAL1 & 0x03) << 8) | VAL2

[Soul Doll Adapter] : Soul Doll Data Obfuscation

The EEPROM data is obfuscated with a repeating 32-bit key. This makes the data somewhat inaccessible unless parsed first. The 32-bit key is 0xA8262CDB as an LSB first value. Each 32-bit value from EEPROM is simply XOR'ed by the key. Another way to unscramble EEPROM is demonstrated by the following psuedocode:

ARRAY = 0xDB, 0x2C, 0x26, 0xA8 UNSCRAMBLED VALUE = EEPROM BYTE XOR ARRAY[EEPROM ADDRESS AND 0x03]

This obfuscation only occurs on bytes 0x380 through 0x3FF. The checksum is calculated and XOR'ed by its own 16-bit value before XOR'ing this 128-byte region with the above mentioned 32-bit value.

Battle Chip Gate

General Hardware Information

Compatible Games

Protocol

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: Most of these IDs were generated artificially by testing them against the games. Entries marked with a "!" represent actual IDs directly captured from a MPOS. The artificially generated ones are, however, sufficient for the purposes of emulation or using homebrew on a second GBA to fake a connected MPOS.

PF001 :: Beetma ! 0x1780 * 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

Commands

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.

AGB-006

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.

Virtureal Racing System

General Hardware Information

Carrera Racing

VRS Protocol

LED Indicator

Multiplayer Protocol

[Virtureal Racing System] : General Hardware Information

The Virtureal Racing System, also known as the VRS, is a specialized Carrera GO!!! connection track designed to communicate with GBAs. It was introduced exclusively in European markets in 2003. Described as a "motor driver", it replaces the standard connection section for 1:43 Carrera GO!!! tracks and allows players digital control of their slot cars via the GBA. The VRS is used in conjunction with the game Carrera Power Slide, which provides the interface through the Carrera Racing mode.

[Virtureal Racing System] : Carrera Racing

The VRS lets 2 GBAs connect to the motor driver to move slot cars along the track and/or to monitor conditions of the race such as number of laps, total race duration, damage, and fuel level. Power Slide uses a dedicated software mode called "Carrera Racing" for this purpose. The first GBA acts as master and requires a Power Slide cart. The second downloads data from the first via MultiBoot. Power Slide offers several modes of "Real Racing" play through Carrera Racing:

Stop Watch is the only mode that does not use the GBA to control a slot car. Instead, the GBA is used to record lap times, and The Carrera GO!!! hand controls must be used instead. For all other modes, the GBA controls the slot car, even if hand controls are plugged in. Also note that only the first GBA is required for Carrera Racing. The second racer may use an additional GBA or (if such a GBA is absent) hand controls. If hand controls are used for the second racer, however, Power Slide only recognizes the first racer for the above 2-player modes.

When using a second GBA, the first GBA running Power Slide will send data and code via MultiBoot. Once downloaded, the second GBA will feature an near-exact copy of the Carrera Racing interface, except without the ability to select the "Real Racing" modes or set any options (this is the role of the first GBA).

[Virtureal Racing System] : VRS Protocol

All communication with the VRS uses the GBA's Multi16 mode with a baud rate of 115200bps. The first GBA acts as the Parent, while the second GBA acts as the Child 2. Even though the VRS has only two Link Cables, the entire setup behaves as if an additional GBA is connected as Child 1. This extra connection reports the status for each racer. The entire multiplayer model works as follows

Racer 1 Input Parent Race Status Child 1 Racer 2 Input Child 2 Unused Child 3

Each GBA writes to their own input, which in turn controls the speed of the slot car. The VRS is responsible for updating the racers' status which simply consists of counting laps. Because of the nature of Multi16 mode, the first GBA must continually transfer data, even if that racer is not actively sending input to their slot car, otherwise input from the second GBA would not reach the VRS. The format for input and status are described below:

------------------------------------------------- Input ------------------------------------------------- Speed Level 0 - Lane 1 | 0xFFC0 Speed Level 1 - Lane 1 | 0xFF41 Speed Level 2 - Lane 1 | 0xFF42 Speed Level 3 - Lane 1 | 0xFFC3 Speed Level 4 - Lane 1 | 0xFF44 Speed Level 5 - Lane 1 | 0xFFC5 Speed Level 6 - Lane 1 | 0xFFC6 Speed Level 7 - Lane 1 | 0xFF47 Speed Level 8 - Lane 1 | 0xFF48 Speed Level 9 - Lane 1 | 0xFFC9 Speed Level 10 - Lane 1 | 0xFFCA Speed Level 11 - Lane 1 | 0xFF4B Speed Level 12 - Lane 1 | 0xFFCC Speed Level 13 - Lane 1 | 0xFF4D Speed Level 14 - Lane 1 | 0xFF4E Speed Level 15 - Lane 1 | 0xFFCF ------------------------------------------------- Speed Level 0 - Lane 2 | 0xFF50 Speed Level 1 - Lane 2 | 0xFFD1 Speed Level 2 - Lane 2 | 0xFFD2 Speed Level 3 - Lane 2 | 0xFF53 Speed Level 4 - Lane 2 | 0xFFD4 Speed Level 5 - Lane 2 | 0xFF55 Speed Level 6 - Lane 2 | 0xFF56 Speed Level 7 - Lane 2 | 0xFFD7 Speed Level 8 - Lane 2 | 0xFFD8 Speed Level 9 - Lane 2 | 0xFF59 Speed Level 10 - Lane 2 | 0xFF5A Speed Level 11 - Lane 2 | 0xFFDB Speed Level 12 - Lane 2 | 0xFF5C Speed Level 13 - Lane 2 | 0xFFDD Speed Level 14 - Lane 2 | 0xFFDE Speed Level 15 - Lane 2 | 0xFF5F -------------------------------------------------

Slot car speeds span 16 different levels. The higher the level, the faster the car moves. The lower the level, the slower the car moves. Normally, the maximum is Level 7, however turbo boosts temporarily allow cars to reach the upper levels. Technically, any speed less than or equal to Level 3 results in the slot car not moving at all. This is used when enabling fuel levels during races. In that scenario, Power Slide keeps track of how long it has been sending commands to move the slot car and constantly decreases a virtual amount of fuel. When the software sees that there is no more virtual fuel, it forcibly limits the slot car by setting the speed to Level 3. The racer must then perform a pit stop via the software to recover virtual fuel and continue running the track.

Similar to the virtual fuel, slot cars on the VRS can simulate damage from crashes or collisions. This is entirely a feature of Power Slide's software. When damage is enabled for a race, a "crash" is registered whenever a slot car stops moving for a certain period of time. In the event of a crash, a racer would normally stop input on their GBA and move around to put the slot car back on the track. If a racer takes too much damage, the software limits the speed to Level 3. Racers must then perform a pit stop to repair the car. Unfortunately, the software registers any and all stops (outside of pit stops) as damage, even if no crash physically occurred. The VRS itself has no method to detect when a slot car has left the track, so this software solution based on human behavior works as an approximation.

Either GBA may use Lane 1 or Lane 2; this is not hardwired. Depending on the input received, the VRS will control the slot car for that lane.

------------------------------------------------- Status ------------------------------------------------- Current Lap Count - Lane 1 | Bits 0 - 2 Current Lap Count - Lane 2 | Bits 3 - 6 Not used - Set Low | Bit 7 Not used - Set High | Bits 8 - 15 -------------------------------------------------

The lap count is merely a 3-bit value of 0 through 7. Every time a slot car moves through one of the physical switches built into the VRS' two lanes, Bits 0 - 2 or Bits 3 - 6 increment. Once these either of these 3 bits overflow, they begin again at zero. Power Slide constantly monitors these value for any changes, at which point it updates the time for a finished lap. By comparing lap times and the total number of laps completed, the software can determine which racer is in first place as well.

When the VRS and GBAs are connected, Child 1 Multi16 data reads 0xFFFF when the power is off. When the power is on, Child 1 returns the status in the form 0xFF--, where Bit 7 must be low. These values can be used by software to determine whether the VRS is attached and whether or not it is active. If Child 2 Multi16 data reads 0xFFFF, this normally indicates that there is no second GBA attached.

[Virtureal Racing System] : LED Indicator

The LED built into the VRS generally signals whether or not the unit has any external power. However, while the first GBA transmits MultiBoot data to the second GBA prior to racing, the light will temporarily turn off. It will stay off until the MultiBoot process is complete, at which point it comes back on again. The LED appears to shut off whenever a large series of transfers occurs, followed by a pause (presumably of 1/16 seconds or greater), followed by another large series of transfers. Power Slide likely achieves this when calling the MultiBoot Software Interrupt, as that function in the GBA BIOS does contain a brief delay before sending more transfers. Afterwards, the LED will remain off for approximately 54 seconds. Power Slide finishes all MultiBoot transfers by that time. There does not appear to be a way to shut the LED off via software again until the power button is released.

Even when the VRS has no external power, or when external power is provided but the power button is released, serial input/output can cause the LED to come on at a lower brightness. Any time the GBA sets SO as LOW the LED goes dark, while any time the GBA sets SO as HIGH the LED lights up. If both GBAs set their SO values as HIGH, this causes the LED to become slightly brighter than when only one GBA sets SO as HIGH. When the power button is pressed down, the LED reaches its brightest level constantly, and all such traces of serial input/output activity are no longer observable.

[Virtureal Racing System] : Multiplayer Protocol

When using the Carrera Racing interface, any time first GBA sends a value not listed in the VRS protocol, the second GBA running the MultiBoot program is expected to eventually echo what was sent. The first GBA sends specific values in groups of three. If it receives an echo, it knows that the MultiBoot program is running and will enable 2-player functionality in the various racing modes. If no second GBA with the MultiBoot program is detected, Power Slide restricts Carrera Racing to 1-player. Even though a second racer can join in without a GBA by using the standard hand controls, Power Slide will not recognize them via software.

If the first GBA is powered off or reset, the MultiBoot program running on the second GBA does not need to be downloaded again. As long as the second GBA continues running, it will successfully echo any bytes to establish contact.

Magical Watch

General Hardware Information

Communication Protocol - Overview

Communication Protocol - Start Signal

Communication Protocol - Data & Command Upload

Communication Protocol - Data Download

Communication Protocol - Stop Signal

[Magical Watch] : General Hardware Information

The Magical Watch is a digital watch bundled with the GBA game Wagamama☆Fairy: Mirumo de Pon! Hachinin no Toki no Yousei. It was released on December 11, 2003 by Konami. This device allowed users to play various minigames and activities on the watch itself through the use of its LCD screen and buttons. A Link Cable port lets players transfer data to the game and unlock special items.

[Magical Watch] : Communication Protocol - Overview

The GBA sets its serial port to General Purpose mode to send or receive data with the Magical Watch. Its protocol consists of four distinct phases as listed below:

Because the Magical Watch uses unknown components, a chip-on-board design encapsulated by a glob top, timing information for most transfers is also documented below. These are rough approximations based on how Mirumo de Pon! Hachinin no Toki no Yousei's code communicates with the Magical Watch.

[Magical Watch] : Communication Protocol - Start Signal

The Start Signal involves writing 2 specific values to the RCNT register over a set number of iterations. The value 0x80B0 is written 100 times; following that, the value 0x8000 is written 100 times as well. Mirumo de Pon! Hachinin no Toki no Yousei enters into a fairly small loop and cycles through these writes relatively quickly.

When sending a Start Signal, the transition between these two values may alert the Magical Watch that the GBA is ready to begin communications. It may not be necessary to perform exactly 100 writes of each value, but rather the Magical Watch may simply need sufficient time to detect when the SC, SD, and SO lines switch from HIGH to LOW. The 0x80B0 and 0x8000 writes both last ~0.77ms. Between the end of the Start Signal and the beginning of the Command Upload, there is a ~15.87ms gap before the GBA resumes communication.

Before Mirumo de Pon! Hachinin no Toki no Yousei issues a Start Signal, it temporarily switches to the serial port to UART mode for ~0.77ms. This, however, is not necessary to begin communicating with the Magical Watch. At the end of the Start Signal, before transitioning to the Command Upload phase, the game also temporarily switches to Normal 8-bit mode, however this too is likely irrelevant to properly link with the Magical Watch. In either case, no data is transferred when the game enters UART or Normal 8-bit mode.

Ultimately the Start Signal looks something like this:

----------------------------------------------------------- Description | Duration in ms ----------------------------------------------------------- UART Switch | 0.77ms General Purpose: RCNT = 0x80B0 | 0.77ms General Purpose: RCNT = 0x8000 | 0.77ms -----------------------------------------------------------

[Magical Watch] : Communication Protocol - Data & Command Upload

The GBA sends 80 bytes serially to the Magical Watch. The first portion stores a copy of the "Fairy Picturebook" data that the user has unlocked in the main game. The second portion instructs the device to return data that is later used to generate in-game items. During this phase, the GBA sets the direction of SC and SD as Output. SC is constantly set HIGH, and SD changes to represent the current bit being sent. Essentially, the GBA will write 0x8033 to RCNT to transmit a value of "1" and 0x8031 to transmit a value of "0". Bytes are sent MSB first.

Before sending any bytes, a brief sync signal must be issued. After the first byte is sent, additional syncs must be sent in between each subsequent byte. After the last byte, the GBA sends a final sync signal. Typical transmissions look like this:

----------------------------------------------------------- Value | Delay in ms | Description ----------------------------------------------------------- 0x8031 | N/A | Initial Command Sync 0x8033 | 0.65ms | Sets SD LOW, HIGH, LOW, HIGH, LOW 0x8031 | 6.50ms | 0x8033 | 1.30ms | 0x8031 | 0.65ms | ----------------------------------------------------------- xxxx | 0.65ms | Bit 7 of Byte to Send xxxx | 0.65ms | Bit 6 of Byte to Send xxxx | 0.65ms | Bit 5 of Byte to Send xxxx | 0.65ms | Bit 4 of Byte to Send xxxx | 0.65ms | Bit 3 of Byte to Send xxxx | 0.65ms | Bit 2 of Byte to Send xxxx | 0.65ms | Bit 1 of Byte to Send xxxx | 0.65ms | Bit 0 of Byte to Send ----------------------------------------------------------- 0x8031 | 0.65ms | Recurring Sync 0x8033 | 1.30ms | Sets SD LOW, HIGH, LOW 0x8031 | 0.65ms | ----------------------------------------------------------- xxxx | 0.65ms | Bit 7 of Next Byte to Send xxxx | 0.65ms | Bit 6 of Next Byte to Send xxxx | 0.65ms | Bit 5 of Next Byte to Send xxxx | 0.65ms | Bit 4 of Next Byte to Send xxxx | 0.65ms | Bit 3 of Next Byte to Send xxxx | 0.65ms | Bit 2 of Next Byte to Send xxxx | 0.65ms | Bit 1 of Next Byte to Send xxxx | 0.65ms | Bit 0 of Next Byte to Send ----------------------------------------------------------- ... Repeat Recurring Sync ... ----------------------------------------------------------- ... Send Next Byte ... ----------------------------------------------------------- 0x8033 | 0.65ms | Final Command Sync 0x8033 | 0.65ms | 0x8033 | 0.65ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | 0x8033 | 0.65ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | 0x8031 | 0.65ms | -----------------------------------------------------------

The first 8 bytes sent to the Magical Watch represent any entries in the "Fairy Picturebook" obtained by the player. These are gained by interacting with various characters throughout the game, and some are granted automatically as part of the story's progression. Each entry occupies a single bit, with "0" meaning the player has not met that character, and "1" meaning they have. There are a total of 60 entries, so only 7.5 bytes are actually used. The data here corresponds 1:1 to the player's "Fairy Picturebook" when reading the bytes LSB first from Byte 0 to Byte 7.

The other 72 bytes appear to be commands that tell the Magical Watch to retrieve data for several special items. There are evidently 6 commands issued during this time, each consisting of 12 bytes. The exact significance of each individual byte or command is currently unknown.

----------------------------------------------------------- Commands 0 - 5 ----------------------------------------------------------- 0x58 0x40 0x88 0x48 0x70 0x40 0x50 0x00 0x00 0x01 0x00 0x01 0x58 0x40 0x88 0x48 0x70 0x40 0x50 0x00 0x19 0x06 0x19 0x06 0x58 0x40 0x88 0x48 0x70 0x40 0x50 0x00 0x19 0x06 0x19 0x06 0x58 0x40 0x88 0x48 0x70 0x40 0x50 0x00 0x19 0x06 0x19 0x06 0x58 0x40 0x88 0x48 0x70 0x40 0x50 0x00 0x19 0x06 0x19 0x06 0x58 0x40 0x88 0x48 0x70 0x40 0x50 0x00 0x19 0x06 0x19 0x06 -----------------------------------------------------------

[Magical Watch] : Communication Protocol - Data Transfer

After sending the commands mentioned above, the GBA will receive a total of 9 bytes from the Magical Watch. Mirumo de Pon! Hachinin no Toki no Yousei waits ~1.95ms after the Final Sync has completed. From there, bytes can be read serially, MSB first. The SI line is used to indicate the individual bits as well as a Stop Bit. The game follows this convention when reading the RCNT register for each byte:

----------------------------------------------------------- Read # | Delay in ms | Description ----------------------------------------------------------- Read 0 | 1.95ms | Stop Bit Read 1 | 1.95ms | Receive Bit 7 Read 2 | 1.95ms | Receive Bit 6 Read 3 | 1.95ms | Receive Bit 5 Read 4 | 1.95ms | Receive Bit 4 Read 5 | 1.95ms | Receive Bit 3 Read 6 | 1.95ms | Receive Bit 2 Read 7 | 1.95ms | Receive Bit 1 Read 8 | 1.95ms | Receive Bit 0 -----------------------------------------------------------

The received bytes can then be converted into the following in-game items depending on their values.

----------------------------------------------------------- Byte 0 | Small Drop of Time (0 - 99) Byte 1 | Large Drop of Time (0 - 99) Byte 2 | Lucky Jewel (0 - 99) Byte 3 | Add 15 seconds Byte 4 | Add 1 hour + 4 minutes Byte 5 | Add 2 hours + 30 Minutes Byte 6 | Screw of Time (0 - 99) Byte 7 | N/A Byte 8 | 8-bit checksum -----------------------------------------------------------

For Bytes 0, 1, 2, and 6, the game only permits players to have 99 items. Even if the Magical Watch sends values above 0x63, the game will only recognize 99 as the absolute maximum.

When transferring Time to the game, Bytes 3, 4, and 5 are used as a total sum. The absolute maximum value the game recognizes is 2 hours and 30 minutes. Byte 3 is used to add individual minutes, essentially by dividing its raw binary value by 4 (e.g. 0x8 = add 2 minutes). Byte 4 adds 1 hour and 4 minutes multiplied by its raw binary value (e.g. 0x2 = add 2 hours and 8 minutes). Byte 5 is used to set Time to its maximum value with any non-zero value.

The checksum is simply the sum of Bytes 0 - 7. Mirumo de Pon! Hachinin no Toki no Yousei validates this upon receiving all 9 bytes from the Magical Watch.

After all 9 bytes have been read, a sync signal is sent from the GBA:

----------------------------------------------------------- Value | Delay in ms | Description ----------------------------------------------------------- 0x8031 | 1.95ms | Data Transfer Sync 0x8031 | 6.50ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | 0x8031 | 0.65ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | 0x8033 | 0.65ms | 0x8031 | 0.65ms | -----------------------------------------------------------

[Magical Watch] : Communication Protocol - Stop Signal

Once the Data Transfer is complete, a brief delay (slightly greater than 5ms) occurs before sending the Stop Signal. Like the Start Signal, Mirumo de Pon! Hachinin no Toki no Yousei switches the serial port into UART mode for ~0.77ms. Afterwards, it re-enters General Purpose Mode for ~0.77ms, writing the value 0x8031 to RCNT 100 times. Again, it switches to UART mode for ~0.77ms. Just like the Start Signal, no data is actually transferred when the game switches to UART mode. Finally, it re-enters General Purpose mode, writing the value 0x80B0 to RCNT 100 times, and then writing the value 0x8000 to RCNT 100 times, with each duration lasting ~0.77ms.

Ultimately, the Stop Signal looks something like this:

----------------------------------------------------------- Description | Duration in ms ----------------------------------------------------------- UART Switch | 0.77ms General Purpose: RCNT = 0x8031 | 0.77ms UART Switch | 0.77ms General Purpose: RCNT = 0x80B0 | 0.77ms General Purpose: RCNT = 0x8000 | 0.77ms -----------------------------------------------------------

Joy Carry Cartridge

General Hardware Information

GameCube Communication

ROM Mapping

Flash Commands

Status Register

[Joy Carry Cartridge] : General Hardware Information

The Joy Carry Cartridge is a special Game Boy Advance cartridge that came bundled with the GameCube title Hikaru no Go 3. Released in Japan on March 20, 2003, it allowed players to rewrite most of the contents on the cartridge, working as an officially licensed flashcart of sorts. The underlying hardware is referred to as Nintendo's Debugging and Communication System, also known as DACS, and it was the only recorded instance where this technology was sold to the public. Joy Carry was the name of the GBA-to-GameCube functionality in Japan, often associated with temporary download. The Joy Carry Cartridge aimed to make large amounts of transferred data persistent.

[Joy Carry Cartridge] : GameCube Communication

Hikaru no Go 3 gives players the choice of sending two specific pieces of software to the Game Boy Advance. The first Igo Mondaishuu (囲碁問題集) consists of 200 individual Go-based challenges. Igo Mondaishuu is divided into 4 separate sections of 50 problems. Only 1 section at a time may be downloaded to the Joy Carry Cartridge. As players solve each Go question, their progress is saved with the results ("O" = Passed, "-" = Attempted, "X" = Failed). The second software Keitai Magnet Goban (携帯マグネット碁盤) is intended to act as a virtual, portable Go board. It lets players link up with other GBAs for 1v1 or 2v2 Go matches. It saves the results of recent matches along with various statistics. The software will also display the player's name, rank, win/loss counts, and their ID generated by Hikaru no Go 3 on GameCube.

When transferring data from the GameCube to the GBA, the handheld must be booted with the Joy Carry Cartridge inserted. Players must hold down both the START and SELECT buttons to force the BIOS to enter MultiBoot mode and wait for data via JoyBus communications. Initially, a small program is loaded to manage downloading data from the GameCube and overwriting the previous contents of the Joy Carry Cartridge. This program helpfully displays a progress bar, as does the GameCube's screen. Due to the amount of data sent and the time it takes to issue flash commands, the process takes several minutes. Once finished, the GBA may be turned off or reset and the Joy Carry Cartridge will boot its newly written software.

[Joy Carry Cartridge] : ROM Mapping

The data stored on the Joy Carry Cartridge's flash memory is mapped to the last 1MB of the GBA's ROM address space, from 0x9F00000 to 0x9FFFFFF. In order to properly start the game, however, an 8KB boot sector is mapped from 0x9FFC000 to 0x8000000. The ~31MB gap inbetween these two sections should read as zero. This unique mapping prevents most commercial games from simply being copied onto the Joy Carry Cartridge and treating it like a normal flashcart, as portions of code would need to be adapted to handle having data in the upper region of ROM address space. Additionally, the limited size of the Joy Carry Cartridge further complicates matters.

The last 8KB section of the Joy Carry Cartridge, located at 0x9FFE000 can be used to ID the cartridge. This data is not known to be rewritable, making it a reliable method of determining whether or not hardware is a Joy Carry Cartridge or not. Thanks to this, however, the full capacity of the Joy Carry Cartridge is only around 1016KB.

[Joy Carry Cartridge] : Flash Commands

The Joy Carry Cartridge accepts standard flash commands for manipulating data. The following commands have been verified to work on the LH28F800BLE:

----------------------------------------------------------- Command Byte | Description ----------------------------------------------------------- 0x10 | Write Data 0x20 | Block Erase 0x40 | Write Data 0x60 | Set Block-lock Bit / Clear Block-lock bit 0x50 | Clear Status Register 0x70 | Read Status Register 0x90 | Read Flash ID Codes / Enter ID Mode 0xF0 | Terminate ID Mode 0xFF | Read Data / Reset -----------------------------------------------------------

Operations appear to work based on 8KB sectors or blocks. Depending on the address where certain commands are issued (such as the Set Block-lock Bit command or Block Erase command), it will have an effect on that specific block only. Note that these commands are all sent to mirrored addresses, specifically Wait State 2 (0xC000000 - 0xDFFFFFF).

Reading the Flash ID codes involves the following process. Take note which reads/writes are 16-bit and 32-bit:

----------------------------------------------------------- WRITE-16 0x00AA to 0xDFE0AAA WRITE-16 0x0055 to 0xDFE0554 WRITE-16 0x0090 to 0xDFE0AAA //Enter ID Mode WRITE-16 0x00F0 to 0xDFE0000 //Terminate ID Mode WRITE-16 0x0055 to 0xDFE0554 WRITE-16 0x00AA to 0xDFE0AAA WRITE-16 0x00E0 to 0xDFE0554 //??? WRITE-16 0x0055 to 0xDFE0554 WRITE-16 0x00AA to 0xDFE0AAA WRITE-16 0x00E0 to 0xDFE0554 //??? READ-32 FROM 0xDF00000 //Read 16-bit Manufacture code + 16-bit Lock Bit data WRITE-16 0x00FF to 0xDFE0AAA //Reset, also exits ID Mode -----------------------------------------------------------

Other commands don't appear to rely on writing to the 0x----554 addresses. Instead, they're issued as follows:

----------------------------------------------------------- WRITE-16 COMMAND to 0xDFE0AAA or WRITE-16 COMMAND to 0xDF----- //Issue command for specific 8KB block ...then for any parameters... WRITE-16 PARAMETER to 0xDFE0AAA or WRITE-16 PARAMETER to 0xDF----- //Issues command parameters for specific 8KB block -----------------------------------------------------------

The above information is the bare minimum necesary for operating the Joy Carry Cartridge via the Game Boy Advance or GameCube. For more detailed information beyond the scope of this document, refer to other similar Sharp flash components with available datasheets such as the LH28F800BJE.

[Joy Carry Cartridge] : Status Register

The Status Register monitors the state of the flash controller. It works on a per-block level, typically reporting on the write or protection status of that block. While the LH28F800BLE should more or less resemble similar controllers, only the following status bits have been verified:

----------------------------------------------------------- Bit | Function ----------------------------------------------------------- 0 | 1 | Device Protection Status, 0 = Unlocked, 1 = Locked 2 | 3 | 4 | 5 | 6 | 7 | Write Status, 0 = Busy, 1 = Ready -----------------------------------------------------------

When reading from any 0x----AAA address, it appears to return the Status Register for that block (e.g. if the program needs to determine if a specific block's Lock Bit is set). Otherwise, reading any other address will return data from flash memory or zeroes if the area is outside the mapped 1MB ROM.

It should be noted that the software often issues an unknown parameter (0x77) to the Set Lock Bit command. It is not well understood what this does exactly or how it affects the Status Register.

Also regarding the Status Register, both Igo Mondaishuu and Keitai Magnet Goban check it to assess whether the flash controller responds in a timely fashion. On boot, the software are particularly concerned with the Write Status and will abort initial flash operations such as verifying save data. Failing this part will not stop the programs from attempting to write data to flash memory later on, however. For the rest of flash operations, the programs generally examine whether a block is locked or unlocked. If a block is locked, they will abort writing any new save data.

Advance Movie Adapter

General Hardware Information

Cartridge Mapping

Adapter I/O Registers

AM_BLK_STAT

Commands

Command Usage

Read Pointer

File System And Hierarchy

00.AM3

Error Handling

List of AM3 Cards and Products

[Advance Movie Adapter] : General Hardware Information

The Advance Movie Adapter is a specialized Game Boy Advance cartridge capable of reading SmartMedia cards. Released on November 20, 2003, the adapter and its software were designed for audio/video playback. SmartMedia cards with prewritten data could be inserted, and the internal firmware would read, decrypt, decode, and finally play the media.

[Advance Movie Adapter] : Cartridge Mapping

Unlike many other GBA cartridges, the Advance Movie Adapter has an unusual method of mapping cartridge data. Only 2KB are addressable at any given time. The lower 1KB (0x8000000 - 0x80003FF) contains data pulled from either the firmware or the SmartMedia card. The upper 1KB (0x8000400 - 0x80007FF) contains memory-mapped I/O registers used to control what data is accessible from the lower half. Data is "swapped" or "banked" dynamically into the lower 1KB in a manner similar to the old memory bank controllers found in DMG/GBC cartridges.

These 2KB sections of data and I/O registers are mirrored endlessly across the 32MB of addresses the GBA reserves for the cartridge. Within the 1KB region reserved for the adapter's I/O registers, the registers are mirrored every 64 bytes.

[Advance Movie Adapter] : Adapter I/O Registers

The vast majority of the Advance Movie Adapter's function is to read data from the SmartMedia card. As such, it dedicates a number of memory-mapped I/O registers to control this process. Although the registers are mirrored across many different addresses, the firmware uses only one specific mirror. For simplicity, only those addresses are noted in this document.

---------------------------------------------------------------------------------------------------------------------- Data Block Control ---------------------------------------------------------------------------------------------------------------------- AM_BLK_ADDR (R/w) 0x08010400 32-bit Address where data block will be copied AM_BLK_SIZE (R/W) 0x08010408 32-bit Size of block to copy to AM_BLK_ADDR AM_BLK_STAT (R/W) 0x08010420 16-bit Controls block operations / Reports operation status ----------------------------------------------------------------------------------------------------------------------

AM_BLK_ADDR determines where any data (from either the firmware or the SmartMedia card) will be mapped to. This is always 0x8000000 as far as the firmware is concerned.

AM_BLK_SIZE determines the size of data to read from the firmware. As the Advance Movie Adapter only maps in a maximum of 1KB for data blocks, this value is never greater than 0x400 as far as the firmware is concerned. Note that setting the size of data for SmartMedia card reads is a separate register.

AM_BLK_STAT controls the majority of operations on the Advance Movie Adapter. By writing to the register and setting certain bits, it starts the mapping process, switches between firmware and SmartMedia card, and makes the 128-bit DES key readable. It also reserves several bits that report on the status of current operations. See the next section for further details.

---------------------------------------------------------------------------------------------------------------------- SmartMedia Control ---------------------------------------------------------------------------------------------------------------------- AM_SMC_OFFS (R/W) 0x08010404 32-bit Move data read pointer by signed offset AM_SMC_SIZE (R/W) 0x0801040A 16-bit Size of data block to copy from SmartMedia card AM_SMC_FILE (R/W) 0x0801040C 16-bit Sets current file to read from the FAT on the SmartMedia card AM_SMC_EOF (R) 0x0801040E 16-bit Remaining bytes from current read pointer to End-Of-File ----------------------------------------------------------------------------------------------------------------------

AM_SMC_OFFS adjusts the current read pointer by a signed (2's complement) 32-bit integer, making it possible to shift it forwards or backwards. This is used when a select portion of data or data at a specific location must be read. The read pointer does have some quirks, as detailed in a following section.

AM_SMC_SIZE determines the size of data to read from the SmartMedia card. As the Advance Movie Adapter only maps in a maximum of 1KB for data blocks, this value is never greater than 0x400 as far as the firmware is concerned. Note that setting the size of data for firmware reads is a separate register.

AM_SMC_FILE selects the current file to begin reading data from. Below in further section, a thorough explanation of the AM3 file hierarchy is provided.

AM_SMC_EOF returns the remaining bytes from the current read pointer until the current End-Of-File is reached. This value normally reports the same 16-bit value as AM_SMC_SIZE when at least that many bytes remain between the read pointer and EOF. If the read pointer advances after mapping in new data, and the distance between the read pointer and the EOF is less than AM_SMC_SIZE, AM_SMC_EOF will report the smaller value. Note that AM_SMC_EOF can also change when simply switching to a new file (by writing to AM_SMC_FILE) that is smaller than AM_SMC_SIZE.

---------------------------------------------------------------------------------------------------------------------- Misc ---------------------------------------------------------------------------------------------------------------------- AM_FILE_SIZE (R) 0x08010410 32-bit Current file size according to FAT AM_SMID (R) 0x08010410 128-bit 16-byte SmartMedia ID used for copy-protection ----------------------------------------------------------------------------------------------------------------------

AM_FILE_SIZE returns the current file size as determined by the FAT of the SmartMedia card. Note that this register overlaps with AM_SMID. To switch, the CPU must write the value 0x05 to AM_BLK_STAT.

AM_SMID returns the 128-bit (16-byte) SmartMedia ID (SMID) that the firmware verifies for copy-protection purposes. This ID is unique to every SmartMedia cards and is embedded in a region not normally accessible by standard card readers. When no SmartMedia card is inserted in the adapter, these bytes return zero. Note that this register partially overlaps with AM_FILE_SIZE. To switch, the CPU must write the value 0x03 to AM_BLK_STAT.

To properly access any of the I/O registers, the PHI terminal output should be set to 16.78MHz. On that note, the amount of cycles spent in various waitstates does not appear to affect the overall operation of the adapter. However, slower access, if significant, could potentially degrade the firmware's video playback functions. The firmware should handle a small amount slower access without issue. For example, on the DS Lite, there is a brief pause during the initial setup (before the AM3 logo appears) with a small loading icon. This screen is not shown on an original Game Boy Advance due to apparent timing differences.

[Advance Movie Adapter] : AM_BLK_STAT

This I/O register is heavily used by the adapter and is central to its operation. It acts as a way for the CPU to send commands to the adapter as well as determine the status of firmware or SmartMedia card mapping. Its various bits work as follows:

----------------------------------------------------------- Bit 0 (R/W) Execute Operation Bit 1-2 (R/W) Operation Type Bit 3 (R/W) Internal Operation/External Operation ... Bit 8 (R) EOF Reached/Passed Flag ... Bit 14 (R) I/O Registers Ready Flag -----------------------------------------------------------

Whenever AM_BLK_STAT is written, firmware waits indefinitely to validate that the register holds the new value. Every command issued to the adapter must set Bit 0 to "1" to take effect. Afterwards, it waits until Bit 0 returns to "0" to signal the end of the operation. After every operation, the lower 8-bits of AM_BLK_STAT will always read as zero, however, depending on the current status of the adapter, the upper read-only 8-bits may be set.

Operation Type describes 4 fundamental operations available:

----------------------------------------------------------- Value | Operation Description ----------------------------------------------------------- 0 | Read Block 1 | Write I/O Register 2 | Set File Size Mode 3 | Set SMID Mode -----------------------------------------------------------

The most common operation is "Read Block" which simply copies a data block of a set size from either firmware or the SmartMedia card.

Writing to an I/O register is exactly that. AM_BLK_STAT needs to signal to the adapter that the CPU will update one of its I/O registers.

Set File Size Mode and Set SMID Mode refer to the values held in AM_FILE_SIZE and AM_SMID. Since these registers have overlapping addresses, AM_BLK_STAT controls which mode the adapter will use, and which values to return when reading these memory locations. Once the SMID is read, there is usually no need to return to this mode.

These operations can be further divided as being "internal" or "external". The first deals with data that resides on the Advance Movie Adapter itself, such as reading firmware or writing to I/O registers. The second deals with data residing on the SmartMedia card, such as the files themselves, file sizes, and SMID. A value of "1" chooses internal operations, while a value of "0" chooses external operations. In practice, however, only a few limited values are ever written to AM_BLK_STAT. These can then be seen as single-byte "commands".

----------------------------------------------------------- Command | Description ----------------------------------------------------------- 0x01 | Read SmartMedia Card Data Block 0x03 | Set SMID Mode 0x05 | Set File Size Mode & Update File Size 0x09 | Read Firmware Data Block 0x0B | Write I/O Register -----------------------------------------------------------

When performing any of these commands, it is recommended to disable interrupts. Any non-zero writes to AM_BLK_STAT will trigger a GamePak IRQ once the value of AM_BLK_STAT is updated. Servicing other interrupts may delay the progam from determining when exactly an operation has finished when AM_BLK_STAT's Bit 0 reads zero. For AM3 cards, this timing is critical to deliver smooth audio and video playback, so interrupts are disabled frequently in the firmware while it waits in several tight loops.

[Advance Movie Adapter] : Commands

Command 0x01 - Read SmartMedia Card Data Block

Data Source: File Specified By AM_SMC_FILE + Current Read Pointer + AM_SMC_OFFS

Data Destination: AM_BLK_ADDR

Data Size: AM_SMC_SIZE

This command reads a fixed amount of bytes as specified by AM_SMC_SIZE from the current file. The exact position within the file is the current read pointer plus the offsets specified by AM_SMC_OFFS. For further information on this command's various behaviors, see the next section regarding the read pointer.

Command 0x03 - Set SMID Mode

After issuing this command, the 16 bytes beginning at AM_SMID (0x08010410 - 0x0801041F) will return the 128-bit SmartMedia ID whenever read.

Command 0x05 - Set File Size Mode

After issuing this command, the 4 bytes at AM_FILE_SIZE (0x08010410 - 0x08010413) will return the current file size. These values are pulled from the File Allocation Table written to the SmartMedia card. Most importantly, when switching to a new file by writing to AM_SMC_FILE, this commands updates the current file size the CPU will read. When a new file is chosen, AM_SMC_FILE does not update automatically. That is to say, the old value will be read unless the Set File Size Mode command is called.

Command 0x09 - Read Firmware Data Block

Data Source: Current Read Pointer

Data Destination: AM_BLK_ADDR

Data Size: AM_BLK_SIZE

This command reads a fixed amount of bytes as specified by AM_BLK_SIZE from the Advance Movie Adapter's firmware. Unlike reading from SmartMedia cards, there are no offsets. Instead, only the read pointer is used. For further information on this command's various behaviors, see the next section regarding the read pointer.

Command 0x0B - Write I/O Register

Before writing to any of the Advance Movie Adapter's I/O registers, the CPU must send this command. Once the adapter is ready for the CPU to write to its I/O registers, Bit 14 of AM_BLK_STAT will change to "1" and then back to "0". After both Bit 14 and Bit 0 are clear, the CPU can then write to a given I/O register. The firmware issues this command every time it writes to an I/O register, even if it needs to write to multiple registers.

[Advance Movie Adapter] : Command Usage

Below are psuedo-code samples explaining how to use the adapter's various commands.

----------------------------------------------------------- Writing to Adapter I/O Registers: ----------------------------------------------------------- WRITE_IO(AM_IO_REG, VALUE): IME = 0 [AM_BLK_STAT] = 0x0B WHILE [AM_BLK_STAT] NOT EQUAL TO 0x0B READ [AM_BLK_STAT] AGAIN WHILE [AM_BLK_STAT].BIT14 EQUALS 0 READ [AM_BLK_STAT] AGAIN [AM_IO_REG] = VALUE WHILE [AM_BLK_STAT].BIT0 EQUALS 1 READ [AM_BLK_STAT] AGAIN IME = 1 ----------------------------------------------------------- Read Firmware ----------------------------------------------------------- WRITE_IO(AM_BLK_ADDR, 0x8000000) WRITE_IO(AM_BLK_SIZE, 0x400) IME = 0 WHILE [AM_BLK_STAT].BIT8 EQUALS ZERO [AM_BLK_STAT] = 0x09 WHILE [AM_BLK_STAT] NOT EQUAL TO 0x09 READ [AM_BLK_STAT] AGAIN COPY DATA @ 0x8000000 TO RAM - 0x400 BYTES TOTAL INCREMENT RAM POINTER BY 0x400 IME = 1 ----------------------------------------------------------- Read SmartMedia Card ----------------------------------------------------------- WRITE_IO(AM_BLK_ADDR, 0x8000000) //Only if this has not been done before WRITE_IO(AM_BLK_SIZE, 0x400) //Only if this has not been done before WRITE_IO(AM_SMC_OFFS, 0x8000000) WRITE_IO(AM_SMC_SIZE, 0x400) WRITE_IO(AM_SMC_FILE, INDEX_GOES_HERE) IME = 0 WHILE [AM_BLK_STAT].BIT8 EQUALS ZERO [AM_BLK_STAT] = 0x01 WHILE [AM_BLK_STAT] != 0x01 READ [AM_BLK_STAT] AGAIN COPY DATA @ 0x8000000 TO RAM - COPY NUMBER OF BYTES IN AM_SMC_EOF INCREMENT RAM POINTER BY NUMBER OF BYTES IN AM_SMC_EOF IME = 1 ----------------------------------------------------------- Read Current File Size ----------------------------------------------------------- [AM_BLK_STAT] = 0x05 WHILE [AM_BLK_STAT] NOT EQUAL TO 0x05 READ [AM_BLK_STAT] AGAIN CURRENT_FILE_SIZE = [AM_FILE_SIZE] ----------------------------------------------------------- Read SMID in 32-bit Chunks ----------------------------------------------------------- [AM_BLK_STAT] = 0x03 WHILE [AM_BLK_STAT] NOT EQUAL TO 0x03 READ [AM_BLK_STAT] AGAIN SMID_0 = [AM_SMID + 0x00] //Read 0x08010410 - 0x08010413 SMID_1 = [AM_SMID + 0x04] //Read 0x08010414 - 0x08010417 SMID_2 = [AM_SMID + 0x08] //Read 0x08010418 - 0x0801041B SMID_3 = [AM_SMID + 0x0C] //Read 0x0801041C - 0x0801041F

[Advance Movie Adapter] : Read Pointer

The read pointer is an internal and inaccessible value that indicates where within firmware or the SmartMedia card the adapter should begin reading data. As a result, it is the CPU's job to manage and track the read pointer based on the commands it issues and the I/O registers it writes. The read pointer will automatically advance whenever the 0x01 or 0x09 commands are sent. The amount incremented depends on the value held in AM_BLK_SIZE for firmware and AM_SMC_SIZE for the SmartMedia card. There are several specific edge cases that need to be accounted for.

Read Pointer Value On Boot

When turning on the Game Boy Advance, the first 1KB of firmware (the bootloader) is loaded into the address space at 0x8000000 - 0x80003FF. As such, it has already advanced by 0x400 bytes by the time the CPU begins executing instructions from that area of memory.

Reading More Than 11KB of Firmware

If the CPU should try to read more 11KB of firmware, the read pointer essentially resets itself as zero. Reading a 12th 1KB data block will simply read the 1st 1KB data block (e.g. the bootloader. Note that when reading the 11th 1KB data block of firmware, Bit 8 of AM_BLK_STAT will be set to "1" to indicate that all the data for the firmware has been read, treating the firmware as if it were another file.

Reading Data Past EOF

If the read pointer advances past a given file's EOF position, the read pointer will reset itself as zero. The next 0x01 command sent by the CPU will read data at the beginning of the file. Bit 8 of AM_BLK_STAT will be set to "1" to indicate that all the data for the file has been read.

Setting the Read Pointer Before The File

If the read pointer is adjusted with a negative offset that would technically put it before the start of the current file, the read pointer is forcibly reset to zero. Additionally, the value of AM_SMC_EOF returns zero, likely indicating an error. These two outcomes are true even when the read pointer wraps due to reading data past the EOF. That is to say, there is no wrapping of the read pointer at all when trying to move backwards.

[Advance Movie Adapter] : File System And Hierarchy

AM3's SmartMedia cards utilize the FAT12 filesystem. The adapter itself is responsible for parsing information from File Allocation Table to determine where the audio, video, and data files are located within the card. This brief overview outlines the basics of navigating through the raw bytes of a SmartMedia image.

Master Boot Record (MBR):

Located in the first 512 bytes. Holds data on how partitions are arranged on the medium. Most importantly, it points to the Volume Boot Record through the Logical Block Address (LBA) of the partitions first sector. AM3 files are stored on the first partition with Bytes Per Sector at a size of 512 bytes. Therefore the LBA can be calculated as:

Volume Boot Record Logical Block Address = (32-bit value of bytes 0x1C6 - 0x1C9) * 512

Volume Boot Record (VBR):

Also known as the Volume ID and the start of the FAT filesystem. It contains crucial information such as Bytes Per Sector, Sectors Per Cluster, Reserved Sector Count, Number of File Allocation Tables, Maximum Number of Root Directory Entries, and Sectors Per File Allocation Table. The VBR consists of 32-byte entries with these various fields. This information is used to calculate the logical addresses of the First Fat, the Root Directory, and Data Region.

First FAT Logical Block Address = VBR Logical Address + (Reserved Sector Count * Bytes Per Sector) Root Directory Logical Block Address = First FAT Logical Address + ((Number of File Allocation Tables * Sectors Per File Allocation Table) * Bytes Per Sector) Data Region Logical Block Address = Root Directory Logical Address + (Maximum Number of Root Directory Entries * 32)

Data Region:

Represents the actual data stored on the medium. At the start of this a single directory with various AM3 related files. Typically the files are ordered in the following manner

01.AM3 02.AM3 03.AM3 ... 11.AM3 INFO.AM3 00.AM3

The first set of numbered AM3 files are for audio/video playback. INFO.AM3 contains more metadata that explains which files are mapped to a given index when writing to AM_SMC_FILE. 00.AM3 contains encrypted data. It must be decrypted internally, then certain data from that file is checked against the card's SMID. The firmware fails to boot if the data from 00.AM3 and the SMID are different.

INFO.AM3 is particularly relevant for the Advance Movie Adapter. It consists of large table offset 512 bytes from the start of the file. Each 32-byte entry merely lists a file name. The first file listed is mapped to index "0" for AM_SMC_FILE; the second file listed in mapped to index "1" for AM_SMC_FILE, so on and so forth. The order that the card's files appear at the start of the Data Region thus does not reflect how the adapter ultimately arranges them internally. Files not listed in INFO.AM3 are inaccessible to the Advance Movie Adapter.

For any invalid index written to AM_SMC_FILE, the adapter will treat it as if the index points to the last file in the list. For example, if there are only a total of 11 files, writing 12 to AM_SMC_FILE will point to the 11th file. The exception to this is when the value 0xFFFF is written to AM_SMC_FILE, in which case it points to the 1st file. Under normal circumstances, the firmware only ever does the first case, typically as a shortcut to read INFO.AM3, which is generally the last file on the card. If an error occurs that interferes with the boot process, the firmware does write 0xFFFF to AM_SMC_FILE before it aborts.

The table entries in the Data Region has fields for File Attributes, Creation Date/Time, Modification Data/Time, but most of all the File Cluster and File Size. The last two bits of data describe the logical address of the file and how many bytes total the file occupies. These values are calculated automatically by the adapter and only used internally when it reads data. As far as the CPU is concerned, it only needs to feed the appropiate index to AM_SMC_FILE. The Logical Block Address of the file is thus:

Data Region Logical Address + ((File Cluster - 2) * Sectors Per Cluster * Bytes Per Sector)

It is important to note that as AM3 SmartMedia cards use FAT filesystems, they are still vulnerable to file fragmentation. Evidently, some cards were fragmented even when users first purchased them. However, as far as the Advance Movie Adapter is concerned, data can be extracted normally in continuous 1KB segments regardless of fragmentation. The adapter automatically pieces files together as a whole, so the firmware reads them without jumping across clusters.

[Advance Movie Adapter] : 00.AM3

This acts as a "lock file", a small encrypted portion of the SmartMedia card that determines whether or not the SMID is valid. The rest of the data on the SmartMedia card is apparently unencrypted. That is to say, between two separate copies of the same anime/TV show episode, the 00.AM3 file should be the only difference between them. For example, with multiple copies of Detective Conan Episode 1, the data for all files except 00.AM3 will match. When the firmware decrypts 00.AM3, a portion of the file contains its own 128-bit ID. This internal ID is compared again the external one from AM_SMID. In order to play any videos, both IDs must match.

As the firmware internally calculates what the correct ID should be, at multiple points it's possible to intercept the expected value. This can be done by simply pausing the firmware's execution through a debugger and reading select RAM locations. As long as a fake, non-zero ID is provided when reading AM_SMID, the firmware generates its own for comparison.

Although this "security" is easily defeated, at the time, it was only meant to deter casual, physical piracy, as SmartMedia card readers and writers were once common. The SmartMedia's 128-bit ID is permanently set at the time of manufacture, so even commercially available blank cards would have a different ID, meaning the AM3 files could not blindly be copied over. Digital solutions, however, such as emulators, are not bound by these constraints.

The ID can be legitimately extracted by any GBA ROM dumper or other homebrew by simply trying to read the Advance Movie Adapter as if it were a normal game cartridge. As long as an AM3 SmartMedia card is inserted, the ID will appear at the bytes 0x08010410 through 0x0801041F.

[Advance Movie Adapter] : Error Handling

The Advance Movie Adapter behaves slightly differently when the SmartMedia card cannot be read. While the first 1KB section of the firmware is loaded normally for the initial bootloader, trying to read subsequent 1KB blocks of the firmware returns a repeating 5KB section of code dedicated to error handling. This 5KB section is distinct from the regular firmware 11KB that deals with decoding and playing audio/video files. It can only be accessed when a SmartMedia card related issue occurs. Examples include a missing/improperly inserted card, an unsupported SmartMedia card type, or a damaged SmartMedia card. The error handling code helpfully displays an on-screen message in Japanese and English (with a typo) in such an event.

Additionally, when the adapter needs to handle SmartMedia card errors, Bit 8 of AM_BLK_STAT no longer serves as an EOF flag. The GBA can read an indefinite amount of repeating 1KB blocks from firmware (the 5KB section) without ever changing the status of Bit 8. Lastly, AM_SMID will return zeroes for each of its 16-bytes. These two conditions can be used for software to manually check whether or not a SmartMedia card is inside the adapter.

[Advance Movie Adapter] : List of AM3 Cards and Products

----------------------------------------------------------- Individual Cards with Video ----------------------------------------------------------- am3-00002 Detective Conan Episode 2: 社長令嬢誘拐事件 am3-00003 Detective Conan Episode 3: アイドル密室殺人事件 am3-00004 Detective Conan Episode 4: 大都会暗号マップ事件 am3-00007 Time Bokan Episode 1: 「発進!タイムボカンだペッチャ」 am3-00008 Time Bokan Episode 2: 「ギリシャのズッコケ戦争だペッチャ」 am3-00009 Time Bokan Episode 3: 「恐怖の魔女狩りだペッチャ」 am3-00010 Time Bokan Episode 4: 「へんてこ西遊記だペッチャ」 am3-00012 Detective Conan Episode 5: 新幹線大爆破事件 am3-00013 Detective Conan Episode 6: バレンタイン殺人事件 am3-00014 Detective Conan Episode 7: 月いちプレゼント脅迫事件 am3-00015 Time Bokan Episode 5: 「原始人はやさしいだペッチャ」 am3-00016 Time Bokan Episode 6: 「海賊はオウムが好きだペッチャ」 am3-00017 Time Bokan Episode 7: 「合図はひらけゴマだペッチャ」 am3-00018 Detective Conan Episode 8: 美術館オーナー殺人事件 am3-00019 Detective Conan Episode 9: 天下一夜祭殺人事件 am3-00020 Detective Conan Episode 10: プロサッカー選手脅迫事件 am3-00025 Rerere no Tensai Bakabon Vol. 1 am3-00026 Rerere no Tensai Bakabon Vol. 2 am3-00027 Detective Conan Episode 12: 歩美ちゃん誘拐殺人事件 am3-00028 Detective Conan Episode 13: 奇妙な人捜し殺人事件 am3-00029 Detective Conan Episode 14: 謎のメッセージ殺人事件 am3-00030 Detective Conan Episode 11: ピアノソナタ『月光』殺人事件 am3-00033 Pokemon Movie: 劇場版ポケットモンスター ピカチュウのなつやすみ am3-00035 Pokemon TV Anime Episode 1 am3-00046 Pokemon TV Anime Episode 2 am3-00047 Pokemon TV Anime Episode 3 am3-00067 Pokemon Movie: 劇場版ポケットモンスター ミュウツーの逆襲 完全版 am3-00069 Pokemon Movie: 劇場版ポケットモンスター ピカチュウたんけんたい am3-00085 Pokemon Movie: 劇場版ポケットモンスター ピチューとピカチュウ am3-00104 Pokemon Movie: 劇場版ポケットモンスター 幻のポケモン ルギア爆誕 am3-00131 Pokemon Movie: 劇場版ポケットモンスター 結晶塔の帝王 エンテイ am3-00137 Bakusho Mondai no Bakuten: パラパラまんが am3-00144 Crayon Shin-chan Movie: ブリブリ王国の秘宝 am3-00167 Pokemon Movie: 劇場版ポケットモンスターセレビィ~時を超えた遭遇~ ----------------------------------------------------------- Individual Cards with Video + Adapter Bundle ----------------------------------------------------------- am3-00001 Detective Conan Episode 1: ジェットコースター殺人事件 am3-00006 Time Bokan Episode 1: 「発進!タイムボカンだペッチャ」 am3-00024 Rerere no Tensai Bakabon Vol. 1 am3-00031 Pokemon Movie: 劇場版ポケットモンスター ピカチュウのなつやすみ am3-00034 Pokemon TV Anime Episode 1 am3-00065 Pokemon Original Animation: オリジナルアニメーション ピカチュウのふゆやすみ am3-00068 Pokemon Movie: 劇場版ポケットモンスター ピカチュウたんけんたい am3-00084 Pokemon Movie: 劇場版ポケットモンスター ピチューとピカチュウ am3-00090 Akubi-chan: Episode 1 (???) am3-00111 Ocha-ken: ちょこっとものがたり vol.1収録 ----------------------------------------------------------- Blank Gashapon Cards ----------------------------------------------------------- am3-00049 Pikachu Gashapon Card am3-00052 Bulbasaur Gashapon Card am3-00054 Charmander Gashapon Card am3-00056 Squirtle Gashapon Card am3-00080 Mew Gashapon Card am3-00082 Lucario Gashapon Card am3-00083 Munchlax Gashapon Card am3-00086 Akubi-chan Gashapon Card #1 am3-00088 Akubi-chan Gashapon Card #2 am3-00089 Akubi-chan Gashapon Card #3 am3-00112 Ocha-ken Gashapon Card am3-00116 Time Bokan Gashapon Card am3-00130 Kyorge Gashapon Card am3-00139 Bakusho Mondai no Bakuten Gashapon Card am3-00146 Crayon Shin-chan Gashapon Card #1 am3-00147 Crayon Shin-chan Gashapon Card #2 am3-00148 Crayon Shin-chan Gashapon Card #3 am3-00166 Manaphy Gashapon Card ------------------------------------------------------------ Blank Gashapon Cards + Adapter Bundle ------------------------------------------------------------ am3-00049 Pikachu Gashapon Card am3-00081 Lucario Gashapon Card am3-00087 Akubi-chan Gashapon Card #1

Music Recorder

General Hardware Information

I/O Registers

Command Overview

Command Usage

Index Overview & Usage

Recording File Formats

CompactFlash File & Directory Structure

[Music Recorder] : General Hardware Information

The Game Boy Advance Music Recorder is a cartridge for the Game Boy Advance capable of playing MP3s, recording audio, and performing karaoke. Designed and developed by Kemco, it was released on November 15, 2002 in Japan. A year later, Radica Games became the distributor for the product in North America and released it as the Game Boy Advance Jukebox. It marked the first time an officially licensed product could playback media of the user's choosing on the Game Boy.

[Music Recorder] : I/O Registers

All registers for the Music Recorder/Jukebox are 8-bit. They are located in the 0xB------ address range.

----------------------------------------------------------- Address | Register Name ----------------------------------------------------------- 0xB000000 | UNKNOWN 0xB020000 | UNKNOWN 0xB080000 | ZMP_INDEX_HI 0xB0A0000 | ZMP_INDEX_LO 0xB0C0000 | ZMP_DATA_HI 0xB0E0000 | ZMP_DATA_LO 0xB100000 | UNKNOWN 0xB120000 | ZMP_STATUS_RESET

ZMP_INDEX_HI and ZMP_INDEX_LO are used to set the current index. Each index points to specific data from the hardware, such as the current output volume, users settings, battery level, and the time remaining for recording or music playback. Each index is 16-bit and ZMP_INDEX_HI and ZMP_INDEX_LO form two 8-bits components of that value. ZMP_INDEX_HI contains the upper 8-bits and ZMP_INDEX_LO contains the lower 8-bits.

ZMP_DATA_HI and ZMP_DATA_LO are used to read data from or write data to the selected index. Data inside each index is also 16-bit, therefore ZMP_DATA_HI accesses the upper 8-bits and ZMP_DATA_LO accesses the lower 8-bits.

ZMP_STATUS_RESET forcibly resets the current value of cartridge's reported status. To do so, ZMP_STATUS_RESET must first be set to 0x00. After brief delay (approximately 16ms is sufficient) ZMP_STATUS_RESET must then be set to 0x01. The cartridge's status will then reset to zero after a period of about 500ms. The status is reported by the Device Status index. The upper-half of the index appears to represent the current audio playback state while lower half represent the current command issued to the cartridge.

Registers 0xB000000, 0xB020000, and 0xB100000 appear to be used by the software under certain circumstances, however, their purpose is currently unknown.

[Music Recorder] : Command Overview

The major functions of the Music Recorder/Jukebox are controlled from the software by sending a series of commands. Complex tasks such as reading the CompactFlash memory card or even deciding when to decode MP3 files are largely abstracted away from the CPU by a simple, high-level interface. To issue a command, software must follow the proceedure listed below:

  1. Write the value 0x0000 to the index 0x0081, then delay about 16ms.
  2. Write the command to the index 0x0080.
  3. Write the value 0x0000 to ZMP_STATUS_RESET, delay about 16ms, then write the value 0x0001 to ZMP_STATUS_RESET.

After writing to ZMP_STATUS_RESET, the Device Status index will then return either 0x100 in most cases, or 0x8000 when performing certain audio operations.

Each command is 8-bits in length and occupy the lower half of the Device Status index. Their values serve as enumerations to various audio and memory related functions. The software has been observed using the below commands:

----------------------------------------------------------- Command | Description ----------------------------------------------------------- 0x00 | Unknown 0x01 | Unknown 0x02 | Format CompactFlash Card 0x08 | Select Music Files 0x09 | Record Music Files 0x0A | Select Voice Memo Files 0x0B | Record Voice Memo Files 0x0C | Select Karaoke Files 0x0D | Record Karaoke Files 0x0E | Unknown 0x10 | Unknown 0x11 | Commit Title/Artist Changes 0x13 | Play Selected Audio File/Record New Audio File 0x14 | Reset Currently Selected Audio File 0x15 | Move Forward 1 Audio File 0x16 | Move Backward 1 Audio File 0x19 | Delete Current Audio File 0x20 | Stop Playing/Recording Audio File

[Music Recorder] : Command Usage

For all commands dealing with audio input/output (0x109, 0x10B, 0x10D, 0x113), refer to the section below for dealing with the actual data transfers.

Command 0x00 - Unknown

This is the first command that the software for the Music Recorder/Jukebox issues. The software also sends this command after finishing recording Music Files, indicating that it might reset or initialize functions related to the Line-In jack.

Command 0x01 - Unknown

This is the second command that the software for the Music Recorder/Jukebox issues, indicating that it is possibly used to initialize the hardware.

Command 0x02 - Format CompactFlash Card

This command will format the CompactFlash card inserted into the Music Recorder/Jukebox. Presumably, it also creates several directories used to separate music files into different categories. It also creates the AGB.INFO file in the root directory, which contains a list of all MP3 files detected by the hardware.

Once this command has been sent, the index 0x101 is used to measure the progress of the formatting process. The 16-bit value in that index represent progress in 1 / 32768 units. That is to say, 0% is 0x0000, 25% is 0x2000, 50% is 0x4000, 75% is 0x6000, and 100% is 0x8000. Various percentages can be created using any value in between 0x0000 through 0x8000. For example, ~14.22% would be 0x1234.

The software only displays whole integers, ignoring any decimals results. Surprisingly, it can measure 0% through 199%.

Command 0x08 - Select Music Files

This command is used to read information about MP3 music files or any music recordings via Line-In stored on the CompactFlash card. It is also used to select the Music/Line-In Recordings category when playing files. The command largely affects the output of indices 0x00A1 - 0x00A6 and 0x00B0 - 0x00CF for data relating to the music's filename, formal title, and artist.

Command 0x09 - Record Music

This command prepares the Music Recorder/Jukebox to record audio data from the Line-In jack. After sending this command, the software waits for the CompactFlash Status index to change to the value 0x1010 to indicate the hardware is ready. Input data from the jack is then stored as a sequentially numbered .GB3 file. The user can optionally turn on a "Silence Detection" feature that splits incoming audio data into seperate files when a period of silence appears in the stream, automatically breaking up songs from CDs or cassette players for example.

Command 0x0A - Select Voice Memo Files

This command is used to read information about Voice Memo files recorded via the built-in microphone and stored on the CompactFlash card. It is also used to select the Voice Memo category when playing files. The command largely affects the output of indices 0x00A1 - 0x00A6 for data relating to the memo's filename.

Command 0x0B - Record Voice Memo Files

This command prepares the Music Recorder/Jukebox's to record audio data from the microphone. Input data from the microphone is then stored in sequentially numbered .WAV files.

Command 0x0C - Select Karaoke Files

This command is used to read information about Karaoke Files stored on the CompactFlash card and created by playing audio from the Music Files and recording over them with the microphone. The command largely affects the output of indices 0x00A1 - 0x00A6 for data relating to the memo's filename.

Command 0x0D - Record Karaoke Files

This command prepares the Music Recorder/Jukebox to record audio data from the microphone on top of the unit and by mixing audio samples from one of the Music Files. When recording Karaoke Files, the user is prompted to first select an existing Music File.

Command 0x0E - Unknown

This command always follows the 0x01 command. The Music Recorder/Jukebox's software appears to only issue this command at the very beginning when initializing hardware.

Command 0x10 - Unknown

This command always follows a command related to file access (0x08, 0x0A, 0x0C, 0x14, 0x15, 0x16, and 0x19), indicating that it might serve as a means to update the current list of files for a given category. For commands that select a given category (0x08, 0x0A, and 0x0C), the software for the Music Recorder/Jukebox issues this command twice in a row.

Command 0x11 - Commit Title/Artist Changes

For .GB3 files recorded via the Line-In jack, the Music Recorder/Jukebox software allows users to manually input the song's full name as well as the artist. Up to 30 characters can be used for either the title or artist fields. The software writes the data to the relevant indices at 0xB0 - 0xCF and sends this command to save the data.

Command 0x13 - Play Selected Audio File/Record New Audio File

This command either plays a selected audio file or starts recording a new file, depending on which commands were previously issued. All 3 categories of audio - Music, Voice Memo, and Karaoke - use this command to actually output audio. For recording, the commands 0x09, 0x0B, and 0x0D merely prep the hardware for recording a new file, while this command actually instructs the hardware to start grabbing input audio samples. Most importantly, this command affects the value of the CompactFlash Status index, depending on which category of audio has been selected and whether the mode is playing or recording:

----------------------------------------------------------- Mode | CompactFlash Status ----------------------------------------------------------- Music Play | 0x1001 Music Record | 0x1012 Voice Memo Play | 0x1101 Voice Memo Record | 0x1112 Karaoke Play | 0x1201 Karaoke Record | 0x1211 -----------------------------------------------------------

When the song is finished playing, or when there is no space left on the CompactFlash card, the CompactFlash Status index stops matching those above values.

Command 0x14 - Reset Currently Selected Audio File

This command appears to reset any information regarding the currently selected file. The Music Recorder/Jukebox issues this command on boot and again every time the user exits the "PLAY" or "REC" menus for a given category of audio.

Command 0x15 - Move Forward 1 Audio File

Select the next audio file for playback. If the current file is the last file for a given audio category, the audio file at the beginning of the list is selected instead.

Command 0x16 - Move Backward 1 Audio File

Selects the previous audio file for playback. If the current file is the first file for a given audio category, the audio file at the end of the list is selected instead.

Command 0x19 - Delete Current Audio File

Erases all data for the current audio file from the CompactFlash card.

Command 0x20 - Stop Playing/Recording Audio File

Halts all audio input/output for a given audio file.

[Music Recorder] : Index Overview & Usage

Each index is mapped to different hardware data, giving the CPU access to information regarding music playback or recording. Below is a list of known indices and their roles:

----------------------------------------------------------- Index | R/W | Description ----------------------------------------------------------- 0x0080 | W | Write Device Status 0x0081 | R | Read Device Status 0x0082 | R | CompactFlash Status 0x0084 | R | Remaining Playback Time (Minutes) 0x0085 | R | Remaining Playback Time (Seconds) 0x0086 | R | Remaining Recording Time (Minutes) 0x0087 | R | Remaining Recording Time (Seconds) 0x0088 | R/W | Music Output Volume (0x3F = Min, 0x00 = Max) 0x008A | R/W | Voice Output Volume (0x3F = Min, 0x00 = Max) 0x008C | R/W | Equalizer Settings 0x008B | R | Recording Volume (0xFFEE = Min, 0x0004 = Max) 0x008F | R/W | Voice Cancellation Settings 0x009A | R/W | Spectrum Analyzer Update Status 0x009B | R/W | GBA Speaker Volume db (0xFFEC = Min, 0x0013 = Max) 0x009C | R | CompactFlash Detection Flag 0x009D | R | Battery Level (Min = 0x02, Max = 0x00) 0x00A0 | R | Current File Track Number 0x00AD | R | Current Number of Music Files Detected 0x00AE | R | Current Number of Voice Memo Files Detected 0x00AF | R | Current Number of Karaoke Files Detected 0x0100 | R | Audio Index Length 0x0101 | R | CompactFlash Format Progress / CompactFlash Access Progress??? 0x0102 | R | Current Karaoke File Number for Recording (Hundreds Value) 0x0103 | R | Current Karaoke File Number for Recording (Tens and Ones Values) 0x01C8 | R/W | General Configuration Settings 0x01C9 | R/W | Line-In and Microphone Input Levels

Index 0x0080 - Write Device Status

Allows the CPU to overwrite the cartridge's 16-bit STATUS value. When STATUS is set to certain values, it acts as a command.

Index 0x0081 - Read Device Status

Returns the CPU to read the cartridge's 16-bit STATUS value. Primarily used to see if the cartridge is ready to perform certain operations after issuing a command.

Index 0x0082 - CompactFlash Status

Returns the current state of the CompactFlash card. When recording music, it should read 0x1010.

Index 0x0084 - Remaining Playback Time (Minutes)

Returns the remaining minutes left when playing a music file or recording. Has a range of 0 - 99. The cartridge's hardware will automatically update the value during playback.

Index 0x0085 - Remaining Playback Time (Seconds)

Returns the remaining seconds left when playing a music file or recording. Has a range of 0 - 59. The cartridge's hardware will automatically update the value during playback.

Index 0x0086 - Remaining Recording Time (Minutes)

Returns the remaining minutes left when making any recording. Has a range of 0 - 99. The value is dependent on remaining free space of the CompactFlash card and the audio quality chosen for recording. The cartridge's hardware will automatically update the value during a recording session.

Index 0x0087 - Remaining Recording Time (Seconds)

Returns the remaining seconds left when making any recording. Has a range of 0 - 59. The value is dependent on remaining free space of the CompactFlash card and the audio quality chosen for recording. The cartridge's hardware will automatically update the value during a recording session.

Index 0x0088 - Music Output Volume

Specifies the output volume for Music and Karaoke Files through either the GBA's speakers or the cartridge's built-in headphone jack. Has a range of 0x3F - 0x00, for minimum to maximum volume. Operates separately from the Voice Output Volume index.

Index 0x008A - Voice Output Volume

Specifies the output volume for Voice Memo Files through either the GBA's speakers or the cartridge's built-in headphone jack. Has a range of 0x3F - 0x00, minimum to maximum volume. Operates separately from the Music Output Volume index, however an apparent software glitch seems to overwrite this index with the other volume index when switching audio categories.

Index 0x008C - Equalizer Settings

Specifies the type of equalizer to apply for music playback. Accepts values of 0 - 4 to select the following equalizers respectively: None, Jazz, Pop, Classical, Rock.

Index 0x008B - Recording Volume

Returns the current volume of input audio from the a recording (via Line-In or the microphone).

Index 0x008F - Voice Cancellation Settings

Toggles voice cancellation during audio playback. 0 = OFF, 1 = ON.

Index 0x009A - Spectrum Analyzer Update Status

Represents when the spectrum analyzer for Music Files needs to be updated. When this value is zero, the spectrum analyzer is disabled. For any non-zero values, the spectrum analyzer is enabled. When enabled, this index will increase in to indicate the spectrum analyzer needs to be redrawn. The update only happens when the current value of the index is greater than the previously recorded value. If this index overflows 16-bits and reads zero or if the value is frozen, the software will not update the spectrum analyzer.

As it is limited to 16-bit values, the spectrum analyzer can only be updated a certain amount of times before it overflows. The software appears to check this index a maximum of 45 times per-second during playback, so the Music Record/Jukebox can play songs up about 18:30 long without issue.

Index 0x009B - GBA Speaker Volume db

Adjusts the output volume from the GBA speakers in the range of -20 to +19 db. The index itself goes from 0xFFEC as the minimum to 0x0013 as the maximum.

Index 0x009C - CompactFlash Detection Flag

Determines whether a CompactFlash card has been inserted into the cartridge. Any non-zero value indicates the card cannot be detected.

Index 0x009D - Battery Level

Returns the current level of the AA battery inside the cartridge. Has 3 levels total with the values 0x02 representing 1 bar, 0x01 representing 2 bars, and 0x00 representing 3 bars.

Index 0x00A0 - Current File Track Number

Returns the current file track number. This is determined by how the cartridge arranges files, not by any metadata from the file itself. For Music, Voice Memos, and Karaoke files, this value is used for playback purposes. For Music and Voice Memos, this value is also used during recording. When recording Karaoke files, however, indices 0x0102 and 0x0103 are used instead.

Index 0x00AC - Current Number of Music Files Detected

Returns the current number of Music Files detected on the CompactFlash card.

Index 0x00AE - Current Number of Voice Memo Files Detected

Returns the current number of Voice Memo Files detected on the CompactFlash card.

Index 0x00AF - Current Number of Karaoke Files Detected

Returns the current number of Karaoke Files detected on the CompactFlash card.

Index 0x0100 - Audio Index Length

Determines how many indices to read from 0x102 and beyond for audio input/output data.

Index 0x0101 - CompactFlash Format Progress / CompactFlash Access Progress

Appears to indicate the progress of certain tasks involving the CompactFlash card. For formatting the card, this index represents the overall progress of that process from 0% to 100% using the range 0x0000 through 0x8000. For playing and recording audio data, it seems to determine when certain chunks are finished using a range of 0x0000 through 0x4000.

Index 0x0102 - Current Karaoke File Number for Recording (Hundreds Value)

Returns 8-bits representing the current file number (in hundreds) for recording Karaoke files. It has an unusual offset not seen in the 0x00A0 index. It can be calculated as the following:

INDEX = (((CURRENT_FILE / 100) + 0xA6) AND 0xFF)

Index 0x0103 - Current Karaoke File Number for Recording (Tens and Ones Values)

Returns 8-bits representing the current file number (in tens and ones) for recording Karaoke files. It has an unusual offset not seen in the 0x00A0 index. It can be calculated as the following:

INDEX = (((CURRENT_FILE modulo 100) + 0xA8) AND 0xFF)

Index 0x01C9 - Line-In and Microphone Input Levels

Used to calibrate volumes when recording via Line-In or the microphone. The Music Recorder/Jukebox uses an 8-bit value for this calibration. The high byte is used for microphone sensitivity while the low byte is used for Line-In volumes.

Some indices have a widespread range and serve as string data or audio input/output

----------------------------------------------------------- Index Range | R/W | Description ----------------------------------------------------------- 0x0090 - 0x0098 | R | Spectrum Analyzer Level For Bars 1 - 9 (0x00 = Min, 0x13 = Max) 0x00A1 - 0x00A6 | R/W | "8.3" DOS-style short name for music file 0x00B0 - 0x00BE | R/W | 30 character song title 0x00BF - 0x00CD | R/W | 30 character artist name 0x0102+ | R/W | Audio in/out data for recording/playing

For the string data at 0x00A1 through 0x00CD, the string is terminated by a null character (value 0x00). The strings for the Jukebox use ASCII.

When reading input/output audio data, the software accesses indices starting at 0x0102 and ends at the length specified by index 0x100. For example, if the Audio Index Length is 0x0004, the CPU reads indices 0x0102 through 0x0105 inclusive. Note that the 0x0102 and 0x0103 are also used for other purposes. Depending on the context, it may represent audio sample data or a Karaoke file number.

[Music Recorder] : Recording File Formats

The Music Recorder/Jukebox uses 2 different file formats for recording. For Voice Memos and Karaoke, the device encodes audio via IMA ADPCM into a WAV file. This format uses a 11025Hz sample rate, 16-bits per sample, and just one channel.

For Music recorded via the Line-In jack, an MP3 file is generated. Depending on the user's settings, it will have a bit-rate of 128Kbps, 96Kbps, or 64Kbps. It uses ID3v1 to store metadata at the very last 128 bytes of the file. Instead of regular MP3 files, the Music Recorder/Jukebox produces "GB3" files. However, these GB3 files appear to be normal MP3s without a header. This design prevents music from being recorded and copied to a PC and may have been intended to deter piracy.

[Music Recorder] : CompactFlash File & Directory Structure

The CompactFlash card used by the Music Recorder/Jukebox contains a FAT-12 filesystem. The hardware is capable of formatting the card as necessary without the need of a PC or any other kind of media writing device. By default, it has a volume label that reads "AGB-MP3 ". 4 folders and 1 file in the root directory are created after a formatting the card:

----------------------------------------------------------- Name | Description ----------------------------------------------------------- ADPCM | Folder - Holds all Voice Memo recordings GB3 | Folder - Holds all Music recordings MP3 | Folder - Holds all user MP3s for playback SONG | Folder - Holds all Karaoke recordings INFO.AGB | File - Contains filenames for content in the above folders

Despite its name, INFO.AGB contains no executable code intended to run on the GBA. Instead, simply has a list of all the files present for each category of audio. Additionally, it links MP3 and GB3 files to a given Karaoke recording. INFO.AGB is always 15KB exactly and is divided into the following 4 sections:

----------------------------------------------------------- Offset | Description ----------------------------------------------------------- 0x0000 | MP3 + GB3 Folder File List 0x1800 | ADPCM Folder File List 0x2400 | Song Folder File List 0x3000 | Karaoke Link Data

For sections listing filenames, MP3 files use "8.3" DOS-style short names in ASCII. WAV and GB3 files (named sequentially e.g. 0001.WAV or 0002.WAV) use an even shorter "4.3" style in ASCII. Data is stored as strings with no terminating character or padding. The strings are formatted such that they use 16-bit pairs of characters that need to be read LSB first. Do note that the MP3 and GB3 files are listed together rather than separately.

The Karaoke Link Data essentially points to the relevant MP3 or GB3 file that acted as the source of a Karaoke recording. The files here are ordered sequentially according to how the Music Recorder/Jukebox displays Karaoke files for playback. That is to say, the first file listed in INFO.AGB corresponds to the first file viewed from the Karaoke -> Play menu. This seems necessary for the Jukebox as it allows the software to pull up the 30 character song title and artist fields from the MP3 and GB3 files even though it plays the WAV Karaoke recording (which has no such metadata). If the Karaoke Link Data is corrupted or missing, the Music Recorder/Jukebox refuses to play any Karaoke recordings.

The Music Recorder/Jukebox automatically updates INFO.AGB during various operations, such as deleting files. After a reformat, the Music Recorder/Jukebox inserts a blank INFO.AGB in the root directory.

Play-Yan

General Hardware Information

Hardware Registers and I/O

Reading and Writing Firmware

Reading SD Card Data

Play-Yan Commands

Game Pak IRQs

Reading Video Frames and Video Thumbnails

Garage Games

[Play-Yan] : General Hardware Information

On February 21, 2005, Nintendo released their very own video/music player for the Game Boy Advance in the form of a unique cartridge. It was branded the Play-Yan and was designated the product code AGS-006. Sold exclusively in Japan, it handled MP3 audio files as well and MPEG-4 video files. The hardware had a dedicated SD card slot so users could access their own media.

[Play-Yan] : Hardware Registers and I/O

The Play-Yan has a large number of addresses mapped to cartridge ROM that control firmware access, issue playback commands, and retrieve information such as filenames, thumbnails, and other metadata.

---------------------------------------------------------------------------------------------------------------------- Hardware Registers | R/W | Address | Size | Description ---------------------------------------------------------------------------------------------------------------------- PY_INIT_DATA | (R) | 0x9000000 | 8-bit | Appears to be some kind of data stream. PY_STAT | (R) | 0x9000006 | 8-bit | Play-Yan Status Register. UNKNOWN REGISTER 00 | (w) | 0xB000000 | 16-bit | Unknown. Play-Yan mostly writes zero to this register. UNKNOWN REGISTER 02 | (R/W) | 0xB000002 | 16-bit | Unknown. Play-Yan mostly writes zero to this register. PY_DATA_ADDR | (R/W) | 0xB000004 | 16-bit | Address used to access Play-Yan data. PY_DATA_MODE | (R/W) | 0xB000006 | 16-bit | Determines data access mode (e.g. firmware read or firmware write). PY_DATA_PARAM | (R/W) | 0xB000010 | 16-bit | Appears to be some kind of parameter for data access. PY_FIRM_STAT | (R/W) | 0xB000012 | 16-bit | Play-Yan Firmware Status Register. ----------------------------------------------------------------------------------------------------------------------

PY_INIT_DATA is read a number of times during the initial boot sequence. It appears to be a data stream of unknown purpose.

PY_STAT acts as the overall status register for the Play-Yan. Its primary purpose appears to be checking whether or not firmware is available accessible. Before uploading any portion of firmware during the initial boot sequence, the Play-Yan checks Bit 7 of PY_STAT, which acts as a busy flag for firmware operations. If Bit 7 is set LOW, the firmware is busy, otherwise if Bit 7 is set HIGH, firmware is ready for more data.

PY_DATA_ADDR determines the address used for data operations for Play-Yan related data. It is used in conjunction with the I/O regions listed below as well as PY_DATA_MODE. Depending on the value of PY_DATA_ADDR, different contexts are used to retrieve data from these regions, e.g. it distinguishes between writing commands for the Play-Yan to execute or writing firmware data. The address is actually 32-bits. The Play-Yan must write to PY_DATA_ADDR twice, with the lower 16-bit first, and the upper 16-bit second.

PY_DATA_MODE determines what kind of data read or write the Play-Yan will perform. Used in conjection with the IO regions listed below as well as PY_DATA_ADDR.

PY_DATA_PARAM appears to be a parameter passed along to the Play-Yan that affects data access. Currently unknown exactly how it functions.

PY_FIRM_STAT appears to be another type of firmware status register. Before reading any portion of firmware, the Play-Yan checks this to make sure Bit 4 is set.

Several regions of memory on the Play-Yan are dedicated to unique purposes. Some of them overlap, and their function often depends on whether data is being written or read. The Play-Yan typically uses these for accessing large amounts of information, such as pixels representing video data, firmware, or commands.

---------------------------------------------------------------------------------------------------------------------- I/O Regions | I/O Direction | Description ---------------------------------------------------------------------------------------------------------------------- 0xB000100 - 0xB0002FF | Input | Play-Yan Command 0xB000100 - 0xB0002FF | Input | Firmware In 0xB000300 - 0xB00031F | Output | Game Pak IRQ Data 0xB000300 - 0xB0004FF | Output | Play-Yan SD Card and Internal Data 0xB000500 - 0xB0006FF | Output | Play-Yan Thumbnail and Video Data ----------------------------------------------------------------------------------------------------------------------

[Play-Yan] : Reading and Writing Firmware

To write to the Play-Yan's firmware, the following steps are performed:

----------------------------------------------------------------------- PY_DATA_PARAM = 0x0A PY_DATA_MODE = 0x68 PY_DATA_ADDR = LOW 16 BITS OF ADDRESS PY_DATA_ADDR = HIGH 16 BITS OF ADDRESS UNKNOWN REGISTER 02 = 0x00 WAIT FOR BIT 7 OF PY_STAT TO READ HIGH WRITE DATA INTO 0xB000300 THROUGH 0xB0004FF -----------------------------------------------------------------------

The address to write the firmware is internal to the Play-Yan. This is evidently any address from 0x00000 - 0xEFFFF. Only 512 bytes can be written at a time, so writing the entire firmware to the Play-Yan requires multiple iterations of the above steps.

The Play-Yan provides its own default firmware in its ROM and uploads this accordingly on every boot. This method ensures that the firmware is never corrupted by a bad update. A similar method is used for the WiiSpeak accessory on the Wii. The Play-Yan can update to a newer firmware if such a file is included on the SD card. For the original Play-Yan, the software looks for the file "playan.fup". Nintendo did release at least one firmware update as well, allowing the original Play-Yan to run MP4 files, something the later Play-Yan Micro version could do out-of-the-box.

To read from the Play-Yan's firmware, the following steps are performed:

----------------------------------------------------------------------- PY_DATA_PARAM = 0x08 PY_DATA_MODE = 0x78 PY_DATA_ADDR = LOW 16 BITS OF ADDRESS PY_DATA_ADDR = HIGH 16 BITS OF ADDRESS UNKNOWN REGISTER 02 = 0x00 PY_DATA_PARAM = 0x09 WAIT FOR BIT 4 OF PY_FIRM_STAT TO READ HIGH READ DATA FROM 0xB000300 THROUGH 0xB0004FF -----------------------------------------------------------------------

It's possible to read sequential blocks of firmware without repeating all of the above steps. The Play-Yan's ROM, for example, reads a total of 0xA00 bytes at a time. After each 0x200 bytes, only PY_FIRM_STAT needs to be checked before reading the next block. Once a total of 0xA00 bytes have been read, however, all the steps mentioned above are repeated before reading sequentially yet again.

[Play-Yan] : Reading SD Card Data

The Play-Yan is capable of reading select data from the SD Card. After the software issues a command, the Play-Yan will respond with different kinds of data, for example, a list of all files in a given directory. This means that while the Play-Yan's software does not have direct access to the card, it has a vastly simpler interface to retrieve information. The memory region used overlaps with where firmware is read from, however, the process for accessing is somewhat different. The following steps are performed:

----------------------------------------------------------------------- PY_DATA_PARAM = 0x08 PY_DATA_MODE = 0x78 PY_DATA_ADDR = 0x00 PY_DATA_ADDR = 0x00 UNKNOWN REGISTER 02 = 0x00 PY_DATA_PARAM = 0x09 WAIT FOR BIT 4 OF PY_FIRM_STAT TO READ HIGH PY_DATA_PARAM = 0x08 READ DATA FROM 0xB000300 THROUGH 0xB0004FF -----------------------------------------------------------------------

As with reading firmware, sequential 512-byte blocks can be read at a time. This is once again achieved by checking PY_FIRM_STAT. An additional step, setting PY_DATA_PARAM to 0x08, however, is necessary. The Play-Yan's software does not update the address when sequentially reading SD card data. Typically, the Play-Yan reads around 0x6600 bytes worth of data at a time and later copying that to RAM. Such a large amount of data allows it to process long lists of filenames, video frames, or vast amounts of metadata, depending on the expected response to a command.

[Play-Yan] : Play-Yan Commands

A number of commands may be issued to the Play-Yan. These allow the software to access many of the cartridge's advanced functions surrounding multimedia playback and file handling. Rather than manually processing things, the Play-Yan hands things over to its hardware and firmware through an interface. Each command typically consists of a series of 12 bytes written to the 0xB000100 - 0xB00011F address range. Some commands may contain additional parameter data beyond this, and not every command follows the same pattern of using 32-bit parameters. In general, however, the structure of a command is as follows:

----------------------------------------------------------------------- Address | Data ----------------------------------------------------------------------- 0xB000100 - 0xB000103 | Command 0xB000104 - 0xB000107 | Parameter 1 0xB000108 - 0xB00010B | Parameter 2 -----------------------------------------------------------------------

Data for most commands is usually broken into 32-bit chunks, sent LSB first. Essentially, the Play-Yan just sends a command along with 2 parameters, both of which are optional. Below is a list of known or observed commands along with their parameters:

---------------------------------------------------------------------------------------------------------------------------------------------- Command | Parameter 1 | Parameter 2 ---------------------------------------------------------------------------------------------------------------------------------------------- 0x200 - Get File Information | N/A | N/A 0x300 - Adjust Video Brightness | Brightness level, Min = 0x101, Max = 0x2C0, 0x40 increments | N/A 0x500 - Grab Video Thumbnail Data* | Width of thumbnail (60 pixels) | Height of thumbnail (40 pixels) 0x600 - Unknown | N/A | N/A 0x700 - Play Video/Grab Video Frame* | Width of video (240 pixels) | Height of video (160 pixels) 0x701 - Stop Video Playback | N/A | N/A 0x600 - Play Music File* | Music Filename | N/A 0x801 - Stop Music Playback | N/A | N/A 0x902 - Pause Music/Video Playback | N/A | N/A 0x904 - Resume Music/Video Playback | N/A | N/A 0xB00 - Adjust Volume | Volume level, Min = 0x00, Max = 0x38 | N/A 0xD00 - Adjust Bass Boost | Bass boost level, Min = 0x00, Max = 0x0F | N/A 0xD01 - Enabled/Disable Bass Boost | ON = 0x800F, OFF = 0x8F0F | N/A 0x2000 - Update File Information | N/A | N/A 0x8000 - Get SD Card Status | N/A | N/A 0x10000 - Enter Sleep Mode | N/A | N/A 0x800000 - Unknown | N/A | N/A ----------------------------------------------------------------------------------------------------------------------------------------------

*These commands send non-standard amounts of data for their parameters. See the end of this sectiond for further details on each. additional data beyond a second parameter. Overall, it sends a total of 0x218 bytes, the latter portion of which has an unknown purpose.

The following proceedure is used to issue commands:

----------------------------------------------------------------------- PY_DATA_MODE = 0x68 PY_DATA_ADDR = 0xF020 PY_DATA_ADDR = 0x000F UNKNOWN REGISTER 02 = 0x00 WAIT FOR BIT 7 OF PY_STAT TO READ HIGH WRITE DATA INTO 0xB000100 THROUGH 0xB00010B PY_DATA_PARAM = 0x0C PY_DATA_PARAM = 0x08 -----------------------------------------------------------------------

Note that the data address specified by PY_DATA_ADDR is 0xFF020. Some commands will trigger a Game Pak IRQ when the Play-Yan responds. See the section below for more details.

The 0x500 Grab Video Thumbnail Data command sends additional unknown data via Parameter 3. Altogether, 0x218 bytes are sent. Since this amount exceeds the 0xB0002FF boundary for parameter input, the last 0x18 bytes are written at the beginning of the section, starting over at 0xB000100.

The 0x600 Play Music File command uses Parameter 1 as a null-terminated string representing the filename of specific music file to play. The Play-Yan software internally keeps track of which song the user has currently highlighted, and it passes the filename's string to the hardware. The string has no fixed length, thus making this an irregular command. The Play-Yan appears to send additional unknown data after the string.

The 0x700 Play Video command uses Parameter 3 as a null-terminated string representing the filename of a specific video file to play. Like music, the Play-Yan software internally monitors which video the user has highlighted and passes the filename's string to the hardware. This string likewise has no fixed length. The Play-Yan appears to send additional unknown data after the string.

[Play-Yan] : Game Pak IRQs

The Play-Yan's hardware produces a variety of Game Pak IRQs when the software sends certain commands. Not every command will generate an IRQ, however, the ones that do are pivotal to operating the Play-Yan. For example, during the initial boot process, the Play-Yan's software waits indefinitely until several commands to respond with IRQs, without which the software essentially locks up. Each Game Pak IRQ returns data that can be read at 0xB000300 - 0xB00031F. Some commands may cause multiple IRQs to be generated as well. Use the following process to read the Game Pak IRQ data:

----------------------------------------------------------------------- PY_DATA_PARAM = 0x08 PY_DATA_MODE = 0x78 PY_DATA_ADDR = 0xF000 PY_DATA_ADDR = 0x000F UNKNOWN REGISTER 02 = 0x00 PY_DATA_PARAM = 0x09 WAIT FOR BIT 4 OF PY_FIRM_STAT TO READ HIGH PY_DATA_PARAM = 0x08 READ DATA FROM 0xB000300 THROUGH 0xB00031F -----------------------------------------------------------------------

A list of commands and their known IRQs and the IRQ data is shown below:

----------------------------------------------------------------------- Command 0x200 - Get File Information - 3 IRQs* ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80000100 or 0x80001000 Bytes 0x04 - 0x07 | 0x00 ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000200 Bytes 0x04 - 0x07 | Unknown ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000201 -----------------------------------------------------------------------

This command prompts the Play-Yan to start reading the filesystem on the SD card. It allows the software to grab a list of available files or folders for music, or video files. This apparently needs to be used in conjunction with the 0x2000 command, which is responsible for accessing multimedia files. Prior to executing the 0x2000 command, the 0x200 command seems to be reading some kind of data from the File Allocation Table, e.g. strings like "System Volume Information".

The first 32-bit value in the first IRQ differs based on context. During the initial boot section, 0x80000100 is used. It is also used when entering or exiting the video menu. For entering and exiting the music menu, however, the value 0x80001000 is used.

*The last two IRQs are generated multiple times during the boot process, before the 0x2000 is executed.

----------------------------------------------------------------------- Command 0x500 - Grab Video Thumbnail Data - 1 IRQ ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000500 Bytes 0x04 - 0x07 | Unknown Bytes 0x08 - 0x0B | Unknown -----------------------------------------------------------------------

After the 0x500 command is issued, a corresponding Game Pak IRQ signals that the Play-Yan is ready to provide a 60x40 thumbnail image for a video file. For the specifics regarding reading these thumbnails, refer to the appropiate section below.

----------------------------------------------------------------------- Command 0x600 - Unknown - 1 IRQ ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000600 -----------------------------------------------------------------------

The purpose of the command remains unknown. It always precedes the 0x800 command when playing music. Note, however, that it does not appear when playing videos.

----------------------------------------------------------------------- Command 0x700 - Play Video/Grab Video Frame - 2 IRQs* ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000700 ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80001000 Bytes 0x04 - 0x07 | Video Length Counter Bytes 0x08 - 0x0B | Frame Size in Bytes Bytes 0x14 - 0x18 | Current Video Position -----------------------------------------------------------------------

These interrupts are responsible for alerting the Play-Yan's software when a new video frame is ready for display, as well as the current position within a video as it is playing. The first IRQ initializes the process, while the second IRQ repeats indefinitely until the end of the video.

Each time the second IRQ is fired, the Current Video Position is updated. The Play-Yan software uses this to determine the minutes/seconds timestamp. It appears that the value 0x3C0 roughly equates 1 second. This IRQ fires every time a video frame needs to be displayed, therefore it should match the video's framerate. Each increment of the Current Video Position should thus reflect that. E.g. for a video playing at 30 frames-per-second, the Current Video Position updates at roughly 0x20 intervals.

The frame itself is read similarly to video thumbnails. Refers to the appropiate section below for more details. The size of the frame is the video's resolution (typically 240x160) in 15-bit color pixels. Therefore, this value is usually 0x12C00.

*The second IRQ constantly fires for the duration of the video for as many frames need to be updated each second.

----------------------------------------------------------------------- Command 0x701 - Stop Video Playback - 2 IRQs ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000701 ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80001000 -----------------------------------------------------------------------

Stops the current video file that is playing.

----------------------------------------------------------------------- Command 0x800 - Play Music File - 2 IRQs* ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000800 ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80001000 Bytes 0x0C - 0x0F | Unknown Bytes 0x10 - 0x13 | Unknown -----------------------------------------------------------------------

After the 0x800 command is issued, a Game Pak IRQ is generated when the Play-Yan hardware begins processing an audio file. This command always follows the 0x600 command.

*The second IRQ constantly fires for the duration of the music.

----------------------------------------------------------------------- Command 0x801 - Stop Music Playback - 2 IRQs ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40000801 ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80001000 -----------------------------------------------------------------------

Stops the current music file that is playing.

----------------------------------------------------------------------- Command 0x2000 - Update File Information - 1 IRQ ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80000100 -----------------------------------------------------------------------

Only 1 IRQ is fired for this command. It appears to update the current list of available files for videos, and files and folders for music. After executing this command, SD card data will return the appropiate files depending on the category selected.

----------------------------------------------------------------------- Command 0x8000 - Get SD Card Status - 2 IRQs ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x80000100 ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40008000 Bytes 0x04 - 0x07 | SD Card Status -----------------------------------------------------------------------

A single value is returned for the SD card's status. This can be used to determine if an appropiate SD card has been inserted. As the SD card is essential for the Play-Yan, this is the first command executed when booting. The status is returned in the second IRQ. If no SD card is detected, this value reads 0x03. If an incompatible card is detected (such as an SDHC card), this value reads 0x02. If a compatible card is detected, this value reads 0x05.

----------------------------------------------------------------------- Command 0x800000 - Unknown - 1 IRQ ----------------------------------------------------------------------- Bytes 0x00 - 0x03 | 0x40800000 Bytes 0x04 - 0x07 | SD Card Status -----------------------------------------------------------------------

This command is issued shortly after Get SD Card Status. It's purpose is currently unknown. It generates 1 IRQ, which also returns the card's status.

[Play-Yan] : Reading Video Frames and Video Thumbnails

Use the following process to read thumbnail data after issuing the 0x500 command:

----------------------------------------------------------------------- PY_DATA_PARAM = 0x08 PY_DATA_MODE = 0x78 PY_DATA_ADDR = 0x0000 PY_DATA_ADDR = 0x0000 UNKNOWN REGISTER 02 = 0x00 PY_DATA_PARAM = 0x09 WAIT FOR BIT 4 OF PY_FIRM_STAT TO READ HIGH READ DATA FROM 0xB000500 THROUGH 0xB0006FF -----------------------------------------------------------------------

Data can be read sequentially in 512-byte blocks without the need for writing to other registers. Simply waiting for Bit 4 of PY_FIRM_STAT is sufficient. Each frame or thumbnail will be the size as specified by the 0x500 or the 0x700 command, which ordinarily is 60x40 and 240x160, respectively. Both use 15-bit pixels, and their format is an exact match for the Game Boy Advance's bitmap mode (BG Mode 3). In total, the Play-Yan will typically provide 0x12C0 bytes of data for each thumbnail and 0x12C00 for each video frame.

A 0x500 command must be issued for each thumbnail the Play-Yan needs to process. Each page in the Play-Yan's file browser can only contain 6 videos, therefore, the Play-Yan's software only issues 6 of these commands at a time. If a page has less than 6 entries, only that many 0x500 commands need to be sent. It seems a 0x2000 command is always issued before the first 0x500 command; this may be the mechanism that tells the Play-Yan which videos need thumbnails generated.

For video frames, the 0x700 command is only issued once. Subsequent Game Pak IRQs are automatically generated by the video processing hardware for each frame, at which point the Play-Yan can read back this data and display them using BG Mode 3 for fullscreen bitmap display.

[Play-Yan] : Garage Games

The original Play-Yan allowed users to access 13 minigames called "Garage Games". After the Play-Yan launched, Nintendo released them on their website in a weekly fashion. Users downloaded a special .ASF file, and when stored on an SD card, the Play-Yan would start the game. The entire game took place in the 60x40 window dedicated to video thumbnails. Contrary to most available information, these Garage Games are technically not "DLC". Each Garage Game already exists in the Play-Yan ROM and the .ASF files contain no executable code. However, the Garage Games are normally inaccessible without the .ASF files present. The files Nintendo provided act as a sort of key that unlocks the content.

Each .ASF file is a valid video and will generate a thumbnail preview on the Play-Yan. This thumbnail acts as a fingerprint that the Play-Yan can use to identify an individual file. The 0x12C0 bytes of thumbnail data is quickly hashed into a 32-bit number and compared against a list of expected values. Should the thumbnail's hash match that internal list, the Play-Yan recognizes it as a Garage Game.

It should also be noted that the video file's name has to match as well. If the file name is incorrect, the Play-Yan won't bother creating a hash and will simply treat it as a regular video file. This behavior can be reproduced by renaming any of the .ASF files from Nintendo. The names of each Garage Game is case-sensitive as well; they all need to be uppercase in order to work. A list of all the Garage Games and their 32-bit hashes is provided below:

AVOID 0xF8CB9008 BAT 0xD911FE57 CREDIT 0x02F86041 FIRE 0x0D78A9FE FISH 0x5741DE47 INSECT 0x4D5E5AEB JUMP 0x748C5BAF KEEPER 0x3FEBEFE5 MEMORY 0x90119AE6 NEKOROID 0xD839D809 NOSE 0x86D3BA78 TRIPLE 0xD5C0A40B WAVE 0xE7DCD82B

The hash can be calculated using the following psuedo-code:

----------------------------------------------------------------------- HASH = 0 INDEX = 0 WHILE INDEX NOT EQUAL TO 0x960 HASH = HASH + 16-BIT THUMBNAIL PIXEL DATA HASH = HASH ROTATE RIGHT 31 INCREMENT INDEX BY 1 -----------------------------------------------------------------------

Although this hashing prevents most ordinary videos from randomly generating a thumbnail that triggers the Garage Game to play, the hashing method is prone to collisions. It is possible, therefore, to specifically create a thumbnail that matches any of the above listed hashes, in effect creating "bootleg" Garage Games.

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.

HCV-1000

General Hardware Information

Compatible Games

Device Detection

I/O Registers

Operation

[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-01 | アバレ ピッグ | 0000 JS1-02 | アダーガニ | 0001 JS1-04 | レッドバンサー | 0003 JS1-06 | イカレコング | 0005 JS1-07 | タコ力士 | 0006 JS1-08 | ナックルリザード | 0007 JS1-09 | イーグルカンフー | 0008 JS1-10 | バルキー バイソン | 0009 JS1-11 | バクルオン | 000A JS1-12 | ブラックドーベル | 000B JS1-13 | ガオー | 000C JS1-14 | 剛力獣神ガオー | 000D JS1-15 | モドリ玉 | 000E JS1-18 | ダイバクハーン | 0011 JS1-20 | ソードザック | 0013 JS1-21 | スルメボーイ | 0014 JS1-22 | 八つ裂きバチ | 0015 JS1-23 | カワ・ウソン | 0016 JS1-25 | クワガイアス | 0018 JS1-26 | スカルドレイン | 0019 JS1-28 | ヨロイガエル | 001B JS1-32 | ザバット | 001F JS1-33 | シャア | 0020 JS1-37 | シールドブレイク | 0024 JS1-38 | ソードブレイク | 0025 JS1-39 | 聖なる闘技場 | 0026 JS1-41 | ポメ剣士 | 0028 JS1-42 | シロクマックス | 0029 JS1-43 | アチョーモンキー | 002A JS1-47 | ハイエナガード | 002E JS1-48 | ヘビダイル | 002F JS1-49 | ブルドクター | 0030 JS1-50 | エンゼルスワン | 0031 JS1-52 | 怪力エレファン | 0033 JS1-53 | タイガ | 0034 JS1-57 | いでよ鋼の盾 | 0038 JS1-59 | 炎の闘技場 | 003A

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 | High byte of Packet Data length Byte 4 | Low byte of Packet Data length ------------------------------------------------- ------------------------------------------------- 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). The Mobile Adapter discards any packets bigger than 255 bytes, effectively forcing the high byte of the packet data length to be 0.

Data greater than the maximum packet length 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.

The Command ID byte in the Acknowledgement Signal may also be used for the receiver to indicate an error. If the checksum verification fails, the receiving side will send error 0xF1. This causes the sender to immediately re-attempt sending the packet up to 4 times. If the command isn't implemented/supported by the receiving Mobile Adapter, error 0xF0 will be sent. Error 0xF2 indicates an internal error, such as the Mobile Adapter's TCP/telephone transfer buffer being full.

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.

When the GBC or GBA first start communicating with the Mobile Adapter, the first byte sent in response will be garbage data. Sending this first byte causes the Mobile Adapter to exit sleep mode, and the GBC or GBA will then have to wait a short interval (around 100ms) before starting communications proper. If it doesn't, the Mobile Adapter might send more garbage. Afterwards, however, it will reply with 0xD2 as its "idle" byte until a command is finished being sent. The Mobile Adapter enters sleep mode after 3 seconds since the last serial byte was transmitted. This implicitly cancels the command currently being processed, closes all connections currently open and ends the session.

[Mobile Adapter GB] : Protocol - Commands

Command 0x0F - Empty

Data Sent: N/A. Empty Packet Data

Doesn't incite a reply from the adapter at all, aside from the Acknowledgement Signal. Presumably used to ping the adapter, not seen in any games in the wild.

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. This command causes all connections to be closed, and the phone to be hung up.

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, but seems to vary depending on the adapter type. 0 is sent for the blue/PDC adapter, 1 is sent for the green/PHS or red/DDI adapters, and 2 for the yellow/cdmaOne adapter. For unknown reasons, the blue adapter also accepts 16, the red adapter also accepts 9, and the yellow adapter doesn't actually verify this value. The following data is the telephone number represented in ASCII values, consisting of decimal numbers "0" through "9", as well as "#" and "*". Any ASCII values not within this range are ignored. The maximum length of the phone number is 32 bytes.

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. This implicitly disconnects any open TCP/UDP connections. 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 and pick up an incoming call. This returns inmediately if there is no call to pick up, with an error packet with code 0. The Packet Data is empty, and the length is zero bytes.

Command 0x15 - Transfer Data

Data Sent: Connection ID + Arbitrary Data (optional)

Data Received: Connection ID + Arbitrary Data (optional)

Used to transfer data over TCP after command 0x23 (Open TCP Connection), transfer data over UDP after command 0x25 (Open UDP connection), or transfer data over the phone line after either 0x12 (Dial Telephone) or 0x14 (Wait For Telephone Call) have successfully been called. Only TCP/UDP communication is possible after a 0x21 (ISP Login) command, and the first byte indicates the connection that's being transferred over, as multiple can be opened simultaneously. If it's a mobile connection, the first byte is ignored, usually being set to 0xFF.

Generally, additional data is appended, although it is not required, such as when waiting for the server/other phone to send a reply. Large chunks of data greater than 254 bytes must be broken down into separate packets. While a connection is active, the Command ID in the Reply is 0x15 for the sender and 0x95 for the receiver. When a TCP connection is closed by the remote server (e.g. when an HTTP response has finished), and there's no leftover data to be received by the Game Boy, the Command ID in the Reply becomes 0x1F for the sender and 0x9F for the receiver, with a packet length of 0. Additionally, for TCP connections, if no data is sent, this command will wait for data to be received up to 1 second, before sending a reply.

During a phone-to-phone communication, no disconnection is detected, instead being indicated by the 0x17 (Telephone Status) command. However, most games implement this instead through a timeout during which no data has been received.

Command 0x16 - Reset

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

This command does the same as sending commands 0x11 (End Session), followed by 0x10 (Begin Session). Additionally, it resets SIO32 Mode to the default state. Presumably used to reset the adapter, though not seen in any games in the wild.

Command 0x17 - Telephone Status

Data Sent: N/A. Empty Packet Data

Data Received: 3 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 3 bytes. The first byte indicates the phone's status, where 0xFF is returned if the phone is disconnected. If the phone isn't disconnected, bit 2 indicates whether the phone line is "busy" (i.e. in a call/picked up), and bit 0 indicates the presence of an incoming call (this remains if the incoming call is picked up). As such, the valid values are 0, 1, 4 and 5. Software may check bit 2 to know if the phone line is still connected. Most software doesn't seem to care about bit 0, but Net de Get: Mini Game @ 100 refuses to work with bit 0 set (value 5).

The second byte is related to the adapter type, where the blue/PDC adapter returns 0x4D, and the red/DDI and yellow/cdmaOne adapters return 0x48, though the actual meaning is unknown. The third byte is unknown, and usually hardcoded to 0. However, Pokemon Crystal reacts to the third byte being 0xF0 by allowing the player to bypass the 10 min/day battle time limit.

Command 0x18 - SIO32 Mode

Data Sent: 1 byte

Data Received: N/A. Empty Packet Data

This command is generally sent after Command 0x10. It enables/disables SIO32 Mode, which is useful for GBA games to be able to send more data, faster. The sent byte must be 1 to enable SIO32 mode, and 0 to disable it. SIO32 mode implies that any transmission will happen in chunks of 4 bytes instead of 1, which has implications with respect to the alignment of the communication.

When SIO32 mode is on, the packet data will be aligned to a multiple of 4 bytes, padding the remaining bytes with 0, and this won't be reflected in the packet length field. Similarly, the Acknowledgement Signal gains 2 padding bytes (hardcoded 0, not verified) at the end. Since the entire transmission (including Magic Bytes) is sent in chunks of 4, this means that the checksum is sent along with either the packet length (if length is 0) or the last 2 bytes of the packet (if length is not 0), and the acknowledgement signal is sent in the next chunk.

SIO32 Mode will only be toggled after the reply to this packet has been sent. The adapter should be allowed at least 100ms to toggle, as it might otherwise start sending garbage.

Command 0x19 - Read Configuration Data

Data Sent: 1 byte offset + 1 byte read length

Data Received: 1 byte offset + Requested Configuration Data

Requests data from the adapter's 256-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 the same offset byte followed by configuration data from the adapter's internal memory. The maximum amount of data that can be requested at once is 128 bytes, and the adapter may return an error if the game requests more data. Most software send 2 of these commands to read 96-byte chunks, for a total of 192 bytes, which is the area of this memory that is actually used.

Command 0x1A - Write Configuration Data

Data Sent: 1 byte offset + Configuration Data to Write

Data Received: 1 byte offset

Writes data to the adapter's 256-byte configuration memory. The first byte sent to the adapter is the offset. The following bytes are the data to be written in the adapters internal memory. A maximum of 128 bytes may be written at once.

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 assigned IP + 4 bytes assigned DNS Address #1 + 4 bytes assigned DNS Address #2 /p>

Logs into the DION dial-up service, after calling it with command 0x12 (Dial Telephone), allowing the adapter to connect to the internet. Both the Login ID and Password are prefixed with bytes declaring their lengths, with a maximum length of 0x20. The IPv4 DNS addresses are 4 bytes each, with a single byte representing one octet. The reply contains the assigned IP address and DNS addresses. If the game sets either of the DNS addresses to 0, the adapter may assign the DNS address on its own, and return that in the reply, otherwise, the reply's DNS addresses are 0.0.0.0.

Command 0x22 - ISP Logout

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

Logs out of the DION service. This command causes all connections to be closed.

Command 0x23 - Open TCP Connection

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

Data Received: 1 byte Connection ID

Opens a TCP connection at the given IP address on the given port, after logging into the DION dial-up service. 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 the software and the server. The Mobile Adapter is merely responsible for opening the connection and handling TCP transfers such as when using Command 0x15. The reply contains the Connection ID, which must be used when using Command 0x15 (Transfer Data). The maximum amount of connections on a real adapter is 2.

Command 0x24 - Close TCP Connection

Data Sent: 1 byte Connection ID

Data Received: 1 byte Connection ID

Closes an active TCP connection.

Command 0x25 - Open UDP Connection

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

Data Received: 1 byte Connection ID

Opens a UDP connection at the given IP address on the given port, after logging into the DION dial-up service. It's an analog of Command 0x23 (Open TCP Connection), but opens a UDP connection instead. This UDP connection is bound to the specified IP address and Port until it's closed. When using Command 0x15 (Transfer Data) with a UDP connection, it's impossible to know the sender of any received data, as it isn't verified.

Command 0x26 - Close UDP Connection

Data Sent: 1 byte Connection ID

Data Received: 1 byte Connection ID

Closes an active UDP 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, using the DNS server addresses sent in Command 0x21. This command also accepts an ASCII IPv4 address (as parsed by the inet_addr(3) function of POSIX), converting it into a 4-byte IPv4 address instead of querying the DNS server. The domain name is in ASCII and may contain zeroes, which truncate the name.

Command 0x3F - Firmware Version

Data Sent: N/A. Empty Packet Data

Data Received: N/A. Empty Packet Data

On a real Mobile Adapter, this causes it to send firmware version information through the serial pins on the phone connector, and enter a state in which no other commands can be used. Presumably, this enters a test mode of some kind. Likely not used by any games.

This command may not be used if the phone line is in use. The only way to resume sending commands after this one is sent, is sending Command 0x16 (Reset), or, exclusively on the blue adapter, Command 0x11 (End Session) may also be used.

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 0x11: Error Code 0x02 - Still connected/failed to disconnect(?) 0x12: Error Code 0x00 - Telephone line is busy 0x12: Error Code 0x01 - Invalid use (already connected) 0x12: Error Code 0x02 - Invalid contents (first byte isn't correct) 0x12: Error Code 0x03 - Communication failed/phone not connected 0x12: Error Code 0x04 - Call not established, redial 0x13: Error Code 0x01 - Invalid use (already hung up/phone not connected) 0x14: Error Code 0x00 - No call received/phone not connected 0x14: Error Code 0x01 - Invalid use (already calling) 0x14: Error Code 0x03 - Internal error (ringing but picking up fails) 0x15: Error Code 0x00 - Invalid connection/communication failed 0x15: Error Code 0x01 - Invalid use (Call was ended/never made) 0x16: Error Code 0x00 - Still connected/failed to disconnect(?) 0x18: Error Code 0x02 - Invalid contents (first byte not either 1 or 0) 0x19: Error Code 0x00 - Internal error (Failed to read config) 0x19: Error Code 0x02 - Read outside of config area/too big a chunk 0x1A: Error Code 0x00 - Internal error (Failed to write config) 0x1A: Error Code 0x02 - Write outside of config area/too big a chunk 0x21: Error Code 0x01 - Invalid use (Not in a call) 0x21: Error Code 0x02 - Unknown error (some kind of timeout?) 0x21: Error Code 0x03 - Unknown error (internal error?) 0x22: Error Code 0x00 - Invalid use (Not logged in) 0x22: Error Code 0x01 - Invalid use (Not in a call) 0x22: Error Code 0x02 - Unknown error (some kind of timeout?) 0x23: Error Code 0x00 - Too many connections 0x23: Error Code 0x01 - Invalid use (Not logged in) 0x23: Error Code 0x03 - Connection failed 0x24: Error Code 0x00 - Invalid connection (Not connected) 0x24: Error Code 0x01 - Invalid use (Not logged in) 0x24: Error Code 0x02 - Unknown error (???) 0x25: Error Code 0x00 - Too many connections 0x25: Error Code 0x01 - Invalid use (Not logged in) 0x25: Error Code 0x03 - Connection failed (though this can't happen) 0x26: Error Code 0x00 - Invalid connection (Not connected) 0x26: Error Code 0x01 - Invalid use (Not logged in) 0x26: Error Code 0x02 - Unknown error (???) 0x28: Error Code 0x01 - Invalid use (not logged in) 0x28: Error Code 0x02 - Invalid contents/lookup failed

[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 (210.196.3.183) 0x08 - 0x0B :: Secondary DNS server (210.141.112.163) 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 logging in to the DION dial-up service. 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 256 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 256 bytes. No data is returned either, as both commands respond with Error Status packets.

Game Boy Wars 3

General Information

Server Structure

0.map_menu.txt

map/map_****.cgb

charge/****.cgb

mbox/mbox_serial.txt

mbox/mbox_**.cgb

0.youhei_menu.txt

[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

Email

Item Codes

[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.

[Hello Kitty no Happy House] : Item Codes

Below are a list of 3-letter codes and the items they generate when used in the email header. If the game does not recognize the code, a present icon will appear next to the email, but no item is actually received.

--------------------------------------------------- Codes | Item --------------------------------------------------- AAB Heart Clock AAC Pendulum Clock AAD Futuristic Clock AAE Landscape Painting AAF Pop Art Painting AAG Kitty Elastomer AAH Bronze Angel Statue AAI Bronze Goddess Statue AAJ Bronze Kitty Statue AAK ABA Hanging Scroll AAL ABB Dragon Pennant AAM ABC Noble Pennant AAN ABD Wide TV AAO ABE Cute TV AAP ABF Wall-mounted TV AAQ ABG Digital Component Stereo AAR ABH Component Stereo AAS ABI Gramophone AAT ABJ Massage Chair AAU ABK ACA "Sexy" Massage Chair AAV ABL ACB Relaxing Chair AAW ABM ACC Globe AAX ABN ACD Cosmic Globe AAY ABO ACE Miniature House AAZ ABP ACF Pink Chest ABQ ACG Japanese Drawer ABR ACH Toy Case ABS ACI Japanese Vase ABT ACJ Western Vase ABU ACK ADA Arabian Vase ABV ACL ADB Tetra Aquarium ABW ACM ADC Turtle Aquarium ABX ACN ADD Arowana Aquarium ABY ACO ADE Floor Light ABZ ACP ADF Standing Light ACQ ADG Mood Light ACR ADH Doggy Doll ACS ADI Sheep Doll ACT ADJ Lion Doll ACU ADK AEA Puppet Storage Box ACV ADL AEB Robot Base ACW ADM AEC Doll House ACX ADN AED Magazine Rack ACY ADO AEE Letter Rack ACZ ADP AEF Bookstand ADQ AEG Hat Stand ADR AEH Coat Stand ADS AEI Dear Daniel Doll ADT AEJ Pink Living Room Furniture ADU AEK AFA Blue Living Room Furniture ADV AEL AFB White Living Room Furniture ADW AEM AFC Thai Living Room Furniture ADX AEN AFD Chinese Living Room Furniture ADY AEO AFE Asian Living Room Furniture ADZ AEP AFF Japanese Living Room Furniture AEQ AFG Wooden Japanese Chestnut Living Room Furniture AER AFH Wajima Lacquer Living Room Furniture AES AFI Cozy Living Room Furniture AET AFJ Checkered Living Room Furniture AEU AFK AGA Pop Living Room Furniture AEV AFL AGB Old Living Room Furniture AEW AFM AGC Old-fashioned Living Room Furniture AEX AFN AGD Antique Living Room Furniture AEY AFO AGE Heart-themed Living Room Furniture AEZ AFP AGF Apple-themed Living Room Furniture AFQ AGG Flower-themed Living Room Furniture AFR AGH Red Kotatsu AFS AGI Blue Kotatsu AFT AGJ Yellow Kotatsu AFU AGK AHA Extravagant Living Room Furniture AFV AGL AHB Elegant Living Room Furniture AFW AGM AHC Hello Kitty-themed Living Room Furniture AFX AGN AHD Red Art Studio AFY AGO AHE Blue Art Studio AFZ AGP AHF Elegant Art Studio AGQ AHG Model Train AGR AHH Toy Blocks AGS AHI Playing House Set AGT AHJ Standing Table AGU AHK AIA Flower-pattern Table AGV AHL AIB Glass Table AGW AHM AIC Japanese Flower Arranged Desk AGX AHN AID Flower Arrangement AGY AHO AIE Bonsai AGZ AHP AIF Red Carpet AHQ AIG Green Carpet AHR AIH Blue Carpet (says blue, looks purple) AHS AII Blue Playground Slide AHT AIJ Red Playground Slide (says red, looks pink) AHU AIK AJA White Playground Slide AHV AIL AJB Easy Chair AHW AIM AJC Tranquil Chair AHX AIN AJD Relaxing Chair AHY AIO AJE Gold Tearoom AHZ AIP AJF Silver Tearoom AIQ AJG Play Set AIR AJH Changing-clothes Box AIS AJI Changing-clothes Case AIT AJJ Strange Box AIU AJK AKA Somersault Platform AIV AJL AKB Jump Sheet AIW AJM AKC Trampoline AIX AJN AKD Pink Refrigerator AIY AJO AKE Wood-grain Refrigerator AIZ AJP AKF Play Refrigerator AJQ AKG White Iron AJR AKH Green Iron AJS AKI Purple Iron AJT AKJ Brown Builder (workout set) AJU AKK ALA Purple Builder (workout set) AJV AKL ALB Green Builder (workout set) AJW AKM ALC Brown Runner (treadmill) AJX AKN ALD Red Runner (treadmill, says red, looks pink) AJY AKO ALE Blue Runner (treadmill) AJZ AKP ALF Flower Piano AKQ ALG Star Piano AKR ALH Classic Piano AKS ALI Crystal Ball Set AKT ALJ Fortune-Telling Set AKU ALK AMA Tarot Card Divination

Mobile Trainer

General Information

Server Structure

index.html

Web Browser

Email

[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

h0000.cgb

RomList.cgb

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

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 from the internet and save them locally to flash memory for offline play. Players could browse an online list of available software and purchase them.

[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

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

---------------------------------- Header - 4 bytes ---------------------------------- 0x0000 - "M" :: 0x4D 0x0001 - "N" :: 0x4E 0x0002 - "G" :: 0x47 0x0003 - "L" :: 0x4C ---------------------------------- Text offset - 6 bytes ---------------------------------- 0x0004 - Offset :: Offset to text string. Calculated as 10 + (Offset * 5). 0x0005 - ??? :: 0x0005 through 0x0009 seem to be ignored. 0x0006 - ??? :: 0x0007 - ??? :: 0x0008 - ??? :: 0x0009 - ??? ::

[Net de Get] : RomList.cgb

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

---------------------------------- Entry Count - 1 byte ---------------------------------- 0x00 - Number of entries :: (1 - ?) Maximum not currently known. ---------------------------------- Data Offsets - 2 bytes each ---------------------------------- 0x01 :: Low byte of 16-bit internal offset to RomsList.cgb data structure. 0x02 :: High byte of 16-bit internal offset to RomsList.cgb data structure. ... :: Repeat offsets as needed. ---------------------------------- Data Structure ---------------------------------- 0x00 :: Number of memory blocks necessary for the download (modulus 100). Should be 0x00 - 0x63 ideally. 0x01 :: Mini-game icon type. See Icon Type below for details. 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:

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

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

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

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

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

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

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

[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.

Zen Nihon GT Senshuken

General Information

Server Structure

gtconfig.cgb

gtrkconfig.cgb

100.gtexcrs***.cgb

gtgst00.cgb - gtgst06.cgb

Ghost Data

gtrk00.cgb - gtrk06.cgb

Rank Entry

[Zen Nihon GT Senshuken] : General Information

Zen Nihon GT Senshuken (released as Top Gear GT Championship in the west) is a behind-the-car racing game for the Game Boy Advance. It served as a launch title in Japan and supported the Mobile Adapter GB for several functions including downloading custom racetracks and ghost car data, as well as uploading race result to get ranked.

[Zen Nihon GT Senshuken] : Server Structure

Zen Nihon GT Senshuken is currently known to access the following URLs:

[Zen Nihon GT Senshuken] : gtconfig.cgb

This file configures downloads for additional courses, Time Trial Ghosts, and online mobile rankings. gtconfig.cgb is only 200 bytes (0xC8) in size, as the game will not process any data beyond that. The format is as follows:

---------------------------------- File Structure ---------------------------------- 0x00 :: Unknown data. 0x01 :: Enables Time Trial Ghost downloads for select race tracks. 0x02 :: Numerical suffix for downloadable course 0x03 :: Unknown data. 0x04 - 0xC3 :: Dynamic URL data for mobile rank files. Uses ASCII characters. 0xC4 - 0xC7 :: A 32-bit checksum for all bytes from 0x00 - 0xC3. All bytes are added, one-by-one. Checksum stored LSB first.

When downloading Time Trial Ghosts, the game will display 7 menus, 1 for each race track. For Byte 0x01, each of the bits from Bit 0 through Bit 6 controls whether an individual track is enabled. Setting the bit to "0" enables it, while setting the bit to "1" disables it.

When downloading extra courses, Byte 0x02 is converted to Base 10 (decimal) and appended to the file name as a 3 digit number. For example, if the value of Byte 0x02 is 0x30, the game will download the file "100.gtexcrs048.cgb" for the course.

The dynamic URL data is an ASCII string terminated with a null character (0x00). The string points the game to the file gtrkconfig.cgb as well as the gtrk00.cgb through gtrk06.cgb files. Apparently, some portions of the string are ignored when the game makes the actual HTTP GET request. For example, if the string is "gameboy.datacenter.ne.jp/cgb/", the GET request only appears as "/cgb/". Any text prior to the first "/" character is effectively removed. This string is exclusively used for files related to mobile ranking.

[Zen Nihon GT Senshuken] : gtrkconfig.cgb

The purpose of this file is similar to gtconfig.cgb. It controls which menus to display for online mobile rankings. It has a total length of 8 bytes. The last 4 bytes compose a simple additive checksum of the file's first half. The format is as follows:

---------------------------------- File Structure ---------------------------------- 0x00 :: Enables mobile rankings for select race tracks 0x01 - 0x03 :: Unknown data. 0x04 - 0x07 :: A 32-bit checksum for all bytes from 0x00 - 0x03. All bytes are added, one-by-one. Checksum stored LSB first.

When downloading mobile rankings, the game will display 7 menus, 1 for each race track. For Byte 0x00, each of the bits from Bit 0 through Bit 6 controls whether an individual track is enabled. Setting the bit to "0" enables it, while setting the bit to "1" disables it.

[Zen Nihon GT Senshuken] : 100.gtexcrs***.cgb

This file represents a custom racetrack that can be downloaded from the servers and saved on the player's game cartridge. It is available through the Mobile Menu and selecting Course Download. A 100 yen service charge is attached to each download. The "***" part of the file name is replaced by Byte 0x02 of gtconfig.cgb when converted into a 3-digit decimal. The file length is 272 bytes total. The format is as follows:

---------------------------------- Racetrack Download Format ---------------------------------- 0x0000 - 0x0003 :: Unknown 32-bit value. Seems to be ignored. 0x0004 - 0x001B :: 10 character title plus terminating character. Uses a custom 16-bit character encoding. 0x001C - 0x010B :: Racetrack data. 0x010C - 0x010F :: A 32-bit checksum for all bytes from 0x0000 - 0x010B. All bytes are added, one-by-one. Checksum stored LSB first.

The format of the racetrack data is identical to the same data saved on the cartridge when a user creates their own custom track. Each racetrack consists of a 10x6 grid wherein blocks of the track are positioned. The binary data for the racetracks allocates 4 bytes for each block. Blocks are arranged left to right, top to bottom. The format is as follows:

---------------------------------- Racetrack Block Format ---------------------------------- 0x00 :: Block Type. 0x01 = Straight Track, 0x02 = Turn, 0x03 = Starting Position. 0x01 :: Turn Type or Starting Position Type. 0x02 :: Must be 0x01 to signal a valid block. 0x03 :: Not used, reads 0x00.

Depending on whether the block is a turn or a starting position, Byte 0x01 has different meanings. They are listed below:

---------------------------------- Block Turn Types ---------------------------------- 0x00 :: East-to-South turn. 0x01 :: South-to-West turn. 0x02 :: West-to-North turn. 0x03 :: North-to-East turn.

---------------------------------- Block Starting Position Types ---------------------------------- 0x00 :: Start race facing East. 0x01 :: Start race facing South. 0x02 :: Start race facing West. 0x03 :: Start race facing North.

[Zen Nihon GT Senshuken] : gtgst00.cgb - gtgst06.cgb

These 7 files represent menus for different ghost data that can be downloaded. From this menu, the player can choose a specific ghost from a specific track and then proceed to save it to the game cartridge. Each file 0x9E4 bytes long. Together, they give the player access to 210 sets of ghost data for each of the 7 race courses available (30 per track). The file for each .cgb file is as follows

---------------------------------- Ghost Menu File Structure ---------------------------------- 0x0000 - 0x0001 :: Year of last update, LSB first. 0x0002 :: Month of last update. 0x0003 :: Day of last update. 0x0004 - 0x0007 :: Unknown data. 0x000A - 0x09DF :: Ghost Data Entries. 0x09E0 - 0x09E3 :: A 32-bit checksum for all bytes from 0x0000 - 0x09DF. All bytes are added, one-by-one. Checksum stored LSB first.

---------------------------------- Ghost Data Entries ---------------------------------- 0x00 :: Unknown data. 0x01 :: Weather condition for ghost data (0 = Sunny, 1 = Rain). 0x02 :: Car type used for ghost data. 0x03 :: Car transmission used for ghost data (0 = Automatic, 1 = Manual). 0x04 - 0x0B :: Unknown data. 0x0C - 0x0D :: Handicap Weight. 16-bit value stored LSB first. Max value is 990, game displays values as units of 10 (e.g. 10, 20, 30, 40...) May be zero. 0x0E - 0x23 :: Ghost Name. 10 characters plus terminating character. Uses a custom 16-bit character encoding. 0x24 - 0x27 :: Ghost Time. 32-bit value stored LSB first. See notes below on format 0x28 - 0x33 :: Unknown data. 0x34 - 0x55 :: URL to download the ghost data. Uses ASCII characters.

Each Ghost Data Entry takes up 84 bytes. Once the player selects an entry, the game goes on to download the file specified by the URL. The URL in the entry is limited to 32 characters. Ultimately, if the URL is something like "myghostfile.cgb", the game ends up downloading from the following address:

http://gameboy.datacenter.ne.jp/cgb/download?name=/28/AGB-AGTJ/myghostfile.cgb

The total time used for the ghost is stored in a 32-bit value. The overall time works based on 1/100s of a second. To calculate the total time, start counting at zero and add according to this table:

---------------------------------- Ghost Entry Time Format ---------------------------------- 0x00 :: Time = Time + (1/100) * Byte Value 0x01 :: Time = Time + (256 * (1/100)) * Byte Value 0x02 :: Time = Time + (65536 * (1/100)) * Byte Value 0x03 :: Time = Time + (16777216 * (1/100)) * Byte Value

The maximum time alotted for any Ghost 99 minutes, 99 seconds, and 99 hundreths of a second.

[Zen Nihon GT Senshuken] : Ghost Data

The actual Ghost Data downloaded from the servers is saved to Flash RAM inside the cartridge. A fairly large portion of the 64KB of backup data is reserved just for Time Trial ghosts, and out of all the downloadable content, Ghost Data is potentially the largest. The file format is described below.

---------------------------------- Ghost Data File Format ---------------------------------- 0x00 :: Race Track. 0x01 :: Weather condition for ghost data (0 = Sunny, 1 = Rain). 0x02 :: Car type used for ghost data. 0x03 :: Car transmission used for ghost data (0 = Automatic, 1 = Manual). 0x04 - 0x0B :: Unknown data. 0x0C - 0x0D :: Handicap Weight. 16-bit value stored LSB first. Max value is 990, game displays values as units of 10 (e.g. 10, 20, 30, 40...) May be zero. 0x0E - 0x23 :: Ghost Name. 10 characters plus terminating character. Uses a custom 16-bit character encoding. 0x24 - 0x27 :: Ghost Time. 32-bit value stored LSB first. See notes above on format. 0x28 - 0x33 :: Unknown data. 0x34 - EOF :: Track Movement Data.

The format for the metadata is largely the same as the ghost menu. Byte 0 is used here, however, to define the specific race track the ghost belongs to. This forces the game to run that exact course, regardless of which menu it was downloaded from online. A list of all possible options follows:

---------------------------------- Ghost Race Track Values ---------------------------------- 0x00 :: Twin Ring Motegi 0x01 :: Fuji Speedway 0x02 :: Sportsland Sugo 0x03 :: Ti Circuit Aida 0x04 :: Central Park Mine Circuit 0x05 :: Suzuka Circuit 0x06 :: EDIT - 1st custom course name 0x07 :: EDIT - 2nd custom course name 0x08 :: EDIT - 3rd custom course name 0x09 :: Twin Ring Motegi (Mirror) 0x0A :: Fuji Speedway (Mirror) 0x0B :: Sportsland Sugo (Mirror) 0x0C :: Ti Circuit Aida (Mirror) 0x0D :: Central Park Mine Circuit (Mirror) 0x0E :: Suzuka Circuit (Mirror) 0x0F :: EDIT - (Mirror) 1st custom course name 0x10 :: EDIT - (Mirror) 2nd custom course name 0x11 :: EDIT - (Mirror) 3rd custom course name

Time Trial Ghost Data can apply to custom courses as well, thus allowing players of Zen Nihon GT to both download a unique track from the server as well as a ghost for it as well. Mirrored versions of each course is also available.

The Track Movement Data is a recording of a car's movements along the race course. For the downloaded file, it has the exact same format as regular Time Trial ghosts made locally by the player and saved on the cartridge. Zen Nihon GT essentially copy + pastes this section to Flash RAM as is.

No checksum is need for this file. The Track Movement Data uses 32-bit checksums periodically (approximately once every 4KB) to ensure data integrity, however.

[Zen Nihon GT Senshuken] : gtrk00.cgb - gtrk06.cgb

These files are the online mobile rankings. Players could sumbit their completion times for a certain race track (in the form of a Time Trial Ghost) and the fastest times would be listed for all to see. It was essentially a somewhat static leaderboard, as it required the player to manually send data to the servers. The exact URL is specified by the first string in gtconfig.cgb. Each file is 0xA34 bytes long. The format is as follows:

---------------------------------- Mobile Ranking File Format ---------------------------------- 0x0000 - 0x0001 :: Year of last update, LSB first. 0x0002 :: Month of last update. 0x0003 :: Day of last update. 0x0004 :: Hour of last update. 0x0005 :: Minute of last update. 0x0006 - 0x0007 :: Unknown Data. 0x0008 - 0x0A2F :: Mobile Rank Entries. 0x0A30 - 0x0A33 :: A 32-bit checksum for all bytes from 0x0000 - 0x0A2F. All bytes are added, one-by-one. Checksum stored LSB first.

Each file corresponds to a different race track and contains 50 entries. Each entry is 52 bytes long. The format of these entries (nearly identical to Ghost Data Entries) is as specified:

---------------------------------- Mobile Rank Entry ---------------------------------- 0x00 :: Unknown Data. 0x01 :: Weather condition for ghost data (0 = Sunny, 1 = Rain). 0x02 :: Car type used for the race. 0x03 :: Car transmission used for the race (0 = Automatic, 1 = Manual). 0x04 - 0x0B :: Unknown Data. 0x0C - 0x0D :: Handicap Weight. 16-bit value stored LSB first. Max value is 990, game displays values as units of 10 (e.g. 10, 20, 30, 40...) May be zero. 0x0E - 0x23 :: Player Name 0x24 - 0x27 :: Course Completion Time. 32-bit value stored LSB first. Same format as Ghost Time, see notes above. 0x28 - 0x33 :: Unknown Data. Appears to be three 32-bit values that must be non-zero.

[Zen Nihon GT Senshuken] : Rank Entry

Players could enter their Time Trial Ghosts to participate in online mobile rankings. Zen Nihon GT transfers to Ghost Data to the server and the leaderboard would be updated. It is unknown if the process was manually handled by server administrators or if server-side software automatically parsed and sorted the fastest times. The game transmits the data as part of an email attachment via SMTP. The format of the sent email is as follows:

From: xxxxxxxx@yyyy.dion.ne.jp To: Subject: GT-CHAMP-ENTRY X-Game-code: AGB-AGTJ-00 X-Game-title: GT-CHAMP MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="--AGB-AGTJ" ----AGB-AGTJ Content-Type: text/plain; charset=iso-2022-jp Context-Transfer-Encoding: 7bit ----------------------- 【全日本GT選手権】でランキング登録が失敗している可能性があります。 ----------------------- ----AGB-AGTJ Content-Type: application/octec-stream; name="gtent**.cgb" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="gtent**.cgb" DATA DATA DATA ----AGB-AGTJ--

The attached file varies depending on which race track was recorded in the Time Trial Ghost. The server will receive files from gtent00.cgb through gtent06.cgb.

The message, encoded as ISO-2022 JP translates to: "There is a possibility that ranking registration has failed in the [All Japan GT Championship]."