# PSX JL-9 In-Level Event Investigation This note isolates one question from the broader JL-9 work on PlayStation `SLUS_002.68`: - what natural in-level event writes `psx_debug_extra_channel_gate` and makes the later hidden `L0SR` + `R1 + Circle` path unlock `JL-9`? ## Current status The downstream half is now closed. - user validation proved that forcing `0x8006739d = 0x01`, then entering `L0SR`, then pressing `R1 + Circle` successfully adds `JL-9` - therefore the remaining mystery is entirely on the natural gate-arm side - `MFM4` is no longer the main mystery; it is only the strongest **natural prime candidate** Current best interpretation: - the more direct thing being bypassed by the manual poke is the in-level event itself - natural `MFM4` failing means `MFM4` alone is not sufficient - the missing event is most likely an uncommon or optional scripted/control event in a small late-level family ## Proven sink-side mechanics ### Gate byte - `psx_debug_extra_channel_gate` = `0x8006739d` - writer: `0x800232f0` - reader: `0x8002fff4` - storage is byte-wide (`sb` write, `lbu` read) - late check is nonzero-based, not literal-value-based ### Natural gate-arm branch Natural arm still converges on `psx_set_debug_extra_channel_gate` at `0x800230e4`. The exact write branch is: - tuple: `(slot=0x0f, arg1=0x0a, arg2=0x04)` - hidden must still be off - `psx_level_runtime_header_state` must be `3` - only then does `0x800232f0` store `1` to `0x8006739d` ### Hidden trigger half Later JL-9 unlock still requires: - hidden passcode branch `L0SR` / `?0SR` - input code `0x1e` - practical mapping `R1 + Circle` That later path reads `0x8006739d` at `0x8002fff4` and performs the extra `0x0d` unlock when nonzero. ## Proven dispatcher path ### Sink feeder `0x800214ac..0x800215f8` is now promoted as: - `psx_level_gate_slot_dispatch_from_action_record` Recovered structure: - dispatch slot byte comes from pointer at `record + 0x00` - `arg1` byte comes from pointer at `record + 0x08` - `arg2` byte comes from pointer at `record + 0x0c` - handler call is indirect through `psx_level_gate_slot_handler_table[slot]` at `0x800640a0` Important table entries: - `psx_level_gate_slot_handler_table[0x0d] = 0x80022c6c` - `psx_level_gate_slot_handler_table[0x0e] = 0x80022ea8` - `psx_level_gate_slot_handler_table[0x0f] = 0x800230e4` ## Recovered slot-family behavior ### Slot `0x0d` `0x80022c6c` is now named: - `psx_control_event_slot0d_handler` Recovered strong branch: - `(0x0a,0x02)` => mission-complete passcode generation/display lane ### Slot `0x0e` `0x80022ea8` is now named: - `psx_control_event_slot0e_handler` Recovered branches: - `(0x0a,0x01)` => mission-complete passcode generation/display lane using quad index `0x0f` - `(0x0a,0x02..0x04)` => mode/timer setup branches - `(0x0a,0x06)` => selector/stage apply lane that force-applies selector `0x0f` ### Slot `0x0f` `0x800230e4` remains: - `psx_set_debug_extra_channel_gate` Recovered `0x0a` cases: - `1` - `2` - `3` - `4` - `0x2e` The JL-9 natural arm branch is specifically: - `(0x0a,0x04)` ## Host-level narrowing The recovered gate family is still: - `{54,55,56,57,58,82}` Best current host ranking: 1. `54` 2. `55` 3. `56` 4. `57` 5. `82` 6. `58` Why `54` remains the best anchor: - `MFM4` is the only ordinary published code that statically satisfies the prime-side conditions - selector `0x0f` maps to map/level `54` - `DAT_80063e68[54] = 0x0f` Why this still does not close the event: - user-tested natural `MFM4` did **not** produce `JL-9` - so level-family membership alone is not sufficient - the missing event now looks optional, late, rare, or route-specific ## Upstream producer state ### What still exists as topology The older behavior/subop chain still exists in tables: - `psx_behavior_opcode_handler_table[54] = 0x80027ecc` - `psx_behavior_subop_handler_table[49] = 0x800214ac` `0x80027ecc` is now named conservatively: - `psx_behavior_subopcode_dispatch` ### Why it is weaker now The only currently proven caller into `psx_object_behavior_opcode_dispatch` is still range-limited: - known caller path bounds `(opcode_word - 1) < 0x0a` at `0x80026710` - that means the known active path can only reach indices `0..9` - so `54 -> 49` is still valid topology, but it is no longer the best **active** explanation Current practical reading: - keep `54 -> 49` alive as structure - deprioritize it as the leading runtime explanation until a second active caller/context is recovered ## Strongest event hypothesis now The strongest remaining hypothesis is: - the natural gate-arm is a sibling in the same late control-event family as mission-complete / transition handlers around `0x80022c6c..0x80023390` - it is probably an uncommon or optional in-level scripted/control outcome - it is more likely tied to a rare objective-path or late-event branch than to ordinary mission completion itself Why this is stronger than the older theories: - the sink-side tuple and slot family are concrete - mission-complete siblings are already proven in adjacent handlers - hard-clear / beat-the-game theory stayed weak - direct forced-gate tests show the real unknown is the natural writer event, not the hidden code ## Ghidra changes applied in this event pass ### Functions / blocks - `0x800204fc` -> `psx_show_mission_complete_congrats_text` - `0x80020f7c` -> `psx_control_event_apply_level_channel_preset` - `0x800214ac` -> `psx_level_gate_slot_dispatch_from_action_record` - `0x80022c6c` -> `psx_control_event_slot0d_handler` - `0x80022ea8` -> `psx_control_event_slot0e_handler` - `0x80027ecc` -> `psx_behavior_subopcode_dispatch` ### Tables / data - `0x80063e54` -> `psx_selector_to_map_id_table` - `0x80063e68` -> `psx_map_id_to_gate_slot_table` - `0x80063eac` -> `psx_map_progression_table` - `0x80063610` -> `psx_behavior_subop_handler_table` - `0x800640a0` -> `psx_level_gate_slot_handler_table` - `0x800641ac` -> `psx_behavior_opcode_handler_table` ### Key comments added - `0x800214bc` - `0x800215bc` - `0x800215cc` - `0x800215dc` - `0x800215e0` - `0x800230e4` - `0x800232f0` - `0x80026710` - `0x8002685c` - `0x80027f0c` - `0x80034d60` ## Best next code targets 1. Fully classify the control-event family around `0x80022c6c..0x80023390` as one switch/tuple cluster and align each sibling branch with concrete player-facing outcomes. 2. Recover one actual authored producer for `(slot=0x0f, arg1=0x0a, arg2=0x04)` by tracing the action-record inputs feeding `0x800215cc` / `0x800215e0`. 3. Find a second active caller/context into `psx_object_behavior_opcode_dispatch` or an alternate feeder into `0x800214ac` that can justify a high-index producer path in live gameplay. ## Deferred emulator experiments Keep these queued for later: 1. Experiment 2: hard-clear / beat-the-game test 2. Experiment 4: compare `MFM4` against another header-state-`3` code under matched in-level actions 3. Experiment 5: hold map/event family constant and vary only the suspected scripted event 4. Experiment 6: ordering test (`event -> L0SR -> trigger` versus `L0SR -> event -> trigger`)