Commit Graph
2 Commits
Author SHA1 Message Date
arti d211ff0770 fix(badapple): --no-load must not wait for ICMP; survive a slow readback
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.
2026-10-31 22:20:58 +02:00
arti eabc3051be feat(badapple): the demo as a tool -- rdebug delivery, clip builder, one command
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).
2026-10-31 20:20:35 +02:00