From c8c7677f6d0734838ddfaa6079daf287666689c0 Mon Sep 17 00:00:00 2001 From: Sylpheed RE agent Date: Fri, 28 Aug 2026 19:52:02 +0000 Subject: [PATCH] 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. --- docs/port/HANDOFF.md | 11 ++-- docs/re/METHOD.md | 11 ++++ docs/re/REFUTED.md | 7 +++ docs/re/boot-config-and-gamepart-registry.md | 49 +++++++++++++++++ docs/re/data/name-lookup-callsites.txt | 57 ++++++++++++++++++++ 5 files changed, 130 insertions(+), 5 deletions(-) create mode 100644 docs/re/data/name-lookup-callsites.txt diff --git a/docs/port/HANDOFF.md b/docs/port/HANDOFF.md index 58b6044..cd1034a 100644 --- a/docs/port/HANDOFF.md +++ b/docs/port/HANDOFF.md @@ -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 ~8–10 s → `ADV.wmv` in full → diff --git a/docs/re/METHOD.md b/docs/re/METHOD.md index 55315d1..d270192 100644 --- a/docs/re/METHOD.md +++ b/docs/re/METHOD.md @@ -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 | 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`. diff --git a/docs/re/REFUTED.md b/docs/re/REFUTED.md index 2c239bd..10a145b 100644 --- a/docs/re/REFUTED.md +++ b/docs/re/REFUTED.md @@ -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 diff --git a/docs/re/boot-config-and-gamepart-registry.md b/docs/re/boot-config-and-gamepart-registry.md index 3df79fd..41c700a 100644 --- a/docs/re/boot-config-and-gamepart-registry.md +++ b/docs/re/boot-config-and-gamepart-registry.md @@ -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. diff --git a/docs/re/data/name-lookup-callsites.txt b/docs/re/data/name-lookup-callsites.txt new file mode 100644 index 0000000..09e372c --- /dev/null +++ b/docs/re/data/name-lookup-callsites.txt @@ -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.