"""Enumerate the death-cam frame's primitives: capture every DMA-list word written by the coefficient-copy (0xf0411cd4) across the whole draw, decode {addr,opcode} pairs, and collect the distinct SEND/SENDE payload addresses = distinct primitives. Tells us how many pieces (object + terrain + sky) a from-scratch full frame must render.""" import sys, time, struct, pickle sys.path.insert(0, r'C:\VWE\TeslaRel410\emulator\firmware-decomp') import emu860, dis860, emu_main emu860.Mem.log = lambda self, *a, **k: None S = r'C:\Users\cyd\AppData\Local\Temp\claude\c--VWE-TeslaRel410\4e848c76-6e89-4034-8047-d8d491cb32d8\scratchpad' snap = pickle.load(open(S + r'\snapv2.pkl', 'rb')) r = emu_main.MainRunner(r'C:\VWE\TeslaRel410\dpl3-revive\patha\cap7.raw.bin', fw='capfw7', max_cmds=6000) cpu = r.cpu cpu.mem.pages = {k: bytearray(v) for k, v in snap['pages'].items()} cpu.ctrl.clear(); cpu.ctrl.update(snap['ctrl']) cpu.r = list(snap['r']); cpu.f = list(snap['f']); cpu.cr = dict(snap['cr']); cpu.pc = snap['pc'] cpu._apipe = list(snap['apipe']); cpu._mpipe = list(snap['mpipe']); cpu._fp_pipes() cpu._lpipe = list(snap['lpipe']); cpu._gpipe = list(snap['gpipe']) cpu._kr, cpu._ki, cpu._t = snap['kr'], snap['ki'], snap['t'] cpu.lcc = snap['lcc']; r.qi = snap['qi']; r.heap = list(snap['heap']) COPY = 0xf0411cd4 pairs = [] # (addr_word, opcode_word) consecutive buf = [] orig = emu860.Mem.w32 def w32(self, addr, val): if cpu.pc == COPY: buf.append(val & 0xffffffff) return orig(self, addr, val) emu860.Mem.w32 = w32 t0 = time.time(); startq = r.qi; seen_copy = False while time.time() - t0 < 150: if len(buf) >= 8000: break # stop shortly after the copy activity ends (draw done) if seen_copy and len(buf) and cpu.pc != COPY and (time.time() - t0) > 8 and len(buf) % 2 == 0: pass if len(buf): seen_copy = True h = r.hooks.get(cpu.pc) if h: if h(cpu) == 'done': break continue if not cpu.step(): break emu860.Mem.w32 = orig print("(ran to cmd %d)" % r.qi) OPS = {0x1: 'SEND', 0x9: 'SENDE', 0x2: 'TILE', 0x3: 'TXDN', 0x6: 'FLUSH', 0x0: 'GOTO', 0xf: 'STOP', 0x8: 'WAIT', 0x7: 'RETE'} sends = {} # payload addr -> set of sizes op_counts = {} tiles = set() for i in range(0, len(buf) - 1, 2): a, op = buf[i], buf[i + 1] code = (op >> 28) & 0xf name = OPS.get(code, '?%x' % code) op_counts[name] = op_counts.get(name, 0) + 1 if name in ('SEND', 'SENDE'): sends.setdefault(a, set()).add(op & 0x7f) if name == 'TILE': tiles.add(a) print("coeff-copy words captured: %d (%d pairs)" % (len(buf), len(buf) // 2)) print("opcode counts:", op_counts) print("\ndistinct SEND/SENDE payload addresses (= primitives' coeff blocks): %d" % len(sends)) for a in sorted(sends): print(" %#010x sizes=%s" % (a, sorted(sends[a]))) print("\ndistinct TILE ids referenced: %d ->" % len(tiles), sorted(hex(t) for t in tiles)[:24])