Picking up after e5cd3df, which retracted the 16-byte tie vertex element for
want of a detectable stride. There is one, at 64 bytes, and it beats a shuffle
control by a factor of ten:
regions with a signature 7,314 of 15,219
same test on shuffled bytes 731 of 15,219
stride 64 6,463 of the 7,314
Range: every tie vertex region on all 27 levels, 15,219 regions. A byte offset
counts as constant at stride s when every unit of length s agrees there, with
at least three units, an exact divide, and at least eight constant bytes.
Dumping the regions shows four *different* 16-byte layouts repeating at
+00 +10 +20 +30: one is a small i16 followed by two zeroes, one carries 255,-1
mid-element, the other two carry neither. So the element is 16 bytes and the
layout cycles with period four. That is a partial retraction of a retraction:
e5cd3df was right that the four layouts differ, and right that pooling them
spans the whole i16 range. It was wrong to conclude that 16 is not the stride.
Four tests still do not separate the four layouts, and the table records all
four because the negative is the finding: LOD1/LOD2 sharing is 16.1/16.2/16.2/
16.3 percent across the four groups, f32-in-band is 23 percent in all four
(which is what uniform random gives), and i32-in-band is 0/2/6/0. The position
stays unnamed.
Also clears the clippy warnings that had accumulated on main from the disassembly
work: doc_lazy_continuation on three prose blocks, two negated-comparison guards
in gs.rs, a doc-then-item blank line twice over, a useless usize::from, and an
as_chunks that needs 1.88 while the workspace declares 1.85 -- replaced with
chunks_exact rather than moving the MSRV.
Clippy is clean. Suite with the disc: 67 disc tests, 156 gc-formats, 22
gc-trace, 23 gc-engine, 19 gc-game; without it, 67 disc tests skip early and
report the same count.
The fix e6b3e0b called for, with the verification that six commits kept deferring.
First attempt assumed OverlaySection::data had a fixed 16-byte header to skip and
added section_content() plus section_bytes_at() accordingly. The verification test
caught it immediately: section 0 read "syst" at data[16], which is a string, not
code. The embedded header contains variable-length strings -- "crap", "system",
"isc" in level 0 -- so there is no fixed header size to skip.
What is actually true: the overlay lump is a MEMORY IMAGE. Its first word is
0x001A7C80, the load address of .lit, and overlay[addr - LIT_BASE] is the byte at
addr. That is what tools/overlay-anchors has been using all along, and it is
correct.
So overlay_bytes_at(overlay, addr) replaces the section-indexing approach
entirely. Bounds-checked, so it cannot read past the image.
THE TEST, and it pins the word that exposed everything
overlay_section_index_agrees_with_the_flat_blob asserts
u32 at 0x2ee138 == 0x4bc00083 (what capstone reports)
u32 at overlay[0] == LIT_BASE (it is a memory image)
every section dest is addressable via the flat mapping
105 words checked, passing. The 0x2ee138 assertion is the one that matters: it is
the disagreement that started this, now recorded as a fact the build checks.
What this does not do: re-read 0x2ee138, or redo any of the sixteen probes. Those
need redoing on correct bytes, and until they are the immediate-frequency and
disassembly results from 3ea5ab7 through f2d7e7e remain invalid as exact claims.
Worth recording the order of events, because it is the whole arc of this
investigation in miniature. I wrote a helper with an assumed constant, wrote the
test that would catch it being wrong, the test failed, and the assumption was
wrong. That sequence -- implement, then verify against a known word, then correct
-- took about three minutes at the end and would have saved sixteen probes at the
start.
285 passing with the disc present (23 + 19 + 65 + 156 + 22; disc binary 34.94s),
clippy clean.
Last commit read bit 31 of a tie vertex region's first word as "VIF code word"
and told a two-encoding story on it. The split is real; the identification is
wrong, and I checked it before building anything on top.
Walking those regions as VIF packets, levels 0-2, 914 records:
walk reaches the region end 17
walk dies after exactly ONE packet 1,571
packets before dying: min 0, median 1, max 4
tfrag walks VIF the same way -- VifCode::decode, then num * 4 payload words -- and
reaches the end of its lists every time. So the walk is not the problem; these
regions are not VIF packet streams. Bit 31 is set on whatever this word actually
is, and that is still unknown.
The specific thing that made me overreach: I quoted 0xf5c1a3c5 as "a VIF code
word, cmd 0x75 num 193" and treated that as establishing the format. Decoding one
word as a packet header says nothing about whether the next 193 words are its
payload. Here they are not -- the walk dies immediately after.
This is the third time in this area that one plausible word produced a confident
story: the 305x class-ID slot, the UV-corner texcoords, and now this. All three
shared a shape -- a single readable item at the head of a population, treated as
evidence about the whole. The bit is the only thing the two kinds reliably
differ on, so it stays; the name goes.
The test now asserts BOTH the split and the walk failure, which is the part worth
keeping. If these ever do turn out to be VIF, the test fails and says so, rather
than two findings drifting apart silently -- which is how "half VIF, half flat"
would have sat in the docs indefinitely.
Docs corrected in both roadmap and format file, including the quoted example.
258 tests.
Ported ReRAC's (vendor/rerac/crates/rc-formats/src/level_overlay.rs) mask /
Relocation machinery into gc-formats:
- parse_overlay_sections, read_overlay: section table {dest,size,kind,entry},
ends on entry mismatch; kind==8 = BSS; plus LevelOverlay with .text words,
text_start and function starts.
- mask: hides relocated fields (j/jal targets, lui of main-RAM 0x0010..0x0040,
%lo/move/$gp completions tracked per-register).
- walk/HiState/address_refs/key: PS2 code walk with branch-delay-slot register
state.
- Relocation::new/same_code/copies/func/data: masked-code index, one-copy
lookup, data-address relocations.
A real-disc test asserts that a level-01 engine function's relocated copy is
found exactly once on all 26 other overlays (gate: every level-01 function is
reachable by masked-code identity on all 27).
Co-authored-by: reaper <reaper@users.noreply.github.com>