+typedef void (irq_func)();
+
+static irq_func * const irq_funcs[] = {
+ [PSXINT_SIO] = sioInterrupt,
+ [PSXINT_CDR] = cdrInterrupt,
+ [PSXINT_CDREAD] = cdrReadInterrupt,
+ [PSXINT_GPUDMA] = gpuInterrupt,
+ [PSXINT_MDECOUTDMA] = mdec1Interrupt,
+ [PSXINT_SPUDMA] = spuInterrupt,
+ [PSXINT_MDECINDMA] = mdec0Interrupt,
+ [PSXINT_GPUOTCDMA] = gpuotcInterrupt,
+};
+
+/* local dupe of psxBranchTest, using event_cycles */
+static void irq_test(void)
+{
+ u32 irqs = psxRegs.interrupt;
+ u32 cycle = psxRegs.cycle;
+ u32 irq, irq_bits;
+
+ if ((psxRegs.cycle - psxNextsCounter) >= psxNextCounter)
+ psxRcntUpdate();
+
+ // irq_funcs() may queue more irqs
+ psxRegs.interrupt = 0;
+
+ for (irq = 0, irq_bits = irqs; irq_bits != 0; irq++, irq_bits >>= 1) {
+ if (!(irq_bits & 1))
+ continue;
+ if ((s32)(cycle - event_cycles[irq]) >= 0) {
+ irqs &= ~(1 << irq);
+ irq_funcs[irq]();
+ }
+ }
+ psxRegs.interrupt |= irqs;
+
+ if ((psxHu32(0x1070) & psxHu32(0x1074)) && (Status & 0x401) == 0x401) {
+ psxException(0x400, 0);
+ pending_exception = 1;
+ }
+}
+