diff --git a/src/video_core/pica/pica_core.cpp b/src/video_core/pica/pica_core.cpp index 91e06252d..f09210a29 100644 --- a/src/video_core/pica/pica_core.cpp +++ b/src/video_core/pica/pica_core.cpp @@ -58,6 +58,7 @@ void PicaCore::InitializeRegs() { // Values initialized by GSP regs.internal.irq_autostop = 1; regs.internal.irq_mask = 0xFFFFFFF0; + regs.internal.irq_compare = 0x12345678; auto& framebuffer_top = regs.framebuffer_config[0]; auto& framebuffer_sub = regs.framebuffer_config[1]; @@ -134,6 +135,11 @@ void PicaCore::ProcessCmdList(PAddr list, u32 size, bool ignore_list) { } } +static bool any_byte_match(u32 a, u32 b) { + return ((a & 0xFF) == (b & 0xFF)) || (((a >> 8) & 0xFF) == ((b >> 8) & 0xFF)) || + (((a >> 16) & 0xFF) == ((b >> 16) & 0xFF)) || (((a >> 24) & 0xFF) == ((b >> 24) & 0xFF)); +} + void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask, bool& stop_requested) { if (id >= RegsInternal::NUM_REGS) { LOG_ERROR( @@ -168,7 +174,9 @@ void PicaCore::WriteInternalReg(u32 id, u32 value, u32 mask, bool& stop_requeste switch (id) { // Trigger IRQ case PICA_REG_INDEX(irq_request): - if (regs.internal.reg_array[id] != 0) [[likely]] { + // TODO(PabloMK7): This logic is not fully accurate, but close enough: + // https://problemkaputt.de/gbatek-3ds-gpu-internal-registers-finalize-interrupt-registers.htm + if (any_byte_match(regs.internal.reg_array[id], regs.internal.irq_compare)) [[likely]] { signal_interrupt(Service::GSP::InterruptId::P3D, delay_generator.CalculateAndResetDelay()); if (regs.internal.irq_autostop) [[likely]] {