Gate the PCSX2 claims as tests; two corrections fall out of writing them

The audit two commits ago listed three claims as "not assertable here -- needs a
savestate". With PCSX2 running they are assertable, so they now are. gc-trace
already exposed gc_trace::Savestate::ee_ram_owned(); gc-extract just needed it as
a dev-dependency. Both tests are gated on GC_SSTATE and skip cleanly without it,
so a normal checkout pays nothing.

Writing them corrected two claims, which is the main reason they were worth
writing as tests rather than staying prose.

1. The collision payload is NOT "byte-for-byte identical". The original claim
   rested on a 4 KiB probe; the test compares the whole 903,248-byte payload:

     payload                903,248 bytes at RAM 0xac6800
     first difference       +0xdc82c, i.e. 903,212 bytes in
     bytes that differ      6  (0.00%)

   903,212 of 903,248 bytes are verbatim and 6 are not, all in the final 36.
   "Verbatim" was an overclaim on a probe that never looked at the tail. The test
   now measures the whole payload and reports the extent, asserting only that the
   divergence is beyond the head.

2. The tfrag relocation base is the TABLE address, not the block base. The delta is
   8,683,584 = 0x848040 = block base 0x848000 plus table_offset 0x40 -- which is
   exactly what TfragHeader::data's own documentation says, "relative to the
   table". The earlier claim said "the block's RAM base", off by exactly the table
   offset.

   Also: +0x10 and +0x38 do NOT share one constant. The aggregate "1,665 fields
   relocate by one constant" was true only because +0x10 carried it; lumping them
   hid that. The test asserts +0x10 and REPORTS +0x38's delta rather than assuming.

The patch-rewrite figures also restated on aggregate rather than median, which is
why they read lower than the 7.80%/8.12% medians recorded earlier:

  patch bytes rewritten -- cannot morph 1.9% of 334, can morph 2.1% of 499

Same conclusion, stated on a total instead of a per-patch median, and asserted to
within 3 percentage points of each other.

Net: the audit table in docs/formats/core-data-regions.md now has no "prose only"
rows for disc-or-savestate-readable claims.
This commit is contained in:
2026-10-13 06:59:22 +02:00
parent 9f938f47de
commit 26a0918178
5 changed files with 279 additions and 8 deletions
+9 -5
View File
@@ -247,8 +247,10 @@ Phase 1 hands over the extents; this phase works out what each one contains.
unrecovered" note wrongly implied.
- [x] The tfrag **table record has exactly two relocated pointer fields**, at
`+0x10` and `+0x38`, verified against PCSX2 across all **833** records: the
loader adds the block's RAM base (`0x848000`) to each, every other byte of
every record is verbatim, and 1,665 fields differ where 1,666 were possible.
loader adds the **table's** RAM address (`0x848040` = block base plus
`table_offset`, matching `TfragHeader::data`'s own "relative to the table")
to `+0x10`; every other byte of every record is verbatim, and 1,665 fields
differ where 1,666 were possible.
They are the existing `TfragHeader::data` and `::cube_ofs` -- what RAM adds
is that both are **pointers**, not plain offsets. All **833** patches parse,
carrying **43,613** vertex-info entries; **499 of 833** have at least one
@@ -365,9 +367,11 @@ Phase 1 hands over the extents; this phase works out what each one contains.
with no arithmetic relating the two. A 64-byte RAM stride looked promising
and is **disproved** -- the longest such run is 27 records of identity
matrices, one per level.
- [x] **The collision payload is verbatim in RAM, not reshaped.** Level 0's sits
at RAM `0xac6800` for a disc address of `0x27e800`, byte-for-byte
identical. This **overturns** the earlier claim that the grid dimensions
- [x] **The collision payload is essentially verbatim in RAM, not reshaped.**
Level 0's sits at RAM `0xac6800` for a disc address of `0x27e800`:
**903,212 of 903,248 bytes identical**, first difference at `+0xdc82c`, with
**6** bytes differing in the final 36. Asserted by a savestate-gated test
that compares the whole payload. This **overturns** the earlier claim that the grid dimensions
are absent from RAM: level 0's `11 x 33` are the first two bytes of that
block. The earlier negative came from searching for the dimensions as a
`u32` pair when they are two `u16`s -- a bad pattern, not a property of