Files
TeslaRel410/emulator/firmware-decomp/M4B-RESULTS.md
T
CydandClaude Opus 4.8 695aacec30 M4b: offline end-to-end seam -- live mission -> faithful frame SEQUENCE
m4b_frames.py fuses the two proven halves: battle_frames.py's live per-draw
program capture (from running-firmware C memory) + render_final.py's verified
M5 texel render (perspective divide + real-texture decode). Result: the whole
renderer chain runs offline from a real fifodump -- production VREND.MNG on the
C i860 core -> per-draw coefficient program -> faithful frame -> PNG sequence.

Verified over netdeath-20260708.fifodump: 12 frames, scene assembles draw by
draw (26->48->78->87->127 quads), frame 11 = coherent perspective-correct arena
interior (tiled floor to vanishing point, ceiling, side structures). This is
the dress rehearsal for the live DOSBox seam -- identical pipeline, wire from a
file instead of the C012 device.

FINDING: firmware is real-time-capable (3.7s), the CPU numpy per-poly render is
the bottleneck (69.9s/12 frames, ~5.8s/frame). The fix already exists: the
conformant GPU tile path (igc_gpu). Moving the per-draw raster onto it is the
M4b->M4c bridge to real-time. Full writeup in M4B-RESULTS.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 09:01:50 -05:00

2.5 KiB

M4b — offline end-to-end seam: RESULTS (2026-07-20)

emu860c/m4b_frames.py — the whole renderer chain, offline, no DOSBox:

fifodump (VPXM wire)  ->  production VREND.MNG on the C i860 core (351x)
  ->  per-draw coefficient program captured LIVE from C memory (0x08158000..)
  ->  M5 faithful render (verified perspective divide + real-texture texel decode)
  ->  frame_NNNN.png sequence  +  timing

Run (netdeath-20260708.fifodump, 12 frames)

queued 53088 records
13 textures decoded from the wire
frame 0:  26 quads (cmd 4584)
frame 2:  48 quads (cmd 5155)
frame 4:  78 quads (cmd 6234)
frame 6:  87 quads (cmd 8046)
frame 10: 127 quads (cmd 10273)
frame 11: 127 quads (cmd 10478)
done: 12 faithful frames in 73.6s (3.7s firmware, 69.9s render), cmd 10479

The chain works end-to-end. Frames show the scene assembling draw by draw (26 -> 48 -> 78 -> 87 -> 127 quads): frame 0 is ceiling + horizon before the floor lands; frame 11 is a coherent, perspective-correct arena interior — tiled floor receding to a vanishing point, paneled ceiling, side structures, with green/blue detail where distinctive textures (emblems/labels) land.

The one finding: render is the bottleneck, not the firmware

  • Firmware: 3.7 s for 10,479 wire commands producing 12 frames — real-time-capable.
  • Render: 69.9 s — the CPU numpy per-poly path (O(quads x 832 x 512) float ops per draw). ~5.8 s/frame. This is the gap to close for the live seam.

The fix already exists: the GPU tile path (igc_gpu / igc_gpu_frame, M1/M2-conformant) does the raster on the RTX in the compute shader. Moving the per-draw raster onto it — reading the full pixel fields (texz/texu/texv/texid) from the tile output and running the same verified texel decode as a vectorized post-pass — is the M4b->M4c bridge to real-time.

Honest scope

  • Verified: geometry, winding, perspective divide, texel decode, live per-draw program capture, full-mission drive, frame sequencing.
  • Best-effort (documented M5-B limit): exact per-surface texid->texture handle. Palette shifts with the mapping (grayscale here vs teal on the static pkl); both are real decoded textures, best-effort placement.

Next (M4c)

  1. GPU raster in the per-draw loop (real-time render to match the real-time firmware).
  2. The C012 link device in DOSBox-X + socket bridge (wire from the live game instead of a file — identical pipeline downstream).
  3. Present path (render-bridge window / vr_readpixels).