gameboy-rust/docs/hardware/serial.md

18 KiB
Raw Permalink Blame History

Disconnected serial subset

The core supports disconnected normal-mode transfers, external-clock waiting, idle multiplayer, local Joybus registers, and general-purpose pins. Internal clocks shift pulled-high input at nominal GBA rates. No link partner is emulated. External clock edges, connected multiplayer transfers, UART, Joybus communication, and GPIO interrupts remain unsupported. Unsupported activity remains diagnostic rather than reporting a fabricated completion.

Registers

  • SIODATA32 at 0x04000120 holds the 32-bit shift register. Byte lanes and halfword accesses are supported.
  • SIODATA8 at 0x0400012a holds the 8-bit shift register; its upper byte reads zero. Each transfer shifts only its selected data register. The other register retains its value.
  • SIOCNT at 0x04000128 retains normal 8/32-bit mode, IRQ configuration, clock selection, and the output-data bit. The retained mask is 0x508b. The disconnected serial input is high, except when a general-purpose output drives it low. Start bit 7 requests a transfer. Bit 0 selects external or internal clock; bit 1 selects the internal rate. Completion or software cancellation clears start. Multiplayer uses the separate format described below; UART remains diagnostic.
  • RCNT at 0x04000134 retains mode bits, interrupt configuration, output latches, and pin directions with mask 0xc1ff. With bit 15 clear, bits 8 and 14 are writable latches without GPIO interrupt or Joybus effects. With bit 15 set, bit 14 selects Joybus; bit 8 is unused in that mode. With bit 15 set and bit 14 clear, bit 8 enables GPIO interrupts, which remain diagnostic. In general-purpose mode, each input reads high through its pull-up. Each output reads its output latch. RCNT=0x8000 therefore reads back as 0x800f, not 0x8000. Normal, multiplayer, and Joybus low-byte pin readback remains unmapped rather than guessed.
  • JOYCNT, JOY_RECV, JOY_TRANS, and JOYSTAT support the disconnected configuration described below.

GPIO means general-purpose input/output. UART means universal asynchronous receiver/transmitter. No external serial device is connected. Only an enabled internal serial clock can shift data or generate a completion IRQ. Configuration that hardware accepts in other modes can still be rejected by this intentionally limited subset.

External-clock waiting

In normal 8-bit or 32-bit mode, setting start with clock-source bit 0 clear requests externally clocked communication. No device is connected, so no external clock edges arrive. Start remains set; data does not shift and no completion IRQ occurs. The internal-rate selector, bit 1, does not supply clocks when bit 0 is clear. CPU cycles, timer overflows, display events, and DMA activity cannot manufacture external serial clocks. Repeated start writes do not complete the request. Software can cancel it by clearing start, including through BIOS serial reset.

General-purpose mode does not shift serial data. A retained external-clock start bit has no link-port effect there. Returning to normal mode still cannot complete a transfer without external clock edges. Selecting internal clock while an unshifted request is pending starts a fresh nominal bit period. This is a disconnected waiting model, not an implementation of a connected link or an external clock-input API.

Original tests cover both widths, rate settings, control lanes, cancellation, GPIO selection, HALT/STOP, and ARM/Thumb stores. DMA tests distinguish its own completion IRQ from a serial IRQ. Invalid word/block stores cannot leave a partial start request.

Internal clocks and completion

Normal mode shifts most-significant bit first. At each nominal sampling edge, the selected register shifts left and receives a one. The disconnected SI input is high. Completion therefore leaves 0xff or 0xffffffff, without inventing peer data. Reads between edges expose the partially shifted value. SO waveforms and normal-mode RCNT pin samples remain unmodeled.

At the nominal 16,777,216 Hz system clock:

SIOCNT bit 1 Cycles per bit 8-bit transfer 32-bit transfer
0 64 512 cycles 2,048 cycles
1 8 64 cycles 256 cycles

The first sample occurs one full bit period after activation. Selecting internal clock for an unshifted external request uses this same rule. A repeated start write with unchanged width/clock fields preserves the current phase and remaining bit count. A width/clock change before any bit has shifted starts a fresh period. Data writes before that first bit preserve the phase. Software cancellation clears progress but retains already shifted data. Whole-access writes merge control and data lanes before applying start/cancel behavior; byte writes remain separate accesses.

Completion clears start and latches IF bit 7 when SIOCNT bit 14 is enabled at the final edge. IE, IME, and CPSR.I gate wake-up or delivery, not request latching. Clearing IF acknowledges the request. A completed request does not reassert IF without another transfer. HALT continues internal shifting and bounds its idle batch at serial completion. STOP freezes the bit phase and remaining count. Only keypad wake is implemented for STOP; serial GPIO wake still requires its missing external-input model.

Bus timing and validation

Serial state shares the timer/audio transaction during CPU instructions, IRQ entry, and DMA units. Each access observes all elapsed source/data cycles through its bus-completion phase. A start write excludes its preceding cycles. A load excludes its trailing internal cycle. IF reads and acknowledgements include serial completion through that access, alongside timer requests. Successful steps commit serial state and requests once. Failed steps discard speculative shifts, writes, and completion IRQs. The display/capture scheduler does not clock serial again after that commit. CPU-only stepping can change registers but does not advance serial clocks.

Block-store preflight simulates ordered access phases on temporary timing/device copies before committing any write. Validation can therefore accept reconfiguration when an earlier request completes before the write reaches the bus. The actual transfers then execute once from the original state. Other IF sources and DMA completion flags remain independent.

Bounded behavior

After any bit has shifted, changes to width, clock selection/rate, or the selected data register remain diagnostic while start stays set. Selecting GPIO or Joybus during an internally clocked request also remains diagnostic. Clear start before these operations. IRQ-enable and idle SO configuration writes remain supported without restarting progress. These limits also apply to BIOS services that write serial registers; cancel active transfers before requesting serial reset. Unverified live reconfiguration is not silently approximated.

The period arithmetic follows documented GBA rates. Activation phase, mid-transfer register visibility, and exact pin edges lack physical-hardware validation. No external pin waveform, cable, connected partner, or serial-device protocol is implemented. Original tests cover individual shifts, batching, cancellation, IRQ gating, HALT/STOP, bus phases, DMA, capture independence, and rollback.

Disconnected multiplayer configuration

With RCNT bit 15 clear, SIOCNT mode bits 12–13 equal to 2 select multiplayer format. The retained control mask is 0x6f03: baud selection, unused writable bits 8–11, mode, and IRQ enable. This subset models an idle unit without a cable, not a parent with missing players.

  • SI reads high in status bit 2, identifying a child rather than a parent.
  • SD reads high in bit 3 because the local idle output is high. This does not establish connected peers.
  • ID bits 4–5 read a deterministic zero placeholder. Hardware does not define the ID before a completed transfer. Zero must not be interpreted as an assigned parent role; SI determines that role.
  • Error bit 6 and busy bit 7 remain clear. No parent supplies the clock that starts a child transfer.
  • Start is read-only for a child. Writing it cannot start a transfer, reset receive data, or request an IRQ.

All baud settings retain this idle behavior. Elapsed cycles, DMA, and repeated start writes cannot create a linked transfer. No multiplayer event can wake HALT. STOP retains the configuration without advancing clocks. When GPIO is selected, SI/SD status follows the existing GPIO pin model; multiplayer transfers still cannot run. RCNT low-byte samples remain unmapped outside GPIO mode. Floating clock-pin timing is not guessed.

Multiplayer data registers

SIOMLT_SEND at 0x0400012a is a 16-bit latch in multiplayer format. It shares its low byte with normal-mode SIODATA8. Normal upper-byte reads return zero and writes are ignored. Normal 8-bit shifts change only the low byte. The hidden upper byte survives mode changes in this bounded model. A word write to SIOCNT selects the final format before applying both SEND lanes.

SIOMULTI0 through SIOMULTI3 occupy halfwords at 0x04000120, 0x04000122, 0x04000124, and 0x04000126. The first two alias SIODATA32. The last two are accessible only with multiplayer format selected, including under GPIO. Byte, halfword, and word accesses preserve independent lanes. Receive latches start at zero under the synthetic reset policy and retain data across mode changes. Selecting multiplayer or writing child start does not replace them with 0xffff, local SEND data, or invented peer data.

Receive writes follow GBATEK's R/W register description. The pinned mGBA implementation instead leaves these writes unhandled. Physical receive-write behavior, reset values, and hidden upper-byte retention have not been independently measured. These are bounded register-model choices, not evidence of successful reception or full firmware-reset accuracy.

Validation and limits

Mode changes use staged serial state at the bus-completion phase. A high-byte mode write cannot silently cancel a busy normal transfer through multiplayer's read-only start mask. Clear start explicitly, or wait for normal completion. A completion IRQ already requested remains pending after mode selection. Block-store preflight observes earlier mode writes and rejects later invalid accesses without committing preceding writes.

Original tests cover control masks, all baud selections, register lanes, aliases, GPIO, HALT/STOP, and ARM/Thumb/DMA stores. Bus-phase tests cover normal completion, retryable diagnostics, block loads/stores, and mode-dependent staged reads. There is no parent, cable topology, external clock input, multiplayer timeout, or linked-game compatibility claim.

Disconnected Joybus configuration

RCNT bits 14–15 both set select Joybus. The GBA is a slave; an external master must initiate communication. This subset has no master, cable, commands, or external clock input. Selecting the mode does not start communication. RCNT bit 8 remains a writable inactive latch, not a GPIO interrupt enable. RCNT low-byte pin samples remain unmapped: GPIO output latches must not substitute for unverified Joybus pin levels. SIOCNT is unused in Joybus. Its existing format latches remain readable without synthetic SI/SD status or internal shifting. UART-format writes still return the existing diagnostic, including while Joybus is selected.

  • JOYCNT at 0x04000140 retains interrupt enable in bit 6. Unused bits read zero. Reset, receive-complete, and send-complete flags in bits 0–2 are write-one-to-clear. They remain zero because no master can produce those events. Enabling interrupts cannot itself request IF bit 7.
  • JOY_RECV at 0x04000150 and JOY_TRANS at 0x04000154 retain independent 32-bit data latches. Byte, halfword, and word accesses preserve other lanes. Synthetic initial data is zero, not received peer data. Local receive writes do not set receive status or a completion flag.
  • JOYSTAT at 0x04000158 retains software flags in bits 4–5. Every local transmit-data write sets bit 1, including a zero write or a write to an upper lane. This means a reply is available for a master; it does not mean transmission completed. Software cannot directly set or clear hardware status bits 1/3 by writing JOYSTAT. Receive-pending bit 3 remains zero. Receive reads therefore have no observable read-clear effect in this disconnected subset.

Transmit pending survives elapsed time, mode changes, status writes, and empty-event acknowledgements. No Joybus event wakes HALT or STOP. Joybus selection disables the normal serial clock even if SIOCNT retains start. The existing live normal-transfer limits still apply when entering Joybus. Clear start or wait for normal completion first. A normal completion at the write's bus phase remains pending in IF after the mode change. Registers participate in serial transactions, including failed CPU/DMA access rollback and block-store preflight. Word accesses to JOYCNT and JOYSTAT reject unmapped upper padding without partial writes.

Local Joybus registers remain accessible in other modes under this bounded latch model. Receive writes follow GBATEK's R/W description; the pinned mGBA implementation leaves them unhandled rather than storing them. mGBA corroborates JOYCNT/JOYSTAT masks in Joybus and sets transmit pending from either halfword outside mode dispatch. Cross-mode masks, CPU receive writes, synthetic reset values, and byte-lane behavior lack physical-hardware validation. These choices do not establish GameCube communication, hardware reset accuracy, or linked-game compatibility.

Original tests cover masks, lanes, pending status, mode gating, inactive IRQ bits, HALT/STOP, and ARM/Thumb/DMA accesses. Staged tests cover completion boundaries, local readback, rollback, and later block-store failures. Original desktop programs also check status/data through terminal and native-window execution.

BIOS reset

RegisterRamReset always clears the low halfword of SIODATA32, even without bit 5. The upper halfword remains unchanged in this functional subset. With bit 5 selected, the firmware clears SIOCNT and SIODATA8 and selects general-purpose inputs. It clears JOYCNT interrupt enable and both Joybus data latches. Its zero write to JOY_TRANS sets transmit pending. It does not write JOYSTAT; software flags remain unchanged. This is the replacement's functional sequence, not a claim about complete hardware BIOS reset side effects. It uses ordinary ARM bus stores, not a host-side reset bypass. Clearing SIOCNT cancels a pending external-clock request. Unselected serial reset leaves that request pending. The firmware writes SIODATA8 after selecting normal format. This does not clear the retained upper multiplayer SEND byte. Full multiplayer reset side effects remain unverified; this increment does not extend the firmware reset sequence.

Original tests cover independent byte lanes, input pull-ups, output directions, reset flag selection, and explicit unsupported operations. Whole-access and block-store validation prevent a rejected control value from committing preceding bytes or registers. Static RCNT mode rejection uses the complete high byte. Live-transfer validation additionally uses staged serial state. Mode-gating tests cover every high-byte value, previous modes, low-byte preservation, CPU stores, DMA retries, and unchanged interrupt state. Inactive configuration bits do not wake HALT. RCNT word accesses still reject the unmapped padding at 0x04000136.

References

  • GBATEK reset functions: reset flags, general-purpose selection, and the unconditional SIODATA32 side effect.
  • GBATEK normal serial mode: data widths, MSB-first shifting, rates, pulled-high SI, start/completion, IRQ selection, and external-clock waiting.
  • GBATEK multiplayer mode: child start restrictions, SI/SD status, undefined pre-transfer ID, register widths, and R/W receive registers.
  • LinkRawCable at c61bf351: public API usage for mode selection, SEND, receive words, and separate role/readiness/ID checks. Its disconnected-cable warning is not a pin-level measurement.
  • GBATEK Joybus mode: slave-only communication, RCNT/SIOCNT roles, local register masks, R/W data, and status side effects.
  • mGBA I/O implementation at 3a5e34be: transmit-pending writes and receive-status read clearing; compare with masks and unhandled receive writes in its serial implementation below.
  • GBATEK mode summary: RCNT/SIOCNT mode selection.
  • mGBA serial implementation at 3a5e34be: cross-checked normal transfer-duration arithmetic and completion IRQ handling. Its no-driver scheduled completion and zero receive data are not copied; they do not establish disconnected hardware behavior. Multiplayer comparison covers SI/SD defaults, receive-write disagreement, and uncertain floating SC timing.
  • GBATEK: GBA general-purpose pin directions, internal pull-ups, SI falling-edge interrupts, and the SIO mode-selection table.
  • mGBA BIOS implementation at 3a5e34be: functional serial reset defaults, not copied source.

Exact firmware write ordering and hardware pin timing remain unverified.