diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 4d79d764d9..db9ed3852f 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -98,7 +98,8 @@ static int sceKernelCpuSuspendIntr() static void sceKernelCpuResumeIntr(u32 enable) { VERBOSE_LOG(Log::sceIntc, "sceKernelCpuResumeIntr(%i)", enable); - if (enable) + // This is mtic a0, $0, which only looks at bit 0 (tests/intr/mfic). + if (enable & 1) { __EnableInterrupts(); hleRunInterrupts(); diff --git a/Core/MIPS/Interpreter.cpp b/Core/MIPS/Interpreter.cpp index c65e20db88..723b566a64 100644 --- a/Core/MIPS/Interpreter.cpp +++ b/Core/MIPS/Interpreter.cpp @@ -35,6 +35,7 @@ #include "Core/HLE/HLE.h" #include "Core/HLE/HLETables.h" #include "Core/HLE/ReplaceTables.h" +#include "Core/HLE/sceKernelInterrupt.h" #include "Core/HW/GpioMMIO.h" #define R(i) (mips->r[i]) @@ -1054,25 +1055,22 @@ namespace MIPSInt { PC += 4; } + // The interrupt enable flag, shared with the HLE sceKernelCpuSuspendIntr/ResumeIntr, which on + // hardware are just mfic v0, $0; mtic zero, $0 and mtic a0, $0. Only $0 exists. void Int_Special2(MIPSState *mips, MIPSOpcode op) { - static int reported = 0; + int rt = _RT; switch (op & 0x3F) { case 36: // mfic - // move from interrupt controller, not implemented - // See related report https://report.ppsspp.org/logs/kind/316 for possible locations. - // Also see https://forums.ps2dev.org/viewtopic.php?p=32700#p32700 . - // TODO: Should we actually implement this? - if (!reported) { - WARN_LOG(Log::CPU, "MFIC Disable/Enable Interrupt CPU instruction"); - reported = 1; - } + if (rt != 0) + R(rt) = __InterruptsEnabled() ? 1 : 0; break; case 38: // mtic - // move to interrupt controller, not implemented - if (!reported) { - WARN_LOG(Log::CPU, "MTIC Disable/Enable Interrupt CPU instruction"); - reported = 1; - } + // Only bit 0 counts: mtic 2 disables. Pending interrupts run at the next scheduling point, + // not right away as with sceKernelCpuResumeIntr. + if (R(rt) & 1) + __EnableInterrupts(); + else + __DisableInterrupts(); break; } PC += 4; diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index 093f708360..6ace0f2712 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -261,9 +261,9 @@ static const MIPSInstruction tableSpecial2[64] = // 011100 ..... ..... ..... ... INVALID_X_8, //32 INVALID, INVALID, INVALID, INVALID, - INSTR("mfic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER), + INSTR("mfic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_RT | OUT_OTHER), INVALID, - INSTR("mtic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, OUT_OTHER), + INSTR("mtic", JITFUNC(Comp_Generic), Dis_Generic, Int_Special2, IN_RT | OUT_OTHER), INVALID, //40 INVALID_X_8, diff --git a/pspautotests b/pspautotests index 8d51020081..3dc4690e7d 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit 8d510200812366931e7becb743cdbaea51174999 +Subproject commit 3dc4690e7d4f704764d23ef1ef0eb82ccc3dc30d diff --git a/test.py b/test.py index c1455dc759..df5fd93a24 100755 --- a/test.py +++ b/test.py @@ -262,6 +262,7 @@ tests_good = [ "hash/sha1ctx", "hle/check_not_used_uids", "intr/intr", + "intr/mfic", "intr/enablesub", "intr/suspended", "intr/vblank/vblank",