From b07b678ef0e979cbc5f0834e4a209b61ab9b6bb8 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Tue, 25 Aug 2026 16:58:49 +0000 Subject: [PATCH] re: unit_state reads rec+4 and rec+104, never rec+16 Disassembling built-in 69's handler at 0x8226ADF0 instead of trusting the summary: it loads rec = base[idx], tests rec+4 against zero (early exit = absent), passes rec+4 to sub_82301240 for the lifecycle lookup, and compares the byte at rec+104. rec+16 is never touched on that path. That explains the null poke result exactly -- I wrote into a field the condition does not consult. +16 remains a faithful OBSERVABLE (the arrival and death transitions were real) but it is a readout, not the input. It also explains why rec+4 holds small consecutive integers: it is a handle that sub_82301240 resolves, not a pointer. The corrected simulation of 'this squadron is gone' is rec+4 = 0, taking the documented early exit. Flags a general caution: this built-in table came from a subagent's reading of handler behaviour, and this is the second per-offset field description that did not survive the disassembly. The identifications of which built-in does what have held up; the offset meanings are leads to verify. --- docs/re/structures/isl-builtins.md | 38 ++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/docs/re/structures/isl-builtins.md b/docs/re/structures/isl-builtins.md index 1d78151..33dc307 100644 --- a/docs/re/structures/isl-builtins.md +++ b/docs/re/structures/isl-builtins.md @@ -184,6 +184,44 @@ unconditional jump. **Not confirmed** — the handlers (`0x82271598` for op10, `0x82271830` for op13) have not been read, and I am not going to name them from a pattern alone. +## 🔴 Correction: `unit_state` does NOT read `+16` — it reads `+4` and `+104` + +Disassembling built-in 69's handler (`0x8226ADF0`) rather than trusting the +one-line summary: + +``` +lwz r10, 324(r30) ; the unit array +lwz r11, 4(r31) ; arg blob +4 = the symbol-table-2 index +lwz r10, 4(r10) ; records base +lwzx r9, r11, r10 ; rec = base[idx] +lwz r9, 4(r9) ; <-- rec+4 +cmplwi r9, 0 +beq 0x8226AF44 ; rec+4 == 0 -> early exit, "absent" +lwz r4, 4(r11) ; rec+4 again +bl 0x82301240 ; lifecycle lookup ON rec+4 +... +lbz r11, 104(r11) ; rec+104, a BYTE, compared against 1 +li r11, 2 ; -> result 2 +``` + +**`rec+16` is never touched on this path.** The predicate reads the **handle at +`rec+4`** — which is why it holds small consecutive integers (26/27/28) rather +than pointers; `sub_82301240` resolves it — plus the byte at `rec+104`. + +That is exactly why poking `+16` to 4 changed nothing +([script-runtime-probe](../script-runtime-probe.md)): the value was written into +a field the condition does not consult. `+16` still tracks +deployed/active/destroyed faithfully as an *observable* — the arrival and death +transitions were real — but it is a **readout, not the input**. + +**The corrected way to simulate "this squadron is gone" is `rec+4 = 0`**, which +takes the documented early exit. That is the next experiment. + +⚠️ General lesson for this table: it was assembled by a subagent from handler +behaviour, and this is the second field description that did not survive contact +with the disassembly. Treat the per-offset meanings as leads to verify, not as +facts — the *identifications* (which built-in does what) have held up well. + ## 🟡 Not settled * **Three handlers resisted**: id 55 (`vt35`, 411 instructions, returns a float),