1- # joypad-gba
1+ # joypad-tester / gba
2+
3+ GBA multiboot payloads that ship inside [ joypad-tester] ( .. ) . Two ROMs
4+ build from this one source tree:
5+
6+ - ** ` joypad_mb.gba ` ** — Doridian-style joybus controller + animated
7+ cartoon eyes overlay. Consumed by
8+ [ joypad-os] ( https://github.com/joypad-ai/joypad-os ) via submodule for
9+ its GBA-as-controller mode.
10+ - ** ` tester_mb.gba ` ** — Doridian-style joybus controller + an on-GBA
11+ console showing live button state, with an idle screensaver that
12+ bounces the joypad logo (color-cycling on each wall hit) à la the
13+ GameCube tester. Embedded into joypad-tester's GameCube/Wii host so
14+ testers see visual feedback on the GBA, and runnable standalone from
15+ a flash cart as a pure button-tester ROM.
16+
17+ The ` build/ ` tree ships pre-built artifacts so consumers using this
18+ folder as a submodule (e.g. joypad-os) don't need devkitARM unless
19+ they're modifying the source:
220
3- GBA multiboot payload that doubles as a USB controller (via the GameCube↔GBA
4- link cable) and renders animated cartoon eyes on the GBA screen.
21+ ```
22+ build/joypad/joypad_mb.gba # eyes ROM (raw multiboot binary)
23+ build/joypad/joypad_payload.c # (C array for embedding)
24+ build/tester/tester_mb.gba # tester ROM (raw multiboot binary)
25+ build/tester/tester_payload.c # (C array for embedding)
26+ ```
527
6- Designed to be embedded into firmware that drives the GameCube side of a
7- joybus link — e.g. RP2040-based controller adapters — but the payload itself
8- is host-agnostic. Anyone with a working joybus multiboot uploader can use it.
28+ Each ` *_payload.c ` exports the same symbol names:
929
10- The ` build/ ` directory ships pre-built artifacts so consumers using this
11- repo as a submodule don't need devkitARM unless they're modifying the source:
30+ ``` c
31+ extern const uint8_t joypad_payload[];
32+ extern const uint32_t joypad_payload_len;
33+ ```
1234
13- - ** ` build/joypad_payload.c ` ** — the payload as a C array (` joypad_payload[] `
14- + ` joypad_payload_len ` ) ready to compile into a host project
15- - ** ` build/joypad_mb.gba ` ** — the raw multiboot binary, suitable for dumping
16- onto a flashcart or piping through any joyboot uploader
35+ so a host can drop either file in and the embedding code doesn't have
36+ to change. Pick the variant that fits your product.
1737
1838## Lineage
1939
20- The joybus handshake + main loop in ` source/main.c ` (the ` 0x30303030 `
21- exchange, ` ResetHalt ` , ` REG_JSTAT ` polls, SVC ` 0x26 ` BIOS reset on
22- ` JOYCNT.RST ` ) is taken verbatim from ** Doridian's
40+ The joybus handshake + main loop in ` source/main.c ` and
41+ ` source/main_tester.c ` (the ` 0x30303030 ` exchange, status-bit polls,
42+ SVC ` 0x26 ` BIOS reset on ` JOYCNT.RST ` ) is taken from ** Doridian's
2343[ Joybus-PIO] ( https://github.com/Doridian/Joybus-PIO ) ** ` gba/source/main.c `
2444(2023). That sequence is load-bearing for the cable's level-shifter MCU;
25- modifying it breaks the host's view of input. The animated- eyes overlay
26- runs in the VBlank slot on top of it.
45+ modifying it breaks the host's view of input. The eyes overlay and the
46+ tester console run on top of it.
2747
2848Chain of credit:
2949
3050- ** [ gbatek] ( https://problemkaputt.de/gbatek.htm ) ** (Martin Korth) —
31- authoritative GBA hardware reference (SIO / Joybus / BIOS reset semantics)
32- - ** [ libgbacom] ( https://github.com/Sage-of-Mirrors/libgbacom ) ** (Sage-of-Mirrors,
33- ported from VisualBoyAdvance) — original reverse-engineering of the
34- joyboot stream cipher
51+ authoritative GBA hardware reference (SIO / Joybus / BIOS reset
52+ semantics)
53+ - ** [ libgbacom] ( https://github.com/Sage-of-Mirrors/libgbacom ) **
54+ (Sage-of-Mirrors, ported from VisualBoyAdvance) — original
55+ reverse-engineering of the joyboot stream cipher
3556- ** [ gc-gba-link-cable-demo] ( https://github.com/FIX94/gc-gba-link-cable-demo ) **
3657 (FIX94) — canonical GameCube-side reference for booting a GBA over the
3758 link cable
3859- ** [ Joybus-PIO] ( https://github.com/Doridian/Joybus-PIO ) ** (Doridian) —
3960 RP2040-PIO implementation of the GameCube side, plus the GBA-side
40- controller payload this repo forks
41- - ** This repo** — animated-eyes overlay (port of joypad-os's ` eyes_anim ` ),
42- per-emotion FG/pupil palette, dpad-as-self-centering-analog gaze,
43- ACTIVE → wander → sleep cycle
61+ controller payload these variants build on
62+ - ** This subtree** — eyes overlay (port of joypad-os's ` eyes_anim ` ),
63+ Mode-4 page-flipped screensaver matching the joypad-tester GC
64+ variant's logo + colour cycle, two-build Makefile, robust joybus
65+ reset handling (polls ` JOYCNT.RST ` inside the VBlank busy-wait so
66+ host cmd 0xFF triggers ` SystemCall(0x26) ` within microseconds)
4467
4568## Embedding
4669
47- Drop ` build/joypad_payload.c ` into your host firmware's source list. It
48- exports:
49-
50- ``` c
51- extern const uint8_t joypad_payload[];
52- extern const uint32_t joypad_payload_len;
53- ```
54-
55- Then feed those bytes to your joybus multiboot uploader. See
70+ Drop the appropriate ` build/<variant>/<variant>_payload.c ` into your
71+ host firmware's source list, then feed ` joypad_payload[] ` /
72+ ` joypad_payload_len ` to your joybus multiboot uploader. See
5673[ joypad-os] ( https://github.com/joypad-ai/joypad-os ) 's
57- ` src/native/host/gc/gba_multiboot.c ` for a reference uploader implementation
58- (Kawasedo handshake, stream cipher, polled WRITE/READ).
74+ ` src/native/host/gc/gba_multiboot.c ` or this repo's
75+ [ ` ../gamecube/ppc/gba.c ` ] ( ../gamecube/ppc/gba.c ) for reference uploader
76+ implementations (Kawasedo handshake, stream cipher, polled WRITE/READ,
77+ unconditional handshake-complete write).
5978
6079## Building (only if you change source)
6180
@@ -70,36 +89,38 @@ sudo dkp-pacman -S gba-dev
7089# https://devkitpro.org/wiki/devkitPro_pacman
7190
7291export DEVKITPRO=/opt/devkitpro
73- make
74- ```
75-
76- Outputs:
7792
78- ```
79- build/joypad_mb.gba # multiboot ROM
80- build/joypad_payload.c # same bytes as a C array
93+ make # build both variants
94+ make joypad # build only the eyes ROM
95+ make tester # build only the tester ROM
96+ make clean # nuke build/
8197```
8298
83- Both are committed in this repo; rebuild and commit them whenever you change
84- the source.
99+ Outputs land in ` build/joypad/ ` and ` build/tester/ ` . Both ` *_mb.gba `
100+ and ` *_payload.c ` are committed; rebuild and commit them whenever you
101+ change source.
85102
86103## Layout
87104
88105```
89106.
90- ├── Makefile # devkitARM build → build/joypad_mb.gba + .c
107+ ├── Makefile # two-variant build → build/<variant>/
91108├── source/
92- │ ├── main.c # entry point, IRQ wiring, joybus handshake (Doridian)
93- │ ├── display.c/.h # Mode-4 framebuffer + DMA present
94- │ ├── eyes_anim.c/.h # cylinder-eye renderer + emotion state machine
109+ │ ├── main.c # eyes variant entry (joybus + eyes_anim)
110+ │ ├── main_tester.c # tester variant entry (joybus + console
111+ │ │ # + Mode-4 page-flipped screensaver)
112+ │ ├── display.c/.h # Mode-4 framebuffer for the eyes variant
113+ │ ├── eyes_anim.c/.h # cylinder-eye renderer + emotion state
114+ │ │ # machine
95115│ └── platform/
96- │ └── platform.h # stub for shared eyes_anim platform API
116+ │ └── platform.h # stub for shared eyes_anim platform API
97117├── tools/
98- │ └── bin2c.py # binary .gba → C array converter
99- └── build/ # committed pre-built payload artifacts
100- ├── joypad_mb.gba
101- └── joypad_payload.c
118+ │ └── bin2c.py # binary .gba → C array converter
119+ └── build/ # committed pre-built payload artifacts
120+ ├── joypad/
121+ │ ├── joypad_mb.gba
122+ │ └── joypad_payload.c
123+ └── tester/
124+ ├── tester_mb.gba
125+ └── tester_payload.c
102126```
103-
104- The flat layout (no ` gba/ ` subdir like Doridian's repo, since this whole
105- repo * is* the GBA payload) keeps embedding paths short.
0 commit comments