Move the loader onto the 68000, and find 5,920 bytes nobody counted
src/player/load.i expands both codebooks to word-per-pixel form and packs the palette to GGGGGRRRRRBBBBBI out of the RAW container header, byte-exact against tools/bench/dlxload.py on both CPU cores. The palette half is gated on words read back out of the palette registers at $E82000, so "the words reached the hardware" is part of what passes. ROADMAP P1 is done; P2's encoder half (a reserved black entry, 23.4) is not, and is a re-encode rather than an edit. A scene change costs 18.96 ms of 68000 time, 22.8% of one 12 fps frame; boot costs 24.70 ms. The scratch tables describe the CRTC, not the scene, so pal_tables is a separate entry point built once at boot -- 5.29 ms off every scene change. The one that moves something: the scene header is 5,920 B that no rate table in this tree included, because it belongs to no frame record. In FINDINGS 51.3's currency it is divided by the surplus pipe - wire, so it is hypersensitive: 138 ms of extra refill climb at 488 KB/s and 1.099 s at 451.4 KB/s, for the same bytes. tools/analysis/22_scene_load.py prices it across explicit rates. Recorded as open: the two CPU cores agree to <3% on every stage but the table build, where they differ by 16.4%. px68k's C68K charges a flat 50 clocks for MULU/MULS (c68kmacro.h:1869) where the 68000 charges 38+2n, which explains 4,608 of the 8,703 clock gap. 4,095 clocks are unexplained. Nothing else in src/player/ multiplies, so no figure in FINDINGS 24-52 is affected. decode.s and stream.s are untouched; decode.bin is still 1,296 B at the same MD5. check.sh gains a stage that gates byte-exactness on both cores and deliberately does not gate the cycle counts -- MAME's clock is 1/55.46 s and a wall timing would make the green light host-sensitive. Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Lay out the LOAD-TIME test: raw container header in, expected results out.
|
||||
|
||||
python3 tools/bench/prep_load.py <in.dlx> [--out tmp/load]
|
||||
|
||||
src/player/load.i does on the 68000 what tools/bench/dlxload.py has been doing
|
||||
host-side since session 1: expand the two codebooks to word-per-pixel form and
|
||||
pack the 24-bit palette into GGGGGRRRRRBBBBBI with the shared LSB chosen per
|
||||
entry (ROADMAP P1 and P2). This writes both halves of that comparison.
|
||||
|
||||
<out>_data.bin the container's HEADER REGION, byte for byte as it comes
|
||||
off the disc: magic, geometry, the three section offsets,
|
||||
the 768-byte palette, CB1 and CB4. Nothing is pre-chewed --
|
||||
that is the entire point. It ends where the frame stream
|
||||
begins, so it is also exactly what a player would have to
|
||||
read before it could draw anything.
|
||||
<out>_expect.bin what dlxload.py says the 68000 must produce: expanded CB1,
|
||||
expanded CB4, then 256 big-endian palette words.
|
||||
<out>_meta.lua sizes, k1/k4, and the expected darkest-entry index.
|
||||
|
||||
The expectation is generated by the SAME module the two decode rigs load
|
||||
through, so this cannot pass by agreeing with a second copy of the maths.
|
||||
"""
|
||||
import sys, argparse
|
||||
sys.path.insert(0, "tools/encoder")
|
||||
sys.path.insert(0, "tools/bench")
|
||||
from dlx import DLX
|
||||
import dlxload as DL
|
||||
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("container")
|
||||
ap.add_argument("--out", default="tmp/load")
|
||||
a = ap.parse_args()
|
||||
|
||||
d = DLX(a.container)
|
||||
if d.version < 3:
|
||||
sys.exit(f"{a.container} is DLX{d.version}: load.i checks for the 'DLX3' magic")
|
||||
if d.idx_bytes != 1:
|
||||
sys.exit("2-byte codebook indices: load.i expands one source byte per pixel")
|
||||
|
||||
off_frm = int.from_bytes(d.raw[28:32], "big")
|
||||
raw = d.raw[:off_frm]
|
||||
|
||||
cb1, cb4 = DL.expand_codebooks(d)
|
||||
palb, dark, _ = DL.pack_palette(d)
|
||||
|
||||
open(a.out + "_data.bin", "wb").write(raw)
|
||||
open(a.out + "_expect.bin", "wb").write(cb1.tobytes() + cb4.tobytes() + palb.tobytes())
|
||||
|
||||
with open(a.out + "_meta.lua", "w") as fh:
|
||||
fh.write("-- generated by tools/bench/prep_load.py -- do not edit\nreturn {\n")
|
||||
fh.write(f" k1={d.k1}, k4={d.k4}, dark={dark},\n")
|
||||
fh.write(f" raw_len={len(raw)}, cb1_len={cb1.nbytes}, cb4_len={cb4.nbytes},\n")
|
||||
fh.write(f" pal_len={palb.nbytes},\n}}\n")
|
||||
|
||||
print(f"{a.container}: k1={d.k1} k4={d.k4}, header region {len(raw)} B "
|
||||
f"(pal 768 + cb1 {d.k1*16} + cb4 {d.k4*4} + 32)")
|
||||
print(f" the 68000 must produce {cb1.nbytes} + {cb4.nbytes} B of expanded "
|
||||
f"codebook and {palb.nbytes} B of palette, darkest entry {dark}")
|
||||
Reference in New Issue
Block a user