The Joybus Protocol is a proprietary, non-standard, serial protocol by which the N64's Serial 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.
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.
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, Densha de Go, Dance Pad, Fishing Rod||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|
|0x06||RTC(1) Info||N64||Dōbutsu no Mori (Animal Forest) Cartridge||1||3|
|0x07||Read RTC(1) Block||N64||Dōbutsu no Mori (Animal Forest) Cartridge||2||9|
|0x08||Write RTC(1) Block||N64||Dōbutsu no Mori (Animal Forest) Cartridge||10||1|
|0x09-0x0D||Unknown||N64||Voice Recognition Unit||?||?|
|0x13(2)||Read Keypress||N64||Randnet Keyboard||2||7|
|0x14(2)||Read GBA||GC, GBA||GBA||3||33|
|0x15(2)||Write GBA||GC, GBA||GBA||35||1|
|0x30||Force Feedback||GC||Steering Wheel||?||?|
(1) Real Time Clock
(2) Requires verification, might be offset by one.
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. Always contains a 2-byte identifier and one byte of extra data.
|Identifier||Console||Device||Third byte (if empty, no details known)|
0x04: checksum error in previous command
0x02: No Pak installed
0x01: Pak installed
|0x0080||N64||4 Kbit EEPROM||Bitfield: 0x80=Write in progress|
|0x00C0||N64||16 Kbit EEPROM||Bitfield: 0x80=Write in progress|
|0x2004(1)||N64||Densha de Go|
|0x0004||GBA||Game Boy Advance|
(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.
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:
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
The game Densha de Go! used an exclusive train controller instead of the standard tri-wing controller. It had five buttons, and two multi-position levers. Refer to the right image for corresponding positions and values for each lever.
Acc refers to the accelerator lever)
While more devices exist that use this command, specific response information is not known at this time.
0x02 - Read Controller Accessory
Reading data from Paks connected to the bottom of a controller, is performed by the console sending this command plus two bytes. These bytes contain an 11 bit address, and a 5 bit checksum which is explained in the next section. The address used is still 16 bits long, however the lower 5 bits will be zeros, meaning addresses can only point to blocks of 32 bytes.
The controller will attempt to read 32 bytes from the Pak starting at the provided address. Upon returning the data bytes, a CRC byte is also returned (also explained below). It must begin responding with data within about 62.5 microseconds.
0x03 - Write Controller Accessory
Similar to reading from a Pak, the write command is followed by two bytes for the address and checksum. But 32 bytes are also provided for writing to the Pak. The controller is still required to respond with a CRC byte for the received data, and it must begin responding within about 62.5 microseconds.
How the Pak interprets the address and data is up to the Pak in question. The Controller Pak uses the most significant bit, in combination with the standard chip-enable, to activate/disable the pak. The Rumble Pak appears to use some kind of flip-flop/toggling logic on certain pins to control it. The Transfer Pak is a gameboy cartridge interface with bank switching. Other homebrew Paks could be utilized in many other ways too.
0x04 - Read EEPROM Block
If EEPROM is available, this command can be used to read 8 bytes of save data at a time. The command (`0x04`) is followed by which block of EEPROM to read from:
|0x0080||4 Kibibits (512 bytes)||0-63|
|0x00C0||16 Kibibits (2048 bytes)||0-255|
In a 512 byte EEPROM, the top two bits of block number are ignored: blocks 64-255 are repeats of the first 64
0x05 - Write EEPROM Block
If EEPROM is available, this command can be used to write 8 bytes of save data at a time. See "Read EEPROM Block" above for block addressing rules. The 8 bytes of data to write are included in the command immediately following the "block" byte. It may take up to 30 milliseconds for the data to be written to EEPROM.
The EEPROM will reply with one byte, 0x80 specifying that the EEPROM was already busy before the write was requested, and 0x00 otherwise.
Real EEPROM data storage has inherent unreliability that requires special consideration: EEPROM chips may become corrupted spontaneously due to uncontrollable factors such as power failure during write or memory cell fatigue causing write failures. It is recommended to use a checksum or parity bits in each EEPROM block to check that the data has not been corrupted. EEPROMs used by retail cartridges are rated for up to 100,000 write cycles and may only retain saved data for up to 10 years. Emulators and flashcarts now provide reliable storage for EEPROM commands that do not suffer from these issues.
0x06 - Real-Time Clock Info
In order to permit using both an EEPROM and the RTC at the same time, the RTC does not respond to command 0, and has its own identify command.
If RTC (Real-Time Clock) is available, this command will return a 2 byte identifier (0x0010) and a status byte. If RTC is not available, this command will respond with three bytes containing zero.
|Status Byte Bit||Meaning||Description|
|7 (0x80)||Stopped||Clock is halted, and it is safe to write to block 2|
|6-2 (0x7C)||Unused||These bits have never been seen set|
|1 (0x02)||Crystal failure||If this bit is set, the crystal is not working|
|0 (0x01)||Battery failure||If this bit is set, the supply voltage of the RTC became too low|
0x07 - Read Real-Time Clock Block
The RTC read command sends 2 bytes (1 for the command, 1 for block selection) and responds with 8 bytes of block data plus a status byte that has the same meaning as the "RTC Info" command's status byte.
The RTC has three blocks each containing 8 bytes of data:
|0||Control registers||Determines the current clock "mode"|
|1||Unused||8 bytes of battery-backed SRAM|
|2||Date/Time Fields||The current date and time in binary-coded decimal|
The top six bits of the block number are ignored: reading from or writing to blocks above the first 4 will wrap within the first four.
All RTC reads also include a status byte with the same meaning as the "RTC Info" command's status byte.
RTC Block 0 (Control Registers)
|7-2 (0xFC)||Empty||Always 0|
|1 (0x02)||Write Protect||Write protects field 2 (RTC)|
|0 (0x01)||Write Protect||Write protects field 1 (NVRAM)|
|7 (0x80)||Unknown||Exists, changeable, no visible function|
|6-3,0 (0x79)||Empty||Always 0|
|2,1 (0x06)||RTC Stop||If either bit is set, stops RTC from counting|
Bytes 2, 3, 6, and 7 always read back as 0.
Bytes 4 and 5 contain 7- and 6- bit numbers respectively that can be updated but have no visible function.
RTC Block 1 (SRAM)
RTC block 1 is not used by Animal Forest, and is not implemented by emulators or flashcarts.
RTC Block 2 (Date/Time)
RTC block 2 updates once per second with 8 bytes of data representing the current date and time. The fields are encoded using packed binary-coded decimals:
|2||Hours||(0-23) + 0x80|
|3||Day of Month||(1-31)|
|4||Day of Week||(0-6) Sunday - Saturday|
|6||Last Two Digits of Year||(0-99)|
|7||Centuries since 1900||(0-1)|
RTC Block 3 (Empty)
RTC block 3 always reads back all zeroes.
0x08 - Write Real-Time Clock Block
The RTC write command sends 10 bytes (1 for the command, 1 for block selection, and 8 for the block data) and responds with a status byte that has the same meaning as the "RTC Info" command's status byte. The block data to write matches the same format as the block read responses in "Read RTC Block" above.
The most-compatible routine for setting the time with the Joybus Real-Time Clock is:
- Send "Write RTC Block" command to Control Registers (Block 0) with write protect disabled and clock stopped (0x0004...).
- Wait 20 milliseconds for RTC block to write.
- Send "Read RTC Status" command, check for "Stopped" (0x80) status: if stopped, proceed; otherwise abort.
- Send "Write RTC Block" command to Date/Time Fields (Block 2) with new time to set.
- Wait 20 milliseconds for RTC block to write.
- Send "Write RTC Block" command to Control Registers (Block 0) with write protect enabled and clock running (0x0300...).
- Poll "RTC Read Status" command until "Running" (0x00) status.
- Wait 500 milliseconds before sending "RTC Read Block" command to Date/Time Fields (Block 2)
Emulator and flashcart support for writing to the Real-Time Clock is not guaranteed:
- Most emulators will ignore RTC write commands and always use the host system's local time.
- EverDrive 64 3.0 and EverDrive64 X7 will ignore Joybus RTC write commands; date/time must be set through the Everdrive OS.
- 64drive hw2 supports Joybus RTC writes, but requires a 500 millisecond delay after setting the time in order to read it back correctly.
For homebrew, it is recommended to test whether the RTC implementation supports the write command to set the proper expectation with players. To do this:
- Read the current RTC time.
- Write a different time to the RTC.
- Read the new RTC time.
- If the new time is within a second of what was written: write back the original time, success; otherwise failure.
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.
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.
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.
If the resulting checksum matches the one provided by the console, the address is valid.
The process as pseudocode:
for bits 15 -> 5 if the bit is set xor the checksum with the corresponding value in the above table
- ↑ 1.0 1.1 LuigiBlood (2019). Reverse enginnering the unreleased GameBoy Printer COLOR.
- ↑ joeldipops (2020). Nintendo 64 Accessory Reference.