Chasing F1 I examined a counter block I had skipped. this+0x10 decrements
every update and fires output bit 0x4 at zero, guarded against the HELD
word by cfg +0xA0; it is re-armed from +0xC4 = 10 and +0xC8 = 8.
So my statement that "the only two timed inputs in the whole decoder are LB
and LT" is false, and two constants I tabulated as ring-word button masks
(B|Y and Y) are counter reload values. A number that is a valid mask AND a
valid duration cannot be told apart by its value, only by its use, and I
classified those two by value.
What it does not change: F1 is still not answered. This channel is guarded
by cfg +0xA0 = ring bit 1 = B, not a direction. The D-pad and left-stick
paths still carry no counter, so "a held DIRECTION has no repeat timer in
C_PAD_DECODER" stands, and the human's observation that it repeats in the
real game is consistent with the caveat this page already carried: the
repeat is in the layer above.
Explicitly NOT offering 10 and 8 as F1's two numbers. They belong to a
channel on a button that is not a direction, and at 60 units/s they are
0.167 s and 0.133 s -- about 7 moves a second, which does not match "a
medium pace, slow enough to see which item is selected". Reporting them as
the menu repeat would be the same read-a-config-infer-a-behaviour error
this correction is about.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
Answers H1's first half with a negative, and decodes what the timing
constants are for.
C_PAD_DECODER's +0xB4/+0xB8 and +0xBC/+0xC0 (10 and 90, twice) are not a
key-repeat delay/interval pair. They are two identical channels of a
DOUBLE-TAP detector, on cfg +0x74 (LT) and +0x70 (LB), firing output bits
0x20 and 0x40.
The mechanism, from the image: both timers tick down once per update; a
press arms the short timer to 10; a RELEASE adds 1000 to it as a flag
stored inside the counter, which is why the tick watches for exactly 1000
and clears both there; a second press while the flag is set arms the long
timer to 90; and while the long timer runs the output bit is asserted on
EVERY update, with the short timer re-armed to 1010 each time.
So it is a latch, not a repeat: a double-tap opens a 90-update window and
the bit is held for its whole duration. That is a dash or barrel-roll
shape, which fits the buttons it is wired to.
H1: the directions have NO timer. The D-pad and left stick reach the output
word through bare mask tests -- the four left-stick literals at 0x8220C458,
C474, C490, C4AC, and DPAD DOWN through cfg +0xA4 -- with no counter
loaded, decremented or tested on any of those paths. On the evidence of
this layer a held direction does not repeat.
Reach: one layer. A menu could implement repeat on top of a held bit, and
this says nothing about that -- but it does establish the repeat is not in
the shared decoder, so it would have to be per-screen. "One step per
deflection" stays authored for the port; this narrows rather than settles.
Refutation of my own earlier note that a decoder "is where a game normally
puts its repeat timing, its edge detection and its button remap": remap
survives, edge detection survives, repeat timing is REFUTED. That clause
was a prior about how games are written, not a reading of this one.
Also commits tools/ppc-dis, the minimal PowerPC disassembler this corpus
has been rebuilding in scratch and losing to container restarts three times
in one session.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t