First frame from a live scene: trek, assembled from the emit stream

trekframe.py parses the captured payload blocks (0x100 headers, rowid words
0x300|row, packed edge fields) into per-scanline spans and composites them onto
an 832x512 canvas -- 21 blocks / 124 spans from the trek demo's compiled stream:
distinct multi-colored objects + slanted band elements. dumppay.py dumps the
payload region at chosen draws (scene verified byte-identical draws 1-300 =
compile-once static showcase). Readout gains §06 with the frame rendered from
the span data. First-approximation decode (edge-field scaling still being
pinned) -- but every mark is a span the firmware's rasteriser emitted.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-16 21:26:40 -05:00
co-authored by Claude Opus 4.8
parent a7a59af9b4
commit c2db52e69b
3 changed files with 193 additions and 1 deletions
+45 -1
View File
@@ -362,7 +362,25 @@
</section>
<section>
<h2><span class="idx">06</span> What it took to get here</h2>
<h2><span class="idx">06</span> First frame from a live scene — the Star Trek demo</h2>
<p class="sub">The archive's <span class="mono">trek</span> capture — unreleased Star Trek
material — now <b>replays and draws</b>. After the dual-instruction-mode fix, its full
pipeline runs on the emulated i860: classify, LOD select, rasterise, and <b>emit compiled
micro-code</b> per 64×128 tile. Below is that frame, assembled by reading the emit stream
back out of DRAM: <b>21 payload blocks, 124 scanline spans</b>, each block a primitive of
the scene. This is a <b>first-approximation decode</b> (the span/edge field scaling is
still being pinned), drawn from the board's own compiled render program — the deepest
read-out of this hardware yet.</p>
<div class="hero-render" style="margin-top:16px">
<span class="tag">decoded from the compiled emit stream · first approximation</span>
<canvas id="trekframe" width="832" height="512" aria-label="frame assembled from trek's compiled emit stream"></canvas>
<div class="cap"><b>trek, draw 1300 (static showcase scene)</b> — every mark is a span
the firmware's rasteriser emitted; colors distinguish payload blocks (primitives).</div>
</div>
</section>
<section>
<h2><span class="idx">07</span> What it took to get here</h2>
<p class="sub">The i860 core was corrected against the toolchain's own assembler output
and MAME's validated i860 model. A selection of the load-bearing fixes:</p>
<div class="fixlist">
@@ -699,6 +717,32 @@
dx.putImageData(img,0,0);
})();
/* ---- trek frame: spans decoded from the compiled emit stream ----
Each block = one primitive's payload; span = [row, edgeA, edgeB] (x = edge*4). */
var TREK=[[[423,3,9],[424,2,8],[425,1,7],[426,6,6],[427,6,6]],[[423,15,21],[424,14,20],[425,13,19],[426,12,18],[427,12,18]],[[428,3,9],[429,2,8],[430,1,7],[431,6,6],[432,6,6]],[[423,24,182]],[[280,4,4],[281,4,4],[282,4,4],[283,4,4],[284,4,4],[285,4,4],[286,4,4],[287,4,4],[438,171,171]],[[280,8,12],[281,8,12],[282,8,12],[283,8,12],[284,8,12],[285,8,12],[286,8,12],[287,8,12],[438,171,171]],[[280,16,20],[281,16,20],[282,16,20],[283,16,20],[284,16,20],[285,16,20],[286,16,20],[287,16,20],[438,171,171]],[[272,204,204],[273,203,203],[274,202,202],[275,201,201],[276,200,200],[277,200,200],[278,200,200],[279,200,200],[439,177,177]],[[264,196,196],[265,195,195],[266,194,194],[267,193,193],[268,192,192],[269,192,192],[270,192,192],[271,192,192],[439,177,177]],[[256,188,188],[257,187,187],[258,186,186],[259,185,185],[260,184,184],[261,184,184],[262,184,184],[263,184,184],[439,177,177]],[[280,177,184]],[[415,28,204],[416,27,203],[417,26,202],[418,25,201],[419,24,200],[420,24,200],[421,24,200],[422,24,200]],[[415,28,196],[416,27,195],[417,26,194],[418,25,193],[419,24,192],[420,24,192],[421,24,192],[422,24,192]],[[415,28,188],[416,27,187],[417,26,186],[418,25,185],[419,24,184],[420,24,184],[421,24,184],[422,24,184]],[[264,202,202],[265,201,201],[266,200,200],[267,200,200],[286,169,169]],[[260,194,194],[261,193,193],[262,192,192],[263,192,192],[286,169,169]],[[256,186,186],[257,185,185],[258,184,184],[259,184,184],[286,169,169]],[[314,183,183]],[[456,98,98],[457,98,98]],[[286,207,207]],[[440,107,107],[441,106,106],[442,105,105],[443,104,104],[444,103,103],[445,102,102],[446,101,101],[447,100,100],[448,99,99],[314,194,194]]];
(function(){
var tc=document.getElementById('trekframe'); if(!tc) return;
var tx=tc.getContext('2d'), W=tc.width, H=tc.height;
// starfield-dark ground
tx.fillStyle='#05080d'; tx.fillRect(0,0,W,H);
var COLS=['#41ff8e','#5fd0ff','#ffb020','#ff5a6a','#eaffef','#a078ff','#c8c85a','#5ac8a0'];
TREK.forEach(function(blk,bi){
tx.fillStyle=COLS[bi%COLS.length];
tx.globalAlpha=0.9;
blk.forEach(function(s){
var y=s[0], x1=s[1]*4, x2=s[2]*4;
tx.fillRect(Math.min(x1,x2), y, Math.max(4, Math.abs(x2-x1)), 1.6);
});
// glow pass
tx.globalAlpha=0.25;
blk.forEach(function(s){
var y=s[0], x1=s[1]*4, x2=s[2]*4;
tx.fillRect(Math.min(x1,x2)-1, y-1, Math.max(6, Math.abs(x2-x1)+2), 4);
});
tx.globalAlpha=1;
});
})();
/* ---- IGC tile footprint: which 64x128 tiles the array lit for the object ---- */
var TILES={ntx:10,nty:5,touched:[[0,2],[1,1],[1,2],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3],[4,1],[4,2],[4,3],[5,1],[5,2],[6,1],[6,2],[7,1],[8,1]]};
(function(){