summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2012-06-09 18:16:11 +0200
committerPierre Bourdon <delroth@gmail.com>2012-06-16 14:38:44 +0200
commitda4141aa9f25ebcf9df557c9547817897ee0d862 (patch)
tree104b5aecb32d39a798d02eba6013081f9c414f95 /Source/Core
parent227580d1a5d2140f4f0b6ca76aeba63058165bc9 (diff)
Simulate ARAM DMAState correctly and check for external exceptions after
MTMSR is executed. This commits fixes issue 617. WWE Day of Reckoning 1 and 2 are now playable with Dolphin. The changes are not implemented for JitIL yet.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Src/HW/DSP.cpp10
-rw-r--r--Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp1
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp11
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit.h2
-rw-r--r--Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp5
5 files changed, 17 insertions, 12 deletions
diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp
index f2509555ed..799fb62f0e 100644
--- a/Source/Core/Core/Src/HW/DSP.cpp
+++ b/Source/Core/Core/Src/HW/DSP.cpp
@@ -436,10 +436,6 @@ void Write16(const u16 _Value, const u32 _Address)
if (tmpControl.ARAM) g_dspState.DSPControl.ARAM = 0;
if (tmpControl.DSP) g_dspState.DSPControl.DSP = 0;
- // Tracking DMAState fixes Knockout Kings 2003 in DSP HLE mode
- if (GetDSPEmulator()->IsLLE())
- g_dspState.DSPControl.DMAState = 0; // keep g_ARAM DMA State zero
-
// unknown
g_dspState.DSPControl.unk3 = tmpControl.unk3;
g_dspState.DSPControl.pad = tmpControl.pad;
@@ -701,9 +697,9 @@ void Do_ARAM_DMA()
// seems like a good estimate
CoreTiming::ScheduleEvent_Threadsafe(g_arDMA.Cnt.count >> 1, et_GenerateDSPInterrupt, INT_ARAM | (1<<16));
- // Emulating the DMA wait time fixes Knockout Kings 2003 in DSP HLE mode
- if (!GetDSPEmulator()->IsLLE())
- g_dspState.DSPControl.DMAState = 1;
+ // Set the "DMA in progress" flag. It will be cleared when the interrupt will
+ // be triggered, after the simulated delay.
+ g_dspState.DSPControl.DMAState = 1;
// Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks
if (g_arDMA.Cnt.dir)
diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp
index bc7e37b533..19fe74b3f2 100644
--- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp
+++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp
@@ -234,6 +234,7 @@ void Interpreter::mtmsr(UGeckoInstruction _inst)
{
// Privileged?
MSR = m_GPR[_inst.RS];
+ PowerPC::CheckExceptions();
m_EndBlock = true;
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
index 357eeb7809..bc0e671f24 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
@@ -300,10 +300,15 @@ void Jit64::Cleanup()
ABI_CallFunctionCCC((void *)&PowerPC::UpdatePerformanceMonitor, js.downcountAmount, jit->js.numLoadStoreInst, jit->js.numFloatingPointInst);
}
-void Jit64::WriteExit(u32 destination, int exit_num)
+void Jit64::WriteExit(u32 destination, int exit_num, bool force_ee_check)
{
Cleanup();
- SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
+
+ // External exceptions are checked when the following instruction sets the <= 0 flag.
+ // If we need to force the check, execute a useless SUB EAX, EAX
+ SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
+ if (force_ee_check)
+ SUB(32, R(EAX), R(EAX));
//If nobody has taken care of this yet (this can be removed when all branches are done)
JitBlock *b = js.curBlock;
@@ -312,7 +317,7 @@ void Jit64::WriteExit(u32 destination, int exit_num)
// Link opportunity!
int block = blocks.GetBlockNumberFromStartAddress(destination);
- if (block >= 0 && jo.enableBlocklink)
+ if (!force_ee_check && block >= 0 && jo.enableBlocklink)
{
// It exists! Joy of joy!
JMP(blocks.GetBlock(block)->checkedEntry, true);
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h
index 1ebd476134..08de7c4609 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.h
@@ -112,7 +112,7 @@ public:
// Utilities for use by opcodes
- void WriteExit(u32 destination, int exit_num);
+ void WriteExit(u32 destination, int exit_num, bool force_ee_check = false);
void WriteExitDestInEAX();
void WriteExceptionExit();
void WriteExternalExceptionExit();
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp
index 14827129f8..b68f4a926c 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_SystemRegisters.cpp
@@ -122,7 +122,10 @@ void Jit64::mtmsr(UGeckoInstruction inst)
gpr.UnlockAll();
gpr.Flush(FLUSH_ALL);
fpr.Flush(FLUSH_ALL);
- WriteExit(js.compilerPC + 4, 0);
+
+ // Force an external exception when going out of mtmsr in order to check
+ // immediately for interrupts that were delayed because of MSR.EE=0.
+ WriteExit(js.compilerPC + 4, 0, true);
js.firstFPInstructionFound = false;
}