Skip to main content
← PSoXide SDK guides and examples · SDK f2fec1c301f1 · All Cargo features enabled; check feature gates before use.

Module interrupts

Module interrupts 

Source
Expand description

Minimal interrupt support used by engine-level clocks.

The first consumer is a monotonic VBlank counter. We install a tiny exception-vector trampoline that handles VBlank IRQs itself, increments a volatile counter, acknowledges the IRQ, then returns with rfe. The handler deliberately uses only the MIPS kernel registers $k0/$k1, so it does not need a stack frame.

Constants§

PRESENT_QUEUE
True when psx-rt was built with the present-queue feature: the VBlank handler kicks frames published through crate::present.
STRICT_FAULTS
True when psx-rt was built with the strict-faults feature: the exception handler halts on every fault instead of stepping over the faulting instruction (see fault_resume_pc).

Functions§

are_interrupts_enabled
True when COP0 SR has interrupts enabled (IEc).
declare_stack_safe_handler⚠
Declare that the game’s own exception handler at handler is safe to take an interrupt on any stack, including a ScratchpadStack.
fault_bad_address
COP0 BadVAddr captured for the latest unexpected exception.
fault_cause
Raw COP0 Cause captured for the latest unexpected exception.
fault_count
Unexpected exceptions survived so far. Non-zero means some access faulted and was stepped over; the value it read or wrote is garbage.
fault_pc
COP0 EPC captured for the latest unexpected exception.
fault_resume_pc
Where psx-rt’s exception handler resumes after a fault (any exception but an interrupt), or None where it halts. badvaddr is COP0 BadVAddr.
gp1_queue_pendingDeprecated
Renamed to is_display_control_queued.
gte_skip_count
Interrupts that landed on a GTE command, whose return the handler moved to EPC + 4 so the command did not run twice.
install_vblank_counter
Install and enable the VBlank counter interrupt path.
interrupt_resume_pc
Where psx-rt’s exception handler resumes after an interrupt: epc, or epc + 4 when word_at_epc is a GTE command.
is_display_control_queued
True while a word queued by queue_display_control_at_vblank has not yet been applied by the VBlank handler.
is_gte_command
True when word is a GTE command (a COP2 cofun: opcode 0x12 with bit 25 set, so the top seven bits are 0100101). psx-spx’s test is (word & 0xFE00_0000) == 0x4A00_0000. GTE register moves (mfc2, mtc2, cfc2, ctc2), lwc2/swc2 and the bc2 branches are not commands: an interrupt on them is taken before they run.
is_handler_installed
True when the general exception vector jumps to psx-rt’s handler, the one that never touches $sp (so interrupts are safe on any stack).
is_stack_safe_handler_installed
True when the general exception vector jumps to psx-rt’s handler or to the one declared with declare_stack_safe_handler.
last_stray_interrupt_sources
The I_STAT & I_MASK bits of the latest stray interrupt (stray_interrupt_count); zero before the first.
queue_display_control_at_vblank
Queue one GP1 word for the VBlank handler to apply at a blank edge (deferred tear-free display flip). Overwrites any unapplied word.
queue_gp1_at_vblankDeprecated
Renamed to queue_display_control_at_vblank.
stray_interrupt_count
Stray interrupts acknowledged so far. psx-rt’s handler owns VBlank only; any other source enabled in I_MASK that fires while no VBlank is pending, and that no handler in front of this one claimed, is acknowledged and counted here instead of re-entering forever. Non-zero means something enabled a source nothing services.
stray_interrupt_sources
The sources psx-rt’s handler acknowledges as strays for one entry, given I_STAT, I_MASK and COP0 Cause; zero when it leaves them alone.
take_pending_gp1Deprecated
Renamed to take_queued_display_control.
take_queued_display_control
Empty the queue and hand back the word the handler has not applied, so the caller can write it to GP1 itself. Returns 0 when nothing was queued.
try_wait_vblank
wait_vblank with its own bound: true once the count has advanced, false after spins reads of it without a change. A false means no VBlank interrupt reached psx-rt’s handler: interrupts are masked (inside a critical_section), the counter was never installed, or a game’s handler does not chain to psx-rt’s. Does not install the counter; wait_vblank does that first.
vblank_count
Current monotonic VBlank count.
wait_vblank
Block until the next VBlank IRQ.