re: WITHDRAWN -- the phase-1 condition IS polled, at 5 Hz
Tracing Stage 02 phase 1 by control flow (following op 12 jumps and the six conditional branches) gives the whole chain: timer5 @ 4.0s -> trigger 0x2D30 (which also does timer_set/timer_resume) -> start_coroutine at 0x2FE8 -> coroutine 0xBB9C, whose body is wait_s(0.2) ; yield -> ... -> 0xF524, the ADN110/111/112 polls that latch set_flag(8). Exactly one of phase 1's 79 coroutine entries reaches 0xF524 under a real control-flow walk, and it is a 0.2s polling loop. So the condition is checked at 5 Hz from 4 seconds into the phase, and my 'the condition coroutine is not polling' explanation -- which I had promoted to real evidence after the poke experiments -- is withdrawn. Two weaker methods gave wrong answers first and are named: linear decode fell through into unrelated code and implicated 30-odd entries; 'nearest preceding entry' implicated the right one only by proximity luck, 0x3988 bytes away. And I matched start_coroutine operands across phases at first, which is meaningless since the operand is relative to [phase+232] -- the same per-phase base trap that broke isl.py's jump targets, hit again three iterations later. The poke results now need a different explanation. The likeliest is that neither poke produced the tested state: +16 is never read by built-in 69, and +4 = 0 takes the early-exit path an UNDEPLOYED unit also takes. Recorded as a hypothesis with the experiment that would settle it.
This commit is contained in:
@@ -476,3 +476,45 @@ That leaves the third candidate: **the anomalous run's mission never loaded**,
|
|||||||
and its `IN FLIGHT` was a misdetection. Consistent with what became of it — it
|
and its `IN FLIGHT` was a misdetection. Consistent with what became of it — it
|
||||||
was **frozen on a black screen** when checked afterwards. Not proven, but it is
|
was **frozen on a black screen** when checked afterwards. Not proven, but it is
|
||||||
now the only surviving explanation rather than one of three.
|
now the only surviving explanation rather than one of three.
|
||||||
|
|
||||||
|
## 🔴 WITHDRAWN: "the condition coroutine is not polling"
|
||||||
|
|
||||||
|
That explanation — promoted to "real evidence" after the poke experiments — is
|
||||||
|
**wrong**. Tracing Stage 02 phase 1 by **control flow** (following op 12 jumps
|
||||||
|
and the six conditional branches, not linear decode) gives the whole chain:
|
||||||
|
|
||||||
|
```
|
||||||
|
timer5 @ 4.0s -> trigger 0x2D30 (timer_set(1200,180); timer_resume; set_flag(0))
|
||||||
|
-> start_coroutine at 0x2FE8
|
||||||
|
-> coroutine 0xBB9C : wait_s(0.2) ; builtin103 ; yield ; unit_hp_pct(TCN001,…)
|
||||||
|
-> … -> 0xF524 : unit_state(ADN110/111/112) -> set_flag(8)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Exactly one** of phase 1's 79 coroutine entries reaches `0xF524` under a real
|
||||||
|
control-flow walk, and its body is a **`wait_s(0.2)` loop**. So the condition is
|
||||||
|
polled at **5 Hz**, from 4 seconds into the phase — the opposite of what I
|
||||||
|
concluded.
|
||||||
|
|
||||||
|
⚠️ Two weaker methods gave the wrong answer first, and both are worth naming:
|
||||||
|
*linear decode* fell through into unrelated code and implicated 30-odd entries;
|
||||||
|
*"nearest preceding entry"* implicated `0xBB9C` only by luck of proximity
|
||||||
|
(`0x3988` bytes away). Only following branches settles containment.
|
||||||
|
|
||||||
|
⚠️ I also matched `start_coroutine` operands **across phases** at first, which is
|
||||||
|
meaningless — the operand is relative to `[phase+232]`, which differs per phase.
|
||||||
|
Same trap that broke `isl.py`'s jump targets, hit again three iterations later.
|
||||||
|
|
||||||
|
### 🟡 So why did the pokes do nothing? A different explanation is needed
|
||||||
|
|
||||||
|
With the polls running at 5 Hz, "nobody was looking" is out. The likeliest
|
||||||
|
remaining reason is that **neither poke produced the state the predicate tests**:
|
||||||
|
|
||||||
|
* `+16` — built-in 69 never reads it (established at `0x8226ADF0`);
|
||||||
|
* `+4 = 0` — that takes the handler's **early-exit** path, which is the same
|
||||||
|
branch an *undeployed* unit takes. The script very likely reads that as "not
|
||||||
|
here" rather than "destroyed".
|
||||||
|
|
||||||
|
**This is a hypothesis, not a finding.** What would settle it: read what built-in
|
||||||
|
69 returns for a genuinely destroyed squadron versus a zeroed handle — the run
|
||||||
|
that caught `ADN111` dying naturally at 433 s is the reference, and its record is
|
||||||
|
the thing to compare against.
|
||||||
|
|||||||
Reference in New Issue
Block a user