# Native move inventory and disputed-claim receipts

This is a reproducible, bounded code audit of **stock Marvel vs. Capcom, Europe 980123**. It is not a claim that every semantic move, every strength/air variant, or every shared effect-object path has been completely understood.

## What the inventory contains

`inventory.json` contains **1,111 native selector contexts** across 21 playable character IDs and 24 character/form contexts: 576 normal contexts, 409 special/super selector contexts, and 126 throw selector contexts. Ryu is expanded to +$385 values 0, 2 and 4; Zangief to +$EB values 0 and 2. Onslaught IDs $00/$22 and exhaustive team/assist permutations are excluded.

Those are **not 1,111 distinct named moves**. A dispatch table can contain aliases, exit handlers, internal continuations, unreachable entries and dynamically selected variants. `completeSemanticInventory` is deliberately false. Each row preserves its exact handler/selector, known command candidates, local readers, effect classification and a specific remaining frontier. A surviving command candidate is not proof that its meter, stance, positioning, timing and matcher-success conditions can all be satisfied.

The reviewed master tables are: normal initializer $0185C8, normal updater $00E6B8, special updater $00E726, human command roots $018DF0/$018E4C, throw detector $018712 and throw initializer $01876E. **$01876E is a throw initializer table, not an assist table**: common routine $0187CA links attacker and victim and calls its selected initializer; $01880E/$01881A set the victim state. Individual continuing throw updater/escape/damage bindings remain unresolved where the row says so.

The data pointer table at $0E8048 selects 48-byte normal-chain blocks. Each of the four stance rows has six **two-byte rank/flag records**, not six move IDs. `B5=0` selects punches; `B5=2` selects kicks. `4D=0/2/4` selects button strength. `B4=0/2/4` selects standing/crouching/air; the two air contexts retain the exact `BA=0`/`BA!=0` native flag without inventing a jump-type label.

`native-tables.json` preserves every selected table entry, raw table bytes and extent evidence. These packed tables have **no explicit runtime bounds check or sentinel**. Most ends are inferred from the first nonnegative code target; manually reviewed exceptions stop before shared prelude/exit code. The exception evidence is stored with each table. Wolverine's throw dispatcher is later than the first 50 bytes of its initializer; Gambit's table has shared setup code before its first indexed target. Both are explicitly included in the final census.

## What was checked per normal

`normal-route-receipts.json` filters the local updater using the exact stance/family/strength, air flag, character and form. All 576 contexts have a receipt; 22 contain local input operands. The other 554 have no local operand in the inspected slice. **That is not a claim that 554 normals cannot be repeated or cancelled**: common routine $01741E, for example, reads held direction byte +$D1 to handle crouch transition. External/indirect edges are retained in each receipt.

The independent review in `normal-review/findings.json` covers 200 contexts and 20 semantic findings. Four additional secret-character annotations are explicitly shared-code attributions, not live tests. Notable local findings include:

- War Machine/Gold standing LP, selected Wolverine normals, Morrigan/Lilith standing LP, and selected Captain America, Venom, Spider-Man and Jin normals have checked restart/continuation branches.
- Hulk/Orange Hulk standing and crouching LK initialize +$3A1 to one and spend that allowance on one local restart. This does not imply extra connected hits or a super extension.
- Wolverine air MP is a counterexample to a reader-only census: `BA=0` bypasses the local restart; `BA!=0` reaches it, despite sharing the same input reader.
- Captain America standing MK advances one additional local stage; that second dispatch leaf bypasses the input reader.

`normal-initializer-receipts.json` records animation installer sites and known D0/D1/D2 arguments. For direction-sensitive initializers it enumerates nine noncontradictory latched masks. The native trigger direction is facing-normalized at $01373C and latched from `D7 & $0F` at $01840C/$018412: back=1, forward=2, down=4, up=8. Those initializer alternatives are **control-path groups**. Unknown installer arguments remain null; stance/direction combinations are not automatically claimed human-reachable.

The static analyzer is a bounded route filter, not a full 68000 emulator or formal proof. Unsupported predicates keep both branches; call results are unknown; partial flags do not turn unknown BNE/BCC/BGE conditions into known decisions. Arithmetic carry/overflow are kept unknown when not modeled. Each receipt reports state-budget exhaustion (none in this export) and all external/indirect frontiers. Positive semantic classifications were checked against exact opcode excerpts rather than inferred from reader counts.

## New native runtime controls

Four fixtures use MAME 0.287. Each contains 10 conditions of 900 callbacks: three repeated no-input baselines, holding all attacks, tapping all attacks, tapping punches, tapping kicks, gapped directions, continuous cardinal rotation and late attack input. Taps alternate press/release callbacks; this is an input stimulus specification, not a human hand-speed claim.

The harness boots with fresh configuration/NVRAM, uses coin/start inputs and native move commands, and seeds the roster selection word `$FF40B0` before match initialization. Before its save it sets P1 meter to 3, both life values to 144, and requested X positions to 160/205. Both participants are human controlled; the defender is Spider-Man. Positions settle before saving and actual coordinates appear in each trial's `initial` object. Character selection therefore includes an explicit fixture RAM write; it is not claimed to be a wholly manual match recording.

**No ROM, active move-state, hit-counter, lifetime or repeat-budget patch is applied.** Each condition restores the same local save. The first three complete 900-row trace digests match for every fixture, after removing only the trial label. Those saves are intentionally not distributed.

The move command is D for callbacks 1–4, DF for 5–8, then F plus LP+MP or LK+MK for 9–12. Further stimulus begins after callback 12 while the first intended attacker state remains active. The late control actually presses after callback 650, well after the original move; `lateStimulusObserved` proves those inputs were present. The harness guards observer reads so they cannot contaminate CPU input-reader taps.

`B0=$2A` includes specials as well as supers. Identification requires the character, native command, `E6` selector, and state transitions together. `firstAttackerState` ends on the first departure from the intended state/selector. It never absorbs a later re-entry. The separate `comboPeakBeforeLateControl` includes the earlier projectile tail but ends before the deliberate late input.

| Fixture | First attacker-state contacts: baseline → attack taps | Relevant causal measurement |
|---|---:|---|
| Maximum Spider, E6=$08 | 5 → 5 | Every tested condition stays at five; the local direction read selects approach. The 25 claim is not reproduced. |
| Mega Man Beat Plane, E6=$08 | 3 → 23 | Zero → four type-$84/subtype-$04 firing objects; all 180 lifetime decrements occur in every condition. |
| Roll Beat Plane, E6=$08 | 3 → 23 | Same firing mechanism and 180-decrement lifetime; directions alone do not create firing objects. |
| Hulk Gamma Wave, E6=$0C | 3 → 3 | Eight wave-child allocations in every condition; continued children bring the tail-inclusive contact count to 11 → 11. |

Five and 23 are **observed fixture results, not universal maximums**. The 36-hit Beat Plane claim is not established here. Independent FBNeo results are in the sibling `core` receipts. The final FBNeo Roll score is 23 during the first move; an additional post-exit event is excluded. An earlier raw count of 24 must not be described as a demonstrated emulator difference.

Beat Plane's fresh-button gates are Mega $0638C6/$0638D2 and Roll $0421A2/$0421AE. Accepted attack mask `$0770` enters subphase +$0A=$0E and clears +$3A4. Shared allocator $0A05D6 writes object type $84 and subtype $04; the object is contingent on the owner's firing phase/lifetime. Mega lifetime +$39E=180 starts at $0633B0 and decrements at $061A7C; Roll starts at **$041C96** and decrements at **$0406EA**. Mashing initiates eligible bursts, not a lifetime refill. These are distinct from E6=$0E Hyper Mega Man/Hyper Roll, whose earlier scheduler evidence is linked separately.

Maximum Spider initializes its continuation/retry fields at $03E3A2–$03E3B4. Its local input read at $03EB98, masked with $000F at $03EB9C, selects approach direction. Hulk's wave cadence is at $09F576/$09F596/$09F59E; successful child allocation is the write at $09F442.

## Read the measurements correctly

A sampled input edge, a spent credit, a scheduler decrement, a successful object allocation, an animation restart and a connected hit are different events. The CSV `combo` is the native counter; it is not a hitbox-contact oracle. Venom's extra throw slams demonstrate why this matters: the native counter can remain one while the animation repeats. Callback counts are observations, not native frame data; hitstop and speed scheduling affect their relationship to game updates.

The inherited CSV column names `budget`, `timer`, `child` and `child50` are raw observations of +$398, +$50, +$392 and the addressed value. **Their names do not establish their role for every move.** In Beat Plane, +$392 is not evidence of a child-object pointer. Use the named +$39E lifetime trace and successful allocator events for its mechanism. Allocation taps are counted at exact successful writes, not allocator entry or visual projectile guesses.

Earlier named findings linked from `inventory.json` retain their earlier, smaller protocols. They are not silently upgraded to the new three-baseline protocol. Orange Hulk and the shared normal aliases are not claimed independently live-tested.

## ROM identity and address interpretation

- Archive SHA-256: `fbb9c9a0fc44c6f26481cc018bdd13d9aac5376806e736c428c4b54b274c032c`.
- Four-MiB data view SHA-256: `d464d1c27542678b8b83ecf1af0a072f0a0ffc383dd6adff21cf8d7e9c7112cd`.
- Four-MiB opcode view SHA-256: `7ede16dc56ffbefe899f98608c6b0a01f2304cd3e8c46da9f912ee0b9bcf7490`.

`provenance.json` records the eight program-member hashes and CPU windows. All PC values are emulated 68000 addresses. The first 512 KiB maps to the 03 program ROM; the next to 04. Physical dump byte offsets are word-swapped, and the opcode view is decrypted. A decoded immediate `$0770` is not a claim that those literal bits appear inside the physical encrypted ROM. RAM addresses such as `$FF30D4` identify live fighter state, not ROM chip locations. Chip/board photos are physical references and may carry different revision labels from the tested Euro members.

Instructions and PC-relative opcode reads use the opcode view. A PC-relative **LEA** only forms an address; a subsequent `(a2)` command-descriptor load uses the data view. Confusing those views can invent commands. Unresolved variable-selector assignments are retained as unresolved rather than borrowing a nearby immediate store.

## Reproduce and inspect

Runtime reproduction requires a locally supplied matching ROM archive, its QSound dependency and MAME 0.287:

```sh
python3 run_runtime.py --rompath /path/to/your/roms --case maximum_spider
python3 run_runtime.py --rompath /path/to/your/roms --case mega_beat_plane
python3 run_runtime.py --rompath /path/to/your/roms --case roll_beat_plane
python3 run_runtime.py --rompath /path/to/your/roms --case hulk_gamma_wave
python3 summarize_runtime.py
```

Static reproduction additionally requires Python/Capstone and locally derived opcode/data views with the hashes above. Set `MVSC_OPCODE_VIEW` and `MVSC_DATA_VIEW` to those local files; neither view is distributed. Run `build_inventory.py`, `normal_routes.py`, `normal_initializers.py`, `context_routes.py`, `annotate_inventory.py`, then `write_excerpts.py`. The review annotation step accepts the bundled `normal-review` files; the original independent reviewer script preserves its workspace-relative source assumptions and is included as a receipt, not as a substitute for those inputs.

`public-files.json` is the explicit distribution allowlist with file sizes and hashes. It includes raw CSVs/logs, harnesses, source scripts, compact tables, selected disassembly excerpts and selected emulator screenshots. It excludes ROMs, decoded ROM views, save states, NVRAM, emulator configuration and complete linear ROM disassemblies. JSON fragments after `#` in evidence links identify record keys; they are not claims that a browser JSON viewer implements anchors.
