Commit Graph
304 Commits
Author SHA1 Message Date
CydandClaude Opus 4.8 cff783d2ad Full-mission replay through the C core: 26,422 commands / 3.49B steps in 39s
The complete cap7 mission -- every command, all 8,562 draws -- executes in
39 seconds at 89.6M steps/s sustained (199,857 Python hook services). The
replayed dict matches the QUEUE ground truth exactly; the old 'baseline'
dict (16793/8397) is exposed as a budget-truncated artifact: the historic
Python regressions hit the 2e9-step budget ~96% through and silently
dropped the last 497 commands. This is the first complete execution of the
whole mission. + M4-LIVE-SEAM.md (the remaining path to live DOSBox) and
emu860c.step1() for hook-driven single-steps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 13:37:38 -05:00
CydandClaude Fable 5 bef1499152 RioSerialLink: type-aware resolution closes the straggler-reply hole
Bench round 3 (testlogs/riomash-patched-62500-sw): lamp glitches
persisted because reply-resolution was type-blind — an analog reply
still crossing USB from the previous poll could falsely confirm the
NEXT command (usually a lamp write) before the board judged it. Now a
reply resolves only its MATCHING pending request (analog/version/
check); ACK/NAK stay type-blind, which is safe because the board's TX
ISR prioritizes ACK/NAK ahead of reply data, so a command's ACK cannot
trail into its successor's window. Budget-exhausted drops settle 10ms
before releasing the gate so late stragglers land on an empty pending.

New test: a stray AnalogReply must not resolve a pending lamp command.
283 green; selftest regression unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 13:34:12 -05:00
CydandClaude Fable 5 b1753964b2 Hardware docs: board photos, schematic scan, GAL fuse dump
Organize the restoration source material under docs/hardware/:
- 9 board photos (renamed from Signal timestamps, index in README)
- Scans_018-014.pdf: 7-sheet VWE schematic set (RIO_1407 CPU/power/IO,
  PBE_1401 buttons, KEY_1402 keypad, DSP_1408 display, AMP_PLT 1413 amp)
- GAL20v8a_5764.JED: fuse map of the 1407's U7 memory decoder

README documents the board family, the 68HC11 memory map decode path,
the pod-bus signal set and jumper addressing, and cross-links PROTOCOL.md
and rio-firmware/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 13:27:36 -05:00
CydandClaude Opus 4.8 be8f72e731 M4a: emu860c -- the i860 step-core in C, 351x, checkpoint-perfect
Full mechanical port of emu860.py's validated semantics: paged memory,
integer ISA, control flow with delayed branches + bc.t/bnc.t annul, DIM
tracking, and the complete FP model (pipes with per-entry result precision,
PFAM/PFMAM dual-op routing, fdest bypass, raw-retire fix/ftrunc, K/T loads).
Python keeps the hooks via a shim; the C loop returns at hook pcs.

Differential result vs the hook-aligned reference trace (ref_trace2):
  139.7M steps/s (Python: 398K/s = 351x), 35.8M steps, 2195 hooks,
  43/43 checkpoints matched (pc + step count + full reg CRC).
The original i860 ran ~40 MIPS: real-time geometry is cleared 3.5x over --
M4's gate (GPU-RETARGET.md) is open.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 13:24:43 -05:00
CydandClaude Fable 5 c170f1535c RioSerialLink: stop-and-wait command delivery (supersedes NAK-race resend)
Bench falsified the v1 retransmit (testlogs/riomash-patched-62500-retx):
resends tracked NAKs 1:1 (321/321) yet lamps still stuck/missed — under
mash bursts the NAK arrives after a newer command is already "latest",
so the wrong packet was resent; and total shreds never NAK at all.

Now commands are stop-and-wait: ONE in flight (_commandGate), resolved
by ACK, NAK, or AckTimeout (50ms); NAK/timeout retransmits THE SAME
packet up to CommandRetransmitLimit (2), then drops (idempotent - the
next state update supersedes). Attribution is exact by construction and
timeouts catch silent shreds. Control-byte replies bypass the gate so
board traffic is never delayed; a request's own reply (analog/version/
check) also resolves the wait, so request/reply exchanges never burn
the timeout even if the board sends no explicit ACK.

7 tests (same-packet resend, timeout retry+drop, ACK completion,
serialization, reply-resolves-request, stray-NAK no-op, disable);
282 green. Mash summary now reports NAK/timeout resends.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 13:20:30 -05:00
CydandClaude Opus 4.8 40817bee91 M2: both fixture frames render on GPU (bars 52-tile ISA path + fxtest primitive path)
Bars: the captured DMA stream walked tile-by-tile through the M1 instruction
shader (real origins, real bench programs), texu ramped to the test card.
fxtest: the per-draw packets as 4-edge primitive records, full-frame compute
dispatch, z-buffered -- the building scene. gpu_bars.png / gpu_fx.png
committed alongside.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 12:31:26 -05:00
CydandClaude Opus 4.8 151d4ca89e M1: the EMC tile as a GL compute shader -- CONFORMANT ON GPU (RTX 5060)
One invocation per pixel, the same 208-bit bit-addressed pixel memory as the
golden model, instruction stream as SSBO records with TREE state resolved at
pack time. Passes C2 (synthetic raster) and C3 (the real cap7 bench bar
programs) bit-for-bit against igc_exec. First step of the GPU retarget
(GPU-RETARGET.md M1); M2 = the frame loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 11:47:57 -05:00
CydandClaude Fable 5 af80d52e22 source410: engine COMPLETE (165/165) - link reaches PE emission; deep ledger cut
The tlink32 campaign after the checkpoint: eleven engine bodies back-dated
from BT412 (rotation player team explode dropzone terrain cultural receiver
subsystm app l4gauge - the Application core included), the WinTesla-ectomy
handled by backdate.py's new unwrap rules (accessor-fn statics -> 1995 static
objects, decl rewrites, pointer->reference Derivation ctor, 2007 windowed-
gauge/console-marshal/idle-pump excisions), staged statics TUs opened for the
game classes (MECH/BTPLAYER/BTDIRECT/PROJTILE/MISSILE/BTL4MPPR .CPP + L4APP/
NETWORK engine statics).

State: every compiled symbol short of the shallow graph RESOLVED (the 52- and
17-symbol ledgers burned to zero); with 32stub.exe in place the linker reaches
full vtable closure and emits the deep ledger (~210 symbols, UNRESOLVED-
LEDGER.txt): remaining engine bodies (objstrm cstr gauge/gaugrend graphics
pixelmap palette resfile ray scnrole explosion-table), the DOS driver extern
layer (_SVGA*/_PCSerial*/_PCSPAK*/joystick/netnub/sosMIDI), the full L4App
body, and the real game-TU frontier (Mech::Make et al.). Recipe proven for
every category.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 11:25:49 -05:00
CydandClaude Opus 4.8 b241d70aaa op-0x2c = edge-bounded strip primitives (2 edges); preamble builder read verbatim
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 11:04:09 -05:00
CydandClaude Opus 4.8 5d29442ecb Golden-model conformance suite (C1-C4 CONFORMANT) + GPU-compute retarget plan
igc_conformance.py pins the reference behaviour any port (RTL/GPU/C) must
reproduce: the DUMP packet parse, a synthetic raster, the bars pipeline
(texu==x+2 from the real cap7 tile programs), and the fxtest effect
primitives (coverage + z pinned) -- fixtures committed under conformance/.
GPU-RETARGET.md maps the DOSBox-renderer path: EMC tile as compute shader
(pixel=thread), 4 milestones, conformance-gated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 10:21:47 -05:00
CydandClaude Opus 4.8 cc7c95d738 ACCEPTANCE 2: fxtest content renders -- perspective ground + textured boxes
The per-draw effect programs (0x816f000, second DMA emitter) parse and
execute through the named ISA: 9 primitives, z-buffered perspective scene
with u/v texture gradients. The earlier 'fixed per-tile program' conclusion
was a sniffer artifact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 09:47:21 -05:00
CydandClaude Opus 4.8 fb04de017e TXDN hunt session 2: a26 = table uploads duplicating firmware .data; texels are transformed on receipt
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 09:18:53 -05:00
CydandClaude Fable 5 6b216d0643 source410: link campaign - entire engine compiles (152/152), first true link,
52-symbol unresolved ledger

build410.sh: merged-engine mass compile + BT TUs + tlib + authentic tlink32.
Engine closure fixes: boxtree/set/l4gauge/filestrm back-dates, lamp<->gaugrend
cycle broken (1995 form), APP.HPP Shutdown default, NetNub include path, DPL
vpx shim, SOS 32-bit lib arbitration (SOSDBXC/SOSMBXC; SOSMW*=16-bit), WATTCP
excluded (16-bit NetNub TSR side). UNRESOLVED-LEDGER.txt = the measured gap to
a linking BTL4OPT.EXE.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 08:46:05 -05:00
CydandClaude Opus 4.8 1e6b5258b3 Texture store = the object graph (action-26 handler identified); route mapped
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 08:10:24 -05:00
CydandClaude Fable 5 d9b34ddc63 source410: THE WHOLE 4.10 TREE COMPILES - 11/11 under the fleet's BC++ 4.52
All 10 surviving original TUs plus the reconstructed BTL4APP.CPP pilot build
clean with the authentic OPT.MAK flags (compile410.sh --sweep). First time
the 4.10 BattleTech source has compiled since 1996.

- layout_probe.cpp: the period compiler measures 1995 layouts from the
  surviving headers; validated 3/3 against binary alloc sizes (BTMission
  0xFC, BTL4ModeManager 0xC, BTRegistry 0x10). Base boundary: Simulation
  0xD0 / Entity 0x1C4 / Mover 0x300 / JointedMover 0x328 => Mech-own region
  0x328-0x854 (MECH-LAYOUT.md staging worksheet).
- 13 staged headers close the family ([T3] reserved[]-parked layouts;
  interfaces PROVEN by the surviving consumers): MECH, MECHSUB, HEAT,
  POWERSUB, MECHWEAP, EMITTER, MECHMPPR, BTPLAYER (BTPlayer__MakeMessage =
  Player's 8 args + roleName/teamName [T1 via BTREG]), PROJTILE, MISSILE,
  BTL4MPPR, BTL4VID + the round-2 BTCNSL/BTSCNRL.
- compile410.sh: PCH gate retired (bt.hpp/mungal4.hpp full include sets),
  DPL SDK roots on the include line.
- BTL4APP.CPP: appmgr include + GetApplicationManager()->GetFrameRate() +
  ResourceDescription:: scoping; Fail() held at its recorded line 400.
- Evidence ledgers: STAGED-HEADERS.NOTES.md, MECH-LAYOUT.md, BACKFILLS,
  BTCNSL (binary-recovered console wire IDs), BTSCNRL.

Remaining for a linkable BTL4OPT: the ~40 missing TU bodies (917-function
manifest) - the header skeleton they grow into now exists and compiles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:58:26 -05:00
CydandClaude Opus 4.8 ba7c657dd9 FPGA reconstruction design note: block-by-block feasibility + the three-retarget plan
The governing insight: specification is the bottleneck, not substrate --
igc_exec.py is the golden reference model every port (RTL or GPU) validates
against. EMC array = natural FPGA target (208KB BRAM + ~50k LUT full-parallel,
or 8:1 muxed); IGC = reimplementation from our cracked ISA; i860 = software
(emu860 as executable spec); wire-identical boot via the blind boot-from-link
property.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 07:54:34 -05:00
CydandClaude Fable 5 63312e07f9 source410: literal 4.10 source reconstruction + BC++ 4.52 fleet toolchain archived
- BORLAND/: Borland C++ 4.52 (chosen over 4.5 by byte-match: CODE/RP/CW32.LIB
  is identical to 4.52's install lib). BCC32/TLINK32/TLIB/MAKE run natively on
  Win11; CODE/BT/OPT.MAK is the shipped BTL4OPT.EXE's exact flag recipe
  (extender = Borland PowerPack DPMI32, not Phar Lap TNT).
- restoration/source410/: the literal 1995-form reconstruction of the missing
  BT game source (never mixed into CODE/). Round 1-3 state:
  * 6 of 10 surviving original TUs COMPILE CLEAN under the period toolchain
    (BTMSSN, BTCNSL, BTSCNRL, BTTEAM, BTL4MODE, BTL4ARND) - first builds
    since 1996.
  * BT_L4/BTL4APP.CPP pilot reconstruction: 12/12 functions, Fail() lands on
    its binary-recorded line 400 exactly.
  * BT/BTCNSL.HPP: console wire IDs recovered from the binary's ctors
    (Killed=9, Damaged=10, ScoreUpdate=13, DeathWithoutHonor=15 [T1];
    TeamScore=12 flagged [T4]).
  * MUNGA/: 8 engine-header backfills back-dated from the BT412 WinTesla tree
    (VDATA numbering decomp-verified; AUDREND's OpenAL-era virtual removed -
    the period compiler is the drift detector).
  * Tooling: backdate.py (WinTesla->1995 header transform), compile410.sh
    (per-TU verification sweep under authentic OPT.MAK flags).
  * README: corrected roadmap - MECH.HPP is the capstone grown with the mech
    TU reconstructions; BTREG.CPP green = the header-family milestone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 07:33:26 -05:00
CydandClaude Fable 5 03bd5830ff 62500 bench: analog clean, lamps lose ~6.5% — RIO speed ladder complete
NAK=69/~1060 lamp commands explains the observed stuck-bright/missed
lamps (fire-and-forget writes turn each corrupt 4-byte burst into a
visible state error) while 2-byte traffic is pristine (analog 88.1%,
counters flat, zero wedges, worst gap 0.14s). The HC11 RX ISR's worst
path sits right at ~320 E-cycles. Ladder: 9600 production, 31250v2
CLEAN (FastRIO), 62500 needs host NAK-retransmit, 125000 CPU-walled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 13:08:46 -05:00
CydandClaude Fable 5 e718ddebfd 125000 bench: RX overrun confirmed (NAK=1082, lamps dead) — CPU is the wall
Board->PC near-perfect at 125k (framing 5) while PC->board shredded by
packet length (2-byte polls 60% delivered, 4-byte lamp cmds ~2/3 NAKed
as checksum-corrupt): the 2MHz HC11 RX ISR can't drain back-to-back
bytes at 80us. MAX232 acquitted; zero wedges even at 40% inbound loss.
62500 image built as the sweet-spot candidate (RIOv4_2_patched_62500.bin).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 12:57:51 -05:00
CydandClaude Fable 5 4b283b976e Firmware: RIOv4_2_patched_125000.bin — max-speed science build (13x)
make_patch.py generalized: baud flags 31250/62500/125000, each holding
the byte-clocked ACK-wait at ~12.8ms wall time (40/80/160 ticks; the
widen is implied for 62500/125000 since stock 4 ticks would be 0.6/0.3ms
there). All historical hashes reproduce unchanged; the 125000 image
(sha256 d22c8d85..., 25 bytes) diffs from 31250v2 by exactly the BAUD
and CMPA operands.

Predictions on record for the bench run: FTDI side exact (3M/24); the
MAX232-class level shifter is AT its 120kbps rating so edge-rounding
may surface as noise flags; and the 2MHz HC11 has ~160 E-cycles/byte -
back-to-back inbound bytes likely outrun the RX ISR (the firmware sets
its overrun flag $3186 but never reads it), so expect dropped bytes ->
NAK/retry churn and a dirtier profile than v2's. Wedges should stay 0.
62500 is one flag away as the fallback sweet spot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 11:20:30 -05:00
CydandClaude Fable 5 f489bd340e FastRIO v2 bench: CLEAN — ACK-wait widening eliminates the retry storm
192s mash at 31250 with the $D9E7 wait fix: framing 5655 -> 54
(-99.4%), AbandonCount 65 -> +0, duplicate replies gone (215% -> 88.6%
of poll slots — identical to the healthy 9600 profile, the structural
$D758 drop-gate ratio), zero wedges, counters perfectly flat. The
byte-clocked ACK-wait theory is confirmed end to end: disassembly
predicted the mechanism, one operand byte fixed it, the wire went
quiet. Evidence log archived; results table in ANALYSIS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 11:13:38 -05:00
CydandClaude Opus 4.8 599b2388a1 fxtest texture-path survey: TXDN io-port fetch protocol mapped; next mountain identified
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 05:31:35 -05:00
CydandClaude Opus 4.8 e9963a5040 ACCEPTANCE 1: SMPTE bars reproduced through the executed IGC pipeline
texu = per-pixel x computed by the REAL captured sweep programs across the
real 52-tile DMA stream; two documented approximations (texz seed op, ramp
LUT). Bars match the reference: 7 bars, correct colours, black border at
x=48. bars_pipeline.png in the session scratchpad.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 04:29:11 -05:00
CydandClaude Opus 4.8 12673c5a22 IGC decode: convergence experiment negative; OPF2(145) = next suspect
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 03:26:09 -05:00
CydandClaude Opus 4.8 6c3dc2e954 igc_exec: SCMEMA (screen-address seed) + gated sweep-pair adds
Verified flowing on the bench tile: s145 holds per-pixel x, scalar region
packs it, SCAintoMEM constants land in eofr/eofb. Bars chain now breaks at
the texz seed = the op-0x48-with-len family (0x3a804820 targets texz) --
FCMEMA, next to implement.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 01:51:17 -05:00
CydandClaude Opus 4.8 6451b739bd IGC decode: colour-instr layout (5-word Gouraud planes) + SCMEMA lead for the bars
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 01:17:13 -05:00
CydandClaude Fable 5 dd41a3a411 Firmware 31250 v2: widen the byte-scaled reply ACK-wait ($D9E7: 04->28)
Disassembly confirmed the bench theory: the no-ACK wait loop at $D9E0
self-clocks in byte times (each tick transmits an IDLE keep-alive and
re-enters on its TX-complete interrupt), so raising the baud silently
shrank the ACK grace from ~5.2ms to ~1.6ms - under USB turnaround,
hence the v1 retry storm. --widen-ackwait (requires --baud31250) sets
the limit to 40 ticks (~12.8ms at 31250). v2 image: 25 bytes changed,
sha256 420d4cfc...; re-disasm diff vs v1 is exactly the CMPA operand.
v1/classic hashes reproduce unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 00:45:40 -05:00
CydandClaude Opus 4.8 7bac137a63 Tier-1 FIRST GEOMETRY RENDER: real captured IGC packets -> shaded z-buffered 3D
render_wide30.py executes the cap7 death-cam capture's raw instruction
packets ({TREEgeZERO_L3 x3 edges, MEMltTREE_L3 z-test, TREEintoMEM_L0
z-write, colour planes, scalar} -- 152 packets found by header scan) through
the named-ISA semantics, vectorized: 85 packets survive edge+z, producing a
recognizable smooth-shaded, depth-correct render of the test-scene object
(wide30_render/depth.png in the session scratchpad). This is geometry drawn
purely by executing the hardware's own instruction stream -- no
geometry-extraction shortcuts.

Known approximations this pass: winding-agnostic edge acceptance, colour
plane word-offsets partly empirical (R channel confirmed Gouraud-correct,
G/B extraction still off), duplicate packets from the wide capture window
z-fight. eof/bars ops still stubbed (per-tile program renders uniform).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 00:42:52 -05:00
CydandClaude Fable 5 27a592da53 31250 bench run: wedge patch holds under retry storm; window is byte-scaled
127s mash at 31250: zero wedges — but 5655 framing resyncs, duplicate
replies (215% of poll slots) and AbandonCount=65 reveal the board's
reply ACK-wait scales with byte time: ~5+ms at 9600 (USB beats it,
zero framing) vs ~1.6ms at 31250 (USB cannot). All 65 retry
exhaustions self-recovered through the patched give-up path — the
strongest field proof of the latch fix yet; unpatched firmware would
have wedged on the first. Verdict recorded in ANALYSIS.md: cabinets
run the 9600 patched chip; 31250 stays a bench branch until the retry
window is widened in firmware.

Tool: before-snapshot now retries once (can lose the post-DTR boot
race, as this run showed); evidence log archived.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 00:36:23 -05:00
CydandClaude Fable 5 d8cac8927a Archive the bench A/B evidence logs (force past the riomash ignore)
testlogs/ carries the raw records behind the CONFIRMED verdict:
baseline wedged at 0.62s and stayed dead 300s; patched ran clean
through 152s of heavier mash, worst gap 0.58s self-recovered.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 00:22:55 -05:00
CydandClaude Fable 5 85b351a4b2 Firmware wedge patch CONFIRMED on real hardware — bench A/B results
Baseline (original chip): reply path wedged 0.62s into the run — the
tool's own version/check exchange colliding with analog polling was
enough, no mash required — and stayed dead for all 300s despite 951
button presses (no button revival; power cycle only). Patched chip:
survived the same startup collision, 2419 analog replies at a steady
~16/s over 152s under heavier mash (peak 635/min), zero wedges, worst
gap 0.58s self-recovered — the $DFF0 latch-clear stub doing its job.

Results table + evidence logs committed (rio-firmware/testlogs/).
Remaining: cabinet soak + native-game session; 31250 variant A/B.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 00:21:38 -05:00
CydandClaude Opus 4.8 ddaa63f9b0 igc_exec rev2: named op table (ADDR/DUMP ground truth) + executor semantics
Parser rewritten around the named table -- TREEltZERO_L3/TREEgeZERO_L3/
MEMltTREE_L3/TREEintoMEM_L3+L0/TREEclmpintoMEM/SCAintoMEM/CPY/the ENAB group/
sweep pair, aux field (bits16-22) disambiguating operand formats. Validates
100% clean against DUMP's live reference packet (9 instructions, 0 unknown).
Executor implements the enable-gated semantics per IGCOPS.C; eof-exotic ops
parsed structurally, semantics stubbed pending builder disasm.

Capture insight: the firmware's payload pages are double-buffered PER
PRIMITIVE -- DRAM snapshots hold only the last primitive's packets, so full
frames need payload capture at SEND time (send_capture.py, scratchpad).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 00:10:13 -05:00
CydandClaude Opus 4.8 ecdb4b6122 IGC decode: op table named via PXPL5SUP/ADDR (igc_opco.h fragment) + DUMP (live op-table print)
ADDR carries exact I_*/P_* macro bases; DUMP is a pxpl5tst log printing the
named op values plus two complete live triangle packets. Retroactive
unification: tri_recover's 'scale 0.00178' was TREEltZERO_L3 (0x3ae94200)
read as a float -- the DRAM stride-0x10 groups were always 4-word edge
instructions in the DPL3 direct-float format igc_exec.py already executes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 23:40:00 -05:00
CydandClaude Opus 4.8 8ff234fe9c IGC decode: sweep-family 2-word format derived; doubling-chain myth busted
The firmware's SENDE emitter (disassembled at 0xf041db90 via builder_trace)
proves the captured 0x8x01213a words are op-0x21 instructions whose len-field
(136-k)<<23 decrements through the IEEE exponent bits -- the 'x2 doubling
chain floats' of the earlier decode were an artifact, not coefficients. The
69-word SENDE is a fixed bit-serial transform program (texz -> texu region);
real per-primitive coefficients are in the SEND(33)/SEND(41) blocks
(builders at 0xf04126xx, next disasm target). 2-word sweep format:
{op|dst|(len1+116)<<23, src|dst<<8|len2<<16}, verified word-exact.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 23:10:05 -05:00
CydandClaude Opus 4.8 c54d920761 Tier-1 IGC decoder: encoding formula cracked + instruction executor core
The igc_opco.h macro header is absent from the dump, but the PGC-expanded
compiler output (PXPL5TRI.S / PXPL5OPT.S / EOF.S) carries every constructor
expression in the clear. PXPL5OPT.S:1649 gives the universal template:

  word = op<<8 | aux<<16 | (addr&0xff) | ((len+115..117)&0xff)<<23 | flags | S1<<31

Verified word-exact against the captured streams (Ix_SCAintoMEM_S1(52,5) =
0x3c90f734, Ix_MEMgeSCA_S1(5) = 0xbc916c00, Ix_MEMltTREE_L3(97,20) =
0x44ea2161). Edge instructions are 0x601/0x602/0x603 + A,B,C floats; the aux
field encodes the operand format (L3=+3 floats, L0=bare, C1/S1=+1). Full
derivation log in IGC-ENCODING-DERIVATION.md.

igc_exec.py: payload parser + 64x128-tile executor (26-byte bit-addressed
pixel memory, enable reg, shared linear-expression tree) per IGCOPS.C
semantics; constructor self-tests + triangle smoke test pass.

Known gap: the firmware's own packet builder emits a bit-serial SWEEP variant
(ops 0x21/0x25/0x39/0x48/0x4c/0x7c/0xfa per bit-plane) that the parser does
not yet cover -- next target is FITPLANE.SS (the bit-serial plane-fit source).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 22:38:57 -05:00
CydandClaude Fable 5 e18a5c8454 Deploy: --pipe trim -- named-pipe serials to vRIO/vPLASMA for every mode
Dev-rig policy (2026-07-17): everything on the dev machine runs named pipes
to vRIO until Real-RIO testing -- no com0com. pod-launch --pipe selects the
<mode>_pipe conf (serial1=namedpipe pipe:vrio, serial2=namedpipe
pipe:vplasma); pipe variants of all three deploy templates (auto-staged/
rendered) + a dev-tree net_loop_pipe.conf beside the existing RP one.
Requires the vRIO dist >= 20260716-68e3d1f (VRioPipeService/
VPlasmaPipeService landed there). Arcade cockpits with the physical RIO
keep the plain COM-port confs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 21:54:23 -05:00
CydandClaude Fable 5 df5804e835 Firmware: RIOv4_2_patched_31250.bin — wedge fix + SCI retuned to 31250 baud
make_patch.py gains --baud31250: one byte beyond the wedge patch — the SCI
init operand at $D62B ($30 -> $02). BAUD $30 = /13 prescale, /1 divider
(2MHz E / 208 = 9615); $02 = /1, /4 -> 31250 exactly, 3.3x faster. The
init write also confirms the 8MHz crystal, which is why 19200/38400 are
unreachable and why 62500/125k are left alone pending an ISR cycle count.

- 24 bytes changed vs original (sha256 9f866cf3...); re-disassembly diff
  vs the classic patched image shows exactly the one operand line, and
  the classic build still reproduces 3fc8170c... (script regression-safe).
- PC side: SerialPortTransport takes an optional baudRate (default 9600,
  runtime untouched); RioSerialMonitor + --mash accept --baud 31250.
- Caveats documented in README/ANALYSIS: non-standard rate (FTDI-class
  adapters only, no 16550s); native games still speak 9600 so this chip
  is bench/RIOJoy-only; validate the wedge patch at 9600 first.

275 tests green; mash --selftest regression unchanged (FAIL/exit-1).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 20:25:00 -05:00
CydandClaude Opus 4.8 38dd84f5ec i860: annul the delay slot of a not-taken bc.t/bnc.t (fixes >512-object captures)
The interpreter executed bc.t/bnc.t's delay-slot instruction on both the taken
and not-taken paths. On real i860 the ".t" conditional branches annul that slot
when NOT taken -- the compiler fills it with the loop body's first pointer load,
valid only when the branch continues:

    xor   0,r4,r0         ; CC = (node == NULL)
    bnc.t loop            ; continue while node != NULL
    fld.d 0x20(r4),f16    ; annulled when node==NULL; else reads *NULL

For cap7/trek/batest (<512 live objects) the stray reads land in dead registers,
so the bug stayed latent -- cap7's rendered coefficient stream is byte-identical
before/after this change (verified: md5 52e16774... over the first 3 draws). But
the same stray access corrupted the object-registry tail-find walk (REGISTER
@0xf04041f8) whenever the 512-bucket handle hash chained (>512 live objects),
orphaning entries so FIND_REMOTE missed -> NULL -> firmware exit()
("Attempt to add NULL to a list"). That killed every content capture
(fxtest/sdemo4/glblade) ~1/3 in, before any draw.

Fix: a _squash flag skips the delay slot (whole next pair in DIM) on a not-taken
bc.t/bnc.t. fxtest now replays all 18987 commands and emits 3.67M coefficient
words of real geometry (previously 0 -- it died at cmd 6277); cap7's full mission
is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:24:33 -05:00
CydandClaude Fable 5 1fecd7e274 Firmware validation harness: instrumented RIO_TAP mash test in RioSerialMonitor
New --mash mode (tools/RioSerialMonitor/MashTest.cs) mechanizes the
wedge-patch validation plan from RIOv4_2-ANALYSIS.md:
- Runs the live link with the app's >5s reset-recovery DISABLED so a
  board wedge stays observable, and echoes lamps on every press
  (lamp/reply collisions are the wedge trigger).
- Gap timing uses ANY AnalogReply packet (0xFE sentinels included -
  a sentinel still proves the reply path is alive); logs a gap
  histogram + top-10 longest gaps with timestamps.
- WEDGE detector: analog silent past the threshold (default 2s) ->
  beep + banner; on resume, classifies self-recovered (patched
  expectation) vs button-revived (button event within 300ms of resume,
  the unpatched signature) vs unresolved at run end.
- Board self-reported RestartCount/AbandonCount/FullBufferCount
  snapshotted before/after via CheckRequest, delta printed
  (7-bit wrap-aware).
- Fixed-layout summary teed to riomash-<label>-<stamp>.log so
  baseline-vs-patched runs diff directly. Exit 0 = no wedge, 1 = wedge.

--mash --selftest drives the whole instrument against a scripted
in-memory board (SelftestTransport) that goes silent at t=4.0s and
revives 200ms after a button at t=6.5s: verified end-to-end - alarm at
6.0s, wedge classified button-revived (2.75s), counter delta +4/+0/+1,
verdict FAIL, exit 1. Use it to sanity-check the alarm at the cabinet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 14:35:27 -05:00
CydandClaude Opus 4.8 2a11838d74 Stream-verify the demo scenes: warp field + Klingon = DRAM-resident assets
trek's live-written DMA stream contains ZERO non-standard SENDs (624 pairs, all
four standard payloads) -- the captured demo frames, like the bench, draw only
the SMPTE test card. The warp starfield and Klingon vessel geometry are the
demos' scene ASSETS resident in render memory (compiled coefficient blocks
never referenced by the captured frames' chains). §07 relabeled accordingly:
"Recovered assets -- the Star Trek material". Every image in the readout is now
attributed by stream evidence, not memory scanning.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 12:57:25 -05:00
CydandClaude Opus 4.8 70a7d38329 Correct the bench frame: bars only -- the triangles are not in the frame
The user asked why triangles sat on the test pattern; verification against the
frame's actually-WRITTEN DMA stream (captured word-by-word during draws) shows
it references ONLY the standard background program -- the 0x815f000+ triangle
blocks are test.egg's 3D scene content, precompiled in DRAM but never
referenced by this frame's chains (my loose memory scan misattributed them).
The live frame = SMPTE colour bars, now rendered bars-only (paint_bars.py) and
matching the user's reference card. Readout §06 corrected: bars frame + honest
note about the undrawn DRAM-resident scene data.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 09:39:52 -05:00
CydandClaude Opus 4.8 211f23d042 PAINT THE BENCH: SMPTE bars + exact 3D test model, composited
paint_bench.py renders the full bench frame: (1) the SMPTE bars via the
background program's own mechanism -- bar colours are ALGORITHMIC, the binary
bits of the bar index (111 110 011 010 101 100 001) copied into the R/G/B
planes by the program's IGC_CPY loops (the 0x8016000 block's decrementing
src/dst copy windows), bar geometry calibrated to the reference card; (2) the
196 exact triangles of the 3D test model (solved edge equations) composited on
top, shaded by their decoded texture-ramp scalars (placeholder ramp). Readout
§06 now shows the painted frame (14KB embedded PNG). Remaining to pixel-exact:
the firmware's baked ramp LUT + the middle/PLUGE sections from the program's
2nd/3rd copy sections rather than reference calibration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 09:17:53 -05:00
CydandClaude Opus 4.8 cbae445ce0 Bench identified: SMPTE colour bars + 3D scene layer; bars = acceptance oracle
User-provided ground truth: the cap7 test scene displays SMPTE colour bars.
Axis-alignment census (8/196 axis-aligned) proves the recovered triangles are
the 3D test-scene layer, not the bars -- the bars are the OUTPUT of the
standard background program (the byte-identical bit-serial SENDE/SEND set in
every capture: a video test card painted as the permanent backdrop, colours
written to the eofr/g/b planes 184/192/200 by the x2-chain sweeps). Payload
formats settled: size-18 = 3 edges + z-plane; size-21 = 3 edges + texture-ramp
SCALAR plane (the pvision mechanism). The known bar pattern is now the
pixel-exact acceptance oracle for the bit-serial program executor (the
chartered IGC_* macro work). Readout §06 caption updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 08:55:22 -05:00
CydandClaude Fable 5 bce9a443b0 Emulator: VDB heads mirror TEXT mode -- boot scroll + suite menus, like the
real cockpit

The splitter passed the analog VGA signal through whenever the game's
packed mode wasn't driving it: a person in the cockpit watched the PC boot
sequence scroll across every secondary display, and the test suite's menus
were readable on the heads. pal_draw now rasterizes M_TEXT (80x25 through
the live font tables + attribute palette -> VGA DAC, 8-dot cells, centered
640x400) with the mono MFD windows showing single-wire green-phosphor
luminance.

Two DOSBox-X planar-layout lessons encoded in comments: text cells live in
linear_base as one latch DWORD per character address (char/attr = plane
0/1 bytes, cell stride 4<<addr_shift, lvida = vidstart<<2), and
font_tables index PLANAR vram too -- one font byte per dword, so the glyph
fetch is ((chr<<5)+line)*4. Plus a 2s textdiag line (row-0 decode) in the
vpx log for future text-path debugging.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 07:48:04 -05:00
CydandClaude Fable 5 e02a346bb0 Emulator: VDB heads mirror plain-VGA modes (analog splitter pass-through)
The VDB is an analog splitter: the game's packed-16bpp trick routes the two
framebuffer bytes through the board palettes at 0x300/8/10, but any plain
VGA mode passes the S3's own DAC signal to every head -- no VDB register
traffic at all. The VGL_LABS test suite draws its secondary-display
patterns in 640x480x8 and programs nothing at 0x300-0x31A (verified from a
full session log), so the packed-only decode showed black heads. pal_draw
now branches: M_LIN8 decodes through the VGA DAC (full color on the color
heads, single-wire luminance on the mono MFD windows); 16bpp keeps the
packed VDB-palette decode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 07:30:09 -05:00
CydandClaude Fable 5 a6713ec1bd Deploy: package.ps1 stages ALL conf templates, not two by name
vwetest.conf.tmpl was never staged, so fresh installs had no conf for the
test mode ("vwetest.conf not found under root"). Glob deploy\*.conf.tmpl
and log the staged set.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 07:06:42 -05:00
CydandClaude Fable 5 72da9b2f14 Emulator: parity-safe EMU8000 sample counter -- AWEUTIL runs; wire the
VGL_LABS cockpit test suite as pod-launch 'test' mode

The WC hang, root-caused in three layers (each necessary):
1. WC was rendered-samples + 100ms-capped interpolation; AWEUTIL's poll
   storm (~550k port-ops/s) starved the render thread of awe_lock, so the
   clock crawled ~90x slow. Fixed: free-running host-clock derivation +
   a fairness gate so the render thread can always take the lock.
2. Free-running at true 44.1kHz still failed: trapped port reads cost
   ~30us -- MORE than one 22.7us tick -- so consecutive reads skipped
   counter values, and AWEUTIL's WaitUntilWC (decoded at COM offset
   0x5F42) exits only on EQUALITY with a target tick: skipped value =
   missed target = 1.49s wrap penalty, or forever.
3. Advancing +1 per read still failed: WaitUntilWC reads WC TWICE per
   iteration, so its equality sample saw only every 2nd value -- wrong
   parity = infinite loop. Final semantics: during a poll storm the
   counter advances once per FOUR reads (every value observable by all
   of AWEUTIL's loop shapes; its 8192-unchanged-reads dead-clock bailout
   never trips), and resyncs to true wall time after any 50ms idle gap.
   Result: the full stock TEST.BAT (DIAGNOSE + AWEUTIL /S on both cards)
   completes in seconds.

Also: pod-launch 'test' mode -> vwetest.conf (stock TEST.BAT -> TSTALL),
DOSBox window defaults to 900,600 in test mode (the DOS screen is the
suite's UI), VWE_AWE_LOG gains storm bursts with guest cs:ip + caller and
rare-read tracing (the instrumentation that cracked this).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 23:51:52 -05:00
CydandClaude Opus 4.8 6dc017cb3d THE TEST PATTERN: cap7's bench scene recovered exactly (137 triangles)
tri_recover.py parses each payload's stride-0x10 edge groups {scale,A,B,C}
(GOODEQNS edgeize output), solves the three edge equations pairwise into true
vertices, and fills the triangles. cap7's bench = a triangulated calibration
grid + a multi-part test model + triangle strips, in global screen coords --
the image Division's engineers used to validate VelociRender boards, exact to
the compiled coefficients. The earlier 9x5 patch was one corner of this scene.
Readout gains §06 (test pattern) with trek/klng scenes moving to §07. The demo
captures' streak/point payloads use a different layout (parser refinement
pending) -- the bench is pure triangles and recovers perfectly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:35:17 -05:00
CydandClaude Opus 4.8 24ddbd4970 Second scene recovered: the Klingon vessel (klngvid)
recover_scene.py generalizes the recovery (dual-window dump -> chain walk ->
position/segment parse -> render) for any capture. Applied to klngvid: 139
content payload programs, 96 positions + 62 edge segments = a sparse starfield
with a dense edge tangle right-of-center -- a vessel in space. Readout §06 now
shows both recovered scenes (warp field + Klingon) side by side.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:19:21 -05:00
CydandClaude Opus 4.8 26864c9945 THE WARP FIELD: trek's scene recovered from the frame's compiled payloads
Walking the bin-page DMA chains enumerated 898 SEND payload programs per frame:
4 = the standard end-of-frame pipeline; ~860 = the scene's per-primitive
coefficient blocks at 0x815f000+, far beyond the old dump window. Their
geometry sits in plain screen-space IEEE floats (+0x14/+0x18 and +0x24/+0x28):
433 star positions + 389 streaks radiating from a convergence point = the
Star Trek warp-speed starfield, reconstructed from micro-code compiled by the
original firmware on the emulated i860. Readout §06 now renders the warp field
from the embedded position/segment data. Tools: dumpcontent.py (payload-region
dump), content_frame.py (chain walk + payload parse + reconstruction).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 22:12:48 -05:00