Joybus Protocol: Difference between revisions

Add command details for EEPROM and RTC
(Add RTC info, set EEPROM read/write byte lengths)
(Add command details for EEPROM and RTC)
Line 113:
 
How the Pak interprets the address and data is up to the Pak in question. The Controller Pak ignores the most significant address bit (the corresponding pin is not physically connected to anything). 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:
 
{| class="wikitable"
! Identifier
! Capacity
! Available Blocks
{{ProtocolIdentifierRow| 0x0080 | 4 Kibibits (512 bytes) | 0-63 }}
{{ProtocolIdentifierRow| 0x00C0 | 16 Kibibits (2048 bytes) | 0-255 }}
|}
 
=== 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.
 
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. Real EEPROMs used by cartridges are rated for up to 100,000 write cycles and may only retain saved data for up to 10 years. Emulators and flashcarts provide alternative storage for EEPROM commands that do not suffer from these issues.
 
=== 0x06 - Read Real-Time Clock Status ===
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.
 
{| class="wikitable"
! Status Byte
! Meaning
! Description
{{ProtocolIdentifierRow| 0x80 | Stopped | RTC is ready for block 2 to be written }}
{{ProtocolIdentifierRow| 0x00 | Running | RTC is ready for block 2 to be read }}
|}
 
=== 0x07 - Read Real-Time Clock Block ===
The RTC has three blocks each containing 8 bytes of data:
 
{| class="wikitable"
! Block
! Purpose
! Comment
{{ProtocolIdentifierRow| 0 | Control registers | Determines the current clock "mode" }}
{{ProtocolIdentifierRow| 1 | Unused | Unknown purpose, theoretically SRAM-backed storage }}
{{ProtocolIdentifierRow| 2 | Date/Time Fields | The current date and time in binary-coded decimal }}
|}
 
RTC Block 0 (Control Registers) use the first 16 bits to control which "mode" the clock is in. The remaining 6 bytes of the response are unused.
 
{| class="wikitable"
! Value
! Mode
! Description
{{ProtocolIdentifierRow| 0x0004 | Set Clock | Clears write-protection bits, sets the stop bit }}
{{ProtocolIdentifierRow| 0x0300 | Run Clock | Sets write-protection bits, clears the stop bit }}
|}
 
RTC Block 1 (Unused) has no discernible purpose. It is not used by Animal Forest, and is not implemented by emulators or flashcarts.
 
RTC Block 2 (Date/Time Fields) updates once per second with 8 bytes of data representing the current date and time. The fields are encoded using packed binary-coded decimals:
 
{| class="wikitable"
! Byte
! Purpose
! Description
{{ProtocolIdentifierRow| 0 | Seconds | (0-59) }}
{{ProtocolIdentifierRow| 1 | Minutes | (0-59) }}
{{ProtocolIdentifierRow| 2 | Hours | (0-23) + 0x80 }}
{{ProtocolIdentifierRow| 3 | Day of Month | (1-31) }}
{{ProtocolIdentifierRow| 4 | Day of Week | (0-6) Sunday - Saturday }}
{{ProtocolIdentifierRow| 5 | Month | (1-12) }}
{{ProtocolIdentifierRow| 6 | Last Two Digits of Year | (0-99) }}
{{ProtocolIdentifierRow| 7 | Centuries since 1900 | (0-1) }}
|}
 
All RTC reads also include a status byte with the same meaning as the "Read RTC Status" command's status byte.
 
=== 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 "Read RTC Status" 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 "Set Mode" (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 "Run Mode" (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.
 
= Checksums =
4

edits