DSP: Signal (faked) interrupt on every frame.

- Hack to work around games checking that the DSP event has been signaled by a real DSP interrupt.
This commit is contained in:
bunnei 2015-01-05 00:19:28 -05:00
parent cc23269ff4
commit e9650f1c61
3 changed files with 28 additions and 5 deletions

View file

@ -12,9 +12,23 @@
namespace DSP_DSP { namespace DSP_DSP {
static u32 read_pipe_count; static u32 read_pipe_count = 0;
static Handle semaphore_event; static Handle semaphore_event = 0;
static Handle interrupt_event; 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 * DSP_DSP::ConvertProcessAddressFromDspDram service function
@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
void WriteReg0x10(Service::Interface* self) { void WriteReg0x10(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer(); u32* cmd_buff = Kernel::GetCommandBuffer();
Kernel::SignalEvent(interrupt_event); SignalInterrupt();
cmd_buff[1] = 0; // No error cmd_buff[1] = 0; // No error

View file

@ -20,4 +20,7 @@ public:
} }
}; };
/// Signals that a DSP interrupt has occurred to userland code
void SignalInterrupt();
} // namespace } // namespace

View file

@ -10,6 +10,7 @@
#include "core/hle/hle.h" #include "core/hle/hle.h"
#include "core/hle/service/gsp_gpu.h" #include "core/hle/service/gsp_gpu.h"
#include "core/hle/service/dsp_dsp.h"
#include "core/hw/gpu.h" #include "core/hw/gpu.h"
@ -214,13 +215,18 @@ void Update() {
// - If frameskip == 0 (disabled), always swap buffers // - 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 other frame (starting from the first frame)
// - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second 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) || if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
Settings::values.frame_skip == 0) { Settings::values.frame_skip == 0) {
VideoCore::g_renderer->SwapBuffers(); VideoCore::g_renderer->SwapBuffers();
} }
// Signal to GSP that GPU interrupt has occurred
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1); 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();
} }
} }
} }