Two faults the 60 fps work exposed, both in the delivery tooling:
* `demo.sh --no-load` waited for the terminal to answer ping. A loaded payload
owns the LANCE and stops the OS's stack with it, so that gate can never pass
once the payload is running -- the recovery path documented for "already
jumped" deadlocked for its full 180 s. The gate now runs only when this
invocation is going to load the payload.
* `rdebug_load.py` used a 5 s socket timeout and no retry, so a readback peek
that timed out on a freshly booted OS failed a load whose pokes had already
been acknowledged. Timeout is 15 s (--timeout) and the readback retries once
before it is believed.
Tests: the retry path is pinned with a fake remote that times out on the first
peek (one timeout, then the successful pass over every chunk) and one that never
answers (it must raise rather than loop). 9 tests in harness/badapple pass.
A new folder so the demo can be reproduced instead of re-derived: the delivery
and the clip packing were living in throwaway scripts under /tmp, and the only
written route to a real clip was an ffmpeg recipe that packs MSB first -- the
order that mirrors every eight pixels on a display.
harness/badapple/rdebug_load.py image -> terminal RAM over the firmware's
own remote-debug service (TCP 771), then
jump to the entry from vidstream.env
harness/badapple/clip_from_video.py video -> LSB-first 1-bpp frames for
make_tiles.py --clip
harness/badapple/demo.sh ICMP gate, load, send; one command
harness/badapple/README.md setup, run in MAME, run on real hardware,
what success looks like, failure modes
The loader records the two protocol facts that cost time to find: a 512-byte
poke chunk (1024 is mis-parsed as a following opcode: "Invalid command
0xA5A5A5A5"), and that nothing can be probed after the jump, so the image is
read back BEFORE jumping and the run is observed from the machine afterwards.
Tests cover what a wrong assumption would silently corrupt -- chunk arithmetic,
the linkage the entry point is read from, and pixel 0 landing on bit 0 -- and
the tool was exercised end to end against MAME: demo.sh loaded the payload and
the terminal reported DICT_BYTES=32768, DICT_BAD=0, RX_OK=28, TILES_DROP=0
while the sender saw frames_rx=129, drops=0.
153 tests pass (7 new).