diff --git a/src/Four_Player_Adapter.md b/src/Four_Player_Adapter.md index 3dfbc92d..139715c0 100644 --- a/src/Four_Player_Adapter.md +++ b/src/Four_Player_Adapter.md @@ -5,41 +5,136 @@ to connect for multiplayer via [serial data transfer](./Serial_Data_Transfer_(Li The device is primarily designed for DMG consoles, with later models requiring Link Cable adapters. -## Communication +## Power + +The DMG-07 will not power on until its Player 1 cable is plugged into +a Game Boy link port to supply power. The Player 1 cable is the only one +permanently attached to the device and has the power pin connected, +unlike typical link port cables. + +## Clock Control + +Serial clock for all transfers is provided by the DMG-07, with connected +Game Boys operating in external clock mode. Trying to send data via internal +clock mode results in garbage data and should not be used. + +## Communication Phases 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. +connection status. Afterwards, the DMG-07 is switched to the transmission +phase where the Game Boys exchange data across the link cable network. +Later, connected Game Boys may switch back to ping phase by sending the +["ping restart sequence"](<#Restarting Ping Phase>). + +## Ping Phase + +When the DMG-07 is powered up it will begin operation by automatically +sending out ping packets periodically on every port. In order to start +receiving these ping packets a connected Game Boy should use external +clock mode (bit 0 of SC set to 0) and request a transfer +(bit 7 of SC set to 1). + +All connected Game Boys will receive 4 bytes for each ping packet. +Transfer of the 4 bytes is not spread evenly over the packet time period; +instead, transfer is clustered at the start, followed by a much longer delay. -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. +The power-up timing for ping packets is as follows: +- Serial Clock period: 15.95 microseconds (62.66 KHz) +- Transfer time per byte: 128 microseconds +- Delay between bytes: 1.42 milliseconds +- Transfer time for all bytes: 4.71 milliseconds +- Delay between packets: 12.29 milliseconds +- Total packet and delay time: 17 milliseconds -### Ping Phase +This means one ping packet with 4 bytes and its subsequent delay takes +a little more time than a single Game Boy video frame. -When a "master" Game Boy (Player 1) is first connected to the adapter, -setting Bit 7 of SC to 1 and setting Bit 0 of SC 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: +### Ping Packet Fields +The ping data received by each Game Boy looks like this: Byte | Value | Description -----|-------|------------- - 1 | \$FE | ID Byte + 1 | \$FE | PING HEADER 2 | ?? | STAT1 3 | ?? | STAT2 4 | ?? | 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 midway through a ping, typically on STAT2 or STAT3. Each STAT byte -looks like such: +The chart below illustrates how Game Boys should respond to bytes in a ping packet: +Received From DMG-07 | Game Boy Reply +---------------------|----------------------- +PING HEADER (\$FE) | ACK1 = (\$88) +STAT1 | ACK2 = (\$88 ) +STAT2 | RATE (Packet Timing) +STAT3 | SIZE (Packet Size) + +Note: Bytes in the Received column should have the matching byte in the Reply +column loaded into the SB register to be sent during the next serial transfer. + +### ACK Replies + +The ACK1 and ACK2 bytes use a fixed value (\$88) and are sent in reply to +the PING HEADER and STAT1 bytes. + +### RATE Setting +The RATE setting configures packet timing and works differently in the ping and +transmission phases. It is sent in reply to the STAT2 byte. + +Note: In both phases the value \$00 for RATE has special behavior where it does not +change the speed, so it should not be used. + +#### RATE in Ping Phase +In ping phase RATE only adjusts the delay between packets (byte timing is unchanged) +and takes effect immediately upon the next packet. The timing is calculated as follows: +``` +Delay between packets = (12.2 milliseconds) + ((RATE & 0x0F) * 1 millisecond) +``` +Where: +- Transfer time for all bytes: 4.71 milliseconds (always) +- Delay between packets: 12.2 to 27.21 milliseconds + +This yields a range of 12.20 to 27.21 milliseconds for the total packet and delay time. + +#### RATE in Transmission Phase +In transmission phase the Clock Rate setting is determined by the **last** RATE value +transmitted before exiting ping phase. The timing is more complex and is calculated +as described below. + +First determine the delay between packet bytes: +``` +Delay between bytes = ((RATE >> 4) x .106 milliseconds) + 0.887 milliseconds +``` + +Then the total packet and delay time will be whichever of the following is larger: +``` +((RATE & 0x0F) x 1 milliseconds) + 17 milliseconds +or +(Transfer time per byte + Delay between bytes) x Byte Count) + (between .36 to 2.15 milliseconds) +``` +Where: +- Transfer time per byte: ~0.128 microseconds +- Byte count: 4, 8, 12 or 16 depending on the setting for SIZE +- The formula for calculating the .36 to 2.15 milliseconds add-on is not yet understood. + +This yields a range of 17.0 to 41.6 milliseconds for the total packet and delay time. + +### SIZE Packet Size setting +SIZE sets the number of usable data bytes sent by each Game Boy during a packet +in transmission phase. It is sent in reply to the STAT3 byte. + +The total number of bytes broadcasted by the DMG-07 in a packet will be SIZE×4. +For example if SIZE is 3 then the total packet size will be 12 bytes (3×4). +The range of values which work without issue is 1 to 4. + +### Ping Connection Status + +The 3 STAT bytes sent by the DMG-07 indicate the current connection status of all +the Game Boys. Each byte is usually the same, however, sometimes the status can +change midway through a ping, typically on STAT2 or STAT3. + +Each STAT byte has the following fields: Bit | Name ----|------------------------ 7 | Player 4 Connected @@ -48,22 +143,20 @@ Bit | Name 4 | Player 1 Connected 0-2 | Player ID (1-4) -The Player ID's 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. +The Player ID values are determined by whichever port a Game Boy is connected +to. As more Game Boys connect and properly reply to pings, 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 \$88 *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. +In this way, each Game Boy broadcasts its presence across the link cable +network. 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. -Some examples of ping packets are shown below: +The upper-half of STAT1, STAT2, and STAT3 are updated based on the ping responses +to show when Game Boys are "connected". If for whatever reason, the ping responses +are not sent, the status bits are unset. +Some examples of ping packets sent byte the DMG-07 are shown below: Packet | Description --------------|------------------------------------------------------- `FE 01 01 01` | Ping packet received by Player 1 with no other Game Boys connected. @@ -81,117 +174,151 @@ 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. -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: +## Transmission Phase -``` ----------------------------- -DMG-07 Game Boy ----------------------------- -\$FE <--> (ACK1) = \$88 -STAT1 <--> (ACK2) = \$88 -STAT2 <--> (RATE) = Link Cable Speed -STAT3 <--> (SIZE) = Packet Size -``` +### Entering Transmission phase -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: +In ping phase, when the connected Game Boys are ready, then one of them +(typically Player 1) should send the begin transmission sequence, which is +4 bytes of \$AA in a row (`AA AA AA AA`). The transmission should be aligned +such that the first byte is sent in reply to the PING HEADER field. This +causes the DMG-07 to switch to the transmission phase. -``` -DMG-07 Bits-Per-Second --> 4194304 / ((6 * RATE) + 512) -``` +At the same time the DMG-07 is receiving the fourth consecutive \$AA byte it +will be sending the first of four \$CC bytes in a row (`CC CC CC CC`). +This is the indicator that connected Game Boys should use for switching to +transmission phase. + +After the DMG-07 finishes sending the indicator packet of \$CC bytes it will immediately +begin sending data packets and the transmission phase RATE and SIZE settings take effect. + +The following chart is an example of switching from ping to transmission phase, +with SIZE of 1 (so total packet size is 4 bytes) and only the Player 1 Game Boy +connected. + +| Packet Byte | Received From
DMG-07 | Game Boy Reply | Meaning | +| ----------- | ----------------------- | -------------- | ------------------------------------------------------------ | +| Byte 1 | $FE | $88 | PING HEADER and ACK1 reply by Game Boy | +| Byte 2 | $11 | $88 | STAT1 and ACK2 reply by Game Boy | +| Byte 3 | $11 | $10 | STAT2 and RATE (with a value of \$10) reply by Game Boy | +| Byte 4 | $11 | $01 | STAT2 and SIZE (with a value of \$01) reply by Game Boy | +| | | | | +| Byte 1 | $FE | $AA | Game Boy initiates switch to transmission (4 x \$AA) | +| Byte 2 | $11 | $AA | | +| Byte 3 | $11 | $AA | | +| Byte 4 | $11 | $AA | | +| | | | | +| Byte 1 | $CC | $00 | Start of transmission phase indicator from DMG-07 (4 x \$CC) | +| Byte 2 | $CC | $00 | | +| Byte 3 | $CC | $00 | | +| Byte 4 | $CC | $00 | Final transmission phase indicator from DMG-07 | +| | | | | +| Byte 1 | $AA | $12 | First data packet from DMG-07 (with random data) | +| Byte 2 | $00 | $00 | | +| Byte 3 | $00 | $00 | | +| Byte 4 | $D6 | $00 | End of first data packet | + +Note: Bytes in the Received column should have the matching byte in the Reply +column loaded into the SB register to be sent during the next serial transfer. + +### Transmission Protocol -The lowest setting (RATE = 0) runs the DMG-07 at the normal speed DMGs usually -transfer data (1KB/s), while setting it to \$FF runs it 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. - -### Transmission Phase - -When the master Game Boy (Player 1) is ready, it should send 4 bytes -(`AA AA AA AA`, if those are actually required should be investigated further). -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 receive | P2 receive | P3 receive | P4 receive | 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. +The protocol is simple: At the same time the DMG-07 is sending data it received +during the previous packet, the Game Boys are replying with their new data. +In effect, while receiving old data, Game Boys are supposed to pump new data +into the network. + +Data received by the DMG-07 is buffered until it is broadcast during the next +packet. This means there is a one-packet delay between when the Game Boys send +data and when they receive the packet which combines all their data together. + +The following chart shows data for two consecutive packets with SIZE of 2 +(so total packet size is 8 bytes). The label for a player byte is +`P[player num].[packet num]`, so `P3.1` is Player 3, Packet 1. + +Packet Byte | Received From
DMG-07 | P1 Reply | P2 Reply | P3 Reply | P4 Reply +------------|-------------------------|---------------|---------------|---------------|----------- +1 | P1.0 (byte 1) | P1.1 (byte 1) | P2.1 (byte 1) | P3.1 (byte 1) | P4.1 (byte 1) +2 | P1.0 (byte 2) | P1.1 (byte 2) | P2.1 (byte 2) | P3.1 (byte 2) | P4.1 (byte 2) +3 | P2.0 (byte 1) | 0 | 0 | 0 | 0 +4 | P2.0 (byte 2) | 0 | 0 | 0 | 0 +5 | P3.0 (byte 1) | 0 | 0 | 0 | 0 +6 | P3.0 (byte 2) | 0 | 0 | 0 | 0 +7 | P4.0 (byte 1) | 0 | 0 | 0 | 0 +8 | P4.0 (byte 2) | 0 | 0 | 0 | 0 +Next Packet | | | | +1 | P1.1 (byte 1) | P1.2 (byte 1) | P2.2 (byte 1) | P3.2 (byte 1) | P4.2 (byte 1) +2 | P1.1 (byte 2) | P1.2 (byte 2) | P2.2 (byte 2) | P3.2 (byte 2) | P4.2 (byte 2) +3 | P2.1 (byte 1) | 0 | 0 | 0 | 0 +4 | P2.1 (byte 2) | 0 | 0 | 0 | 0 +5 | P3.1 (byte 1) | 0 | 0 | 0 | 0 +6 | P3.1 (byte 2) | 0 | 0 | 0 | 0 +7 | P4.1 (byte 1) | 0 | 0 | 0 | 0 +8 | P4.1 (byte 2) | 0 | 0 | 0 | 0 + +Note: Bytes in the Received column should have the matching byte in the Reply +column loaded into the SB register to be sent during the next serial transfer. + + +All connected Game Boys should send their data into the buffer during the first few serial +transfers. Here, the packet size is 2 bytes, so each Game Boy should submit their data +during the first 2 transfers. The other 6 transfers don't care what the Game Boys send; +it won't enter into the buffer. The next 8 transfers return the data each Game Boy +previously sent (if no Game Boy exists for a player, that slot is filled with zeroes). 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 +the ping phase. At this time, it is recommended to ignore the first packet received, however, it is safe to start putting new, relevant data into the -buffer. +buffer immediately. -### Restarting Ping Phase +## 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 -(`FF FF FF FF`, it's possible fewer \$FF bytes need to be sent, -but this has not been extensively investigated yet). The bytes alert the DMG-07 -that the ping phase should begin again, after which it sends ping packets after -a brief delay. During this delay, the transmission protocol is still working as -intended until the switch happens. +phase. To do so, any connected Game Boy can send the ping restart sequence, +which is 3 or more \$FF bytes in a row (`FF FF FF FF`). The transmission +should be aligned such that the first byte is sent in reply to the first +serial transfer of a packet. This causes the DMG-07 to switch back to the +ping phase. + +After the third consecutive \$FF byte is received by the DMG-07 and transmission +of the current packet is completed then the DMG-07 will begin transmitting a +packet where all the bytes are set to \$FF. This is the indicator that connected +Game Boys should use for when to switch back to ping phase. + +To avoid false positives the Game Boys should only perform a switch to ping after +receving an entire packet of consecutive \$FF bytes. For example, if the SIZE +setting is 3 then the total packet size is 12 bytes (3×4), which will be the +number of consecutive \$FF bytes to require from the DMG-07 to indicate a switch. + +After the DMG-07 finishes sending the indicator packet of \$FF bytes it will +immediately begin transmitting ping phase packets. + +The following chart is an example of switching from transmission back to ping phase, +with SIZE of 1 (so total packet size is 4 bytes) and the other 3 Game Boys sending +\$A5 for their data byte. + +| Packet Byte | Received From
DMG-07 | Game Boy Reply | Meaning | +| ----------- | ----------------------- | -------------- | ------------------------------------------------------ | +| Byte 1 | $81 | $81 | Game Boy sends its last transmission data (\$81) | +| Byte 2 | $A5 | $00 | Data from Player 2 (\$A5) | +| Byte 3 | $A5 | $00 | Data from Player 3 (\$A5) | +| Byte 4 | $A5 | $00 | Data from Player 4 (\$A5) | +| | | | +| Byte 1 | $81 | $FF | Game Boy initiates ping restart (4×\$FF) | +| Byte 2 | $A5 | $FF | | +| Byte 3 | $A5 | $FF | | +| Byte 4 | $A5 | $FF | | +| | | | +| Byte 1 | $FF | $00 | Start of switch to ping indicator from DMG-07 (4×\$FF) | +| Byte 2 | $FF | $00 | | +| Byte 3 | $FF | $00 | | +| Byte 4 | $FF | $00 | Final switch to ping indicator from DMG-07 | +| | | | +| Byte 1 | $FE | $00 | Now returned to ping phase, start of first Ping packet | +| Byte 2 | $01 | $88 | | +| Byte 3 | $01 | $88 | | +| Byte 4 | $F1 | $00 | + +Note: Bytes in the Received column should have the matching byte in the Reply +column loaded into the SB register to be sent during the next serial transfer.