Reading one byte and getting 0x00 cannot distinguish 'decode is wrong' from 'reply is late' -- a one-byte window has nowhere for a late answer to show up. These two probes clock EIGHT data bytes and print every slot, so the position of 0x17 (NWAYS) or 0x04 (device ID) gives the latency directly, the same way bit-shift analysis turned 00 00 00 10 into 'correct, 22 bits late'. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
re-bba-rb — on-console test suite (GameCube)
A .dol you run from Swiss that drives the adapter in Serial Port 1 and
reports pass/fail per test on the TV.
Build
Needs devkitPro's gamecube-dev group (devkitPPC + libogc). The devcontainer
installs it — if DEVKITPPC is unset, rebuild the container, since the
toolchain is added in .devcontainer/Dockerfile.
make # -> gc_bba_test.dol
Copy the .dol to your SD card (SD Gecko / SD2SP2) and launch it from Swiss.
Controls
| Button | |
|---|---|
| D-pad up/down | move |
| A | open a suite / rerun the selected test |
| X | run the selected suite |
| START | run everything |
| Y | clear all results |
| B | back |
What it tests
| Suite | Proves |
|---|---|
| Identity | device enumerates: 04 02 02 00, HIPR, NWAYS |
| Registers | PAR0–5, IMR writable and read back; IR is write-1-clear |
| Reset/control | NCRA RESET self-clears, SR holds |
| EXI integrity | 200 reads with no bit errors; which EXI clock indices work |
| Ethernet | MAC readback, 60-byte ARP transmit (TI), frame receive (RWP/RI) |
| SPRAM/DMA | ring descriptor is well-formed; reads ≥ 0x100 stream until CS |
Things that will bite you
The device ID is a ONE-SHOT. Address 0 returns 04 02 02 00 only until
the first NCRA reset clears id_phase in the gateware; after that it reads
back NCRA. That is correct — it matches the GC's own init order — but it means
the Identity test can only pass once per console power cycle. Run it before
the Reset suite. On a re-run the app reports SKIP with an explanation rather
than a misleading failure.
TI is not proof of transmission. It only means TXFrameDrain handed the
frame to the W5100. A frame can set TI and never reach the wire. The TX test
says so; to confirm the wire, capture on a PC or watch the RX test pick up a
reply.
The RX test needs traffic. It waits ~2 s for any frame. On an isolated
link with nothing talking it will fail legitimately — give the PC an address on
the same subnet (the ARP the TX test sends is aimed at 10.0.0.50, so
sudo ip addr add 10.0.0.50/24 dev <nic> makes the PC answer it and both tests
pass together).
Never over-clock a register read. Asking for N bytes and clocking more
leaves stale prefetched bytes queued and desynchronises the next transaction
— a deterministic every-Nth-read corruption that looks like a signal-integrity
fault. bba_read() clocks exactly len; don't "round up" for convenience.
TXDATA takes one byte per transaction. The register file's effective
address auto-increments per data byte, so a 4-byte write to 0x48 would spill
into 0x49–0x4B. bba_tx_bytes() does it correctly.
Build status
Builds clean (no warnings) with devkitPPC 16.1.0 / GCC 16 in the devcontainer:
gc_bba_test.dol, ~172 KB, entry 0x80003100.
.gitignore excludes the build products — run make to produce the .dol.