# Pass 1 NMI callback audit ## Dispatcher The hardware NMI vector enters `$C0A6`. The fixed prologue saves A/X/Y, performs OAM DMA from page `$02`, then executes `JMP ($0002)`. Every installed callback must therefore finish through the common epilogue at `$C0B8` or deliberately reset/restart the program. `$C888` is the generic installer: - Y -> `$0002` (callback low byte) - X -> `$0003` (callback high byte) - PPU NMI remains enabled through the shadow value at `$00` ## Confirmed callback installations ### `$C6C8` installed at `$C0EC` Caller loads Y=`$C8`, X=`$C6`, then calls `$C888`. Role: early/main gameplay display callback. It updates OAM entries at `$0214-$0217` and `$0284-$0287`, advances animation counters `$8E/$8F`, and terminates with `JMP $C0B8`. ### `$CFAA` installed at `$CF5C` Caller loads Y=`$AA`, X=`$CF`, then calls `$C888`. Role: gameplay sequencing callback. It decrements/increments `$32`, updates OAM coordinates, and changes the callback vector to one of the following mid-routine continuations as state thresholds are crossed: - `$CFC3` - `$D03E` - `$D08A` The routine ultimately reaches the gameplay display tail at `$C6C8`, which exits through `$C0B8`. ### `$DAA2` installed at `$DA27` Caller loads Y=`$A2`, X=`$DA`, then calls `$C888`. Role: title/menu/attract controller callback. It polls controller port `$4016`, updates `$09/$0A/$0D`, writes one OAM cursor entry at `$0200-$0203`, and either: - jumps to `$C0B8` for the normal NMI epilogue, - restarts title/game initialization through `$DA2F/$DA4C`, or - restarts the initial state through `$C0C7`. Important correction: `$DB0D` (`78 88 98`) is used as OAM Y-position data for `$0200`, not as an NMI callback-low-byte table. Consequently `$BA78/$BA88/$BA98` are not callbacks. ### `$C5A0` installed at `$FC8E` Caller loads Y=`$A0`, X=`$C5`, then calls `$C888`. Role: active gameplay controller/animation callback. It serially reads `$4016`, updates input-derived state `$2E/$30`, angle/selection fields `$17/$44/$45`, OAM entries, and then enters `$C6C8` before returning through `$C0B8`. ## Direct callback-vector transitions The following direct writes to `$02/$03` are confirmed executable and are part of the `$CFAA-$D121` callback state machine: - `$CFB6/$CFBA`: install `$CFC3` - `$CFDA/$CFDE`: install `$D03E` - `$D006/$D00A`: install `$D03E` - `$D02B/$D02F`: install `$D08A` - `$D05E/$D062`: install `$D08A` - `$D07A/$D07E`: install `$D08A` These are mid-routine continuation entries, not independent top-level systems. They share state in `$17/$1D/$1E/$1F/$32/$34/$35` and converge on `$C6C8`. ## Confirmed callback set Top-level callback installations: - `$C5A0` - `$C6C8` - `$CFAA` - `$DAA2` Dynamic continuation callbacks: - `$CFC3` - `$D03E` - `$D08A` Common normal exit: - `$C0B8` No other verified executable write to `$0002/$0003` has been found. Apparent writes inside compressed hole packages are data and are excluded. ## Source conversion The previously retained callback spans are now emitted as annotated instructions: - `$C5A0-$C71D`: gameplay input/display callback chain - `$CFAA-$D123`: gameplay sequence callback and dynamic continuation entries The three bytes at `$C71E-$C720` remain data because execution at `$C71B` jumps directly to the NMI epilogue and cannot fall through into them.