diff --git a/docs/re/BACKLOG.md b/docs/re/BACKLOG.md index 1a0f21dc..0ddb1720 100644 --- a/docs/re/BACKLOG.md +++ b/docs/re/BACKLOG.md @@ -418,6 +418,38 @@ unknown, what evidence exists, and what the first step would be. Move an item in `[phase+10156]`, which are neighbours of REQUEST_NEXT but have 14 and 11 touching sites rather than one — a different, busier mechanism. +* ✅⚠️ **(2026-08-27) `[phase+10152]` / `[phase+10156]` ARE READ — an ANSWER and a + request STATE, and built-ins 102/103/130 are one trio. + [structures/isl-condition-builtins](structures/isl-condition-builtins.md).** + The backlog carried these as "9 and 7 writers, unread", and warned they are not + `request_next`'s siblings just because they are adjacent. Correct — they belong + to **four consecutive vtable stubs**: 102 → slot 70 `sub_8226BF48`, 103 → slot + 71 `sub_8226BFA8`, 104 → slot 72 (`request_next`), **130 → slot 97** + `sub_8226BFD0`. Built-in 102's body: + `state==1 → return 2` (pending); `state==2 → special[0] = (answer==1); state=0; + return 0`; `else → state=1; answer=0; return 2`. **`2` and `0` are the + dispatcher's thread codes**, so 102 is a *blocking* built-in that yields until + an answer arrives; **103 is the non-blocking form** (`state != 0 && answer == + 1`) and **130 clears the answer**. ⇒ **`[phase+10156]` = request state (0 idle / + 1 pending / 2 answered), `[phase+10152]` = the answer**, tested against 1. + ✅ The answer is published by `sub_821A9DC8` (`[10152] = [r6+4]`, `[10156] = 2`) + **under the same `(16,32]` gate on `[r30+104]+12`** that `request_next`'s writer + uses — one engine→script publish path serves both. + ⚠️ **An inherited name I could not verify: `prompt_yes_no` (102).** Grepping the + corpus, it appears only in a list of built-ins Stage 02 does not call, with **no + derivation recorded anywhere**. The mechanism is consistent with a modal yes/no + prompt but does not establish it, so **103 and 130 are left unnamed** rather + than named off an unverified premise. + 🟡 Not settled: what question is asked. `sub_821A9DC8` has **no strings** and + exactly one reference in the image (a tail `b` from `0x821AC064`), so the + string recipe finds nothing there; and the `(16,32]` gate is still unread. + 📎 Reference picked up on the way: the image carries the **full GamePart id + table** as `silph::GamePartTask::RegisterToFactory` + strings — Title 0, SaveLoad 3/4, Extras 5, MovieTheater 6, MissionSelect 7, + Options 8, Movie 9, Bunk 10, ReadyRoom 11, Hangar 12, Arsenal 13, PilotLog 14, + System 15, MainGame 17, PauseMenu 19, StageClear 20, MissionLog 21, GameOver 22, + Debriefing 23, Dialog 24, Tutorial 25, ChallengeMission 26, Leaderboard 27. + ## ✅✅ SOLVED — the mission freeze was a modal sign-in dialog (2026-08-26) `XamShowSigninUI` opens a modal dialog and `xeXamDispatchDialog` blocks the diff --git a/docs/re/structures/isl-condition-builtins.md b/docs/re/structures/isl-condition-builtins.md index 2cf6a546..cb7ba4f5 100644 --- a/docs/re/structures/isl-condition-builtins.md +++ b/docs/re/structures/isl-condition-builtins.md @@ -88,6 +88,52 @@ each have exactly one dominating condition. `0x20FFFF00`, the third id (used by the `GRAPH_PATH` / `EX_FONT` / `SYSTEM` code in `sub_821D6350` and `sub_821D6A40`). +## ✅ (2026-08-27) `[phase+10152]` and `[phase+10156]` are an ANSWER and a STATE + +The backlog carried these as "9 and 7 writers, unread". They are read now, and +they are not `request_next`'s siblings-by-adjacency: they belong to a **trio of +built-ins** sitting in four consecutive vtable stubs. + +| built-in | vtable slot | handler | body | +|---|---|---|---| +| **102** | 70 | `sub_8226BF48` | the state machine below | +| **103** | 71 | `sub_8226BFA8` | returns `state != 0 && answer == 1` | +| 104 | 72 | `sub_8226BFE0` | `request_next` (above) | +| **130** | 97 | `sub_8226BFD0` | `[phase+10152] = 0` | + +Built-in 102, read straight off `0x8226BF48`: + +``` +state = [phase+10156] + state == 1 -> return 2 ; still pending + state == 2 -> special[0] = (answer == 1) ; state = 0 ; return 0 + otherwise -> state = 1 ; answer = 0 ; return 2 ; issue the request +``` + +**`2` and `0` are the dispatcher's thread codes**, so this is a *blocking* +built-in: it yields the coroutine until an answer arrives, then hands it back. +Built-in 103 is the **non-blocking** form of the same test, and 130 clears the +answer slot. + +⇒ **`[phase+10156]` is a request STATE — 0 idle, 1 pending, 2 answered — and +`[phase+10152]` is the ANSWER**, compared against `1`. + +The answer is published by `sub_821A9DC8`, which writes +`[phase+10152] = [r6+4]` and `[phase+10156] = 2` **under the same `(16, 32]` +gate on `[r30+104]+12`** that `request_next`'s writer uses — so one +engine→script publish path serves both mechanisms. + +⚠️ **A name I did not verify.** `isl.py` calls built-in 102 `prompt_yes_no`, +and the mechanism above is *consistent* with a modal yes/no prompt — but +grepping the corpus, that name appears only in a list of built-ins unused by +Stage 02, with **no derivation recorded anywhere**. What is actually read here is +"a blocking request whose answer is tested against 1". 103 and 130 are therefore +left unnamed rather than named off an unverified premise. + +🟡 Also unread: what question is being asked. `sub_821A9DC8` has **no strings** +and exactly one reference in the image — a tail `b` from `0x821AC064` — so the +string recipe finds nothing there. + 🟡 Its neighbours belong to the same cluster: `builtin103` reads `[phase+10156]` and `[phase+10152]` (9 and 7 writers), and a sibling vtable stub clears `[phase+10152]`. The shape is an engine→script status trio, but that is a