Commit Graph

3 Commits

Author SHA1 Message Date
Matthew Stanley 1a0213ec5e fix: RestoreState escape mechanism — VSync counter now increments
The kernel's inline RestoreState (at BFC1094C inside the exception
handler func_00000C80) restored all registers and did `jr $ra`, but
the generated `return;` went back to psx_check_interrupts instead of
dispatching to the restored $ra (0xBFC421D8 — the VSync callback
loop). Then psx_check_interrupts overwrote all GPRs from the
pre-exception save, wiping RestoreState's changes. VSync counter
was permanently stuck at 0.

Fix has three parts:

1. runtime/src/interrupts.c: Add psx_restore_state_escape() which
   longjmps with code 2 (vs code 1 for ReturnFromException).
   psx_check_interrupts now loops: code 2 re-dispatches to cpu->pc
   (still in exception context), code 1 exits, code 0 is normal.

2. recompiler full_function_emitter: Broaden longjmp-return detection
   from first-instruction-only to scanning ALL instructions for the
   exact encoding 0x8C9F0000 (lw $ra, 0($a0)). This catches both
   standalone RestoreState (func_1FC0227C) and the kernel inline
   copy (func_00000C80 at BFC10964).

3. Generated jr $ra terminators in matched functions now emit:
   cpu->pc = cpu->gpr[31]; psx_restore_state_escape(); return;

Result: VSync counter increments steadily (~256/vblank), zero crashes,
shell renders Memory Card / CD Player screen with no ADEL faults.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:23:25 -07:00
Matthew Stanley fba58d76b3 Phase 4 interrupt fixes: RFE, GPR save/restore, DMA IRQ edge-trigger
Three interrupt delivery bugs fixed that were blocking shell progression:

1. RFE after handler exit: The exception handler's normal exit path
   (jmpbuf longjmp at 0xBFC10944) does not execute RFE. In our model
   the handler returns to psx_check_interrupts, not to the WaitEvent
   caller. Without RFE, IEc stays 0 forever after the first interrupt.
   Fix: apply RFE in psx_check_interrupts if IEc is still 0 after the
   handler returns.

2. GPR save/restore around handler dispatch: The handler's jmpbuf exit
   restores callee-saved registers from the kernel jmpbuf (intended for
   a non-local jump to WaitEvent's caller). In our model this corrupts
   the interrupted code's registers. Fix: save all GPRs before handler
   dispatch and restore them after, matching real hardware where the
   interrupted code's registers are preserved via TCB save/restore.

3. VBlank tick gated on !in_exception: The handler runs thousands of
   block leaders, each calling psx_check_interrupts. Without gating,
   dispatch_count advances inside the handler, firing new VBlanks that
   stack up and starve the main code. Fix: only increment dispatch_count
   and fire VBlank/timer ticks when not in exception handling.

4. DMA IRQ edge-triggered: update_master_irq() was level-triggered,
   re-asserting i_stat bit 3 on every call while master_flag=1. Combined
   with no BIOS callback to acknowledge DMA IRQs, this caused an
   interrupt storm. Fix: edge-detect master_flag 0->1 transition, and
   suppress DMA completion IRQs entirely since transfers are synchronous.

Also adds GPU debug diagnostics: GP0 command counters (nop/fill/draw/
env/copy), draw area/offset in gpu_state, vram_peek debug command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 20:29:03 -07:00
Matthew Stanley a1165d51b7 Phase 2 complete: BIOS boots to GPUSTAT read
Full recompilation pipeline working:
- Recompiler emits 799 functions (46k instructions) from SCPH1001.BIN
- Tail-call trampoline in dispatch loop prevents stack overflow
- Timer registers (3 counters, mode, target) implemented
- Interrupt check at labels + dispatch boundaries with vblank scheduling
- SYSCALL 1/2/3 (Enter/ExitCriticalSection, ReturnFromException) handled
- EPC correctly set from SYSCALL instruction address

BIOS boot reaches first GPU hardware access:
  UNIMPLEMENTED MMIO READ32 (GPUSTAT) @ 0x1F801814

Phase 3 (Sony logo) starts here: GPU, DMA, display pipeline.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 00:03:46 -07:00