Parse the shrub packet header, a fixed signature on all 2056 disc packets
The packets found by the +0x40 table have a header the whole disc agrees on. Range measured: every packet on the disc -- 2056 of them, across the 334 successor-bounded spans -- read at each packet's span-relative offset. bytes 0-3 04 04 00 01 2056 / 2056 bytes 4-7 zero 2056 / 2056 byte 8 zero 2056 / 2056 byte 11 0x05 2056 / 2056 size % 16 zero 2056 / 2056 Zero exceptions on any of the five. And the loader fills the rest in. Read back out of the running game the same records carry byte 8 as a count (0x0b to 0x29 observed), byte 11 as one of four tag values, and bytes 12-15 as an absolute EE RAM pointer where the disc has a span-relative offset. Bytes 8-15 are rewritten wholesale on load. That settles what the disc header is for. It carries no count of its own, and the count the RAM copy has is the +0x40 table's count arriving by another route. The disc header is a signature; the RAM header is populated state. ShrubPacketHeader::parse and Shrub::packet_headers() expose this. parse returns None unless all the invariants hold, rather than a default, so a packet that does not match is reported as not-understood instead of half-interpreted. The gated test asserts all four header invariants and the size alignment on every packet of every bounded span. This is the first piece of the mesh packet format represented in gc-formats; everything known about the packet payloads so far is RAM measurement, since the disc form of bytes 8-15 is rewritten at load.
This commit is contained in:
@@ -1263,3 +1263,36 @@ PS2 primitive lists, which is the obvious next reference to bring in.
|
||||
VIF stream: the 16-byte tiling is uniform across all 29 packets with no
|
||||
command-shaped tail, and a VIF packet would show a changing command byte in its
|
||||
last position rather than the constant `6c` at header byte 15.
|
||||
|
||||
## Shrub packet headers: a fixed disc signature, rewritten on load
|
||||
|
||||
The packets found by the `+0x40` table have a header the whole disc agrees on.
|
||||
|
||||
**Range measured:** every packet on the disc -- **2,056 of them**, across the
|
||||
334 successor-bounded spans -- read at each packet's span-relative offset.
|
||||
|
||||
**Result:**
|
||||
|
||||
| bytes | value | packets |
|
||||
|---|---|---|
|
||||
| 0-3 | `04 04 00 01` | **2056 / 2056** |
|
||||
| 4-7 | zero | **2056 / 2056** |
|
||||
| 8 | zero | **2056 / 2056** |
|
||||
| 11 | `0x05` | **2056 / 2056** |
|
||||
|
||||
Every packet's size is also a multiple of 16 (2056 / 2056). Zero exceptions on
|
||||
any of the four.
|
||||
|
||||
**And the loader fills the rest in.** Read back out of the running game, the
|
||||
same records carry byte 8 as a **count** (0x0b to 0x29 observed), byte 11 as
|
||||
one of four tag values, and bytes 12-15 as an absolute EE RAM pointer where the
|
||||
disc has a span-relative offset.
|
||||
|
||||
So **bytes 8-15 are rewritten wholesale on load.** What that means for reading
|
||||
the disc: the header carries no count of its own, and the one the RAM copy has
|
||||
is the `+0x40` table's `count` arriving by another route. The disc header is a
|
||||
signature; the RAM header is populated state.
|
||||
|
||||
`ShrubPacketHeader::parse` and `Shrub::packet_headers()` expose this, and the
|
||||
gated test asserts all four invariants plus the size alignment on every packet
|
||||
of every bounded span.
|
||||
|
||||
Reference in New Issue
Block a user