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.
This commit is contained in:
Sylpheed RE agent
2026-08-28 19:56:22 +00:00
parent c8c7677f6d
commit 6e92ae4597
3 changed files with 116 additions and 3 deletions

View File

@@ -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.