re: trigger queue walks live -- structure confirmed, record contents refuted

Walked the container's list from +16 for 200s. The structure holds: +20 tracks
the node count, nodes chain through their first word, and entries appear as the
mission runs (0 -> 1 -> 2, then stable).

The record layout does not. I expected node+8 to hold small symbol indices,
which the pop's out-parameters made natural. Every field is a guest heap pointer
(0xBC..), so trigger records reference objects rather than table indices, and
those objects are unidentified.

Also records a false resolution I introduced: a line printed 'f4=0(ADN101)'
because the raw value is 0 and my formatter mapped index 0 to symbol-table-2's
first entry. ADN101 is not in that record -- the pretty-printer invented a name
for a null. A resolver must refuse values that were never indices.

And corrects the previous section: sub_8226E3B8 is a CLEAR, not a push. Its tail
decrements a counter, calls an erase helper, and loops while [+20] != 0. So
built-in 100 clears the queue then rebuilds the thread list, matching the
built-in table's own wording; 'push' was my label, not the disassembly's. Two
callers: vt2 (script) and 0x8226D420 (an engine site). What appends a node is
still unidentified.
This commit is contained in:
Sylpheed RE agent
2026-08-25 18:18:19 +00:00
parent e24b46fbe8
commit cb5dccfcc0

View File

@@ -293,3 +293,48 @@ debugger. That is the first direct view of *what the script is waiting for*.
`0x000A0009`, which is not a pointer. The `addi r31, r30, 12` in the push made
"list head" the obvious reading and the value does not support it. Recorded as
unresolved rather than quietly kept.
## 🟡 Walking the trigger queue live — structure confirmed, contents not
Walked the container's linked list from `+16` for 200 s of a Stage 02 mission:
```
[ 0s] count=0 head=0xBC28E610
[ 80s] count=1 head=0xBC28E610
node 0 @0xBC28E610: f0=0xBC63.. f4=0xBC40.. f8=0xBC25.. dbl=-0.000 f24=0xBC25..
[120s] count=2 head=0xBC28E610
node 1 @0xBC28E630: f0=0xBC65.. f4=0 f8=0xBC25.. dbl=-0.000 f24=0xBC25..
```
**The structure holds**: the count at `+20` tracks the number of nodes, the
nodes chain through their first word, and new entries appear as the mission runs
(0 → 1 → 2, stable thereafter).
🔴 **The record layout does not.** I expected `node+8` to hold small **symbol
indices** — the pop's out-parameters made that the natural reading. Every field
is a **guest heap pointer** (`0xBC…`). So the trigger record references objects,
not table indices, and what those objects are is unidentified.
### ⚠️ A false resolution I introduced myself
The `[120s]` line first printed `f4=0(ADN101)` — because the raw value is **0**
and my formatter mapped index 0 to symbol-table-2's first entry. `ADN101` is not
in that record; it is my own pretty-printer inventing a name for a null. A
resolver must refuse to resolve values that were never indices, and this one had
no such guard. Recorded because it is exactly the sort of plausible label that
would survive into a conclusion.
## 🔴 Correction: `sub_8226E3B8` is a CLEAR, not a push
The previous section called it the push, reached from built-in 100 via `vt2`.
Its tail refutes that: it decrements a counter, calls an erase helper
(`sub_8226EAB8`), and **loops while `[+20] != 0`** (`beq 0x8226E3E4`). That is a
**drain-the-whole-queue** routine.
So built-in 100 *clears* the trigger queue and then rebuilds the thread list via
`sub_82273BE8` — consistent with the built-in table's own description
("push the argument record ... then drain/rebuild"), and the "push" label was
mine, not the disassembly's. `xrefs` gives it two callers: `0x82265DD4` (vt2,
the script side) and **`0x8226D420`, an engine site** — so the engine clears it
too. What actually *appends* a node is still unidentified.