isl: rename built-ins 8/9/93 to stopwatch_start/_elapsed/_stop

They are start / read / stop of one of 32 per-phase stopwatches, not
flag operations.  123-127 keep timer_* -- that is the mission timer,
five scalars at [phase+304..320], a different clock.

Artefact check: 84 lines changed across 5 files and all 84 pair
exactly with their old-name partners once column padding is
normalised (0 removed lines without an old name, 0 added lines
without a new one).  data/isl-timers.txt reproduces the same
675/675, 11.2 % control, 82/1 and identical histograms, which is
what shows the rename is cosmetic.

Also withdraws a label from the previous commit: sub_8230C398 is NOT
the message pump.  It runs every frame but drains nothing -- a state
machine on [0x828E1F8C] that only allocates, builds strings, looks up
and PUSHES.  And bus+8216 is weak evidence: sub_82254A08 is a generic
map find with ~120 sites, and the key looked up is a pointer, not a
tag.  The open handle is now the ring buffer at bus+4, not bus+8216.
This commit is contained in:
Sylpheed RE agent
2026-08-27 09:21:04 +00:00
parent bf17f19f67
commit b86c8c82ba
10 changed files with 153 additions and 106 deletions

View File

@@ -145,11 +145,27 @@ no table of subscribed tags to find either.
### 🟡 Where the subscriber actually lives — located, not read
The bus object at `[0x828F35DC]` carries a **map at `+8216`**, looked up through
`sub_82254A08` from **`sub_823001E8`** — whose only caller is `sub_8230C398`, the
per-frame message pump (itself called from the frame loop `sub_821A6544` with the
frame `dt`). So dispatch is a **runtime registry keyed by the tag**, and the
question "does running out of time end the mission" reduces to: *what inserts into
`bus+8216`, and with which key.* That insert path is not read here.
`sub_82254A08` from **`sub_823001E8`** — whose only caller is `sub_8230C398`.
🔴 **Correction to my own label from the previous pass.** I called
`sub_8230C398` "the per-frame message pump". It is *called* every frame (from
`sub_821A6470` at `0x821A654C` and from the mission loop `sub_821AA1B0` at
`0x821AA7DC`, both with the frame `dt`), but **it drains nothing**: its whole
body is a state machine on the counter at `[0x828E1F8C]`, and across 466
instructions it calls only an allocator (`sub_8230C160`), string building
(`sub_8217FA08`), a map lookup (`sub_823001E8`) and a *push* (`sub_8225FEA0`).
It is a boot/loading sequencer that posts messages, not the consumer of them.
Two further cautions the search turned up:
* `sub_82254A08` is a **generic map find** with ~120 call sites image-wide, and
`+8216` is a common offset — the pair alone identifies nothing.
* The key `sub_823001E8` looks up is a **pointer** (`lwz r4, 13780(r11)` stored
and passed by address), **not a message tag**. So `bus+8216` may not be the
subscriber registry at all.
**So the drain of the queue at `bus+4` is still unlocated**, and with it the
answer to whether running out of time ends the mission.
## 🟡 Not settled

View File

@@ -109,13 +109,16 @@ in a coherent block of stages) — checked before believing.
## 🟡 What this leaves
* The **naming**. `set_flag` / `read_freg` / `clear_flag` describe none of this.
✅ The other timer is now read — [isl-mission-timer](isl-mission-timer.md) —
so the collision is understood: 123/124/125/126/127 act on five *scalar*
fields (`[phase+304…320]`), this family on a 32-entry *bank*. `stopwatch_start`
/ `stopwatch_elapsed` / `stopwatch_stop` would separate them. Still not renamed
here, so every artefact regenerates byte-identical; the rename is its own
change and its own artefact diff.
* ~~The **naming**.~~ ✅ **RENAMED (2026-08-27).** `isl.py` now emits
**`stopwatch_start` (8) / `stopwatch_elapsed` (9) / `stopwatch_stop` (93)**;
built-ins 123127 keep `timer_*` for the *other* clock
([isl-mission-timer](isl-mission-timer.md)), which acts on five scalar fields
rather than a 32-entry bank. The rename touched **84 lines across 5 artefacts
and every one pairs exactly** with its old-name partner once column padding is
normalised — nothing but the three names changed, and this file's own artefact
reproduces the same 675/675, 11.2 %, 82/1 numbers under the new labels.
⚠️ Older prose in the corpus still uses the old names where it is quoting what
was believed at the time; that is deliberate.
* The **one exception**: `read_freg(15)` in Stage 06 phase 1 is not started by a
`set_flag(15)` in that phase. Cross-phase carry-over or a start in the
unreached code — not chased.