Hardware and Accessories
Overview
DMG and GBC
Barcode Taisen Bardigun Scanner
GBA
NDS
Mobile Adapter GB
Hardware Documentation
Game and Server Documentation
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
pfero - Mobile Adapter GB documentation
Robert Abel (Tauwasser) - Net de Get translation help
Barcode Boy
Barcode Boy to DMG Communication
[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:
Overall known communication protocol:
Standard communication flow:
[DMG] [BCB]
Handshake --->
<--- Handshake
<--- 0x2
<--- EAN-13
<--- 0x3
<--- 0x2
<--- EAN-13
<--- 0x3
Since the Barcode Boy acts as master (after the handshake at least), the Game Boy never initiates a transfer during barcode transmission. When sending barcode data, the Barcode Boy doesn't seem to care what value the Game Boy writes to SB, although no Barcode Boy games write to SB at that time anyway. Ultimately unknown if the Barcode Boy accepts input beyond the handshake, but no evidence has been observed to suggest otherwise.
Once the Barcode Boy sends the handshake [0x10, 0x07] back to the Game Boy, the scanner returns 0xFF anytime the Game Boy tries to send additional data while the handheld is still on its own internal clock. After the Barcode Boy finishes sending back the barcode data to the Game Boy, it requires the handshake again. It appears the handshake can fail for unknown reasons (probably related to the hardware). For example, the Barcode Boy at times may send back [0x90, 0x07], which seems to indicate an error of some sort.
[Barcode Boy] : Barcode Format
The two strings are the actual barcode data in numerical form. The barcode format itself is EAN-13, and a few games use JAN-13 specifically. Older JAN-13 barcodes start off with the flag code 49. Interestingly enough, the newer JAN-13 flag code is 45 and was introduced in 1992, the same year the Barcode Boy was released. Probably due to timing or convenience, the JAN-13 barcodes on the cards stuck to the older flag code. Some Barcode Boy barcodes are technically "coupons/vouchers" types, as they use the flag code 99 instead of 45 or 49. Family Jockey 2 and Famista 3 don't use JAN-13 specifically; instead they use random EAN-13 barcodes with varying flag codes.
Using scans of the barcode @ 600 DPI, the smallest bar width is approximately 7 pixels (give or take). With that information, it's possible to recreate the EAN-13 number with a sufficient image and barcode scanning software. It should be noted that the Barcode Boy appears to do away with the center guard, however, it maintains left and right guards.
[Barcode Boy] : Card Dumping + Emulation
Amazingly simple in comparison to something like Barcode Taisen Bardigun, chiefly because such a small amount of bytes need to be sent to the Game Boy. Basically, all you need to do is convert the barcode to EAN-13. Anything capable of reading standard barcodes found on most products should be sufficient to grab the numerical form of each card.
As far as emulation goes, simply convert the EAN-13 ASCII string to hex and transmit it accordingly.
[Barcode Boy] : Barcode Errors
Interestingly enough, a vast majority of the barcodes for Family Jockey 2 are completely incorrect. Only 3 out of the 8 barcodes actually generate horses with the stats listed on the cards. Barcodes A1, B1, and A4 work fine; the rest give stats that do not match up with the card's. Some, such as A2, even generate horses that are totally unfit for competition (A2 produces stats with 2s and 0s, and the max is supposed to be 9 in each category). It's not clear if this was a programming glitch or a mistake Namcot made when printing the cards, or some combination of the two. All other Barcode Boy games came packaged with cards that have no issues whatsoever.
[Barcode Boy] : Barcodes
Below are the full 13 digit barcodes for all known Barcode Boy cards along with any names, other identifying information found on the card, or important notes.
Battle Space
* バーサーカー (Berserker)
* 4907981000301
* バルキリー (Valkyrie)
* 4908052808369
* グリズリー (Grizzly Bear)
* 4916911302309
* マホウセンシ (Magic Soldier aka Rune Knight)
* 4902776809367
* ナイト (Knight)
* 4905672306367
* レイス (Wraith)
* 4912713004366
* シャーマン (Shaman)
* 4913508504399
* シーフ (Thief)
* 4918156001351
* ソーサラー (Sorcerer)
* 4911826551347
* ウォリアー (Warrior)
* 4909062206350
Family Jockey 2
* A1
* 5893713522816
* A2 (Erroneous Barcode)
* 2378649896765
* A4
* 9845554422318
* B1
* 1509843019075
* B2 (Erroneous Barcode)
* 4232978865152
* B4 (Erroneous Barcode)
* 3572821107673
* C3 (Erroneous Barcode)
* 7164625542390
* C5 (Erroneous Barcode)
* 6319537443513
Famista 3
* ホームランバッター (Home-Run Batter)
* 8357933639923
* 高打者バッター (Senior Batter)
* 7814374127798
* 駿打者バッター (Swift Batter)
* 9880692151263
* ピッチャー (Pitcher)
* 1414213562177
Kattobi Road
* フォワールド (Truck)
* 4902105002063
* ガウディ (Sedan)
* 4901121110004
* ナイト 2000 (Racecar)
* 4903301160625
* ミイラターボ (Japanese Street Car)
* 4902888119101
* リイスラックス (4x4 Jeep)
* 4901780161157
* ロクタスヨンート (F1-style racecar)
* 4987084410924
Monster Maker: Barcode Saga
* 弓使いロリエーン (Archer Lorian)
* 9998017308336
* 弓使いエリサイス (Archer Elysice)
* 9447410810323
* 騎士ローラン (Knight Lauren)
* 9052091324955
* 竜騎士ハーグン (Dragon Knight Haagun)
* 9322158686716
* 戦士ディアーネ (Warrior Diane)
* 9752412234900
* 戦士タムローン (Warrior Tamron)
* 9362462085911
Barcode Taisen Bardigun Scanner
Card Reader to GBC Communication
[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
[Barcode Taisen Bardigun] : Barcode Format
Because the incoming barcode data is not consistent byte-for-byte, the patterns are what matters most. To illustrate this idea, below are two sets of data extracted after scanning a card (using a hacked version of Barcode Taisen Bardigun and saving all SIO communications to Cart RAM).
SET_1 SET_2
00 00 00 03
7F FE FF F8
00 01 00 03
FF FF FF FF
FF FF FF FF
FF C0 FF E0
00 3F 00 0F
FF 00 FF 80
00 00 00 00
07 FF 00 FF
00 00 FC 00
FF FF 03 FF
FF C0 FF FF
00 00 C0 00
Each set is actually a bitstream of 0s and 1s like so:
Set 1 [16:0] [14:1] [15:0] [43:1] ...
Set 2 [14:0] [15:1] [14:0] [45:1] ...
The patterns in the sets are roughly the same. They switch between 0s, 1s, and 0s (black, white, black) fairly quickly followed by a long segment of 1s (white) which is roughly the general pattern seen at the beginning/ends of the barcodes. Based on this information, the thinest bars are about 0.0133 inches (8 pixels when scanning at 600dpi). Some further calculations based on this information:
Bar Width (in pixels @ 600dpi) -> Estimated bit-count sent to Game Boy
8 -> ~14-16
16 -> ~27-29
24 -> ~43-45
Every 8 pixels should be approximately 15 bits worth of data sent to the Game Boy, so:
Number of Pixels @ 600dpi * 1.875 = Approximate bit count
The physical barcode format on the actual cards is EAN-13.
[Barcode Taisen Bardigun] : Card Dumping
With the above guideline, it is possible to dump the cards by scanning them, then creating a binary file containing barcodes as alternating bitstreams of 0s and 1s. With this method, no homebrew techniques are needed, and only an image file is necessary to actually preserve the card.
The second method involves using a hacked version of the Barcode Taisen Bardigun ROM on a flashcart to save incoming Serial I/O data as a card is scanned. The binary can be pulled from a save file. Both binary files could be used an input to feed back to an emulator.
[Barcode Taisen Bardigun] : ROM Revision
Barcode Taisen Bardigun has two known ROMs, DMG-ABEJ-JPN and DMG-ABEJ-JPN-1. The later version polishes many rough edges found in the first release (e.g. including a text box when barcode scanning fails). Currently, both games appear to be largely the same besides these UI and UX enhancements. Barcode scanning is exactly the same in each.
[Barcode Taisen Bardigun] : Barcodes
* ラルフ "Ralph"
* 4900758340136
* タマッピ "Tamapi"
* 4900269429252
* チビッシー "Chibisshii"
* 4900287167419
DMG-07 4-Player Adapter
[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
[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
[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
[GBC Infrared] : General Hardware Information
The Game Boy Color came with an infrared port on the very top of the handheld. Previously, where IR communications had to be done with special cartridges (like the HuC-1 variants), the Game Boy itself now had the hardware built-in. Unfortunately, the feature was never popular outside of a few games and accessories. The IR port essentially sends out signals and is also capable of receiving them, allowing for fast, wireless, line-of-sight transmission.
[GBC Infrared] : Compatible Games
This list represents all the games that have been verified to use the IR port. While exhaustive, this list is probably not complete. There are likely more Japanese exclusives that need to be added. It's dubious whether or not Animorphs actually is a "Ubi Key" game. The back boxart doesn't have the "IR Compatible" logo, and the manual makes no mention of IR communication.
The North American version of Disney's Aladdin claims to have infrared support on the box, supposedly for Ubi Key functionality, however, no such option is accessible in the game. Additionally, European variants omit the GBC IR logo from their boxes. It's possible that like Animorphs, Aladdin had its IR features stripped.
It should be noted that a few games that use HuC-3 MBC are not in fact "GB KISS" games. Instead, they use the GBC's built-in IR hardware. Robopon Sun Version (US version only) and Pocket Family GB 2 are such examples. While the other Robopon games use the HuC-3's IR capabilities, these were lost when the game went overseas. A similar phenomenon can be seen with the Japanese release of Pokemon TCG (which used the HuC-1) versus releases for any other region (which use the GBC's native IR). Pocket Family GB 2 abandons the IR diodes on the HuC-3 PCB. At this point in time, Hudson may have finally decided to abandon GB KISS and the HuC-1 and HuC-3's IR features as they were redundant, especially for games designed to run exclusively on the GBC.
[GBC Infrared] : Communication Types
While a number of games may use similar formats for their IR communications, there is no "standard" protocol that all games use. IR communication is entirely determined by the game's code, hence it can vary wildly depending on needs. However, all communications fall into one of several general categories as described below:
[GBC Infrared] : Communication Protocol
Again, there is no set or established infrared protocol that games must follow. Many games vary in their approach. For example, the 2nd Generation Pokemon games use the GBC's hardware timers, while others have hardcoded values that count cycles to check timing. The simplest form is a barebones communication protocol, i.e. something like a binary Morse code where a "0" is a long ON-OFF pulse and "1" is a short ON-OFF pulse or vice versa. Properly done, data could have been short, compact, and easily converted into bytes in RAM. Sakura Taisen GB seems to follow this model in its communications with the Pocket Sakura. Not all games do this, however, and appear to be doing who knows that, opting instead for customized and specialized communications unique to each title. To illustrate this idea, it would be possible to use a table of given lengths of IR ON-OFF pulses so that individual bytes could be sent all at once instead of in a binary, bit-by-bit manner. A number of games try to send a few pulses when pressing input like the A button and wait for another GBC to echo that in response, but after the handshake, most of the IR pulses are impossible to understand without disassembling the code.
One thing to note is that 4 games in particular do share somewhat similar IR protocols, at least in regards to the initial handshake between 2 GBCs. They are Pokemon TCG 1 & 2 and Bombermax Red & Blue, all from the "2-Player Init" category above. Typically, IR capable GBC games will continually wait for an IR signal on both sides, i.e. the "1-Player Init" category. When one player presses certain input, that GBC takes the initiative and sends out a few IR pulses. That is to say, for most IR games, it only takes *just one* player to start the entire process.
The handshake for the 4 games previously mentioned, however, requires *both* players to input at almost the same time. One has to be slightly faster or slower than the other. Each side continually sends a few IR pulses, then reads the sensor to see if anything was received. If so, the GBCs begin to sync. The idea is that one side should be sending while the other is checking, and then the handshake completes. This is why one side needs to be faster or slower to input; if they are sending IR signals at the same time, they don't see anything when reading the sensor. As a result, both GBCs cannot input at exactly the same time. Practically speaking, this is unlikely to happen under normal circumstances, since most humans can't synchronize their actions down to a handful of microseconds, so the handshake will normally succeed.
The following is just theory. This handshake is possibly an artifact of the HuC-1. Consider that the Japanese version of Pokemon TCG 1 used the HuC-1 for its IR communications, and the developers may have borrowed the "best practices" used by other HuC-1/"GB KISS" games. When bringing Pokemon TCG 1 overseas, the IR handling code was likely minimally adapted to use the GBC's IR port, with the underlying protocol remaining unchanged in most regards. Pokemon TCG 2 ditched the HuC-1 in favor of the GBC IR port, so the IR code from non-Japanese versions of Pokemon TCG 1 was copy+pasted. The Bomberman games were made by Hudson Soft, literally the same people who created the HuC-1 in the first place. They too probably used the same protocol that had worked forever in their "GB KISS" games, so they used the same handshake method as before, just on the GBC IR port now. More research into the HuC-1 itself and the games needs to be done to confirm any of this.
[GBC Infrared] : RP Register
On the GBC, the MMIO register located at 0xFF56 controls infrared communication. Simply known as "RP" (Radiation Port? Reception Port? Red Port???), it is responsible for sending and receiving IR signals. Below is a diagram of the 8-bit register:
Bit 0: Turn IR light ON (1) or OFF (0) (R/W)
Bit 1: IR signal (0 = Receiving signal) (1 = Normal/No signal) (R)
Bits 2-5: Unused
Bits 6-7: Signal Read Enable (0 = Disable) (3 = Enable) (R/W)
Turning on the IR light is as simple as writing to Bit 0 of RP. Reading is a bit more complicated. Bits 6 and 7 must both be set (0xC0), to read Bit 1, otherwise Bit 1 returns 1, acting as if no signal is detected, except in edge cases detailed below in "Obscure Behavior". With signal reading enabled, Bit 1 will determine the status of any incoming IR signals. Like other Game Boy MMIO registers, unused bits read high (set to 1).
[GBC Infrared] : Signal Fade
The IR sensor in the GBC adapts to the current level of IR light. That is to say, if the GBC receives a sustained IR signal beyond a certain amount of time, eventually the sensor treats this as a new "normal" level of IR light, and Bit 1 of RP goes back to 1. This is called the signal "fade" because it may appear as if the signal disappears.
Signal fade time is dependent on length and has an inverse relationship with the distance between a GBC and the IR light. The closer a GBC is to the IR source, the longer the fade time. The farther away a GBC is to the IR source, the shorter the fade time. One possible explanation for everything is that the IR signal is weaker on the receiving end, so the signal is prone to get "lost" to surrounding noise. The GBC IR sensor is probably good at sending IR signals (evidenced by the Mission Impossible cheat to turn a GBC into a TV remote) but not so good at picking up signals (evidenced by Chee Chai Aliens plastic add-on to enhance IR reception).
At about 3.0 to 3.5 inches (7.62 to 8.89cm) signal fade time appears to be around 3ms. Optimal distance seems to be 2.5 to 4.0 inches (6.35 to 10.16cm) to maintain a fade time close to 3ms and avoid potential miscommunication. One oddity of note is that putting two GBCs very close together (physically touching) produced unusually short fade times, far shorter than 3ms. There may be some sort of interference at that range.
[GBC Infrared] : Obscure Behavior
The RP register has one very strange quirk. Disabling Bits 6 and 7 and then subsequently re-enabling them causes Bit 1 to go to zero under certain conditions. In other words, the IR sensor will act as if it is detecting a signal if reading the signal is disabled then enabled. It seems this behavior happens in the presence of any light; covering up the sensor during the read signal disable/enable causes the sensor to act normally. It's possible that the sensor resets itself (to its lowest level of detection???) and immediately detects any infrared sources, even from ambient/environmental light. The presence of any noise may temporarily trick the sensor into "seeing" IR light. By abusing this behavior, the GBC has some rudimentary ability to gauge the type of nearby lighting:
--------------------------------------------------------------------------------------------
Result of 1st RP Write (0x00) Result of 2nd RP Write (0xC0) Type of Lighting
--------------------------------------------------------------------------------------------
Bit 1 = 1 Bit 1 = 1 Dark
Bit 1 = 0 Bit 1 = 1 Ambient
Bit 1 = 0 (sometimes 1) Bit 1 = 0 Bright
Writing 0x00 to RP, followed by 0xC0 will trigger these results listed above. One very important thing to note is that when enabling Bits 6 and 7 (writing 0xC0), it does take some time for the sensor to register legitimate IR light coming into the sensor. I.e. if you want to use this method to detect what kind of light a GBC is looking at, the software needs to loop for a bit until Bit 1 of RP changes. Generally a few hundred cycles in double-speed mode will suffice. If Bit 1 of RP remains 1 after the loop, it's safe to assume the lighting is either ambient or dark. This delay doesn't seem to happen when Bits 6 and 7 are never disabled (which is what most official GBC software does). Games typically write either 0xC0 or 0xC1 to RP, with a small handful setting it to 0x00 initially when setting up other MMIO registers (Pokemon G/S/C does this).
The downside to this method is that when detecting a bright IR source, the sensor quickly adjusts to this new level, and the next attempt at writing 0x00 followed by 0xC0 to RP will result in readings of dark or ambient (typically dark though). Essentially the bright result only appears briefly when transitioning from lower levels of light, then it "disappears" thanks to the short time it takes for IR signal fade. Designing a game mechanic (darkness and light) around this quirk is still possible, although it would require careful thought and planning to properly work around the observed limitations.
One suggested method: once the Bright setting is detected, switch to writing only 0xC0 to RP so that the IR sensor works normally. If IR light stops being detected, switch to alternating 0x00 and 0xC0 writes as described above to determine Dark or Ambient settings. Whether it's practical or not to do this in a game remains theoretical at this point.
[GBC Infrared] : Pokemon Pikachu 2
The Pokemon Pikachu 2 (PP2) is a virtual pet device similar in concept to Tamagotchis. The PP2 is the successor to the original Pokemon Pikachu with a number of notable changes, largely the new color screen and the ability to communicate with Pokemon Gold, Silver, and Crystal via IR signals. These signals are used for the Mystery Gift functionality. Unlike normal Mystery Gifts between two GBCs, which produce random items, the PP2 gives out consistent items based on the number of "watts" transferred. The "watts" are the PP2's form of currency generated by the unit's pedometer (via walking, or more commonly, just shaking). Players either give Pikachu watts to make it happy, or send them to another PP2, or use them to Mystery Gift with Pokemon G/S/C.
In addition to giving out predictable items via Mystery Gift, the PP2 can also Mystery Gift without time limits. Normally, when two GBCs Mystery Gift 5 times in Pokemon G/S/C, players have to wait until the following day to try again. No such restriction applies when a GBC communicates with the PP2. The two can Mystery Gift endlessly, as long as the PP2 has watts to transfer. Below is a table of watts and the items they generate:
0 - 99 Watts Eon Mail
100 - 199 Watts Berry
200 - 299 Watts Bitter Berry
300 - 399 Watts Great Ball
400 - 499 Watts Max Repel
500 - 599 Watts Ether
600 - 699 Watts Miracle Berry
700 - 799 Watts Gold Berry
800 - 899 Watts Elixir
900 - 998 Watts Revive
999 Watts Rare Candy
Current analysis of the IR communications between a GBC and a PP2 indicates that the PP2 interacts with Pokemon Crystal differently in comparison to Pokemon Gold and Silver. Each transfer appears to be 2007 ON-OFF transitions long.
[GBC Infrared] : Pocket Sakura
The Pocket Sakura is another virtual pet device similar to the Pokemon Pikachu 2. Design-wise, it is a copy+paste version of the PP2, except it's pink. Interestingly enough, the Pocket Sakura was made by Media Factory, the same people behind Zok Zok Heroes and the Full Changer device. The Pocket Sakura uses a pedometer to make Sakura travel to various locations and meet other Sakura Taisen-based characters. When resting at a location, the pedometer turns steps into "points" (10 steps = 1 point), which can then be sent to a GBC running Sakura Taisen GB or another Pocket Sakura.
Each transfer appears to be 1607 ON-OFF transitions long.
Gyogun Tanchiki: Pocket Sonar
[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
[Power Antenna + Bug Sensor] : General Hardware Information
The Power Antenna are accessories bundled with the Keitai Denjuu Telefang Telefang games for the Game Boy Color and Game Boy Advance. An identical accessory, called the Bug Sensor, was also bundled with the Network Adventure Bugsite games on the GBC. Primarily cosmetic, these devices were essentially LEDs that were programmed to light up depending on certain events in the games.
* The 2nd version of the Power Antenna, the one that came with Telefang 2, is physically only compatible with the GBA's link port. However, it can be used with the GBC games.
[Power Antenna + Bug Sensor] : Game Boy Color Operation
To communicate with the Power Antenna + Bug Sensor, the GBC must run on an internal clock. A single byte is then transmitted via serial communications. The chart below describe what input will affect the LED:
-----------------------------------------------------
Value Sent | LED Result
-----------------------------------------------------
0x00 | Turns LED off
Bit 0 == 1 | Turns LED on (Strong Light)
Bit 0 == 0 | Turns LED on (Weak Light)
-----------------------------------------------------
"Strong Light" refers to the LED turning on and sustaining its brightest output; it will not turn off until a value of 0x00 is sent. "Weak Light" refers to the LED turning on temporarily and rapidly fading on its own. Weak Light is very dim (not noticable under certain lighting conditions) and is extremely short-lived. This mode does not appear to be used by the games. Instead, only Strong Light is turned on. Weak Light can be emitted constantly and indefinitely if multiple and repeated serial transfers occur. Sending such a transfer around 60Hz is enough to get weak light turned on for as long as desired.
It is possible to cause flickering by turning the LED on and off at given intervals. For Strong Light, this involves alternate transfers of 0x00 and some other value with Bit 0 set high. For Weak Light, simply send a value with Bit 0 set low and increase the gaps between transmission (e.g. delay transmission by 2 frames or 3 frames).
When the Power Antenna + Bug Sensor are emitting any kind of light, the device returns 0xF3 to the GBC. This is true even after Weak Light has fully faded. When no light is being emitted, the device returns 0xF2.
[Power Antenna + Bug Sensor] : Game Boy Advance Operation
Communications with the Power Antenna + Bug Sensor are a bit different when operating in GBA mode (i.e. running GBA software, not using a GBA to run GBC software). The GBA must use NORMAL_8BIT or NORMAL_32BIT mode; either one is fine. The following values of SIOCNT will affect the LED:
-----------------------------------------------------
Value Written | LED Result
-----------------------------------------------------
0x0080 | Turns LED off
0x0089 | Turns LED on (Strong Light)
0x0081 | Turns LED on (Weak Light)
-----------------------------------------------------
To turn off the LED, simply set Bit 3 of SIOCNT low and start a serial transfer. It does not matter whether an internal or external clock is set. For Strong and Weak Light, the 8-bit or 32-bit data sent is ignored. Instead, high or low values of Bit 3 of SIOCNT respectively dictate whether Strong or Weak Light is produced.
In NORMAL_8BIT mode, Strong and Weak Light return an 8-bit value of 0xFF instead of 0xF3 as on the GBC. In NORMAL_32BIT mode, the returned 32-bit value is 0x00.
[Power Antenna + Bug Sensor] : Misc. Notes
Since all Power Antenna + Bug Sensors rely on the presence or absence of a single bit, it is possible for other software to inadvertedly turn it on. For example, the GBA BIOS performs a few NORMAL_32BIT transfers on an internal clock, therefore turning on the LED for the duration of the boot logo (and indefinitely if the game does not change SIOCNT). Even software written specifically for these devices may turn them on at odd moments. Telefang triggers the LED on when attempting to use multiplayer via the Link Cable, although in this case, there is a reasonable expectation that the Power Antenna would be unplugged first.
Turbo File GB
[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
Stitching Logic - Regular Stitching
[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
Communication Protocol - Start Signal
Communication Protocol - Read Operations
Communication Protocol - Write Operations
[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:
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:
It's exactly like reading, except no secondary slave address is issued, therefore what would normally be the dummy write command is actually acknowledged. Additionally, there is no need to shift to a different start signal; only [0x25 0x27 0x27 0x25] is used. Once the slave address, write command, and word address are sent, data is written using a start signal plus 32 transfers for the byte. Once again, the format of the byte looks something like this:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5 | 0xAD 0xAF 0xAF 0xAD | 0xA5 0xA7 0xA7 0xA5
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Again, 2nd and 3rd transfers use Bit 3 to determine a "0" or a "1". The above example would be 0b10101010 or 0xAA. Unlike reads, which can continue on updating the internal EEPROM address, writes are done in 16-byte pages. Up to 16-bytes can be written sequentially; anymore and the writes loop around. E.g. if writing to 0x100 a page write has a range of 0x100 to 0x10F. Attempting to write a 17th byte will overwrite 0x100 instead of 0x110. In order to write 0x110 to 0x11F, another write slave address, write command, and word address need to be sent to the 24LC08.
[Soul Doll Adapter] : Soul Doll Data Format
Most of the 1KB data contained on the 24LC08 appears to be related to the Talispod or Talisdam accessories, e.g. such data as the Legend's preferred humidity and tempurature, and their stats. For the games, however, only bytes 0x300 - 0x3FF are relevant. This area of memory specifies the nickname, the owner's name, and various other flags related to auto-training mode. Most importantly, these bytes determine what kind of Legend is generated from the Soul Doll. Byte 0x302 acts as this ID:
0x01 = Windragon (A)?
0x03 = Windragon (B)?
0x04 = Mermaid
0x05 = Werewolf
0x06 = Will 'o' Wisp
0x07 = Tornado Kingdragon
0x08 = Blaze Dragon (A)?
0x09 = Goblin
0x0A = Yeti
0x0B = Hell Hound
0x0C = Volcano Kingdragon
0x0D = Windragon Berserker Mode
0x0E = Blazedragon Berserker Mode
0x0F = Fire Giant
0x10 = Undine
0x11 = Peryton
0x12 = Troll
0x13 = Command Windragon
0x14 = Manticore
0x15 = Carbuncle
0x16 = Command Blazedragon
0x17 = Dwarf
0x18 = Skeleton
0x19 = Earthquake Kingdragon
0x1A = Storm Kingdragon
0x1B = Wyvern
0x1E = Ranshiin (A)?
0x1F = Ranshiin (B)?
0x20 = Chibi Shiron
0x21 = Command Windragon Break Armed
0x22 = Command Blazedragon Volk Armed
0x23 = Chimaera
0x24 = Triton
0x25 = Gargoyle
0x26 = Cloud Giant
0x27 = Command Windragon
0x28 = Command Blazedragon
0x2B = Spiritual Windragon
0x2C = Hexadragon
0x2D = Windragon Berserker Mode (Growing)?
0x2E = Blazedradon Berserker Mode (Growing)?
0x31 = Devour Crocodile (Dandy)
0x32 = Harpy
0x33 = Cait Sith
0x34 = Command Blazedragon Volk Armed
0x35 = Devour Crocodile
0x36 = Vampire
0x37 = Spiritual Kingdragon
0x38 = Ogre
0x39 = Spriggan
0x3A = Command Windragon Break Armed
0x3B = Bicorn
0x3C = Centaur
0x3D = Nekrom Kingdragon
0x3E = Golem
0x3F = Ifrit
0x41 = Gorgon
0x42 = Kraken
0x43 = Minotauros
0x44 = Oberon
0x45 = Lich
0x48 = Colonel Windragon Tornado Soul
0x49 = Pheonix
0x4A = Behemoth
0x4B = Jabberwock
0x4C = Leviathan
0x4D = Fenrir
0x4E = Colonel Blazedragon Volcano Soul
0x4F = Sphinx
0x50 = Cyclops
0x54 = Syclla
0x55 = Titan
0x56 = Echidna
0x59 = Ranshiin (B)?
0x5A = Chibi Shiron (Manga Version)?
0x5B = Blazedragon (B)?
0x5C = Windragon (Manga Version)
0x5D = Griffin
0x5E = Bigfoot
0x5F = Tiamat
0x66 = Wyvern
0x67 = Storm Kingdragon
0x68 = Carbuncle
0x6D = Giant Crab
0x71 = Hydra
0x72 = Iron Golem
0x73 = Valkyrie
0x74 = Cerberus
Several IDs appear to be mapped to the same Legend. This may be explained by the fact that some Soul Dollz were released in A, B, and sometimes C variants. The plastic figurine is different, but the GBA games generate the same sprite and default name for the Soul Doll. All of the potential duplicates are marked with "?" in the list above. Although there are 103 Soul Dollz, the list remains incomplete. The gaps between entries do not generate valid Legendz, which suggests other bytes in EEPROM are also responsible for the ID.
Battle Chip Gate
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:
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:
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
[Multi Plust On System] : General Hardware Information
The Multi Plust On System (MPOS) is an accessory for the Bouken Yuuki Pluster World franchise from Takara. Designed as a "toys-to-life" device, it allows plastic figurines to transfer characters known as "Plusters" into the games. Bouken Yuuki Pluster World: Densetsu no Plust Gate and the EX version are RPGs, while Bouken Yuuki Pluster World: Pluston GP is a racing game. All 3 were released in 2003 and came with special sets featuring the the MPOS and a bundled Pluster figurine.
[Multi Plust On System] : Compatible Games
All 3 games are more or less unplayable without the MPOS. A few minigames can be played in Densetsu no Plust Gate EX, but in both that game and the regular Densetsu no Plust Gate, starting the main RPG requires the MPOS be attached with a Pluster Figure inserted. In Pluston GP, many of the menus can be navigated, but beginning a race also requires the accessory and an inserted figurine.
[Multi Plust On System] : Communication Protocol
Communication between the MPOS and the GBA is very simple. The role of the MPOS is to provide a single 16-bit number. Depending on which spokes the plastic model uses to put on the MPOS' array of pressure pads, a different number is sent to the GBA. The number effectively acts as an ID for the Pluster figurine. Using General Purpose Mode, both sides send a total of 37 transfers. At the beginning, of a session, the games will set all lines (SC, SD, SI, SO) as output with the RCNT value 0x80F0. Afterwards the 37 transfers keep looping indefinitely. The first 4 transfer appear to act as a start signal. The start signal is the following:
----------------------------------------------
RCNT |SC | SD | SI | SO
----------------------------------------------
0x80BD | 1 | 0 | 1 | 1
0x80B5 | 1 | 0 | 1 | 0
0x80BF | 1 | 1 | 1 | 1
0x80BF | 1 | 1 | 1 | 1
Although the games' code ignores the results of the start signal, the MPOS returns these values:
----------------------------------------------
RCNT |SC | SD | SI | SO
----------------------------------------------
0x80B9 | 1 | 0 | 0 | 1
0x80B1 | 1 | 0 | 0 | 0
0x80BB | 1 | 1 | 0 | 1
0x80BB | 1 | 1 | 0 | 1
The next 33 transfers are used for the 16-bit ID, 1 bit for every 2 transfers. The last transfer appears to dangle. This may simply be necessary to complete the transfer of the ID and begin the process over again. The GBA sends the following over and over again until it sends another start signal:
----------------------------------------------
RCNT |SC | SD | SI | SO
----------------------------------------------
0x80BE | 0 | 1 | 1 | 1
0x80BC | 0 | 0 | 1 | 1
In response, the MPOS toggles SI every odd transfer (when receiving 0x80BE from the GBA) to send the the bit. For example, for the Pluster Wyburst (PF002), it produces the ID 0x16A0. The values sent back to the GBA look like this:
------------------------------------------------------
RCNT |SC | SD | SI | SO | Bit
------------------------------------------------------
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BE | 0 | 1 | 1 | 1 | 1
0x80BC | 0 | 0 | 1 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BE | 0 | 1 | 1 | 1 | 1
0x80BC | 0 | 0 | 1 | 1 |
0x80BE | 0 | 1 | 1 | 1 | 1
0x80BC | 0 | 0 | 1 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BE | 0 | 1 | 1 | 1 | 1
0x80BC | 0 | 0 | 1 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BE | 0 | 1 | 1 | 1 | 1
0x80BC | 0 | 0 | 1 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 | 0
0x80B8 | 0 | 0 | 0 | 1 |
0x80BA | 0 | 1 | 0 | 1 |
The ID is received serially, MSB first. Essentially, a "1" bit is transferred whenever both SD and SI go high, and a "0" bit is transferred whenever SD is high, but SI is low.
[Multi Plust On System] : Pluster IDs
Currently, there are 22 identified Pluster figurines along with some 16-bit IDs that will generate that character in the games. There are multiple variants of figurines, therefore Plusters have multiple valid IDs, since the configuration of their spokes is different. The electronic toys may treat them differently, yet the GBA games do not.
IMPORTANT: These IDs were generated artificially by testing them against the games, so with the exception of Wyburst (0x16A0) none of these represent actual IDs captured from a MPOS. They are, however, sufficient for the purposes of emulation or using homebrew on a second GBA to fake a connected MPOS.
PF001 :: Beetma
* 0x16C0
* 0x1682
* 0x1642
PF002 :: Wyburst
* 0x16A0
* 0x1660
* 0x1622
PF003 :: Gabrian
* 0x1650
* 0x1630
PF004 :: Molly
* 0x16D8
* 0x16B2
* 0x1672
PF005 :: Hania
* 0x1688
* 0x1648
* 0x1628
PF006 :: Zagarian
* 0x1614
PF007 :: Tan Q
* 0x16D4
PF008 :: Warrion
* 0x16F0
* 0x1612
PF009 :: Doryuun
* 0x16B8
* 0x1678
PF010 :: Fezard
* 0x16D2
* 0x1618
PF011 :: Mashanta
* 0x1684
* 0x1644
* 0x1624
PF012 :: Gingardo
* 0x16B4
* 0x1674
PF013 :: Torastorm
* 0x16CC
PF014 :: Gongoragon
* 0x16AC
PF015 :: Mighty V
* 0x169C
PF016 :: Dorastorm
* 0x16FC
PF-EX001 :: Beetma EX
* 0x1666
PF-EX002 :: Varouze
* 0x1636
PF-EX003 :: Gigajoule
* 0x164E
PF-EX004 :: Badnick
* 0x161E
PF-EX005 :: Poseihorn
* 0x167E
PF-EX006 :: Tera
* 0x1621
When the MPOS is connected to the GBA but has no Pluster figurine inserted, the device returns the ID 0x1400.
Turbo File Advance
[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
[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
[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 followsRacer 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.
Ubisoft Thrustmaster Pedometer
[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
[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:
Magic Reader
[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:
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:
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
Card Reading Sequence
[Magic Reader] : Card List and Index Values
There are total of 240 cards for Juushinden released in 4 sets of 60. There are also an unknown amount promotional cards. For the regular sets, the index values returned by the Magic Reader roughly matches the number printed on the card itself.
-------------------------------------
Set 1 - 第一弾「大いなる覚醒の時」
-------------------------------------
Card # | Name | Index
-------------------------------------
JS1-06 | イカレコング | 0005
JS1-07 | タコ力士 | 0006
JS1-09 | イーグルカンフー | 0008
JS1-12 | ブラックドーベル | 000B
JS1-13 | ガオー | 000C
JS1-14 | 剛力獣神ガオー | 000D
JS1-18 | ダイバクハーン | 0011
JS1-20 | ソードザック | 0013
JS1-23 | カワ・ウソン | 0016
JS1-25 | クワガイアス | 0018
JS1-26 | スカルドレイン | 0019
JS1-28 | ヨロイガエル | 001B
JS1-32 | ザバット | 001F
JS1-37 | シールドブレイク | 0024
JS1-38 | ソードブレイク | 0025
JS1-39 | 聖なる闘技場 | 0026
JS1-41 | ポメ剣士 | 0028
JS1-42 | シロクマックス | 0029
JS1-43 | アチョーモンキー | 002A
JS1-47 | ハイエナガード | 002E
JS1-49 | ブルドクター | 0030
JS1-52 | 怪力エレファン | 0033
JS1-53 | タイガ | 0034
JS1-57 | いでよ鋼の盾 | 0038
The cards themselves use tiny carbon dots to produce an index value. According to the OID specification, carbon ink can replace K when using CMYK. Black colors would need to be reproduced by merging CMY dots in close proximity to one another. At any rate, these dots are meant to absorb light rather than reflect it. The CMOS inside the Magic Reader can't detect these dots, so these "empty" spots form a pattern that can be recognized and converted into a number. These dots are not completely invisible to the human eye, however. Ordinary cameras are capable of capturing them. The dots occupy the entire face of the card with the exception of the borders and likely the silver text of some cards.
Mobile Adapter GB
Protocol - Flow of Communication
[Mobile Adapter GB] : General Hardware Information
The Mobile Adapter GB was an accessory designed to allow the Game Boy Color, and later the Game Boy Advance, to connect online via cellular networks in Japan. Released on January 27, 2001, it supported a limited number of games before service was shutdown on December 14, 2002. Many of the compatible games supported features such on mail clients, downloadable bonus content, player-versus-player modes, and even online tournaments. It represented Nintendo's first official attempt at online gaming for its handhelds.
Below, the Mobile Adapter variants are explained in further detail:
Blue -> Used to connect PDC phones.
Yellow -> Used to connect cdmaOne phones.
Red -> Used to connect DDI phones.
Green -> Would have been used to connect PHS phones, but this version was never released.
[Mobile Adapter GB] : Compatible Games
There are currently 22 known games that are compatible with the Mobile Adapter:
Game Boy Color : 6 Total
Game Boy Advance : 16 Total
Two games were planned but later cancelled: beatmaniaGB Net Jam for the GBC and Horse Racing Creating Derby for the GBA.
The GBA game Yu-Gi-Oh! Duel Monsters 5 Expert 1 contains code for the Mobile Adapter, but despite being built with the library it does not appear to use it. This functionality may have been planned and later abandoned.
[Mobile Adapter GB] : Protocol - Packet Format
On the GBC, the Mobile Adapter operates using the fastest available setting (64KB/s) by setting Bits 0 and 1 of the SC register (0xFF02) high. It also uses an internal clock for all transfers. Communication is comparable to that of the Game Boy Printer, where the Game Boy sends packets with header, data, command, and checksum sections. On the GBA, the Mobile Adapter operates in NORMAL8 mode using a shift clock of 256KHz. Below is a chart breaking down the Mobile Adapter packet format used by the Game Boy or Mobile Adapter when acting as the sender. For response data sent by the receiver, refer to the next section.
-------------------------------------------------
Section | Length
-------------------------------------------------
Magic Bytes : 0x99 0x66 | 2 bytes
Packet Header | 4 bytes
Packet Data | 0-254 bytes
Packet Checksum | 2 bytes
Acknowledgement Signal | 2 bytes
-------------------------------------------------
-------------------------------------------------
Packet Header
-------------------------------------------------
Byte 1 | Command ID
Byte 2 | Unknown/Unused (0x00)
Byte 3 | Unknown/Unused (0x00)
Byte 4 | Length of Packet Data
-------------------------------------------------
-------------------------------------------------
Packet Data
-------------------------------------------------
Bytes 0-254 | Arbitrary data
-------------------------------------------------
-------------------------------------------------
Packet Checksum
-------------------------------------------------
Byte 1 | High byte of 16-bit sum
Byte 2 | Low byte of 16-bit sum
-------------------------------------------------
-------------------------------------------------
Acknowledgement Signal
-------------------------------------------------
Byte 1 | Device ID
Byte 2 | Command ID
-------------------------------------------------
The magic bytes are simply a pair of bytes used to identify the start of a Mobile Adapter packet.
Packet Data is arbitrary data and varies in length and content. On the Game Boy Color, it has a maximum size of 254 bytes. This restriction may be applied via software and appears to come from the fact that the Packet Data and Packet Checksum are lumped together, thus their total lengths must not exceed 256 bytes. Attempting to send more than 254 bytes of packet data causes communications errors in all supported GBC games. Evidence suggests GBA games can use Bytes 3 and 4 of the Packet Header to specify Packet Data size (possibly up to 64KB).
On the GBC, data greater than 254 bytes may be broken up into multiple packets, however. For example, when sending a large binary file such as an image or executable code, multiple packets are transferred from the Mobile Adapter to the Game Boy while the TCP transfer is ongoing.
The Packet Checksum is simply the 16-bit sum of all previous header bytes and all previous packet data bytes. It does not include the magic bytes. The checksum is transmitted big-endian.
After the checksum, a simple 2-byte Acknowledgement Signal is sent. The first byte is the Device ID OR'ed with the value 0x80. The second byte is 0x00 for the sender. The receiver transfers the Command ID from the Packet Header XOR'ed by 0x80. This essentially confirms what role the Game Boy is acting in. If it is the receiver, it is expecting to read information from the Packet Data from the Mobile Adapter. If it is the sender, it is pushing information from its own Packet Data to the Mobile Adapter. For example, with Command 0x19, the Game Boy is explicitly requesting data from the adapter, and with Command 0x1A the Game Boy is explicitly sending data to the adapter.
If the checksum fails, the receiving side typically immediately sends 0xF1 to indicate an error. 0xF0, and 0xF2 also appear to be failure codes, however, their meaning is currently unknown. 0xEE indicates a specific error from a previously issued command.
The device ID determines what kind of hardware each side is communicating with. Below are the possible values and their meaning:
-------------------------------------------------
Device ID | OR Value | Device Type
-------------------------------------------------
0x00 | 0x80 | Game Boy Color
0x01 | 0x81 | Game Boy Advance
0x08 | 0x88 | PDC Mobile Adapter (Blue)
0x09 | 0x89 | cdmaOne Mobile Adapter (Yellow)
0x0A | 0x8A | PHS Mobile Adapter (Green)
0x0B | 0x8B | DDI Mobile Adapter (Red)
-------------------------------------------------
[Mobile Adapter GB] : Protocol - Flow of Communication
Even though the protocol effectively enables 2-way communication between the Game Boy and a remote server, the handheld is expected to oversee all transmissions to the adapter itself. That is to say, the typical "master-slave" model often used for Game Boy serial I/O still applies in some sense. Once the server starts responding, the Game Boy has to continually initiate another transfer to the adapter (setting Bit 7 of 0xFF02 high) to keep reading any additional bytes that were sent.
It is up to the game software itself to handle secondary protocols (such as HTTP, POP3, or SMTP) which involve one side specifically acting as the sender or receiver. For example, after opening a TCP connection to an HTTP server and issuing the 0x15 command (Data Transfer), the software will determine whether the Game Boy is acting as a sender (making an HTTP request) or a receiver (receiving an HTTP response). Generally, this goes back and forth. The Game Boy sends information via its Packet Data, while the Mobile Adapter responds with 0xD2 "wait" bytes until the Game Boy finishes its TCP transfer. When the Game Boy's TCP transfer is done, the adapter sends any information from the server in its Packet Data while the Game Boy responds with 0x4B "wait" bytes. The chart below illustrates this concept and details what bytes are transferred by each side depending on their current role:
-------------------------------------------------------------------------------------------------------------------------------------------------
Device | Role | Magic Bytes | Packet Header | Packet Checksum | Packet Data | Acknowledgement Signal
-------------------------------------------------------------------------------------------------------------------------------------------------
Game Boy | Sender | 0x96 0x66 | Arbitrary | Arbitrary | Arbitrary | Device ID OR 0x80 + 0x00
Mobile Adapter | Receiver | 0xD2 0xD2 | 0xD2 0xD2 ... | 0xD2 0xD2 ... ... ... | 0xD2 0xD2 ... | Device ID OR 0x80 + Command ID XOR 0x80
-------------------------------------------------------------------------------------------------------------------------------------------------
Game Boy | Receiver | 0x4B 0x4B | 0x4B 0x4B ... | 0x4B 0x4B ... ... ... | 0x4B 0x4B ... | Device ID OR 0x80 + Command ID XOR 0x80
Mobile Adapter | Sender | 0x96 0x66 | Arbitrary | Arbitrary | Arbitrary | Device ID OR 0x80 + 0x00
-------------------------------------------------------------------------------------------------------------------------------------------------
When beginning communications with the Mobile Adapter, the Game Boy typically assumes the role of sender first.
Many games appear to follow a certain order of commands initially. This may have been part of some kind of standard library available to developers in order to connect to an ISP. The commands most commonly look like this:
------------
Command 0x10 Begin Session. First is perhaps to test the presence of the Mobile Adapter
Command 0x11 Close Session.
Command 0x10 Begin Session. Open session for configuration data
------------
Command 0x19 Read Configuration Data. Grab first 96 bytes
Command 0x19 Read Configuration Data. Grab second 96 bytes
Command 0x11 Close Session.
Command 0x10 Begin Session. Open session to read configuration data again
Command 0x19 Read Configuration Data. Grab first 96 bytes
Command 0x19 Read Configuration Data. Grab second 96 bytes
------------
Command 0x17 Check Telephone Status if not busy
Command 0x12 Dial Telephone. Should be the ISP's number stored in configuration data
Command 0x21 ISP Login
Command 0x28 DNS Query
------------
From there, the software decides what next (if anything) needs to be done after successfully connecting to the internet.
[Mobile Adapter GB] : Protocol - Commands
Command 0x10 - Begin Session
Data Sent: "NINTENDO" ASCII string. 8 bytes only, not null-terminated
Data Received: "NINTENDO" ASCII string. 8 bytes only, not null-terminated
Sent to the adapter at the beginning of a session. The Game Boy sends an ASCII string containing "NINTENDO" and the adapter replies with a packet containing the same data. It must be noted that the adapter will not respond to other commands until it receives this command. If this command is sent twice, it returns an error.
Command 0x11 - End Session
Data Sent: N/A. Empty Packet Data
Data Received: N/A. Empty Packet Data
Sent to the adapter at the end of a session. The Packet Data is empty, and the length is zero bytes.
Command 0x12 - Dial Telephone
Data Sent: 1 unknown byte + telephone number
Data Received: N/A. Empty Packet Data
Instructs the adapter to dial a telephone number. The first byte's purpose is unknown. The second byte is "#" in ASCII, and following data is the telephone number represented in ASCII values.
Command 0x13 - Hang Up Telephone
Data Sent: N/A. Empty Packet Data
Data Received: N/A. Empty Packet Data
Instructs the adapter to close a telephone connection. The Packet Data is empty, and the length is zero bytes.
Command 0x14 - Wait For Telephone Call
Data Sent: N/A. Empty Packet Data
Data Received: N/A. Empty Packet Data
Instructs the adapter to wait for a telephone call. The Packet Data is empty, and the length is zero bytes.
Command 0x15 - Transfer Data
Data Sent: 1 unknown byte + Arbitrary Data (optional)
Data Received: 1 unknown byte + Arbitrary Data (optional)
Used to transfer data over TCP after the command 0x23 (Open TCP Connection) has been called. This command can communicate with a remote server or another Mobile Adapter. The Packet Data is a minimum length of 1 byte. That first byte's purpose is unknown. Generally, additional data is appended, although it is not required, such as when closing a connection. Large chunks of data greater than 254 bytes must be broken down into separate packets. While a connection is active (e.g. an HTTP request/response is in progress), the Command ID in the Acknowledgement Signal is 0x15 for the sender and 0x95 for the receiver. When a connection is closed (e.g. when an HTTP response has finished), the Command ID in the Acknowledgement Signal becomes 0x1F for the sender and 0x9F for the receiver.
Command 0x17 - Telephone Status
Data Sent: N/A. Empty Packet Data
Data Received: 1 byte for current telephone status + 2 unknown bytes
Typically sent to the adapter before dialing. Also used to test the telephone status before opening a TCP connection, or to constantly ping the phone to make sure it's still active. The reply is 1 byte. 0x00 means the phone is ready to make a call or connection. 0xFF indicates a disconnected phone. 0x04 and 0x05 indicate that the line is busy (presumably set after a command like 0x12). The difference between the two line-busy values is unknown. Most software does not seem to care which one is sent, but Net de Get: Mini Game @ 100 refuses to work with 0x05.
Additionally, the Game Boy seem to set Bits 0 - 4 high for the Command ID in the Acknowledgement Signal, thus sending 0x1F to the Mobile Adapter.
Command 0x18 - Unknown Command
Data Sent: 1 unknown byte
Data Received: N/A. Empty Packet Data
This command is generally sent after Command 0x10. Only GBA games have been known to use this command. The GBA sends 1 unknown byte. The response Packet Data is empty, and the length is zero bytes.
Command 0x19 - Read Configuration Data
Data Sent: 1 byte offset + 1 byte read length
Data Received: 1 unknown byte + Requested Configuration Data
Requests data from the adapter's 192-byte configuration memory. The first byte sent to the adapter is the offset. The second byte sent is the length of data to read. The adapter responds with 1 unknown byte followed by configuration data from the adapter's internal memory. Although it should be possible to read the entire configuration data with one packet, most software send 2 of these commands to read 96-byte chunks.
Command 0x1A - Write Configuration Data
Data Sent: 1 unknown + Configuration Data to Write
Data Received: N/A. Empty Packet Data
Writes data to the adapter's 192-byte configuration memory. The first byte sent to the adapter unknown. The following bytes are the data to be written in the adapters internal memory.
Command 0x21 - ISP Login
Data Sent: 1 byte Login ID Length + Login ID + 1 byte Password Length + Password + 4 bytes DNS Address #1 + 4 bytes DNS Address #2
Data Received: 4 bytes possibly representing IP address assigned to adapter
Logs into the DION service, which in turn connects to an internet server. Both the Login ID and Password are prefixed with bytes declaring their lengths. The IPv4 DNS addresses are 4 bytes each, with a single byte representing one octet.
Command 0x22 - ISP Logout
Data Sent: N/A. Empty Packet Data
Data Received: N/A. Empty Packet Data
Logs out of the DION service.
Command 0x23 - Open TCP Connection
Data Sent: 4 bytes for IP Address + 2 Bytes for Port Number
Data Received: 1 unknown byte
Opens a TCP connection at the given IP address on the given port. The IPv4 IP address is 4 bytes, with a single byte representing one octet. The port number is big-endian. Depending on which port the TCP connection opens (25, 80, 110), different protocols can be accessed on a server (SMTP, HTTP, and POP respectively). Handling the details of the protocol itself depends on software. The Mobile Adapter is merely responsible for opening the connection and handling TCP transfers such as when using Command 0x15.
Command 0x24 - Close TCP Connection
Data Sent: 1 unknown byte
Data Received: 1 unknown byte
Closes an active TCP connection.
Command 0x28 - DNS Query
Data Sent: Domain Name
Data Received: 4 bytes for IP Address
Looks up the IP address for a domain name, presumably using the DNS server addresses sent in Command 0x21
Command 0x6E - Error Status
Data Sent: N/A. Adapter sends this in response to a failed command
Data Received: 1 byte for command that failed + 1 byte for error status
If a previously sent command fails, the adapter will respond with this instead, indicating the command that failed as well as a brief status code. The error statuses for one command do not indicate the same error for another command, so context matters when parsing the codes. The following commands and their known error status codes are listed below:
0x10: Error Code 0x01 - Sent twice
0x10: Error Code 0x02 - Invalid contents
0x12: Error Code 0x03 - Dial telephone with telephone disconnected
0x14: Error Code 0x00 - Wait for call with telephone disconnected
0x15: Error Code 0x01 - Transfer data without being connected
0x19: Error Code 0x02 - Read outside of config area
0x1A: Error Code 0x02 - Write outside of config area
0x21: Error Code 0x01 - ISP login with disconnected phone
[Mobile Adapter GB] : Protocol - Configuration Data
The Mobile Adapter has small area of built-in memory designed to store various settings for its configuration. It only uses 192 bytes but data is readable and writable via the Commands 0x19 and 0x1A respectively. These fields are filled out when running the initial setup on Mobile Trainer. The memory is laid out as describe below:
--------------------------
0x00 - 0x01 :: "MA" in ASCII. The "Mobile Adapter" header.
0x02 :: Set to 0x1 during Mobile Trainer registration and 0x81 when registration is complete
0x04 - 0x07 :: Primary DNS server (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 making an online connection. Generally, they return the error code 25-000 in that situation.
If any compatible software attempts to read or write configuration data outside the allotted 192 bytes via commands 0x19 and 0x1A, the entire I/O operation is cancelled. No data is written even if the initial offset is within the 192 bytes. No data is returned either, as both commands respond with Error Status packets.
Game Boy Wars 3
[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
[Hello Kitty no Happy House] : General Information
Hello Kitty no Happy House is a Game Boy Color title featuring furniture collection, minigames, and online communication. The game revolves around interacting with Hello Kitty, gaining new furniture, and decorating the "Happy House". As it concerns the Mobile Adapter GB, Hello Kitty no Happy House boasts basic email capabilities. Through the email service, users could share different furniture as presents.
[Hello Kitty no Happy House] : Server Structure
Hello Kitty no Happy House is not known to access any resource via HTTP. Instead, it simply communicates with a SMTP server and POP3 server for sending and receiving email respectively.
[Hello Kitty no Happy House] : Email
Email can be sent and received in Hello Kitty no Happy House, much like Mobile Trainer. The game offers similar tools to write the email, helping users fill out subjects, addresses, and content, and viewing the mailbox for received items. The game also sends "presents" to another user via email. The standard email format looks something like this (note that xxxx, yyyy, and zzzz parts are not exact lengths, consider them as variables):
From: =?ISO-2022-JP?xxxxxxxxxxxxxxxxxxxxxxxx <yyyy@zzzz.dion.ne.jp>
To: =?ISO-2022-JP?xxxxxxxxxxxxxxxxxxxxxxxx <yyyyyyyyy>
Subject: =?ISO-2022-JP?xxxxxxxxxxxxxxxxxxxxxxxx
MIME-Version: 1.0
Content-Type: text/plain; charset="ISO-2022-JP"
Content-Transfer-Encoding: 7bit
X-Mailer: Hello Kitty Happy House
X-Game-title: HKITTY_HH
X-Game-code: CGB-BK7J-00
[content of email]
The game uses two additional custom SMTP email headers to send furniture to another player. These headers are parsed for a 3-letter ASCII code which determines the item received. After the "X-Game-code" header, the following would be inserted before the content of the email:
X-GBmail-type: exclusive
X-HKH-HOUSE: [3-letter code]
The codes appear to be simple, e.g. "AAE" for a framed picture and "AIG" for a green rug.
Mobile Trainer
[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
cgb/download?name=/A4/CGB-BMVJ/*
[Net de Get] : General Information
Net de Get is a Game Boy Color game published by Konami and released on June 12, 2001. In addition to being one of the select few GBC games to support the GB Mobile Adapter, it is the only known game to use the MBC6. This special cartridge allowed the Game Boy to download minigames online and save them locally to Flash memory for offline play. Players earn points based on their performance in minigames. Once enough points have been accumulated, they can be exchanged for downloadable minigames.
[Net de Get] : Server Structure
Net de Get is currently known to access the following URLs:
Although a few other URLs are present within the ROM, the above are the only ones observed in actual use.
[Net de Get] : h0000.cgb
After some points are earned through the base set of minigames, players unlock the "セーバ" or "Server" option from the main menu. After the user's password is given, this file is then downloaded via HTTP GET. The purpose of h0000.cgb is simply to display the text "ミニゲームリスト" or "Minigame List". Selecting this downloads RomList.cgb via HTTP GET. The format of h0000.cgb is described below:
----------------------------------
Header - 4 bytes
----------------------------------
0x0000 - "M" :: 0x4D
0x0001 - "N" :: 0x4E
0x0002 - "G" :: 0x47
0x0003 - "L" :: 0x4C
----------------------------------
Text offset - 6 bytes
----------------------------------
0x0004 - Offset :: Offset to text string. Calculated as 10 + (Offset * 5).
0x0005 - ??? :: 0x0005 through 0x0009 seem to be ignored.
0x0006 - ??? ::
0x0007 - ??? ::
0x0008 - ??? ::
0x0009 - ??? ::
[Net de Get] : RomList.cgb
After h0000.cgb is downloaded, next comes RomList.cgb. This file contains a list of all available minigames the server has to offer. It also displays how many points it costs to download, as well as the type of minigame being downloaded.
----------------------------------
Entry Count - 1 byte
----------------------------------
0x00 - Number of entries :: (1 - ?) Maximum not currently known.
----------------------------------
Data Offsets - 2 bytes each
----------------------------------
0x01 :: Low byte of 16-bit internal offset to RomsList.cgb data structure.
0x02 :: High byte of 16-bit internal offset to RomsList.cgb data structure.
... :: Repeat offsets as needed.
----------------------------------
Data Structure
----------------------------------
0x00 :: Number of points necessary for download (modulus 100). Should be 0x00 - 0x63 ideally.
0x01 :: Mini-game icon type. See Icon Type below for details.
0x08 - 0x0A :: Disables download (grayed out text). All 3 must be zero, otherwise download is disabled.
0x0C - 0x0F :: Disables menu item completely (no text, item not selectable). All 4 must be zero, otherwise menu item is disabled.
0x10 :: String Length 1. Each menu item should ideally be 12 characters or less (font is fixed width). Used for minigame name.
0x11 - ... :: Menu Item Text (see String Format below).
0x11 + String Length 1 :: String Length 2. Each menu item draws additional text to a small on-screen textbox. Used brief explanations about minigame. Ideal max is 0xF.
0x11 + 1 + String Length 1 :: Additional textbox string.
0x11 + 6 + String Length 1 & 2 :: Unique ID for download. 8 characters max.
Minigames have their own categories and can be assigned their own specific icons. The following bytes dictate what icon is drawn:
----------------------------------
Icon Type
----------------------------------
0x00 :: Question Mark 不定その他 Unspecified other aka misc.
0x01 :: Boxing Glove アクション Action
0x02 :: Green Head パズル Puzzle
0x03 :: Running Person オーソドックス Orthodox aka Platformer?
0x04 :: Sword アールピージー RPG
0x05 :: Green Sheet シミュレーション Simulation
0x06 :: Fighter Jet シューティング Shooter/Shooting game
0x07 :: Red Square アドベンチャー Adventure
0x08 :: Blue Square (P) プログラム Program i.e. a full minigame, as opposed to additional data.
0x09 :: Green Square (D) ??? ???
0x0A :: Red Square (A) アペンド Additional minigame data.
0x0B :: Brown Square (S) ??? ???
Each mini game has two icons. The first describes the main type, "Program" for the main minigame, or "Append" for additional data or content. The 2nd icon describes the sub-type for the minigame. Apparently for minigame downloads, the main type is forcibly set to "Program". Byte 0x01 of the data structure controls only the 2nd icon, the sub-type. In that regard, only values of 0x00 through 0x07 are contextually correct. It should also be noted that two other main types seem to exist (the Green and Brown squares), but they are unused, or at least have no mention whatsoever in the game manual.
[Net de Get] : cgb/download?name=/A4/CGB-BMVJ/*
The GB Mobile Adapter attempts to access this URL for downloading minigames. The file containing the minigame is appended to the base URL. The appended part should be 12 characters, 4 for the price in yen, followed by 8 characters for rest of the unique ID. Although it is unknown if this really was the case, it would make sense to use the minigame ID (e.g. "G000") along with ".cgb". Thus a full URL would be something like:
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 :: Points required to play the minigame.
0x06 :: Primary minigame icon.
0x07 :: Secondary minigame icon.
0x09 - 0x0C :: Game ID, simply in the format "Gxyz" where "xyz" are three numbers. E.g. the first minigame ID in the Net de Get ROM is "G000"
0x0F - ... :: Text for game title. Null terminated, but nothing stops it from being too long. Text can technically spill over multiple lines.
0x24 - ... :: Text for dialog box. Null terminated.
0x44 :: If this is 0xFF, it prints the game title, otherwise the title is blank. Oddly enough, the dialog box is unaffected and always printed.
0x6D - 0x6E :: Always 0x3B, 0xB3. Acts like a watermark for valid minigames. Net de Get checks this specifically to tell if a game is on Flash ROM.
0x6F - ... :: Code + Data.
Generally, the jump instruction goes right to Byte 0x6F, but not always. When the minigame is selected from the menu and the play (あそぶ) option is selected, the MBC6 switches Bank 0 (0x4000 - 0x5FFF) with Flash ROM, then performs a CALL 0x4000, which in turn executes the jump instruction and starts the minigame. It should also be noted that the downloaded minigame code is actually executed from Flash ROM rather than copying it somewhere else first like WRAM.
Unlike the previous icons from RomList.cgb, each minigame's primary icon can be specified. The secondary minigame icon is nearly identical to the format in RomList.cgb, but contains some variations:
----------------------------------
Primary Minigame Icon Type
----------------------------------
0x00 :: Gray Square (P) プログラム Program i.e. a full minigame, as opposed to additional data. Might be "disabled" since it's gray.
0x01 :: Blue Square (P) プログラム Program i.e. a full minigame, as opposed to additional data.
0x02 :: Green Square (D) ??? ???
0x03 :: Green Square (D) ??? ???
0x04 :: Red Square (A) アペンド Additional minigame data.
0x05 :: Gray Square (A) アペンド Additional minigame data (disabled?).
0x06 :: Gray Square (A) アペンド Additional minigame data (disabled?).
0x07 :: Gray Square (A) アペンド Additional minigame data (disabled?).
0x08 :: Brown Square (S) ??? ???
----------------------------------
Secondary Minigame Icon Type
----------------------------------
0x00 :: Question Mark 不定その他 Unspecified other aka misc.
0x01 :: Boxing Glove アクション Action
0x02 :: Green Head パズル Puzzle
0x03 :: Running Person オーソドックス Orthodox aka Platformer?
0x04 :: Sword アールピージー RPG
0x05 :: Green Sheet シミュレーション Simulation
0x06 :: Fighter Jet シューティング Shooter/Shooting game
0x07 :: Green Square アドベンチャー Adventure
For the secondary icon, everything above 0x08 results in garbage tile data being drawn on-screen. 0x07 is the same icon as in RomList.cgb, except the color is now green instead of Red. Strangely enough, the game manual only shows the red version of that icon.
[Net de Get] : String Format
Blank entries represent values that are not used and can effectively be treated as spaces.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00
0x10 ! " # $ % & ' ( ) * + ‘ - . /
0x20 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
0x30 [ ¥ ] x ÷ { | } ˜ @ ⌜ ⌟ — ~ 、 。
0x40 A B C D E F G H I J K L M N O
0x50 P Q R S T U V W X Y Z ✜ ‥ ^ _ ’
0x60 a b c d e f g h i j k l m n o
0x70 p q r s t u v w x y z Ⓐ Ⓑ
0x80 ぁ あ ぃ い ぅ う ぇ え ぉ お か き く け こ さ
0x90 し す せ そ た ち っ つ て と な に ぬ ね の は
0xA0 ひ ふ へ ほ ま み む め も ゃ や ゅ ゆ ょ よ ら
0xB0 り る れ ろ ゎ わ を ん → ← ↑ ↓ •
0xC0 ァ ア ィ イ ゥ ウ ェ エ ォ オ カ キ ク ケ コ サ
0xD0 シ ス セ ン タ チ ッ ツ テ ト ナ ニ ヌ ネ ノ ハ
0xE0 ヒ フ ヘ ホ マ ミ ム メ モ ャ ヤ ュ ユ ョ ヨ ラ
0xF0 リ ル レ ロ ヮ ワ ヲ ン ☎ ♪ ☺ ☺ ★ ❤ ゚ ゙
A couple of things to note, since some characters listed are not quite the same in Unicode as they are on Net de Get:
[Net de Get] : MBC6 Flash Operation
The MBC6 writes games to Flash ROM for long-time data storage. Although technically it has a limited number of lifetime writes, it does not rely on a battery unlike cartridge SRAM for DMG/GBC games. The MBC6 uses the MX29F008TC-14. While no specific documentation about the MX29F008TC-14 is available, the following information has been reverse-engineered based on how Net de Get's code expects Flash ROM to work.