From 6e92ae459760b6eae11c5a6a8ad84a917f931685 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Fri, 28 Aug 2026 19:56:22 +0000 Subject: [PATCH] re: the title's state machine is decoded -- ten states, eighteen edges Q6's last open piece was which state leads to which, and it turned out to be a plain switch. state = this+136, compared against 9, dispatched through a jump table at 0x821C6498. The ten words at that address disassemble as lwz r16,N(r28) instructions and are nothing of the kind -- they are the table. That is the same "self-reference" I flagged two iterations ago as looking like a jump table; it is one, and the disassembler was decoding its data. Three states install a named screen: 0 is TITLE_SCREEN, 2 is TITLE_MENU, 8 is LOADING. Eighteen transitions, every one a literal li/stw pair into the state field, giving the full graph. It lines up with the behaviour measured weeks of iterations ago without either side knowing about the other: boot reaches state 0 and A opens state 2; B at the main menu returns to the title, and 4 -> 0 is the ONLY edge back to state 0, reached from 2 -> 4; entering a submenu goes through LOADING and comes back, which is 4 -> 8 at four separate sites then 8 -> 2. I have marked that as corroboration and said plainly it is me matching a graph to observations -- the conditions on the edges are not decoded, so nothing here proves which input picks which branch. Still open and written down as such: the condition on each edge, what states 1/3/5/6/7/9 do, and the fact that state 3 is never a destination in this function, so something outside sets it. --- docs/port/HANDOFF.md | 12 +++-- docs/re/boot-config-and-gamepart-registry.md | 52 ++++++++++++++++++ docs/re/data/title-state-machine.txt | 55 ++++++++++++++++++++ 3 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 docs/re/data/title-state-machine.txt diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index cd1034a..2441967 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -206,8 +206,14 @@ authored version can be deleted. `GAMMA_RGB`. An earlier version of this page claimed `DIFFICULTY` and `EXTRA_MENU` as corroborated screen names; **neither is ever the argument**, and only `TUTORIAL_MENU` survives. - The port can transcribe the state **names**; the order still comes from - measurement. The sequence itself is fully measured: + ✅ **And the state machine itself is decoded**: `state = this+136`, ten states + dispatched through a jump table at `0x821C6498`, with **18 transitions** each a + literal `li`/`stw`. States **0, 2, 8** install `TITLE_SCREEN`, `TITLE_MENU`, + `LOADING`. `4 → 0` is the only edge back to the title, reached from `2 → 4` — + which matches Ⓑ-returns-to-title as measured. Full graph in + [`data/title-state-machine.txt`](../re/data/title-state-machine.txt). + 🟡 The **conditions** on the edges are not decoded, so the port still takes the + order from measurement; the graph corroborates it rather than replacing it. The sequence itself is fully measured: splash → `ADV.wmv` → title + `PRESS Ⓐ` → (idle ~8–10 s → `ADV.wmv` in full → title) → Ⓐ → main menu, with Ⓑ from the main menu returning to the title. @@ -284,7 +290,7 @@ here until 2026-08-28 and is now settled.) | ❔ | **the other ~319 SE cues** (Q8) | located one at a time by triggering them; only the three the menu needs have been done | | 🟡 | **the paint-order tie-break** (Q3) | eight candidates refuted; costs one element's blend on one screen | | 🟡 | **GamePart ids behind the buttons** (Q4) | the *screens* are measured; the ids are a name match onto the executable's class names | -| 🟡 | **the boot transitions in code** (Q6) | a title-side transition is a **screen lookup by NAME** — `sub_821CC860(…, "TITLE_SCREEN"/"TITLE_MENU"/"LOADING", 0)` then install. A candidate name vocabulary of ~12 screens falls out, 3 of them corroborated by measurement. Which state leads to which is still unread | +| 🟡 | **the boot transitions in code** (Q6) | **the state machine is decoded** — `state = this+136`, ten states, jump table at `0x821C6498`, 18 literal transitions; states 0/2/8 install `TITLE_SCREEN`/`TITLE_MENU`/`LOADING`. Still unread: the **condition** on each edge | | ❔ | **builds 0/1 and 10/11**, the `DELTASABER` plates (Q2) | never seen anywhere in the boot path, the title-side screens or the attract loop. A mission load is the remaining candidate and this container kills runs before one completes | (An earlier version of this table called the audio items blocked on "an emulator diff --git a/docs/re/boot-config-and-gamepart-registry.md b/docs/re/boot-config-and-gamepart-registry.md index 41c700a..3c96f76 100644 --- a/docs/re/boot-config-and-gamepart-registry.md +++ b/docs/re/boot-config-and-gamepart-registry.md @@ -298,3 +298,55 @@ That weakens nothing about the title finding itself — `sub_821C6458` really do transition by calling this with `TITLE_SCREEN` / `TITLE_MENU` / `LOADING` — but it removes the inference that the 28 names are a screen vocabulary. They are a **lookup-key vocabulary**, mostly config. + + +## ✅ The title's state machine — decoded + +The last open piece of Q6 was *which state leads to which*. It is a plain +`switch` and it is now read. + +``` +821c6474 lwz r11, 136(r30) ; state = this+0x88 +821c6478 cmplwi cr6, r11, 0x9 ; ten states, 0..9 +821c647c bgt cr6, +821c6480 lis/addi r12, 0x821C6498 ; jump table +821c648c lwzx r0, r12, r0 +821c6494 bctr +``` + +⚠️ The table at `0x821C6498` disassembles as ten `lwz r16, N(r28)` instructions. +**It is data.** That is the "self-reference" this page flagged two sections ago as +*looking* like a jump table — it is one, and the disassembler was decoding its +words as code. + +**Three of the ten states install a named screen**: **0 → `TITLE_SCREEN`**, +**2 → `TITLE_MENU`**, **8 → `LOADING`**. + +**Eighteen transitions**, every one a literal `li rX, N ; stw rX, 136(r30)`: + +``` +0 → 1, 2 2 → 4 4 → 0, 5, 8×4 6 → 7, 9, 2 8 → 2 +1 → 2, 2 3 → 4 5 → 6 7 → 9 9 → (none) +``` + +Full table with addresses in +[`data/title-state-machine.txt`](data/title-state-machine.txt). + +### 🟡 It lines up with what was measured — read as corroboration, not proof + +The boot reaches the title (state 0) and Ⓐ opens the main menu (state 2); the +graph has `0 → 2` directly and `0 → 1 → 2`. Ⓑ at the main menu returns to the +title, and `4 → 0` is the **only** edge back to state 0, reached from `2 → 4`. +Entering a submenu goes through `LOADING` and comes back, and `4 → 8` (four +separate sites) then `8 → 2` is exactly that shape. + +Those readings are **mine, matching a graph to observed behaviour** — the +conditions on the edges are not decoded, so nothing here proves which input picks +which branch. + +### What is still not decoded + +* **the condition on each edge** — which input or event selects it; +* **states 1, 3, 5, 6, 7, 9** install no named screen, so what they do is unknown; +* **state 3 is never a destination** in this function, so something outside sets + it. diff --git a/docs/re/data/title-state-machine.txt b/docs/re/data/title-state-machine.txt new file mode 100644 index 0000000..519d7d7 --- /dev/null +++ b/docs/re/data/title-state-machine.txt @@ -0,0 +1,55 @@ +GamePart_Title's screen state machine -- sub_821C6458, decoded statically. + +DISPATCH + 821c6474 lwz r11, 136(r30) ; state = this+0x88 + 821c6478 cmplwi cr6, r11, 0x9 ; 10 states, 0..9 + 821c647c bgt cr6, 0x821C75B8 ; out of range -> default + 821c6480 lis r12, 0x821C + 821c6484 addi r12, r12, 25752 ; jump table at 0x821C6498 + 821c6488 slwi r0, r11, 2 + 821c648c lwzx r0, r12, r0 + 821c6490 mtctr r0 + 821c6494 bctr + +NOTE: a disassembler decodes 0x821C6498..0x821C64BC as `lwz r16, N(r28)` +instructions. They are the jump TABLE's ten words, not code. + +STATES + case 0 -> 0x821c64c0 installs "TITLE_SCREEN" + case 1 -> 0x821c65d0 + case 2 -> 0x821c66e4 installs "TITLE_MENU" + case 3 -> 0x821c6b18 + case 4 -> 0x821c6b5c nested switch, table at 0x821c6b7c (live: 0,3,5,8) + case 5 -> 0x821c6fd4 + case 6 -> 0x821c7028 + case 7 -> 0x821c72dc + case 8 -> 0x821c733c installs "LOADING" + case 9 -> 0x821c7558 + +TRANSITIONS -- every `li rX,N ; stw rX,136(r30)` in the function + from to at + 0 1 0x821c6598 + 0 2 0x821c65c8 + 1 2 0x821c66a4 + 1 2 0x821c66dc + 2 4 0x821c6afc + 3 4 0x821c6b54 + 4 0 0x821c6e00 + 4 5 0x821c6e70 + 4 8 0x821c6ed0 + 4 8 0x821c6f20 + 4 8 0x821c6f7c + 4 8 0x821c6fcc + 5 6 0x821c7020 + 6 7 0x821c725c + 6 9 0x821c72a8 + 6 2 0x821c72d4 + 7 9 0x821c7334 + 8 2 0x821c7548 + (state 9 stores nothing -- terminal within this function) + +WHAT IS NOT DECODED + * the CONDITION on each edge -- which input or event selects it; + * what states 1, 3, 5, 6, 7 and 9 do (they install no named screen); + * state 3 is never a destination here, so something outside this function + sets it.