diff --git a/docs/plan/pcsx2-verification.md b/docs/plan/pcsx2-verification.md index 0517849..f74479a 100644 --- a/docs/plan/pcsx2-verification.md +++ b/docs/plan/pcsx2-verification.md @@ -163,3 +163,51 @@ Advanced); the socket is `$XDG_RUNTIME_DIR/pcsx2.sock` on Linux. **Nothing here redistributes game data.** The disc, the BIOS and the savestates are the user's own; the repository holds the tool and the numbers. + +## Shrub packet headers are rewritten in RAM: the loader relocates them + +Answering the "what is the tag byte" question needed an anchor, and searching +RAM from scratch was the wrong way to get one -- it finds coincidental matches +(`04 04 00 01` matches unrelated data at `0x1ac988`) and no way to tell them +apart. The savestates are the anchor: slot `.01` is level 0, and searching one +gives candidates that can be *checked* rather than guessed at. + +**Range measured:** savestate slot 1, +`~/.config/PCSX2/sstates/SCUS-97268 (38996035).01.p2s`, records at `0x22a6b8` +onward, read with `gc-trace read --state`. + +**Result: 40+ records beginning `04 04 00 01 00 00 00 00` at `0x30` spacing**, +which is the packet framing identified on disc, and the loader has rewritten +the second half of each header: + + disc: 04 04 00 01 | 00 00 00 00 | 00 00 00 05 | 00 80 0e 6c + RAM: 04 04 00 01 | 00 00 00 00 | 13 00 00 30 | 70 6a 93 00 + +Bytes 0-7 are unchanged. Bytes 8-11 and 12-15 are not: + +- on disc, bytes 12-13 are the constant `00 80` and byte 15 the constant `6c`; +- in RAM, bytes 12-15 hold what is plainly a pointer -- `0x00936a70`, + `0x009376f0`, `0x00937850`, `0x00939c50` in consecutive records, all inside + EE RAM, and ascending across the table exactly as a walk of consecutive + objects would be. + +Byte 11 becomes `0x30` in every record seen, against a constant `0x05` on +disc, and bytes 8-9 hold a varying small value (`0x13`, `0x16`, `0x24`). + +**What this means.** The packet table at `+0x40` is the thing the loader walks: +it holds span-relative offsets on disc and absolute RAM addresses after +loading, which is what the previous pass found and what these 40+ records show +directly. Any header field read past byte 8 on disc is describing something the +loader replaces. + +**Consequence for the tag bytes.** The values at record bytes 7 and 15 measured +on disc are *not* stable identifiers -- at least byte 15 sits in a field the +loader overwrites with a pointer. The four-value and two-value vocabularies are +real (0x30, 0x6d, 0x80 and 0 appear against 1636 records of otherwise-uniform +bytes), but byte 15 being a pointer in RAM means its disc values are being read +as data by something, not stored as a tag. + +**Not settled:** whether byte 7's vocabulary is also rewritten, and whether +`0x6d` marks a payload that the loader expands. That needs the same records +compared one by one against their disc spans, which is the next step and is +now cheap because the anchor exists.