DMG-07 Technical Documentation 0.3
November 23, 2017
Shonumi aka D.S. Baxter

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


The DMG-07 is an accessory that allows 4 Game Boys to connect for multiplayer. First appeared with the game F-1 Race as bundle in 1990. Only a few other games took advantage of it (namely Wave Race and Faceball 2000, Yoshi's Cookie) and it did not see widespread support at all. No idea if the DMG-07 was inspired in part by the NES Four Score (also released in 1990). At any rate, previously the DMG-07 has not been documented in any capacity. Below are my reverse-engineering notes.

***************************************************
2. General Hardware Information
*************************************************** 


DMG-07 is a gray "hub" with 3 input ports for Gen 1 Link Cables.
DMG-07 is largely designed for Gen 1 Link Cables and DMG models. MGB-010s allow any Game Boy (up to the Micro) to connect as Players 2-4.
Player 1 comes with a built-in cable (Gen 1). All other players need extra cables.
Player 1 needs to be a DMG model unless an MGB-004 adapter is used.
DMG-07 uses a Motorola 402038 for multiplexing stuff.

***************************************************
3. DMG-07 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.

===================================================
3.a 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. 

===================================================
3.b 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.

===================================================
3.b DMG-07 Restarting the 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.

The DMG-07 doesn't require the master Game Boy to continually send 0xFF bytes, however. Once it detects them it will eventually switch to the ping phase. The DMG-07 will let all connected Game Boys know about the switch by sending back a certain amount of 0xFF bytes in a special packet:

Transmission-Ping Switch Packet = 0xFF x (Packet Size * 4)

Once that packet has been sent, the DMG-07 immediately sends ping packets and switches speeds if necessary (~256 bytes per second). From there, the entire process starts over.
