Use PCSX2 RAM to recover the chunk loader's transformation
This is what RAM was needed for: nothing about the loader's transformation is recoverable from the disc. Anchor: a 32-byte probe from inside a chunk record in level 0's core_data, searched in the level-0 savestate. It hits at 0x18538a8 and the record's first bytes at 0x185387e -- exactly chunk_base + record_offset, no rescaling. So the chunk payload is copied VERBATIM; unlike collision and the shrub packet tables it is not expanded or repacked. Result 1: the offset table is rewritten to absolute EE addresses. disc: f000057c f00006b0 f00007e4 f0000914 RAM: 0xf185387c 0xf18539b0 0xf1853ae4 0xf1853c14 The 0xf0000000|low24 tag becomes 0xf1850000|low24 -- tag replaced by the chunk's load base, low 24 bits untouched. Consecutive deltas agree exactly (0x134, 0x134, 0x130), which is why the disc-side stride is approximate rather than constant. Result 2: every record gains a constant 2-byte prefix 02 00, and the rewritten table points at THAT rather than at the record data. Walking all 90 records from the RAM dump: prefix 02 00 on 90 of 90; the disc's index bytes preserved unchanged at +2/+3 on 90 of 90. Result 3, the useful one: the byte at +2 takes exactly 0, 16, 32, ... 240 -- the 16 values index_rule predicts for step = 16, phase = 0. The mixed-radix record index derived from the disc is corroborated on the running game's own copy of the chunk. That is a disc-derived claim validated against the game, which is the strongest form of check available here. On disc a chunk is [16-byte header][10 zero bytes][tagged offset table][records]. In RAM it is [16-byte header][10 zero bytes][absolute-pointer table][records each prefixed with 02 00]. The 02 00 is unexplained -- possibly a record type or an alignment the loader needs -- but it is constant, so like the two index bytes it carries no per-record information.
This commit is contained in:
@@ -1427,3 +1427,27 @@ So 9.4%, and no chunk is a template. Six records looked like a majority because
|
||||
that chunk's tail happens to carry shared constants -- the per-type figures range
|
||||
from 9.4% overall to 55.6% on one type. A pooled figure over all types would have
|
||||
hidden that spread again, so it is reported per type as well.
|
||||
|
||||
## What the loader does to a chunk (from RAM)
|
||||
|
||||
Verified against PCSX2 level-0 RAM; method and full dump in
|
||||
`plan/pcsx2-verification.md`.
|
||||
|
||||
The chunk payload is copied **verbatim** -- a probe from inside a record hits at
|
||||
`chunk_base + record_offset` with no rescaling. Two things change around it:
|
||||
|
||||
1. **The offset table is rewritten to absolute EE addresses.** Disc offsets
|
||||
`0xf000057c, 0xf00006b0, 0xf00007e4, 0xf0000914` become
|
||||
`0xf185387c, 0xf18539b0, 0xf1853ae4, 0xf1853c14` in RAM. The
|
||||
`0xf0000000 | low24` tag becomes `0xf1850000 | low24` -- tag replaced by the
|
||||
load base, low 24 bits untouched.
|
||||
|
||||
2. **Every record gains a constant 2-byte prefix `02 00`,** and the rewritten
|
||||
table points at *that* rather than at the record data. Measured on all
|
||||
**90 of 90** records: prefix `02 00` on every one, and the disc's index bytes
|
||||
preserved unchanged at `+2`/`+3` on every one.
|
||||
|
||||
The third result is the useful one: the byte at `+2` takes exactly
|
||||
`0, 16, 32, ... 240` -- the 16 values `index_rule` predicts for `step = 16,
|
||||
phase = 0`. The mixed-radix record index, derived from the disc, is corroborated
|
||||
on the running game's own copy.
|
||||
|
||||
Reference in New Issue
Block a user