Read a moby handler: the chain works, with two caveats and a 110 discrepancy
Followed the chain through -- dispatch table to handler address to disassembly --
and read level 0's class 2 handler at 0x00380a88:
0x00380a84: jal 0x2ee0d0
0x00380a88: .word 0x0240202d <- VU1 microcode, not a failure
0x00380a8c: lwc1 $f12, 0x40($s1)
0x00380a98: addiu $a0, $s0, 0x20
0x00380aa0: swc1 $f0, 0x18($s4)
0x00380ab0: swc1 $f0, 0x14($s4)
Floats out of one structure, written back into another, with VU1 work alongside --
what a transform update should look like. The chain from an asset observation to the
game's own code is now complete and usable.
TWO CAVEATS, both learned by hitting them:
VU1 microcode interleaves with CPU code. 0x0240202d is a COP2 opcode, not an
undecodable word. A tool that counts .word lines as failures is counting the wrong
thing -- a trap I walked into earlier today with the region walkers, now recorded
so it is not repeated.
Handlers are not all independent functions. Level 0's class 2 is at 0x380a88 and
class 0x0E at 0x380a90 -- EIGHT BYTES apart -- and 72 of the 5,788 records sit
within 16 bytes of the one before them. Consecutive classes share one routine with
per-class entry points inside it, so reading "a handler" gives a fragment. That
matters downstream: a class's behaviour is not one function, and assuming
otherwise would misattribute shared code.
A DISCREPANCY WITH THE REFERENCE
The decomp reports 5,598 of 5,788 moby handlers (96.7%) preceded by a jr ra within
three words. Measured here, the same way, over the same 5,788 records: 5,488
(94.8%). Same population, same test, 110 handlers different.
Both figures support the premise, so nothing turns on it, and I am recording it
rather than picking the number that suits. The reference measured on 2026-10-02
against its own pinned overlay set, so a method or version difference is as
plausible as a data difference and there is no basis here for saying which. The
test asserts the premise (>90%) and deliberately NOT either exact figure.
Asserted in moby_handlers_are_overwhelmingly_function_entries.
264 tests.
This commit is contained in:
@@ -3196,3 +3196,47 @@ The camera and sound handler addresses fall inside section 6 of the same overlay
|
||||
which the working disassembler can read directly.
|
||||
|
||||
Asserted in `camera_and_sound_dispatch_tables_decode_at_their_documented_widths`.
|
||||
|
||||
|
||||
## The handler chain works, with two caveats and one discrepancy
|
||||
|
||||
With the dispatch tables decoded and the disassembler fixed, a moby handler can
|
||||
actually be read. Level 0's class 2, handler `0x00380a88`:
|
||||
|
||||
0x00380a84: jal 0x2ee0d0
|
||||
0x00380a88: .word 0x0240202d <- VU1 microcode, not a decoding failure
|
||||
0x00380a8c: lwc1 $f12, 0x40($s1)
|
||||
0x00380a98: addiu $a0, $s0, 0x20
|
||||
0x00380aa0: swc1 $f0, 0x18($s4)
|
||||
0x00380ab0: swc1 $f0, 0x14($s4)
|
||||
|
||||
Floats read out of one structure and written back into another, with VU1 work
|
||||
alongside -- which is what a transform update should look like.
|
||||
|
||||
### Two caveats before reading one
|
||||
|
||||
**VU1 microcode is interleaved with CPU code.** `0x0240202d` is a COP2 opcode, not
|
||||
an undecodable word. A disassembly window will run `.word` lines that are
|
||||
instructions in a different processor, and a tool that counts them as failures is
|
||||
counting the wrong thing.
|
||||
|
||||
**Handlers are not all independent functions.** Level 0's class 2 is at
|
||||
`0x380a88` and class `0x0E` at `0x380a90` -- **eight bytes apart** -- and 72 of the
|
||||
5,788 records sit within 16 bytes of the one before them. So consecutive classes
|
||||
share one routine with per-class entry points inside it, and reading "a handler"
|
||||
gives a fragment, not a whole function.
|
||||
|
||||
### And a discrepancy with the reference
|
||||
|
||||
`docs/MOBY-DISPATCH-TABLES.md` reports 5,598 of 5,788 moby handlers (96.7%)
|
||||
preceded by a `jr ra` within three words. Measured here, the same way, over the
|
||||
same 5,788 records: **5,488 (94.8%)**.
|
||||
|
||||
Same population, same test, 110 handlers different. Both figures confirm the
|
||||
premise, so nothing turns on it, and the residual is recorded rather than explained
|
||||
away. The reference measured on 2026-10-02 against its own pinned overlay set, so
|
||||
a difference in method or version is as plausible as a difference in the data, and
|
||||
there is no basis here for saying which. The test asserts the premise (>90%) and
|
||||
deliberately not either exact figure.
|
||||
|
||||
Asserted in `moby_handlers_are_overwhelmingly_function_entries`.
|
||||
|
||||
Reference in New Issue
Block a user