Commit Graph
234 Commits
Author SHA1 Message Date
Cyd def5840e07 Import RIO board firmware from RIOjoy repo (history preserved)
Board firmware dumps, disassembly, make_patch.py, patched images
(RIO 4.3 + FastRIO), analysis, and bench testlogs — moved from the
RIOjoy repo into the Tesla cockpit restoration archive.

git-subtree-dir: restoration/rio-firmware
git-subtree-mainline: 6c0dfcf792
git-subtree-split: 4fb91775fc
2026-07-19 20:45:16 -05:00
CydandClaude Fable 5 6c0dfcf792 Mech layout: correct AverageOf status (survives) -> 3 missing helpers
Full-archive re-check: AverageOf DOES survive (AVERAGE.HPP, the SIGNATURED
lineage BT411 preserved), so telemetryFilter[5]'s type is available. The
genuinely-missing embedded helpers are just AlarmIndicator, SequenceController,
and NameFilter (confirmed absent from all of CODE; no alarm/filter/sequence
headers) -- to be reconstructed from BT411 decomp before the Mech layout finalizes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:43:02 -05:00
CydandClaude Fable 5 f3668d6dbf Mech milestone: foundational layout analysis + proxy-layer resolution
Begins the Mech reconstruction milestone (analysis phase). Extends the existing
MECH-LAYOUT.md worksheet with the findings needed to build MECH.HPP + the ctor:

- Resolved the BT411 mechrecon.hpp proxy layer to real 1995 types (ReconAlarm ->
  AlarmIndicator, ReconSeq -> SequenceController, ReconFiltered -> AverageOf<
  Scalar>/NameFilter, ReconChain -> ChainOf, ReconMatrix -> AffineMatrix;
  StateIndicator/Reticle survive as-is; BTVal mostly base-class pose fields).
- CRITICAL: AlarmIndicator, SequenceController, NameFilter, AverageOf are ALSO
  absent from the 4.10 archive -- additional helper classes the milestone must
  reconstruct first (their sizes set the embedded-member offsets).
- Subsystem source availability mapped: full (GAUSS/PPC/SENSOR), .TCP partials
  (AMMOBIN/EMITTER/GNRATOR/HEAT/MISSILE/PROJTILE/PROJWEAP), decomp-only (rest).
- Key tractability insight: StateIndicator is fixed-size (level count stored, not
  arrayed), so a FUNCTIONAL fresh build needs only the right member set/types in
  order -- byte-exact offset matching is a later refinement for network wire
  format, not required to boot.
- Revised reconstruction order: helpers -> MechSubsystem+roster -> finalize
  MECH.HPP (probe sizeof==0x854) -> ctor+segment walk -> per-frame path.

Everything below the Mech ctor runs real reconstructed code; the ctor is the
live frontier (spawn factory validated last commit).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:40:43 -05:00
CydandClaude Fable 5 e610a2a3aa 4.10 reconstruction: real spawn factory path -> Mech ctor frontier
BTPlayer::CreatePlayerVehicle reconstructed (faithful; BT411's BT_SPAWN_XZ/
BT_SPAWN_ENEMY bring-up scaffolding dropped): builds the Mech::MakeMessage from
the mission game-model resource and hands it to MakeAndLinkViewpointEntity.
Mech::Make = new Mech(creation_message); a staged Mech ctor chains the real
JointedMover base (so the model skeleton/segments stream from BTL4.RES) then
Fails.

This validates the entire spawn factory chain live: CreatePlayerVehicle ->
MakeAndLinkViewpointEntity -> registry -> Mech::Make -> new Mech -> JointedMover
base ctor (streams the mech model) -> halts at the Mech ctor (mech.cpp:66).

The Mech ctor (@004a1674, 5690 bytes -- the largest function in the game) plus
the subsystem roster is the next MAJOR milestone, not a brick: it needs the full
1995 Mech member layout derived first (MECH.HPP is still reserved[331]; BT411's
decomp uses raw offset pokes that can't compile fresh), the subsystem class
hierarchy (only GAUSS/PPC/SENSOR survive in the 4.10 archive; the rest are the
measured "917 missing functions"), and the segment-table walk. Plan + scope in
MECH.NOTES.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:33:15 -05:00
CydandClaude Fable 5 956fc57681 4.10 reconstruction: BTPlayer message-handler table + DropZone spawn dispatch
Fixes the incorrect DefaultData reuse of Player::MessageHandlers -- BTPlayer now
has its own handler table (DropZoneReply, VehicleDead, Score, ScoreInflicted,
ScoreUpdate; the last two add BT message IDs) chained onto the base set, matching
the .data table recovered in BT411. A mission-start DropZoneReply now routes to
BTPlayer::DropZoneReplyMessageHandler (the real spawn/respawn dispatch skeleton)
instead of the base "should not be handled by base player class" Fail stub.

Boot ladder now runs the full engine + app + network + mission + player path and
reaches the spawn handshake, halting at CreatePlayerVehicle -> Mech::Make -- the
Mech subsystem frontier (Mech ctor + mech2/3/4 + subsystems + weapons), the next
major reconstruction milestone. Scoring/death handlers, PlayerSimulation, and the
mech-placement tail staged with documented Fail bodies (BTPLAYER.NOTES.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:24:27 -05:00
CydandClaude Fable 5 c43e6d873a 4.10 reconstruction: real BTPlayer ctor (binary-accurate experience-level flags)
Boot ladder advances past player creation. BTPlayer ctor/dtor/Make/
TestInstance/GetExperienceLevel reconstructed from BT411's Ghidra-recovered
body (@004c0bc8) backdated to 1995 idiom; the reserved[38] placeholder in
BTPLAYER.HPP replaced with the real BT-own members.

Key fidelity call: the game-mode flags are derived from
btMission->ExperienceLevel() (the egg's per-pilot experience key) with the
binary-accurate switch rows from the [T1] disassembly -- NOT from the scenario
role's returnFromDeath, which BT411's port uses as a [T3] stand-in. Mapping and
residual naming/[T4] uncertainty documented in BTPLAYER.NOTES.md.

Live boot now runs: banner -> resources -> app ctor -> network single-user ->
egg -> mission -> SetPlayerData -> BTRegistry::MakePlayer -> BTPlayer ctor
(resolves team, seeds experience flags) -> halts at the base
Player::DropZoneReplyMessageHandler stub (BTPlayer's own message-handler table
is the next brick -- DefaultData still reuses Player::MessageHandlers).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:18:37 -05:00
CydandClaude Fable 5 4fb91775fc Add pod-owner ELI5 of the wedge bug (wedge-explained.md)
Plain-language explanation of the reply-latch wedge for non-technical
pod owners, linked from the firmware README top. Frames the bug as a
'busy' sticky note the board forgets to take down on the give-up path,
and how RIO 4.3 fixes it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 20:11:02 -05:00
CydandClaude Fable 5 0906d1efa6 4.10 reconstruction: real l4net standalone path + full BTL4Mission::SetPlayerData
Boot ladder progress (each step verified live under DOSBox-X + 32RTM):

- L4NET.CPP v2: real statics (ClassDerivations/MessageHandlers/DefaultData),
  real single-user ctor (egg NotationFile -> last.egg -> local ReceiveEggFile
  post), real StartConnecting/Shutdown/CreateConsoleHost single-user branches,
  all four message handlers (egg assembly, ack, host connect/disconnect),
  1995 netnub-guard idiom (Net_Common_Ptr NULL => benign return) throughout;
  netnub wire primitives remain Fail-staged.  Sources: BT411 engine/MUNGA_L4/
  L4NET.cpp (preserves the 1995 netnub code as comments beside its Winsock
  port) cross-checked against the surviving 1995 L4NET.HPP.
- BTL4MSSN.CPP: full SetPlayerData reconstruction (vehicle/dropzone/color/
  patch/badge/team/experience/advancedDamage/role + score modifiers + plasma
  badge blit), backdated from BT411's Ghidra-recovered body (@004d2c30);
  every API pinned to the surviving 1995 headers (NOTATION/MISSION/SCNROLE/
  L4GREND/BTMSSN).

Boot now runs: banner -> resource load -> app ctor chain -> network manager
single-user init -> egg dispatch -> mission creation -> SetPlayerData (parses
the real TEST.EGG) -> halts at BTPlayer ctor (next staged brick).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 19:57:04 -05:00
CydandClaude Fable 5 5b35eb973c 4.10 reconstruction: BTL4OPT.EXE links clean and BOOTS to the first staged brick
The reconstructed tree now produces a runnable binary with the authentic
1995 toolchain (BC4.52 / tlink32 / DPMI32):

- BTL4.CPP main TU reconstructed from the 4.11 Ghidra decomp (FUN_0040109c)
  + the 4.10 binary's own string pool + surviving RPL4TOOL.CPP house style;
  probe_main.cpp scaffold retired (BTL4.NOTES.md documents every decoded call)
- L4NET.CPP staged: L4NetworkManager ctor/dtor + 10 vtable-pulled virtuals
  (standalone-benign ones no-op, network ones Fail loudly) + NetNub client
  globals (Net_Common_Ptr=NULL routes L4File to its plain-DOS path)
- build410.sh: libs now built in the AUTHENTIC makefile member order
  (MUNGA.MAK / mungal4.mak / BT.MAK / BTL4.MAK). Order is load-bearing:
  tlink emits static-init records in module pull order, and alphabetical
  order booted into a null-vptr crash (IcomManager::ClassDerivations
  constructing before parent NetworkClient::ClassDerivations). Also fixed
  stage_link to the proven 32-bit lib set (SOSDBXC+SOSMBXC, no WATTCPLG)
- BOXTREE.HPP MemoryBlock unify, BTL4GRND notify stubs, remaining engine
  backfills (audio/gauge/resource/stream TUs) that closed the deep ledger

Smoke test (DOSBox-X + 32RTM, copy of the pod BT tree, our exe swapped in):
  BattleTech v4.10
  BTL4Application::BTL4Application
  l4net.cpp(22): L4NetworkManager -- l4net.cpp not yet reconstructed
Static init, main, -egg parse, BTL4.RES load (version 1.0.6 check passes),
ApplicationManager and the BTL4Application ctor chain all execute real
reconstructed code; boot halts at the first staged Fail() as designed.
Next brick: the real l4net.cpp body.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 19:05:53 -05:00
CydandClaude Fable 5 516500d8b7 FastRIO 4.3: RIOv4_3_fastrio.bin (31250 + widened ACK-wait + all 4.3 edits)
Built with the full 4.3 flag set plus --baud31250 --widen-ackwait;
71 bytes vs stock, differing from RIOv4_3.bin in exactly two bytes
($D62B baud, $D9E7 ACK-wait) — disassembly-verified. Production table
updated; acceptance ladder on the FastRIO cockpit still required
before deployment.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 17:28:27 -05:00
CydandClaude Fable 5 bf3b0f1cc1 Edit 7: RIOv4_3 reports firmware version 4.3
The VersionReply builder at $C6EA hardcoded 4.2; --reportversion=4.3
patches the minor operand byte ($C6FF: 02->03). Verified no host
software gates on the value (legacy prints it, RIOJoy parses it, native
games ignore it — Cyd). Rebuilt RIOv4_3.bin: 69 bytes vs stock, sha
6d67a2fc7713...; docs updated. Chips burned before this edit still
announce 4.2 — re-burn to pick up the number; all other bytes match
the certified image.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 17:20:40 -05:00
CydandClaude Fable 5 be70e61d07 Christen RIO 4.3: RIOv4_3.bin is the production firmware
Final gate passed: 120s mash at 549 presses/min sustained (heaviest
stress run of the campaign) — zero wedges, counters flat, NAK 0, all
247 resends healed. RIOv4_3rc1 renamed to RIOv4_3.bin (same bytes,
sha dc59bd51cae3...); README/ANALYSIS promote it, production table
updated (native-game cabinets -> RIOv4_3.bin; FastRIO 4.3 variant is
build-on-demand with the documented flag set + acceptance ladder).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 16:53:02 -05:00
CydandClaude Fable 5 e7869a6d04 RC1 acceptance PASS: E0000305 after check — edit 6 verified on both paths
Over-threshold check exchange repaints and re-renders a live E0 readout
(not the stale 04000000). The +2 drift in $3184 among 65 status frames
refines the counter model: $3184 = started timeout-retry sequences
(give-ups are the exhausted subset); timeout-recovered cycles exit via
the success teardown, NAK-recovered ones via $DA2F ($3185). All
observations from both bench sessions fit. Mash spot-check remains
before christening RIO 4.3.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 16:46:53 -05:00
CydandClaude Fable 5 dd78d323f3 e0test: check-exchange acceptance stage for edit 6; record RC1 first-light
After the flip leaves counters over threshold, the tool now sends a
CheckRequest (ACKing every status frame) — edit-6 chips must repaint
and re-render the E0 readout; 04000000 marks a pre-rc1 chip. Analysis
records the stock-chip archaeology (stock also leaves 04000000, but the
ungated E0 readout papered over it in period — our fixes exposed it)
and RC1's below-threshold first-light PASS (version+check -> F0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 16:29:16 -05:00
CydandClaude Opus 4.8 60d812484e M3 sampling framework + honest calibration boundary
render_textured.py samples the game textures with the quads' texu/texv/texz
planes, z-buffered. Empirical finding: the planes are texscale-encoded
(2^16) homogeneous coords needing the exact perspective_divides mapping
(texu/texz * .Cturn_z_to_tex from FOOTER.SS) -- measured texu/texz ~0.12 on
the ground quad. That final texel-coordinate calibration is a precise
reverse-engineering step against EOF.C, not a guess; left as the last mile.

The verified M3 result is the texture DECODE: the netdeath textures are real
game art (texstore.py). Geometry + texel format are both solved from the
live wire.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:23:29 -05:00
CydandClaude Opus 4.8 cc2d9290be M3 texel decode: the game's own textures recovered from the wire
Action 0x1a carries the textures: header[32] {handle, byte_size, u, v, mode}
+ v rows of 256 bytes, texels in 0x00BBGGRR words. The netdeath session's 20
textures decode to real game art -- 'PLAYER 1/5' HUD labels, a squadron
dragon emblem, metal-panel/grating/terrain surfaces, and the pilot callsign
'Cyd' (texsheet.png in the session scratchpad). The M3 texel FORMAT is
solved; texstore.py builds the handle->RGB store. Remaining: per-quad texid
binding + (texu,texv) sampling to skin the geometry.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:18:39 -05:00
CydandClaude Fable 5 c29a9d5343 RIOv4_3rc1 candidate: wedge fix + E0 threshold + check-display repaint; archive prior images
New edit 6 (--checkrepaint, requires --e0thresh): hooks the CheckRequest
handler's final notify ($C5E4) through a 10-byte cave at $E020 that
repaints F0000000 after the self-test and re-renders the E0 readout only
when a counter is at/over threshold — no more stale 04000000 after
status checks. Candidate = 9600 native-game-compatible base + edits
1-2/5/6, 68 bytes vs stock, disassembly-verified, awaiting burn; on
verification it will be christened RIO 4.3.

All prior patched generations (wedge-only, 31250/31250v2, 62500/125000
science builds, e0t5 pair) moved to rio-firmware/archive/ with their
disassemblies; RIOv4_2.bin stays at top level as the pristine patch
source.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 16:13:13 -05:00
CydandClaude Opus 4.8 b4c2337ab1 Battle geometry, rendered honestly: coherent arena floor + horizon + sky
Fixed the readout: the effect packets are 3-4 edge TEXTURED quads (0x2c/0x42/
0x0d edges + z + texz/texu/texv planes -- NO Gouraud colour, confirming the
scene is textured). Two bugs in the first pass: (1) 0x2c edges were treated
as 'accept both sides', turning every quad into a full-plane fill; (2) only
2-edge packets were caught, dropping ~3/4 of the geometry. render_battle.py
applies the render_wide30 polygon-winding rule (inside = all-edges>=0 OR
all<0) -> 78 polygons of 141 setups.

Result (flat-per-polygon + depth): a geometrically coherent first-person
scene -- sky at far depth, a ground plane ramping smoothly from horizon to
foreground, a clean horizon line, upright structures. The perspective is
consistent; this is real scene geometry, not the muddy u/v wedges of the
first attempt. Surfaces still need texels (TXDN/M3) for their skin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:10:49 -05:00
CydandClaude Fable 5 a9ae6ff0c8 Correct 04000000 finding: CheckRequest self-test leftover, not test mode
Bench refutation (display is static under axis movement; version-only
exchanges leave it alone) kills the A-9-E chord theory. Real mechanism:
the CheckRequest handler at $C5A6 runs a full self-test — sets the
test-display flag $2421, brackets itself with TestModeChange 0x8C,
lamp pattern, pod scan, five-channel encoder sweep — and returns
without repainting, leaving the channel-4 frame (04000000) as a stale
cosmetic snapshot. Board fully healthy; no reset needed. PROTOCOL.md
now warns hosts that 0x8C fires around every check. Candidate firmware
fix (repaint cave off $C5E4) noted for a future burn.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 16:04:11 -05:00
CydandClaude Opus 4.8 fecb5a5f20 M4c COMPLETE: real battle geometry from live game wire, end to end
battle_frames.py extracts the per-draw effect programs (the production
build emits them at ~0x815f000, like fxtest's 0x816f000) and rasterizes
their {edge, z, u/v} primitives through the render_fx GPU path. Running the
netdeath battle capture on the production firmware (vrend410) + emu860c +
GPU: 8 frames in 2.8s showing the actual mech-combat arena -- ground plane,
horizon, a building, receding structures -- with 31..148 primitives/frame
growing as the scene loads (cmd 8125 deep).

The full chain is now proven on real game content: game's own firmware ->
C-accelerated i860 -> the card's own IGC/EMC instruction set on the GPU ->
recognizable battle frames. Surfaces are u/v false-colour pending texel
sampling (the TXDN path, M3); the geometry is the game's.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 15:48:31 -05:00
CydandClaude Fable 5 054fbc6a40 e0t5 mash regression: PASS (0 wedges, counters flat) + live test-mode incident
120s lamps-on mash on the burned 9600 e0t5 chip: 236/236 presses, 88.0%
analog fill, NAK 0, zero wedges, board counters flat — normal operation
unaffected by the E0-threshold patch. Bonus field data: the keypad
A-9-E chord fired mid-mash and dropped the board into axis test 4
(display 04000000), confirming that button scanning halts in test mode
while ISR-driven serial keeps running — visible in the log as presses
freezing at 236 while analog continued to 1919.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 15:48:30 -05:00
CydandClaude Opus 4.8 979c82b37c M4c end-to-end: production firmware runs LIVE BATTLE WIRE on the C core
live_server now boots fw=vrend410 (the shipped game build) and replays the
netdeath battle capture's 53,088-record VelociRender wire through emu860c +
the GPU tile path: 8 frames in 5.8s, thousands of commands deep (cmd 6235),
25 tiles/100 sends each. The whole authentic backend -- vpxlog transport,
production firmware, C core, GPU raster -- is proven on real game wire.

Honest scope: the rendered image is still the bench readout (texu->SMPTE
ramp via the texz=x seed), not the battle scene -- live_server uses the bars
readout path, not the per-draw effect-primitive extraction (render_fx). The
battle geometry is present in the wire and executes; wiring the fx-primitive
readout into the live loop is the remaining refinement for real content.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 15:44:16 -05:00
CydandClaude Opus 4.8 99f46bea78 emu_main: vrend410 map -- the production firmware (game BT/RP VREND.MNG)
Hook addrs re-derived by masked-immediate signature match vs capfw7 (12/13
exact; reply via unique opcode-only signature). vrend410.mng = the shipped
385KB build with its 7-word Division header rewritten to the loader's 3-word
form. Result: the production build boots and dispatches init + create from
the live netdeath battle wire -- where capfw7 died instantly on the newer
action 0x2d. Stalls at cmd 2 in a bla+fst.d memclear (~1.1M iters / ~9MB)
that pure Python can't chew but the C core (emu860c, 90M steps/s) will --
next: live_server on the C core with fw=vrend410.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 15:42:49 -05:00
CydandClaude Fable 5 52a3317ed6 Docs: record E0-threshold bench PASS (E0000105) + corrected counter semantics
The display observation recalibrates the counters: $3184 = give-up
cycles (once per exhausted retry sequence, not per retransmit), $3185 =
teardowns of any reply cycle needing at least one retransmission — the
counter behind a lone E0000001. Also recorded in the error-handling
inventory: 5 retransmits per cycle, reply-await arms only after the
complete frame, NAK forces exactly one counted retransmit, late ACKs
cannot rescue a cycle. (Previous commit's doc edits had silently missed
their anchors; applied properly this time.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 15:40:57 -05:00
CydandClaude Fable 5 f98fc481cc Firmware README: complete the patched-image inventory (speed ladder, e0t5)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 15:14:14 -05:00
CydandClaude Opus 4.8 28785d9486 M4c: live_server -- the authentic backend for the vpxlog wire feed
Consumes VPXM records (fifodump file or live VPX_FIFOSOCK) and renders
through emu860c + the GPU tile path. The 'new C012 device' of the plan
turned out to already exist: vpxlog.cpp IS the link adapter and already
streams the wire over TCP; this server is the drop-in authentic listener
beside the GL bridge.

Validation on the netdeath battle capture (53,088 records) found the real
gap: the firmware dies with 'unrecognised or illegal action 0x2d' -- the
battle games speak a newer protocol than capfw7 (cap7's booted build).
Census: every boot-carrying capture ships the same old build; the 0x2d
sessions were all captured mid-run. The production build is in the game
files themselves: ALPHA_1/REL410/{BT,RP}/VREND.MNG (identical, 385KB,
csize 0x3ac80). Next: re-derive the hook map for that build (signature
anchors in emu_main) and replay the battle wire on its matching firmware.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 15:03:00 -05:00
CydandClaude Fable 5 cb95c229da Firmware: --e0thresh patch — gate the E0 error display (default N=5)
Stock $D5F2 repaints the cockpit display to the E0 counter readout on
the FIRST increment of $3187/$3184/$3185, so one benign give-up shows
E0000001 forever. New opt-in make_patch.py edit 5 hijacks the render's
LDX #$2038 into a 30-byte cave at $E000: all three counters below N ->
exit via the routine's own epilogue (registers restored, display
untouched); any >= N -> resume the render. Counters still accumulate.

Built + disassembly-verified (not yet burned): RIOv4_2_patched_e0t5.bin
(9600) and RIOv4_2_patched_31250v2_e0t5.bin (FastRIO). Docs updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 15:02:22 -05:00
CydandClaude Fable 5 83fcb198c8 Error-handling inventory: E0 diagnostics, dEAd crash screen, no watchdog
The display has a third use: serial error annunciator. $D5F2 renders
'E0' + three live counters (TX-ring overflow $3187, reply retries
$3184, give-up teardowns $3185); $DAB8/$DAB2 is a terminal crash
screen spelling 'dEAd' when the TX dispatcher meets an unknown command
byte. Also recorded: RX overrun is unhandled (checksum NAKs are the only
symptom), unused vectors hang in BRA-self stubs, FAULT LED = MAX690 PFO,
manual/remote reset works by pulling PFI low, RUN LED = buffered AS*,
and the MAX690 watchdog is unconnected/unserviced — software wedges
persist until reset, matching bench observations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 14:47:01 -05:00
CydandClaude Opus 4.8 ff91bc675f M4b: offline end-to-end frames -- firmware -> C core -> GPU, live
emu860c gains a C-side write-watch (watch_add/watch_drain: watched ranges
log (addr,val) into a ring buffer at negligible cost). frames.py runs the
cap7 mission on the C core, drains the DMA queue-page writes at each
receive->receive draw span, reconstructs the frame's SEND payloads from
live C memory, dispatches the GPU tile shader per TILE entry, and
accumulates interlaced fields. Result: the complete SMPTE test card
(frame_0004) -- 6 draw frames in 2.0s including boot; the content draws
alternate 25-tile fields with eof/present passes, matching the hardware
cadence.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 14:23:29 -05:00
CydandClaude Fable 5 d95e390b0d FastRIO certified: 31250v2 final runs clean; config plumbing for baud/poll
Operator-verified zero lamp misses/hangs through the slow-chord test
(62500's killer) and 392/min mash. Final run: NAK=0, 25 timeout resends
silently healing inbound response loss, counters flat, zero wedges.
--poll 20 delivered ~31Hz analog (1.7x legacy); the shortfall vs 50Hz
is additive host pacing (delay after awaited exchange), not board
saturation - noted as a future host tweak.

AppConfig gains RioBaudRate (default 9600) + AnalogPollMs (default 55),
plumbed through RioCoordinator; existing configs unchanged. Production
matrix recorded in ANALYSIS.md: 9600 patched chip for native-game
cabinets, 31250v2 + poll 20-25 + FTDI for RIOJoy cockpits.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 14:19:30 -05:00
CydandClaude Fable 5 3c9455eb97 62500 SHELVED: chord-driven RX overrun is host-unfixable; 31250v2 is FastRIO
Slow chorded presses still glitch lamps at 62500 after three rounds of
host-side hardening (NAK-race resend -> stop-and-wait -> typed
resolution): a chord maximizes board ISR latency exactly when lamp
replies arrive, and a 2-byte RX buffer loses bytes no protocol can
recover. Full post-mortem in ANALYSIS.md; all bench evidence archived.
Final ladder: 9600 production / 31250v2 FastRIO / 62500 shelved /
125000 not viable. Stop-and-wait stays on everywhere as cheap delivery
insurance.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 13:40:48 -05:00
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 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