mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-27 02:32:02 -04:00
fba58d76b3
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>
37 lines
939 B
C
37 lines
939 B
C
#ifndef PSXRECOMP_V4_SIO_H
|
|
#define PSXRECOMP_V4_SIO_H
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* SIO0 register base: 0x1F801040 */
|
|
#define SIO_BASE 0x1F801040
|
|
|
|
void sio_init(void);
|
|
|
|
/* MMIO read/write (0x1F801040-0x1F80104E) */
|
|
uint32_t sio_read(uint32_t addr);
|
|
void sio_write(uint32_t addr, uint32_t value);
|
|
|
|
/* Advance SIO timing by one step. Called from psx_check_interrupts().
|
|
* Fires pending IRQ7 after the transfer delay expires. */
|
|
void sio_tick(void);
|
|
|
|
/* Update pad button state. Buttons use PS1 convention: 0=pressed, 1=released.
|
|
Bit layout: SELECT, L3, R3, START, UP, RIGHT, DOWN, LEFT,
|
|
L2, R2, L1, R1, TRIANGLE, CIRCLE, CROSS, SQUARE */
|
|
void sio_set_pad_state(uint16_t buttons);
|
|
|
|
/* Connect a pad to a slot (0=port1, 1=port2). By default no pads are
|
|
* connected during initial BIOS boot. */
|
|
void sio_connect_pad(int slot);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PSXRECOMP_V4_SIO_H */
|