re: the lookup argument is decoded at 46 of 48 sites -- and it refutes my

own corroboration from last iteration

Last iteration I listed a candidate name vocabulary from "upper-case
strings the callers reference", marked it amber because those are not
proven arguments, and named the check: confirm per call site which string
actually lands in r5. Ran the check. It fired.

The first extractor FAILED ITS OWN CONTROL -- a backward scan for
addi r5 recovered 7 of 48 sites and missed both title sites I had already
read by eye, because there the name is built in r27 and reaches r5 via a
later mr. Rewritten as a forward register simulation it reproduces all
three known sites and recovers 46 of 48, giving 28 distinct names.

Two of my own claims die. DIFFICULTY and EXTRA_MENU are NOT arguments at
any site -- they are strings that merely live in the same functions, so
the "independently corroborated by measurement" line I wrote was an
artifact of the loose filter. Only TUTORIAL_MENU survives. And
sub_821CC860 is not a screen factory at all: its real arguments include
BG, BLACK, FADE, FILE, KEY, PAD, SOUND and GAMMA_RGB. It is a generic
name-keyed lookup, mostly config, which the title part happens to call
with its three state names.

The title finding itself is untouched -- sub_821C6458 really does
transition by calling this with TITLE_SCREEN, TITLE_MENU and LOADING.
What is gone is the inference that the 28 names are a screen vocabulary.

Two METHOD lines, both earned here: strings a function references are not
arguments it passes, and a backward scan for a destination register
misses arguments staged through a scratch register.
This commit is contained in:
Sylpheed RE agent
2026-08-28 19:52:02 +00:00
parent 82b2f861f0
commit fd92b235a7
5 changed files with 130 additions and 5 deletions

View File

@@ -200,11 +200,12 @@ authored version can be deleted.
game, in the game's own words — and installs the result. So a transition is a
call with a **name** argument, which is also why `GP_ADVERTISE_DEMO` has no
xrefs: at this level the screen graph is name-keyed, not id-keyed.
That lookup has 28 callers, and the identifier strings around them include
`DIFFICULTY`, `EXTRA_MENU` and `TUTORIAL_MENU` — screens measured independently
before the function was read. 🟡 a **candidate** vocabulary: those strings are
referenced by the callers, not proven to be the argument, and the list mixes in
config keys (`TEXT_FONT`, `GAMMA_RGB`, …).
✅ The argument is now **decoded** at 46 of that function's 48 call sites (28
distinct names). ⚠️ It is a **generic name-keyed lookup**, not a screen factory —
its arguments include `BG`, `BLACK`, `FADE`, `FILE`, `KEY`, `PAD`, `SOUND`,
`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:
splash → `ADV.wmv` → title + `PRESS Ⓐ` → (idle ~810 s → `ADV.wmv` in full →

View File

@@ -209,3 +209,14 @@ agent's loop prompt, i.e. nowhere durable. See [`README.md`](README.md) for the
already had `xma_param_probe` — visible in the startup CONFIG DUMP the whole
time — added by this project for exactly that purpose. Read the cvar dump, or
`nm -C <binary> | grep cvars::`, before concluding you cannot measure something.
* **"Strings a function references" is not "arguments a function passes".** A
loose filter over the strings in a caller produced a tidy-looking screen
vocabulary; recovering the actual register argument at each call site removed
half of it, including two names that appeared to be corroborated by independent
measurement. If the claim is about an argument, simulate the registers — the
cheap proxy manufactures agreement.
* **A backward scan for `addi rN, …` misses arguments staged through another
register.** PPC code often builds a pointer in a scratch register and moves it
into place later (`addi r27, r11, X``mr r5, r27`). A backward search for the
destination register alone found 7 of 48 sites and missed the two known-good
ones. Simulate forward over a window instead, tracking `lis`/`addi`/`mr`.

View File

@@ -35,6 +35,13 @@ neighbourhood, not just the line.
## Screens, classes and RTTI
* "`sub_821CC860` is the game's by-name screen factory" → **mine, and wrong.** Its
decoded arguments include `BG`, `BLACK`, `FADE`, `FILE`, `KEY`, `PAD`, `SOUND`,
`GAMMA_RGB` — it is a **generic name-keyed lookup**, mostly config.
* "`DIFFICULTY` and `EXTRA_MENU` are corroborated screen names" → **mine, and
wrong.** Neither appears in `r5` at any of the 48 call sites; they were strings
merely referenced by the same functions. Only `TUTORIAL_MENU` survives.
[`boot-config-and-gamepart-registry.md`](boot-config-and-gamepart-registry.md)
* "the `{func, func, ptr}` triples at `0x820a3b48` are a GamePart state table" →
**static-initialiser records trailing the `RegisterToFactory` strings.** The
bytes before them are the tail of a diagnostic string and the data column is

View File

@@ -249,3 +249,52 @@ Which state leads to which. The three lookups sit in different branches of one
function and at least one (`TITLE_MENU`) is guarded by a `cmplwi`/`bne`, but the
branch structure was not traced, so the *order* still comes from measurement, not
from the code.
## ✅ The argument is now decoded — and it refutes my own corroboration
The section above listed a **candidate** vocabulary from "upper-case strings the
callers reference", flagged 🟡 because those are not proven arguments, and named
the check: *confirm per call site which string actually lands in `r5`.* That check
has been run, and it fired.
**Method.** Forward register simulation over the 100 instructions before each of
the **48** call sites of `sub_821CC860`, tracking `lis` / `addi` / `subi` / `mr`.
Full table in [`data/name-lookup-callsites.txt`](data/name-lookup-callsites.txt).
**Gated on a control, and the first version failed it.** A backward scan for
`addi r5, …` recovered only 7/48 and **missed both title sites I had read by
eye** — because there the name goes into `r27` first and reaches `r5` via a later
`mr`. The rewritten forward simulation reproduces all three known sites
(`TITLE_SCREEN`, `TITLE_MENU`, `LOADING`) and then recovers **46 of 48**.
### 🔴 `DIFFICULTY` and `EXTRA_MENU` are *not* arguments
Last section I wrote that three names were "independently corroborated by
measurement": `DIFFICULTY`, `EXTRA_MENU`, `TUTORIAL_MENU`. **Only
`TUTORIAL_MENU` survives.** `DIFFICULTY` and `EXTRA_MENU` never appear in `r5` at
any of the 48 sites — they are strings that merely live in the same functions.
The corroboration I claimed was an artifact of the loose filter, and the 🟡 I put
on it is exactly what caught it.
### The 28 names that ARE passed
```
BASE BASE(x3) BG(x3) BLACK(x2) BUTTON DEBRIEFING DETAIL EXTRA FADE(x3)
FILE(x5) GAME GAMMA_RGB GAMMA_TITLE INFO KEY LIVE_BOARD(x2) LOADING(x2)
LOCAL_BOARD(x2) MENU(x2) MENU_DISABLE_SKIP MESSAGE NEW_ITEM(x2) PAD SOUND
TITLE(x2) TITLE_MENU TITLE_SCREEN(x2) TUTORIAL_MENU WINDOW
```
### 🔴 So `sub_821CC860` is not a screen factory
The previous section called it one. The real argument list says otherwise:
`BG`, `BLACK`, `FADE`, `FILE`, `KEY`, `PAD`, `SOUND`, `WINDOW`, `GAMMA_RGB`,
`MENU_DISABLE_SKIP` are **not screens**. It is a **generic name-keyed lookup**
a named-entry getter used for config and resources throughout the executable, of
which the title part happens to call it with its three state names.
That weakens nothing about the title finding itself — `sub_821C6458` really does
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.

View File

@@ -0,0 +1,57 @@
The r5 (name) argument at every call site of sub_821CC860.
Recovered by forward register simulation over the 100 instructions before
each call, tracking lis/addi/subi/mr. Gated on three sites read by eye:
0x821c6524 TITLE_SCREEN, 0x821c67c8 TITLE_MENU, 0x821c73c8 LOADING -- all three
reproduce, so the remaining rows are trusted.
call site caller r5 name
0x82185f14 sub_82185E80 0x820a2160 EXTRA
0x821860b4 sub_82186050 0x820a214c LOADING
0x82186350 sub_82186270 0x820a2140 NEW_ITEM
0x821863f8 sub_82186270 0x820a2140 NEW_ITEM
0x8218c094 sub_8218BFE0 0x820a2384 MENU
0x8219403c sub_82193648 - (not recovered)
0x82196b44 sub_82196A50 0x820a2168 FILE
0x82198540 sub_82198440 0x820a2570 BASE
0x821988e4 sub_82198808 0x820a270c MESSAGE
0x82198a5c sub_82198808 0x820a28ec MENU_DISABLE_SKIP
0x8219c3b4 sub_8219C328 0x820a2acc INFO
0x821a0b4c sub_821A0AD0 0x820a255c FADE
0x821a0b98 sub_821A0AD0 0x820a2ae8 BG
0x821a0bdc sub_821A0AD0 0x820a2adc DEBRIEFING
0x821a1028 sub_821A0F80 0x820a2ab4 LOCAL_BOARD
0x821a113c sub_821A0F80 0x820a255c FADE
0x821a1188 sub_821A0F80 0x820a2ae8 BG
0x821a129c sub_821A0F80 0x820a2554 TITLE
0x821a12e8 sub_821A0F80 0x820a2ad4 BLACK
0x821a13b4 sub_821A0F80 0x820a2ab4 LOCAL_BOARD
0x821a1a6c sub_821A19B0 0x820a2ac0 LIVE_BOARD
0x821a1bd4 sub_821A19B0 0x820a255c FADE
0x821a1c20 sub_821A19B0 0x820a2ae8 BG
0x821a1d34 sub_821A19B0 0x820a2554 TITLE
0x821a1d80 sub_821A19B0 0x820a2ad4 BLACK
0x821a1e4c sub_821A19B0 0x820a2ac0 LIVE_BOARD
0x821a2b48 sub_821A2A80 0x820a2a74 DETAIL
0x821b368c sub_821B34E8 0x820a2570 BASE
0x821b3780 sub_821B34E8 0x820a32ac WINDOW
0x821b9210 sub_821B9118 0x820a2168 FILE
0x821bc60c sub_821BC568 - (not recovered)
0x821bca58 sub_821BC978 0x820a2384 MENU
0x821be188 sub_821BDF88 0x820a2570 BASE
0x821be1ec sub_821BDF88 0x820a38ac TUTORIAL_MENU
0x821c1d30 sub_821C1B58 0x820a2168 FILE
0x821c2f04 sub_821C2EA0 0x820a2168 FILE
0x821c5c88 sub_821C5818 0x820a3d3c TITLE_SCREEN
0x821c5d70 sub_821C5818 0x820a339c BUTTON
0x821c6524 sub_821C6458 0x820a3d3c TITLE_SCREEN
0x821c67c8 sub_821C6458 0x820a3d30 TITLE_MENU
0x821c73c8 sub_821C6458 0x820a214c LOADING
0x821c9488 sub_821C93C8 0x820a2168 FILE
0x822b2e04 sub_822B2D80 0x820ab24c KEY
0x822b581c sub_822B5790 0x820ab2a4 GAMMA_TITLE
0x822b5914 sub_822B5790 0x820ab298 GAMMA_RGB
0x822b71ac sub_822B7128 0x820a99dc GAME
0x822b8700 sub_822B8670 0x820a3124 PAD
0x822b9ebc sub_822B9E38 0x820a1784 SOUND
46/48 recovered.