Joybus Protocol

Revision as of 19:23, 12 November 2020 by Bigbass (talk | contribs) (Added bold and italics to emphasize checksum vs CRC)

The Joybus Protocol is a proprietary, non-standard, serial protocol by which the N64's Peripheral Interface (as well as the GameCube and Game Boy Advance) communicates with controllers, controller accessories (Controller Pak, Rumble Pak, etc.), keyboards, mice, game cartridges, and other devices plugged into the console.

Operation

 

The protocol utilizes four types of bits: Zero, One, the Console Stop Bit, and the Controller Stop Bit. Zero, One, and the Controller Stop Bits are 4μs long, while the Console Stop Bit is 3μs. Communication is always initiated by the console, by sending an 8 bit (one byte) command to the device plugged in (not necessarily always a standard controller). A Console Stop Bit will usually follow after this command byte unless there is more data.

The controller or device will read this command and any extra data, and then respond appropriately. For example, when the console wishes to write to a Controller Pak, it will send 0x03, followed by a 2 byte address, 32 bytes of data, and then the stop bit.

The default state of the data pin is HIGH. If the connected device isn't in the process of sending a signal, it should not default to sending a HIGH signal (either set to LOW for reading, high-impedance, or disconnect). Wrongly setting the pin HIGH may disrupt the console and will prevent intermediate devices from reading any console signals.

Command List

Because all commands are exactly 8 bits long, there can be a total of 256 commands. However, only about 16 are known for the N64, and a few more for GameCube and Game Boy Advance. Games also have the ability to define custom commands with or without extra data, but official controllers or devices will not understand them.

Command Description Console Devices Tx Bytes Rx Bytes
0xFF Reset & Info N64, GC, GBA All 1 3
0x00 Info N64, GC, GBA All 1 3
0x01 Controller State N64 Controller, Mouse 1 4
0x02 Read Controller Accessory N64 Transfer, Controller, Bio Sensor, and Rumble Paks 3 33
0x03 Write Controller Accessory N64 Transfer, Controller, Bio Sensor, and Rumble Paks 35 1
0x04 Read EEPROM N64 Cartridge ? ?
0x05 Write EEPROM N64 Cartridge ? ?
0x06 Read RTC(1) Status N64 64DD, Animal Forest ? ?
0x07 Read RTC(1) Block N64 64DD, Animal Forest ? ?
0x08 Write RTC(1) Block N64 64DD, Animal Forest ? ?
0x09-0x0D Unknown N64 VRU ? ?
0x0E Reserved ? ?
0x0F Unknown ? ?
0x10 Reserved ? ?
0x11 Reserved ? ?
0x12 Reserved ? ?
0x13(2) Read Keypress N64 Randnet Keyboard 2 7
0x14(2) Read GBA[1] GC, GBA GBA 3 33
0x15(2) Write GBA[1] GC, GBA GBA 35 1
0x16-0x2F Unknown ? ?
0x30 Force Feedback GC Steering Wheel ? ?
0x31-0x3F Unknown ? ?
0x40 Short Poll GC Controller ? 8
0x41 Read Origin GC Controller ? ?
0x42 Calibrate GC Controller ? ?
0x43 Long Poll GC Controller 3 10
0x44-0x53 Unknown ? ?
0x54 Poll GC Keyboard ? ?
0x55-0xFE Unknown ? ?

(1) Real Time Clock
(2) Requires verification, might be offset by one.

Command Details

0xFF - Reset / Info

While identical to 0x00 in what data is returned to the console, if a device has an intended reset function, it should be performed when this command is sent. The N64 controller for example will reset the internal position of its analog stick to (0, 0), essentially recalibrating it. Other devices may have similar functionality, or none at all, but either way they should still send back the same data as if the 0x00 command was sent.

0x00 - Info

This command requests information about the device. The N64 a 2-byte identifier and 1 byte of extra data.

Identifier Console Device
0x0500 N64 Controller
0x0500 N64 Dancepad
0x0001 N64 VRU
0x0200 N64 Mouse
0x0002 N64 Randnet Keyboard
0x2004(1) N64 Densha de Go
0x0004 GBA Game Boy Advance
0x0900(1) GC Controller
0x8800(1) GC Receiver
0x8B10(1) GC Wavebird
0x0800(1) GC Steering Wheel
0x0802(1) GC Keyboard
0x0808(1) GC Dance Mat

(1) Requires verification yet.

0x01 - Controller State

The response for this command is always the same length of 4 bytes (32 bits), but the data it represents will change depending on the type of controller device. A Controller Stop Bit is always included after the response bytes. Note that in the following waveform diagrams, any LOW bit should send a Zero Bit as described in the operation section above. Do not hold the line LOW constantly.

Standard Controller

The most common is the standard N64 controller. In which case, the data is the current state of the inputs from the controller: the 14 buttons, the current position of the analog stick, and the reset (RST) bit. The default state of buttons and RST is Zero. If a button is pressed, it becomes One. If LT, RT, and Start are pressed, RST is One, Start becomes Zero, and the analog stick's position is reset to (0, 0). Each axis of the analog stick is a Two's Complement byte, giving a decimal value ranging from -128 to +127, even though a standard controller may not reach the full range due to physical limitations. The bit order from left to right, of the response data, is as follows:

 

Mouse

The mouse follows a similar format to the standard controller. However, it only uses the A and B buttons, and the x/y axis bytes represent the relative position of the mouse.

 

Densha de Go

Dancepad

0x02 - Read Controller Accessory

0x03 - Write Controller Accessory

Checksums

There are two different checksums used in some of the official commands. The first is an 8 bit CRC, and the other uses eleven different XOR values based on the position of each set bit. While the former is used for large chunks of data, the latter is used to check the 11 bit address for where that data is written to or read from. These checksums are used to ensure data integrity. The address checksum, which is 5 bits long, is always a part of the communication sent from the console to the device, just after the 11 bit address.

Data CRC

The 8 bit CRC known to be used in the controller accessory read/write commands, and the GBA read/write commands. It uses a standard CRC8 function, with a seed (initial value) of 0x00, and 0x85 for the polynomial. A CRC polynomial is a mathematical way to say that a particular number is used as a mask, or to be applied to the working CRC byte using an XOR operation. The mathematical form can be expressed as  .

In every known case, the connected device is always the side which generates this CRC. For read commands, it reads 32 bytes of data from a particular address, calculates the CRC, and sends all 32 bytes plus the CRC byte back to the console. For write commands, it calculates the CRC from the 32 bytes sent by the console, sends the CRC byte back, and performs the write operation. The order in which it does this may differ for different devices. For write commands, the device has a window of approx 62.5 microseconds after the console stop bit, to begin sending the CRC byte.

Address Checksum

When the console wishes to read data from, or write data to, a particular address on the connected device, it will send the top 11 bits of a 16 bit address, plus a 5 bit checksum. This means these operations must be done in 32 byte chunks, as the lower 5 bits of the address are assumed to be 0, to make room for the checksum. By definition, this checksum is not a CRC, because it doesn't use a cyclic code (as in, there is no bit shifting used), and the XOR value is not constant.

The 5 bit checksum is calculated using the following table. The working checksum is initially set to zero. For each bit of the 11 address bits, starting at the upper-most bit, if the bit is set (is 1), then XOR the corresponding byte to the working checksum. If the bit is clear (is 0), do nothing and move onto the next bit.

15 14 13 12 11 10 9 8 7 6 5
0x01 0x1A 0x0D 0x1C 0x0E 0x07 0x19 0x16 0x0B 0x1F 0x15

If the resulting checksum matches the one provided by the console, the address is valid.

The process as pseudocode:[2]

for bits 15 -> 5
    if the bit is set
        xor the checksum with the corresponding value in the above table

References