Files
TeslaRel410/emulator/firmware-decomp/extract_capfw.py
T
CydandClaude Opus 4.8 753564aef2 Capture-embedded firmware extracted: cap7 carries the EXACT build the game ran
VR_COMMS.C boot_860() shows the host boots the render board by streaming the
whole .MNG over the wire: args860 ("i860 50MHz and kicking"), a 40-byte
code860 packet holding the 7-word header {csize,dsize,bsize,cstart,dstart,
bstart,entry}, then the code/data/bss segments. cap7's preamble is therefore
a complete firmware image -- and a DIFFERENT BUILD than sda4/RPLIVE/VREND.MNG
(text 0x31440 vs 0x39ec0), which explains the residual global-address
mismatches (version skew) when replaying cap7 against the sda4 build.

The wire header also confirms the link layout from the protocol itself:
cstart=0xf0400000, dstart=0x00001000, bstart=0x0001f4a0, entry=0xf0400000.
Note the streamed "bss" content is NOT zeros (10685/14272 nonzero bytes).

extract_capfw.py reassembles the image (capfw7.mng + capfw7.bss, committed);
it boots in emu860 to 0xf040062c then needs op 0x0d (new ctrl-reg variant).
run_to_draw.py = marathon runner with board-stream dump.

Next: re-derive the hook addresses (main/dN_receive/allocator/...) for the
capture build and replay cap7 against its own firmware, version-matched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-15 11:43:02 -05:00

53 lines
2.2 KiB
Python

"""Extract the firmware image embedded in a wire capture's 860-boot preamble.
The dPL3 host boots the render board by STREAMING the whole .MNG over the wire
(VR_COMMS.C boot_860): args860("i860 50MHz and kicking"), one 40-byte code860
packet = the 7-word header {csize,dsize,bsize,cstart,dstart,bstart,entry},
then code860/data860/bss860 segment packets. So every capture carries the
EXACT firmware build the game ran -- run THAT for a version-matched replay
(sda4/RPLIVE/VREND.MNG is a different build: text 0x39ec0 vs cap7's 0x31440).
Writes <out>.mng (12-byte header + text + data, emu860.load_mng format) and
<out>.bss (the streamed bss-segment content -- NOT all zeros; load at bstart).
Usage: python extract_capfw.py <capture.raw.bin> <out-base>
"""
import sys, os, struct
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, r'C:\VWE\TeslaRel410\dpl3-revive\patha')
from emu_replay import parse_capture
from vrboard import A
cap = sys.argv[1] if len(sys.argv) > 1 else r'C:\VWE\TeslaRel410\dpl3-revive\patha\cap7.raw.bin'
out = sys.argv[2] if len(sys.argv) > 2 else os.path.join(
os.path.dirname(os.path.abspath(__file__)), 'capfw7')
cmds = parse_capture(cap)
code, data, bss, hdr = [], [], [], None
for a, pl in cmds:
if a == A.code860:
if hdr is None and len(pl) == 40:
hdr = struct.unpack_from('<7I', pl, 0)
continue
code.append(pl)
elif a == A.data860:
data.append(pl)
elif a == A.bss860:
bss.append(pl)
csize, dsize, bsize, cstart, dstart, bstart, entry = hdr
text, dat, bs = b''.join(code), b''.join(data), b''.join(bss)
assert len(text) == csize and len(dat) == dsize and len(bs) == bsize, \
f"stream/header mismatch: {len(text):#x}/{csize:#x} {len(dat):#x}/{dsize:#x} {len(bs):#x}/{bsize:#x}"
with open(out + '.mng', 'wb') as f:
f.write(struct.pack('<III', csize, dsize, bsize))
f.write(text)
f.write(dat)
with open(out + '.bss', 'wb') as f:
f.write(bs)
print(f"{os.path.basename(cap)}: csize={csize:#x} dsize={dsize:#x} bsize={bsize:#x}")
print(f" cstart={cstart:#010x} dstart={dstart:#010x} bstart={bstart:#010x} entry={entry:#010x}")
print(f"-> {out}.mng (+ {out}.bss, {sum(1 for b in bs if b)} nonzero bytes)")