diff options
| -rw-r--r-- | src/citra_qt/debugger/graphics_cmdlists.cpp | 4 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_framebuffer.cpp | 16 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_framebuffer.hxx | 4 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/apt_a.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/cfg/cfg_u.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/csnd_snd.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/service/dsp_dsp.cpp | 22 | ||||
| -rw-r--r-- | src/core/hle/service/dsp_dsp.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/ir_rst.cpp | 7 | ||||
| -rw-r--r-- | src/core/hle/service/ldr_ro.cpp | 12 | ||||
| -rw-r--r-- | src/core/hle/service/ndm_u.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/service/soc_u.cpp | 8 | ||||
| -rw-r--r-- | src/core/hle/service/srv.cpp | 16 | ||||
| -rw-r--r-- | src/core/hw/gpu.cpp | 8 | 
15 files changed, 107 insertions, 63 deletions
| diff --git a/src/citra_qt/debugger/graphics_cmdlists.cpp b/src/citra_qt/debugger/graphics_cmdlists.cpp index 753cc25da..708b805a7 100644 --- a/src/citra_qt/debugger/graphics_cmdlists.cpp +++ b/src/citra_qt/debugger/graphics_cmdlists.cpp @@ -229,7 +229,7 @@ void GPUCommandListModel::OnPicaTraceFinished(const Pica::DebugUtils::PicaTrace&       cmd_id < PICA_REG_INDEX(reg_name) + sizeof(decltype(Pica::registers.reg_name)) / 4)  void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) { -    const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); +    const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt();      if (COMMAND_IN_RANGE(command_id, texture0) ||          COMMAND_IN_RANGE(command_id, texture1) ||          COMMAND_IN_RANGE(command_id, texture2)) { @@ -255,7 +255,7 @@ void GPUCommandListWidget::OnCommandDoubleClicked(const QModelIndex& index) {  void GPUCommandListWidget::SetCommandInfo(const QModelIndex& index) {      QWidget* new_info_widget; -    const int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toInt(); +    const unsigned int command_id = list_widget->model()->data(index, GPUCommandListModel::CommandIdRole).toUInt();      if (COMMAND_IN_RANGE(command_id, texture0) ||          COMMAND_IN_RANGE(command_id, texture1) ||          COMMAND_IN_RANGE(command_id, texture2)) { diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp index a9e9de652..7ef699f37 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.cpp +++ b/src/citra_qt/debugger/graphics_framebuffer.cpp @@ -158,7 +158,7 @@ void GraphicsFramebufferWidget::OnFramebufferAddressChanged(qint64 new_value)      }  } -void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value) +void GraphicsFramebufferWidget::OnFramebufferWidthChanged(unsigned int new_value)  {      if (framebuffer_width != new_value) {          framebuffer_width = new_value; @@ -168,7 +168,7 @@ void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value)      }  } -void GraphicsFramebufferWidget::OnFramebufferHeightChanged(int new_value) +void GraphicsFramebufferWidget::OnFramebufferHeightChanged(unsigned int new_value)  {      if (framebuffer_height != new_value) {          framebuffer_height = new_value; @@ -227,8 +227,8 @@ void GraphicsFramebufferWidget::OnUpdate()      {          QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);          u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); -        for (unsigned y = 0; y < framebuffer_height; ++y) { -            for (unsigned x = 0; x < framebuffer_width; ++x) { +        for (unsigned int y = 0; y < framebuffer_height; ++y) { +            for (unsigned int x = 0; x < framebuffer_width; ++x) {                  u32 value = *(color_buffer + x + y * framebuffer_width);                  decoded_image.setPixel(x, y, qRgba((value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, 255/*value >> 24*/)); @@ -242,8 +242,8 @@ void GraphicsFramebufferWidget::OnUpdate()      {          QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);          u8* color_buffer = Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); -        for (unsigned y = 0; y < framebuffer_height; ++y) { -            for (unsigned x = 0; x < framebuffer_width; ++x) { +        for (unsigned int y = 0; y < framebuffer_height; ++y) { +            for (unsigned int x = 0; x < framebuffer_width; ++x) {                  u8* pixel_pointer = color_buffer + x * 3 + y * 3 * framebuffer_width;                  decoded_image.setPixel(x, y, qRgba(pixel_pointer[0], pixel_pointer[1], pixel_pointer[2], 255/*value >> 24*/)); @@ -257,8 +257,8 @@ void GraphicsFramebufferWidget::OnUpdate()      {          QImage decoded_image(framebuffer_width, framebuffer_height, QImage::Format_ARGB32);          u32* color_buffer = (u32*)Memory::GetPointer(Pica::PAddrToVAddr(framebuffer_address)); -        for (unsigned y = 0; y < framebuffer_height; ++y) { -            for (unsigned x = 0; x < framebuffer_width; ++x) { +        for (unsigned int y = 0; y < framebuffer_height; ++y) { +            for (unsigned int x = 0; x < framebuffer_width; ++x) {                  u16 value = *(u16*)(((u8*)color_buffer) + x * 2 + y * framebuffer_width * 2);                  u8 r = Color::Convert5To8((value >> 11) & 0x1F);                  u8 g = Color::Convert5To8((value >> 6) & 0x1F); diff --git a/src/citra_qt/debugger/graphics_framebuffer.hxx b/src/citra_qt/debugger/graphics_framebuffer.hxx index 56215761e..02813525c 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.hxx +++ b/src/citra_qt/debugger/graphics_framebuffer.hxx @@ -62,8 +62,8 @@ public:  public slots:      void OnFramebufferSourceChanged(int new_value);      void OnFramebufferAddressChanged(qint64 new_value); -    void OnFramebufferWidthChanged(int new_value); -    void OnFramebufferHeightChanged(int new_value); +    void OnFramebufferWidthChanged(unsigned int new_value); +    void OnFramebufferHeightChanged(unsigned int new_value);      void OnFramebufferFormatChanged(int new_value);      void OnUpdate(); diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index ffe05cdbc..593e0eabd 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -1419,15 +1419,19 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)      arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));      bx_inst *inst_cream = (bx_inst *)inst_base->component; -    inst_base->cond  = BITS(inst, 28, 31); -    inst_base->idx     = index; -    inst_base->br     = INDIRECT_BRANCH; +    inst_base->cond = BITS(inst, 28, 31); +    inst_base->idx  = index; +    inst_base->br   = INDIRECT_BRANCH; -    inst_cream->Rm     = BITS(inst, 0, 3); +    inst_cream->Rm  = BITS(inst, 0, 3);      return inst_base;  } -ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); } +ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) +{ +    return INTERPRETER_TRANSLATE(bx)(inst, index); +} +  ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){      arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));      cdp_inst *inst_cream = (cdp_inst *)inst_base->component; @@ -4129,22 +4133,35 @@ unsigned InterpreterMainLoop(ARMul_State* state) {          INC_PC(sizeof(blx_inst));          goto DISPATCH;      } +      BX_INST: +    BXJ_INST:      { -        bx_inst *inst_cream = (bx_inst *)inst_base->component; -        if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { +        // Note that only the 'fail' case of BXJ is emulated. This is because +        // the facilities for Jazelle emulation are not implemented. +        // +        // According to the ARM documentation on BXJ, if setting the J bit in the APSR +        // fails, then BXJ functions identically like a regular BX instruction. +		// +		// This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle. + +        if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { +            bx_inst* const inst_cream = (bx_inst*)inst_base->component; +              if (inst_cream->Rm == 15)                  LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]); +              cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;              cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;              INC_PC(sizeof(bx_inst));              goto DISPATCH;          } +          cpu->Reg[15] += GET_INST_SIZE(cpu);          INC_PC(sizeof(bx_inst));          goto DISPATCH;      } -    BXJ_INST: +      CDP_INST:      {          cdp_inst *inst_cream = (cdp_inst *)inst_base->component; @@ -5571,7 +5588,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {                  operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);              RD = operand1 * operand2 + RN; -            // TODO: FIXME: UPDATE Q FLAGS +            if (AddOverflow(operand1 * operand2, RN, RD)) +                cpu->Cpsr |= (1 << 27);          }          cpu->Reg[15] += GET_INST_SIZE(cpu);          INC_PC(sizeof(smla_inst)); diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp index 4b0f761d9..37be4b027 100644 --- a/src/core/hle/service/apt_a.cpp +++ b/src/core/hle/service/apt_a.cpp @@ -25,12 +25,12 @@ const Interface::FunctionInfo FunctionTable[] = {      {0x00040040, nullptr,                   "Finalize?"},      {0x00050040, nullptr,                   "GetAppletManInfo?"},      {0x00060040, nullptr,                   "GetAppletInfo?"}, +    {0x000D0080, APT_U::ReceiveParameter,   "ReceiveParameter?"}, +    {0x000E0080, APT_U::GlanceParameter,    "GlanceParameter?"},      {0x003B0040, nullptr,                   "CancelLibraryApplet?"},      {0x00430040, nullptr,                   "NotifyToWait?"},      {0x004B00C2, nullptr,                   "AppletUtility?"},      {0x00550040, nullptr,                   "WriteInputToNsState?"}, -    {0x000D0080, APT_U::ReceiveParameter,   "ReceiveParameter" }, -    {0x000E0080, APT_U::GlanceParameter,    "GlanceParameter" },  };  //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 03c01cf90..835620909 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp @@ -172,12 +172,12 @@ static void GetModelNintendo2DS(Service::Interface* self) {  const Interface::FunctionInfo FunctionTable[] = {      {0x00010082, GetConfigInfoBlk2,     "GetConfigInfoBlk2"},      {0x00020000, nullptr,               "SecureInfoGetRegion"}, -    {0x00030000, nullptr,               "GenHashConsoleUnique"}, +    {0x00030040, nullptr,               "GenHashConsoleUnique"},      {0x00040000, nullptr,               "GetRegionCanadaUSA"},      {0x00050000, GetSystemModel,        "GetSystemModel"},      {0x00060000, GetModelNintendo2DS,   "GetModelNintendo2DS"}, -    {0x00070040, nullptr,               "unknown"}, -    {0x00080080, nullptr,               "unknown"}, +    {0x00070040, nullptr,               "WriteToFirstByteCfgSavegame"}, +    {0x00080080, nullptr,               "GoThroughTable"},      {0x00090040, GetCountryCodeString,  "GetCountryCodeString"},      {0x000A0040, GetCountryCodeID,      "GetCountryCodeID"},  }; diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index aef8cfbca..3a557efe1 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp @@ -14,16 +14,15 @@ namespace CSND_SND {  const Interface::FunctionInfo FunctionTable[] = {      {0x00010140, nullptr,               "Initialize"},      {0x00020000, nullptr,               "Shutdown"}, -    {0x00030040, nullptr,               "Unknown"}, -    {0x00040080, nullptr,               "Unknown"}, -    {0x00050000, nullptr,               "Unknown"}, -    {0x00060000, nullptr,               "Unknown"}, -    {0x00070000, nullptr,               "Unknown"}, -    {0x00080040, nullptr,               "Unknown"}, +    {0x00030040, nullptr,               "ExecuteType0Commands"}, +    {0x00040080, nullptr,               "ExecuteType1Commands"}, +    {0x00050000, nullptr,               "AcquireSoundChannels"}, +    {0x00060000, nullptr,               "ReleaseSoundChannels"}, +    {0x00070000, nullptr,               "AcquireCaptureDevice"}, +    {0x00080040, nullptr,               "ReleaseCaptureDevice"},      {0x00090082, nullptr,               "FlushDCache"},      {0x000A0082, nullptr,               "StoreDCache"},      {0x000B0082, nullptr,               "InvalidateDCache"}, -    {0x000C0000, nullptr,               "Unknown"},  };  //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 2cf4d118f..d4affdfbf 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -12,9 +12,23 @@  namespace DSP_DSP { -static u32 read_pipe_count; -static Handle semaphore_event; -static Handle interrupt_event; +static u32 read_pipe_count    = 0; +static Handle semaphore_event = 0; +static Handle interrupt_event = 0; + +void SignalInterrupt() { +    // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated +    // application that a DSP interrupt occurred, without specifying which one. Since we do not +    // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games +    // that check the DSP interrupt signal event to run. We should figure out the different types of +    // DSP interrupts, and trigger them at the appropriate times. + +    if (interrupt_event == 0) { +        LOG_WARNING(Service_DSP, "cannot signal interrupt until DSP event has been created!"); +        return; +    } +    Kernel::SignalEvent(interrupt_event); +}  /**   * DSP_DSP::ConvertProcessAddressFromDspDram service function @@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {  void WriteReg0x10(Service::Interface* self) {      u32* cmd_buff = Kernel::GetCommandBuffer(); -    Kernel::SignalEvent(interrupt_event); +    SignalInterrupt();      cmd_buff[1] = 0; // No error diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h index 0b8b64600..fa13bfb7c 100644 --- a/src/core/hle/service/dsp_dsp.h +++ b/src/core/hle/service/dsp_dsp.h @@ -20,4 +20,7 @@ public:      }  }; +/// Signals that a DSP interrupt has occurred to userland code +void SignalInterrupt(); +  } // namespace diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp index b388afb15..d49bd5335 100644 --- a/src/core/hle/service/ir_rst.cpp +++ b/src/core/hle/service/ir_rst.cpp @@ -15,12 +15,7 @@ const Interface::FunctionInfo FunctionTable[] = {      {0x00010000, nullptr,                 "GetHandles"},      {0x00020080, nullptr,                 "Initialize"},      {0x00030000, nullptr,                 "Shutdown"}, -    {0x00040000, nullptr,                 "Unknown"}, -    {0x00050000, nullptr,                 "Unknown"}, -    {0x00060000, nullptr,                 "Unknown"}, -    {0x00070080, nullptr,                 "Unknown"}, -    {0x00080000, nullptr,                 "Unknown"}, -    {0x00090000, nullptr,                 "Unknown"}, +    {0x00090000, nullptr,                 "WriteToTwoFields"},  };  //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 9c9e90a40..7d6e2e8e8 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp @@ -13,10 +13,14 @@ namespace LDR_RO {  const Interface::FunctionInfo FunctionTable[] = {      {0x000100C2, nullptr,               "Initialize"}, -    {0x00020082, nullptr,               "CRR_Load"}, -    {0x00030042, nullptr,               "CRR_Unload"}, -    {0x000402C2, nullptr,               "CRO_LoadAndFix"}, -    {0x000500C2, nullptr,               "CRO_ApplyRelocationPatchesAndLink"} +    {0x00020082, nullptr,               "LoadCRR"}, +    {0x00030042, nullptr,               "UnloadCCR"}, +    {0x000402C2, nullptr,               "LoadExeCRO"}, +    {0x000500C2, nullptr,               "LoadCROSymbols"}, +    {0x00060042, nullptr,               "CRO_Load?"}, +    {0x00070042, nullptr,               "LoadCROSymbols"}, +    {0x00080042, nullptr,               "Shutdown"}, +    {0x000902C2, nullptr,               "LoadExeCRO_New?"},  };  //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp index 233b14f6d..0f03de6ae 100644 --- a/src/core/hle/service/ndm_u.cpp +++ b/src/core/hle/service/ndm_u.cpp @@ -11,10 +11,13 @@  namespace NDM_U {  const Interface::FunctionInfo FunctionTable[] = { -    {0x00060040, nullptr, "SuspendDaemons"}, -    {0x00080040, nullptr, "DisableWifiUsage"}, -    {0x00090000, nullptr, "EnableWifiUsage"}, -    {0x00140040, nullptr, "OverrideDefaultDaemons"}, +    {0x00010042, nullptr,                 "EnterExclusiveState"}, +    {0x00020002, nullptr,                 "LeaveExclusiveState"}, +    {0x00030000, nullptr,                 "QueryExclusiveMode"}, +    {0x00060040, nullptr,                 "SuspendDaemons"}, +    {0x00080040, nullptr,                 "DisableWifiUsage"}, +    {0x00090000, nullptr,                 "EnableWifiUsage"}, +    {0x00140040, nullptr,                 "OverrideDefaultDaemons"},  };  //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index 8e7abcf9c..f502c6afe 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp @@ -308,11 +308,11 @@ static void Socket(Service::Interface* self) {      u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol)); -    if (socket_handle != SOCKET_ERROR_VALUE) +    if ((s32)socket_handle != SOCKET_ERROR_VALUE)          open_sockets[socket_handle] = { socket_handle, true };      int result = 0; -    if (socket_handle == SOCKET_ERROR_VALUE) +    if ((s32)socket_handle == SOCKET_ERROR_VALUE)          result = TranslateError(GET_ERRNO);      cmd_buffer[1] = result; @@ -436,11 +436,11 @@ static void Accept(Service::Interface* self) {      socklen_t addr_len = sizeof(addr);      u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len)); -    if (ret != SOCKET_ERROR_VALUE) +    if ((s32)ret != SOCKET_ERROR_VALUE)          open_sockets[ret] = { ret, true };      int result = 0; -    if (ret == SOCKET_ERROR_VALUE) { +    if ((s32)ret == SOCKET_ERROR_VALUE) {          result = TranslateError(GET_ERRNO);      } else {          CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr); diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 25fab1a4f..912b52adf 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -52,13 +52,15 @@ static void GetServiceHandle(Service::Interface* self) {  }  const Interface::FunctionInfo FunctionTable[] = { -    {0x00010002, Initialize,        "Initialize"}, -    {0x00020000, GetProcSemaphore,  "GetProcSemaphore"}, -    {0x00030100, nullptr,           "RegisterService"}, -    {0x000400C0, nullptr,           "UnregisterService"}, -    {0x00050100, GetServiceHandle,  "GetServiceHandle"}, -    {0x000B0000, nullptr,           "ReceiveNotification"}, -    {0x000C0080, nullptr,           "PublishToSubscriber"} +    {0x00010002, Initialize,          "Initialize"}, +    {0x00020000, GetProcSemaphore,    "GetProcSemaphore"}, +    {0x00030100, nullptr,             "RegisterService"}, +    {0x000400C0, nullptr,             "UnregisterService"}, +    {0x00050100, GetServiceHandle,    "GetServiceHandle"}, +    {0x000600C2, nullptr,             "RegisterHandle"}, +    {0x00090040, nullptr,             "Subscribe"}, +    {0x000B0000, nullptr,             "ReceiveNotification"}, +    {0x000C0080, nullptr,             "PublishToSubscriber"},  };  //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 0ff6c6cde..e346e0ad6 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp @@ -10,6 +10,7 @@  #include "core/hle/hle.h"  #include "core/hle/service/gsp_gpu.h" +#include "core/hle/service/dsp_dsp.h"  #include "core/hw/gpu.h" @@ -214,13 +215,18 @@ void Update() {              //  - If frameskip == 0 (disabled), always swap buffers              //  - If frameskip == 1, swap buffers every other frame (starting from the first frame)              //  - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame) -              if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||                      Settings::values.frame_skip == 0) {                  VideoCore::g_renderer->SwapBuffers();              } +            // Signal to GSP that GPU interrupt has occurred              GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); + +            // TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but +            // until we can emulate DSP interrupts, this is probably the only reasonable place to do +            // this. Certain games expect this to be periodically signaled. +            DSP_DSP::SignalInterrupt();          }      }  } | 
