+ psxException(cause, regs->branching, ®s->CP0);
+ regs->branching = R3000A_BRANCH_NONE_OR_EXCEPTION;
+}
+
+// exception caused by current instruction (excluding unkasking)
+static void intExceptionInsn(psxRegisters *regs, u32 cause)
+{
+ cause |= (regs->code & 0x0c000000) << 2;
+ intException(regs, regs->pc - 4, cause);
+}
+
+static noinline void intExceptionReservedInsn(psxRegisters *regs)
+{
+#ifdef DO_EXCEPTION_RESERVEDI
+ static u32 ppc_ = ~0u;
+ if (regs->pc != ppc_) {
+ SysPrintf("reserved instruction %08x @%08x ra=%08x\n",
+ regs->code, regs->pc - 4, regs->GPR.n.ra);
+ ppc_ = regs->pc;
+ }
+ intExceptionInsn(regs, R3000E_RI << 2);
+#endif
+}
+
+// 29 Enable for 80000000-ffffffff
+// 30 Enable for 00000000-7fffffff
+// 31 Enable exception
+#define DBR_ABIT(dc, a) ((dc) & (1u << (29+(((a)>>31)^1))))
+#define DBR_EN_EXEC(dc, a) (((dc) & 0x01800000) == 0x01800000 && DBR_ABIT(dc, a))
+#define DBR_EN_LD(dc, a) (((dc) & 0x06800000) == 0x06800000 && DBR_ABIT(dc, a))
+#define DBR_EN_ST(dc, a) (((dc) & 0x0a800000) == 0x0a800000 && DBR_ABIT(dc, a))
+static void intExceptionDebugBp(psxRegisters *regs, u32 pc)
+{
+ psxCP0Regs *cp0 = ®s->CP0;
+ dloadFlush(regs);
+ cp0->n.Cause &= 0x300;
+ cp0->n.Cause |= (regs->branching << 30) | (R3000E_Bp << 2);
+ cp0->n.SR = (cp0->n.SR & ~0x3f) | ((cp0->n.SR & 0x0f) << 2);
+ cp0->n.EPC = regs->branching ? pc - 4 : pc;
+ psxRegs.pc = 0x80000040;
+}
+
+static int execBreakCheck(psxRegisters *regs, u32 pc)
+{
+ if (unlikely(DBR_EN_EXEC(regs->CP0.n.DCIC, pc) &&
+ ((pc ^ regs->CP0.n.BPC) & regs->CP0.n.BPCM) == 0))
+ {
+ regs->CP0.n.DCIC |= 0x03;
+ if (regs->CP0.n.DCIC & (1u << 31)) {
+ intExceptionDebugBp(regs, pc);
+ return 1;
+ }
+ }
+ return 0;