Files
TeslaRel410/emulator/firmware-decomp/emu860c/texel_trace.py
T
CydandClaude Opus 4.8 a89d08e1c9 Commit the vrend410 firmware asset + RE tooling; gitignore run artifacts
- vrend410.mng: the production firmware, a HARD dependency of the committed
  live pipeline (emu_main.py MAPS['vrend410'].fw loads it) -- the repo couldn't
  run the live renderer without it.
- txdn_probe.py / texstore_trace.py / texel_trace.py: standalone reverse-
  engineering probes (texture-source/DRAM-write/texel tracing) documenting the
  texid-binding and texel-format investigations.
- .gitignore: exclude the firmware-decomp run artifacts (emu860c.pyd rebuildable
  from source, *.log/*.pkl/*.png renderer outputs + caches), editor junk, and
  the game runtime state/logs written by running the pod.

Left untouched deliberately: the parallel Mech session's in-progress
restoration/source410/BT/{EMITTER,BTPLAYER}.CPP edits (theirs to commit) and
the tracked game runtime state (LAST.EGG/CTMIX.CFG etc. -- transient).

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

63 lines
2.6 KiB
Python

"""Find where the production build stores texels: run the battle wire to the
first sizable set_texmap_texels + its 0x1a bulk run, watching ALL DRAM writes
during those commands -> the texel destination + layout + format."""
import sys, os, struct, collections
HERE=os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0,HERE); sys.path.insert(0,os.path.dirname(HERE))
sys.path.insert(0,r'C:\VWE\TeslaRel410\dpl3-revive\patha')
import emu860, emu_main, emu860c
from driver import boot, CpuShim
from vrboard import A
ANAME={int(a):a.name for a in A}
emu860.Mem.log=lambda self,*a,**k:None
data=open(r'C:/VWE/TeslaRel410/emulator/render-bridge/captures/netdeath-20260708.fifodump','rb').read()
recs=[]; off=0
while True:
i=data.find(b'VPXM',off)
if i<0: break
ln=struct.unpack_from('<I',data,i+4)[0]; body=data[i+8:i+8+ln]; off=i+8+ln
if len(body)>=4:
a=struct.unpack_from('<I',body,0)[0]
if a<0x100: recs.append((a,body[4:]))
# find first set_texmap_texels with header n_texels>0 (mode field) then following 0x1a runs
def w32(p,o): return struct.unpack_from('<I',p,o)[0]
tex_idx=None
for i,(a,p) in enumerate(recs):
if ANAME.get(a)=='set_texmap_texels' and len(p)>=20:
h=[w32(p,4*k) for k in range(5)]
# header: remote, n_texels, u, v, mode
if h[1]>16 and h[2]*h[3]==h[1]:
tex_idx=i; hdr=h; break
print("first real texmap @cmd %d: remote=%#x n=%d u=%d v=%d mode=%d"%((tex_idx,)+tuple(hdr)))
r=boot(fw='vrend410', queue=recs); shim=CpuShim()
RECV=emu_main.MAPS['vrend410']['receive']
# advance to just before tex_idx
while r.qi < tex_idx:
reason,_=emu860c.run(500_000_000)
if reason==3: continue
pc=emu860c.getstate()['pc']; h=r.hooks.get(pc)
if h is None: break
if h: h(shim)
# now watch writes across tex_idx and the next ~10 commands (the 0x1a bulk)
emu860c.watch_add(0x08000000, 0x0c000000)
emu860c.watch_drain()
stop_qi=tex_idx+12
while r.qi < stop_qi:
reason,_=emu860c.run(200_000_000)
if reason==3: continue
pc=emu860c.getstate()['pc']; h=r.hooks.get(pc)
if h is None: break
if h: h(shim)
raw=emu860c.watch_drain()
vals=struct.unpack('<%dI'%(len(raw)//4), raw)
addrs=vals[0::2]
pages=collections.Counter(a>>12 for a in addrs)
print("write pages during texmap upload (top 12):")
for pg,n in pages.most_common(12):
print(" %#x000 : %d"%(pg,n))
# dump a sample of the biggest page's writes to see texel format
top=pages.most_common(1)[0][0]<<12
sample=[(addrs[k], vals[2*k+1]) for k in range(len(addrs)) if (addrs[k]>>12)==(top>>12)][:8]
print("sample writes @%#x:"%top)
for a,v in sample: print(" %#010x <- %08x"%(a,v))