Every .uf2 differs from v2.1.0 — the DAC configuration was reimplemented on top of Adafruit's library, worth about +9.4 KB per game. The audio itself is unchanged, and that was checked on hardware rather than assumed: five games, five distinct synthesis paths, each measured against its own pre-change capture and listened to.
This completes a review of the project's hardware dependencies. v2.1.0 covered storage and portability; this one covers audio and the architecture layout.
src/arch/ — architecture, separated from board
Two layers that had been tangled together:
| example | ||
|---|---|---|
| arch | the silicon | fast-RAM placement, timer registers, PIO, DMA |
| board | the product | which pins, which DAC and its address, which display |
src/arch/arch.h dispatcher and the contract
src/arch/rp2040/rp2040.h placement and time sources
src/arch/rp2040/arch_audio_i2s.* the PIO + DMA I2S transport
src/arch/esp32/esp32.h stub — untested, and labelled as such
A Fruit Jam and a Feather RP2350 are two boards on one architecture; an ESP32 board is a different architecture as well. Adding one is a folder plus a single #include — nothing in src/cpu/ or src/machines/ should need to change.
This is groundwork, not ESP32 support. A working ESP32 target still needs a board backend, and the video path is the hard part: the Fruit Jam drives DVI over the RP2350's HSTX with the second core parked in hal_video_run(), which has no ESP32 equivalent.
The TLV320 is configured through Adafruit's library
Roughly 45 hand-written register pokes became typed calls into Adafruit_TLV320_I2S. The I2S transport — a PIO state machine and a chained DMA pair — stays hand-written and moved to src/arch/rp2040/, because no library replaces it: that library is I2C configuration only, with no data path. Which is the good outcome, since it means none of the interrupt-facing code was touched.
The configuration is a translation, not a redesign: every step is the same operation in the same order, checked against the library's own example.
Verified on hardware
| game | audio type | |
|---|---|---|
| Lunar Rescue | WAV samples + bit-banged speaker | ISR 151→150 µs, 0 samples dropped |
| Burger Time | two emulated AY-3-8910 PSGs | 0 audio underruns |
| Galaga | Namco WSG + 54XX — the busiest mix | ISR average identical; worst 295→289 µs |
| Pac-Man | Namco WSG | starve 0, queue floor unchanged |
| Space Invaders | WAV with the looping UFO channel | work 5,331→5,299 µs |
All five confirmed by ear as well — every sound present, volume correct. Serial can only show the DAC was configured without complaint, not that it was configured correctly.
Also: 13 of 13 examples build, all 8 host harnesses build, REUSE 182/182, arduino-lint --library-manager submit reports 0 errors.
Flashing
Hold BOOT while connecting USB (or hold BOOT and tap RESET), then copy the .uf2 onto the RP2350 drive. The binaries contain no ROM data — you still need a microSD card with legally-obtained ROMs, laid out as each game's README describes.