mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-11-01 12:14:56 +02:00
The receive loop re-armed all 16 descriptors into the other slot after every completed frame. During a burst that re-pointed descriptors the chip had ALREADY filled but the consumer had not read, so those frames were lost without a trace: the LANCE DMA log shows all 23 dictionary datagrams written by the chip, 1.132 ms apart (the MTU/bandwidth poll cadence), while the payload's own counters accounted for 4 (DICT_BYTES=1448, dict_bad=3). Nothing was dropped by MAME; the ring was being rewritten under the frames it held. rx_switch()/rx_armed are gone. A descriptor is held (rx_hold) while its datagram belongs to the frame being assembled, and rx_release() hands each one back -- into the other slot -- only once that frame has been parsed or abandoned. Nothing the chip delivered is ever re-pointed unread. Measured, same zero-gap 23-datagram dictionary upload: before dgram=4 DICT_BYTES=1448 dict_bad=3 release fix, 16 descriptors dgram=18 DICT_BYTES=24616 dict_bad=0 plus a 32-descriptor ring dgram=23 DICT_BYTES=32768 dict_bad=0 The ring is now 32 descriptors because 23 datagrams is the burst the protocol actually defines (a whole 32 KB dictionary at MAX_BODY 1448), and 16 could not hold it while the consumer copied. SLOT_BYTES grows to 49152 to hold the ring; POOL_BYTES does NOT grow -- the 160 KB "framebuffer reserve" was unused slack (the decoder paints straight from the fragments), so the extra 24,576 B per slot comes out of it and the LANCE block keeps its fixed 0x3C000 tail. RX_OK is now published after rx_release(), not inside the dispatch. It is the "frame done" signal a reader polls, and it used to become visible while descriptors were still being rewritten: ring mode caught a descriptor holding slot B's high byte with slot A's low word. A reader that sees RX_OK move now sees a painted picture and a consistent ring. vidstream.lua's ring mode follows: it asserts the invariant that replaced the flip -- the consumed descriptors move to the other slot, the untouched ones stay -- instead of "all 16 in slot B". Evidence: 146 unit tests pass; modes rx, draw, ring, tiles, delta and replay all PASS with their pixel checkers (draw 1024/1024 rows, tiles and replay via tile_check). End to end over rdebug with the STOCK sender (no pacing): the dictionary burst completes (DICT_READY=1, DICT_BYTES=32768, dict_bad=0) and RX_OK=100 frames paint, TILES_DROP=0.