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>
This commit is contained in:
@@ -1,129 +1,133 @@
|
||||
"""emu860c differential driver v2: boot via the Python MainRunner
|
||||
(authoritative loader), copy the state into the C core, run with hooks
|
||||
serviced through a shim, and compare (pc, steps, reg-crc) at HOOK boundaries
|
||||
against the hook-aligned reference trace (ref_trace2.pkl)."""
|
||||
import sys, os, time, pickle, zlib
|
||||
|
||||
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
|
||||
|
||||
emu860.Mem.log = lambda self, *a, **k: None
|
||||
SCRATCH = r'C:\Users\cyd\AppData\Local\Temp\claude\c--VWE-TeslaRel410\4e848c76-6e89-4034-8047-d8d491cb32d8\scratchpad'
|
||||
|
||||
|
||||
class MemShim:
|
||||
def r32(self, a): return emu860c.r32(a & 0xffffffff)
|
||||
def w32(self, a, v): emu860c.w32(a & 0xffffffff, v & 0xffffffff)
|
||||
def load_blob(self, a, b): emu860c.load_blob(a & 0xffffffff, bytes(b))
|
||||
|
||||
|
||||
class CpuShim:
|
||||
def __init__(self):
|
||||
self.mem = MemShim()
|
||||
self.igc = []
|
||||
self.board_log = []
|
||||
self.RET_SENTINEL = 0xc0de0000
|
||||
|
||||
@property
|
||||
def steps(self):
|
||||
return emu860c.getstate()['steps']
|
||||
|
||||
@property
|
||||
def pc(self):
|
||||
return emu860c.getstate()['pc']
|
||||
|
||||
@pc.setter
|
||||
def pc(self, v):
|
||||
emu860c.setpc(v & 0xffffffff)
|
||||
|
||||
def rd(self, i):
|
||||
return 0 if i == 0 else emu860c.getstate()['r'][i]
|
||||
|
||||
def wr(self, i, v):
|
||||
if i:
|
||||
emu860c.setreg(i, v & 0xffffffff, 0)
|
||||
|
||||
|
||||
def boot():
|
||||
r = emu_main.MainRunner(r'C:\VWE\TeslaRel410\dpl3-revive\patha\cap7.raw.bin',
|
||||
fw='capfw7', max_cmds=200000)
|
||||
cpu = r.start()
|
||||
emu860c.init()
|
||||
for pn, page in cpu.mem.pages.items():
|
||||
emu860c.load_blob(pn << 16, bytes(page))
|
||||
for a in range(0xfffff000, 0x100000000, 4):
|
||||
v = cpu.mem.r32(a)
|
||||
if v:
|
||||
emu860c.w32(a & 0xffffffff, v & 0xffffffff)
|
||||
for i in range(32):
|
||||
emu860c.setreg(i, cpu.r[i] & 0xffffffff, 0)
|
||||
emu860c.setreg(i, cpu.f[i] & 0xffffffff, 1)
|
||||
emu860c.setpc(cpu.pc)
|
||||
emu860c.set_sentinel(cpu.RET_SENTINEL)
|
||||
emu860c.set_hooks(sorted(r.hooks.keys()))
|
||||
return r
|
||||
|
||||
|
||||
def crc_state(st):
|
||||
b = b''.join(int(v).to_bytes(4, 'little') for v in st['r'])
|
||||
b += b''.join(int(v).to_bytes(4, 'little') for v in st['f'])
|
||||
return zlib.crc32(b) & 0xffffffff
|
||||
|
||||
|
||||
def main():
|
||||
ref = pickle.load(open(os.path.join(SCRATCH, 'ref_trace2.pkl'), 'rb'))
|
||||
cps = {n: (pc, steps, crc) for n, pc, steps, crc in ref['cps']}
|
||||
max_hook = ref['hookno']
|
||||
r = boot()
|
||||
shim = CpuShim()
|
||||
t0 = time.time()
|
||||
hookno = 0
|
||||
matched = mismatched = 0
|
||||
while hookno < max_hook:
|
||||
reason, steps = emu860c.run(200000000)
|
||||
if reason == 0:
|
||||
st = emu860c.getstate()
|
||||
pc = st['pc']
|
||||
h = r.hooks.get(pc)
|
||||
if h is None:
|
||||
print("sentinel at hook %d" % hookno)
|
||||
break
|
||||
hookno += 1
|
||||
want = cps.get(hookno)
|
||||
if want:
|
||||
got = (pc, st['steps'], crc_state(st))
|
||||
if want != got:
|
||||
print("DIVERGE at hook %d:" % hookno)
|
||||
print(" want pc=%#x steps=%d crc=%08x" % want)
|
||||
print(" got pc=%#x steps=%d crc=%08x" % got)
|
||||
mismatched += 1
|
||||
if mismatched > 3:
|
||||
break
|
||||
else:
|
||||
matched += 1
|
||||
if h(shim) == 'done':
|
||||
break
|
||||
continue
|
||||
if reason == 1:
|
||||
print("STOP: pc=%#x" % emu860c.getstate()['pc'])
|
||||
break
|
||||
if reason == 2:
|
||||
st = emu860c.getstate()
|
||||
print("FP fallback pc=%#x w=%08x" % (st['pc'], emu860c.r32(st['pc'])))
|
||||
break
|
||||
if reason == 3:
|
||||
print("budget exhausted")
|
||||
break
|
||||
dt = time.time() - t0
|
||||
st = emu860c.getstate()
|
||||
print("C core: %d steps, %d hooks in %.2fs = %d steps/s; "
|
||||
"checkpoints %d/%d matched" %
|
||||
(st['steps'], hookno, dt, st['steps'] / max(dt, 1e-9),
|
||||
matched, len(cps)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
"""emu860c differential driver v2: boot via the Python MainRunner
|
||||
(authoritative loader), copy the state into the C core, run with hooks
|
||||
serviced through a shim, and compare (pc, steps, reg-crc) at HOOK boundaries
|
||||
against the hook-aligned reference trace (ref_trace2.pkl)."""
|
||||
import sys, os, time, pickle, zlib
|
||||
|
||||
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
|
||||
|
||||
emu860.Mem.log = lambda self, *a, **k: None
|
||||
SCRATCH = r'C:\Users\cyd\AppData\Local\Temp\claude\c--VWE-TeslaRel410\4e848c76-6e89-4034-8047-d8d491cb32d8\scratchpad'
|
||||
|
||||
|
||||
class MemShim:
|
||||
def r32(self, a): return emu860c.r32(a & 0xffffffff)
|
||||
def w32(self, a, v): emu860c.w32(a & 0xffffffff, v & 0xffffffff)
|
||||
def load_blob(self, a, b): emu860c.load_blob(a & 0xffffffff, bytes(b))
|
||||
|
||||
|
||||
class CpuShim:
|
||||
def __init__(self):
|
||||
self.mem = MemShim()
|
||||
self.igc = []
|
||||
self.board_log = []
|
||||
self.RET_SENTINEL = 0xc0de0000
|
||||
|
||||
@property
|
||||
def steps(self):
|
||||
return emu860c.getstate()['steps']
|
||||
|
||||
@property
|
||||
def pc(self):
|
||||
return emu860c.getstate()['pc']
|
||||
|
||||
@pc.setter
|
||||
def pc(self, v):
|
||||
emu860c.setpc(v & 0xffffffff)
|
||||
|
||||
def rd(self, i):
|
||||
return 0 if i == 0 else emu860c.getstate()['r'][i]
|
||||
|
||||
def wr(self, i, v):
|
||||
if i:
|
||||
emu860c.setreg(i, v & 0xffffffff, 0)
|
||||
|
||||
def step(self):
|
||||
emu860c.step1()
|
||||
return True
|
||||
|
||||
|
||||
def boot():
|
||||
r = emu_main.MainRunner(r'C:\VWE\TeslaRel410\dpl3-revive\patha\cap7.raw.bin',
|
||||
fw='capfw7', max_cmds=200000)
|
||||
cpu = r.start()
|
||||
emu860c.init()
|
||||
for pn, page in cpu.mem.pages.items():
|
||||
emu860c.load_blob(pn << 16, bytes(page))
|
||||
for a in range(0xfffff000, 0x100000000, 4):
|
||||
v = cpu.mem.r32(a)
|
||||
if v:
|
||||
emu860c.w32(a & 0xffffffff, v & 0xffffffff)
|
||||
for i in range(32):
|
||||
emu860c.setreg(i, cpu.r[i] & 0xffffffff, 0)
|
||||
emu860c.setreg(i, cpu.f[i] & 0xffffffff, 1)
|
||||
emu860c.setpc(cpu.pc)
|
||||
emu860c.set_sentinel(cpu.RET_SENTINEL)
|
||||
emu860c.set_hooks(sorted(r.hooks.keys()))
|
||||
return r
|
||||
|
||||
|
||||
def crc_state(st):
|
||||
b = b''.join(int(v).to_bytes(4, 'little') for v in st['r'])
|
||||
b += b''.join(int(v).to_bytes(4, 'little') for v in st['f'])
|
||||
return zlib.crc32(b) & 0xffffffff
|
||||
|
||||
|
||||
def main():
|
||||
ref = pickle.load(open(os.path.join(SCRATCH, 'ref_trace2.pkl'), 'rb'))
|
||||
cps = {n: (pc, steps, crc) for n, pc, steps, crc in ref['cps']}
|
||||
max_hook = ref['hookno']
|
||||
r = boot()
|
||||
shim = CpuShim()
|
||||
t0 = time.time()
|
||||
hookno = 0
|
||||
matched = mismatched = 0
|
||||
while hookno < max_hook:
|
||||
reason, steps = emu860c.run(200000000)
|
||||
if reason == 0:
|
||||
st = emu860c.getstate()
|
||||
pc = st['pc']
|
||||
h = r.hooks.get(pc)
|
||||
if h is None:
|
||||
print("sentinel at hook %d" % hookno)
|
||||
break
|
||||
hookno += 1
|
||||
want = cps.get(hookno)
|
||||
if want:
|
||||
got = (pc, st['steps'], crc_state(st))
|
||||
if want != got:
|
||||
print("DIVERGE at hook %d:" % hookno)
|
||||
print(" want pc=%#x steps=%d crc=%08x" % want)
|
||||
print(" got pc=%#x steps=%d crc=%08x" % got)
|
||||
mismatched += 1
|
||||
if mismatched > 3:
|
||||
break
|
||||
else:
|
||||
matched += 1
|
||||
if h(shim) == 'done':
|
||||
break
|
||||
continue
|
||||
if reason == 1:
|
||||
print("STOP: pc=%#x" % emu860c.getstate()['pc'])
|
||||
break
|
||||
if reason == 2:
|
||||
st = emu860c.getstate()
|
||||
print("FP fallback pc=%#x w=%08x" % (st['pc'], emu860c.r32(st['pc'])))
|
||||
break
|
||||
if reason == 3:
|
||||
print("budget exhausted")
|
||||
break
|
||||
dt = time.time() - t0
|
||||
st = emu860c.getstate()
|
||||
print("C core: %d steps, %d hooks in %.2fs = %d steps/s; "
|
||||
"checkpoints %d/%d matched" %
|
||||
(st['steps'], hookno, dt, st['steps'] / max(dt, 1e-9),
|
||||
matched, len(cps)))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
"""Full-mission replay through the C core: all 26,422 cap7 commands.
|
||||
Must reproduce the known-good replayed dict; reports wall time."""
|
||||
import sys, os, time
|
||||
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
|
||||
|
||||
emu860.Mem.log = lambda self, *a, **k: None
|
||||
|
||||
t_boot = time.time()
|
||||
r = boot()
|
||||
shim = CpuShim()
|
||||
print("boot+copy: %.1fs" % (time.time() - t_boot), flush=True)
|
||||
|
||||
t0 = time.time()
|
||||
hooks = 0
|
||||
while True:
|
||||
reason, steps = emu860c.run(2_000_000_000)
|
||||
if reason == 0:
|
||||
pc = emu860c.getstate()['pc']
|
||||
h = r.hooks.get(pc)
|
||||
if h is None:
|
||||
print("sentinel: main returned", flush=True)
|
||||
break
|
||||
hooks += 1
|
||||
if h(shim) == 'done':
|
||||
print("capture exhausted", flush=True)
|
||||
break
|
||||
continue
|
||||
if reason == 1:
|
||||
print("STOP pc=%#x msg?" % emu860c.getstate()['pc'], flush=True)
|
||||
break
|
||||
if reason == 2:
|
||||
st = emu860c.getstate()
|
||||
print("FP fallback pc=%#x w=%08x" % (st['pc'], emu860c.r32(st['pc'])), flush=True)
|
||||
break
|
||||
if reason == 3:
|
||||
print("budget exhausted", flush=True)
|
||||
break
|
||||
dt = time.time() - t0
|
||||
st = emu860c.getstate()
|
||||
print("MISSION: %d commands, %d steps, %d hook services in %.1fs = %d steps/s" %
|
||||
(r.qi, st['steps'], hooks, dt, st['steps'] / max(dt, 1e-9)), flush=True)
|
||||
print("replayed:", r.done, flush=True)
|
||||
BASE = {'init': 1, 'create': 124, 42: 124, 'flush': 250, 'dcs_link': 2,
|
||||
'list_add': 107, 'set_texmap_texels': 101, 25: 23, 28: 3, 29: 16793,
|
||||
'draw_scene': 8397}
|
||||
norm = {(k if isinstance(k, int) else str(k)): v for k, v in r.done.items()}
|
||||
basen = {(k if isinstance(k, int) else str(k)): v for k, v in BASE.items()}
|
||||
print("BASELINE MATCH:", norm == basen, flush=True)
|
||||
Reference in New Issue
Block a user