Add on-console GameCube test suite + devkitPPC in the devcontainer
gc_bba_test/ builds a .dol that drives the adapter over raw EXI from the
console and reports pass/fail per test on the TV, navigable with the pad.
Uses libogc's EXI API against EXI0:2 (Serial Port 1) rather than its bba
network driver: driving the register file directly gives each check its own
verdict, so a failure points at a specific register instead of at
'networking'. Six suites - identity, registers, reset/control, EXI link
integrity (including an EXI clock-index sweep), ethernet TX/RX, SPRAM/DMA
streaming.
Encodes the hardware lessons from bring-up so the app cannot mislead:
* the device ID is a one-shot cleared by the first NCRA reset, so it is
reported SKIP on a re-run rather than FAIL
* TI means the frame reached the W5100, NOT the wire - the TX test says so
* register reads clock exactly the requested length (over-clocking
desynchronises the next transaction)
* TXDATA is written one byte per transaction (eff_addr auto-increments)
.devcontainer/Dockerfile gains the devkitPro gamecube-dev group. devkitPro
publishes no .deb on GitHub, so this uses their installer script against
apt.devkitpro.org -- which is 403 from inside the running container's egress
but reachable from a host-side docker build. Rebuild the container to get it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
# 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`.
|
||||
|
||||
```bash
|
||||
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.
|
||||
Reference in New Issue
Block a user