re: a Stage 02 clear condition read end to end, with squadron names

Resolving symbol-table-2 indices turns the bytecode into mission logic. At
0xF524 Stage02.ssb polls unit_state on ADN110, ADN111 and ADN112, updates each
one's objective marker, then latches set_flag(8) -- exactly the
trigger/predicate/set_flag/END_PHASE shape predicted from the disassembly, now
observed in the mission's own code with names the roster tables already gave.

The 12 END_PHASE sites are outro sequences (wait_cmds_drained / fade_sound(3) /
builtin85(3) / wait_s(3) / END_PHASE / yield) -- the terminator, not the
decision.

Fixes a decode bug that hid every argument: the tracker only followed
local[i] = special[0], but the common form is an immediate written straight into
local[i] (k=01,03), so every unit predicate printed with NO arguments. The
disassembly looked complete while being empty exactly where it mattered.

Also records the live probe result: the phase mirror at [*(0x828F35F8)+236]
stayed 0 for ~530s of actively-hunting flight, no advance observed -- which is
what the static analysis predicts for phase 1, since ChangePhase only posts once
the ordinal exceeds 1.
This commit is contained in:
Sylpheed RE agent
2026-08-25 12:42:50 +00:00
parent 70cff9ca21
commit dcf37bcf93
3 changed files with 426 additions and 5 deletions

View File

@@ -110,6 +110,41 @@ is not.
⚠️ Scoped to Stage 02. Other stages may well use `squad_survival_pct` — the
counting is per-file and cheap to repeat.
## ✅ A real Stage 02 condition, read end to end
With the symbol tables resolved (unit arguments are symbol-table-2 indices), the
bytecode reads as mission logic. From `Stage02.ssb` at `0xF524`
(`data/isl-stage02-conditions.txt`):
```
unit_state(1, ADN110) objective_marker(1, 0x01, 0, 8, 0)
unit_state(1, ADN111) objective_marker(1, 0x02, 0, 8, 0)
unit_state(1, ADN112) objective_marker(1, 0x05, 0, 8, 0)
objective_marker(1, 0x3A, 1, 8, 0)
set_flag(8)
```
Three **named ADAN squadrons** are polled for lifecycle state, each with its
objective marker updated, and then **flag 8** is latched. That is the shape
[mission-phase-advance](../mission-phase-advance.md) predicted from the
disassembly alone — trigger → predicate → `set_flag` → (later) `END_PHASE` — now
seen in the mission's own code with the squadron names the roster tables already
gave us.
The 12 `END_PHASE` sites are, by contrast, **outro sequences**:
`wait_cmds_drained``fade_sound(3)``builtin85(3)``wait_s(3)`
`END_PHASE``yield`. The *decision* is not there; the terminator is.
### ⚠️ A decode bug that hid every argument
The first version of the argument tracker only followed
`local[i] = special[0]`. But the common form is
**`set.i k=01,03` — an immediate written straight into `local[i]`** — and
missing it meant every unit predicate printed with **no arguments at all**
(`unit_state` rather than `unit_state(1, ADN110)`). The disassembly looked
complete and was silently empty where it mattered most. Both staging forms are
now handled.
## 🟡 Not settled
* **Three handlers resisted**: id 55 (`vt35`, 411 instructions, returns a float),