Compile the ARAM DMA exception checks into the JIT block in a similar style to FIFO writes. This ensures that the ARAM DMA is handled soon after the DMA completes. Fixes issue 7122 and issue 7342.
This commit is contained in:
parent
23e2301223
commit
d09e2abb0d
|
@ -38,6 +38,7 @@
|
||||||
#include "Core/HW/MMIO.h"
|
#include "Core/HW/MMIO.h"
|
||||||
#include "Core/HW/ProcessorInterface.h"
|
#include "Core/HW/ProcessorInterface.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||||
|
|
||||||
namespace DSP
|
namespace DSP
|
||||||
{
|
{
|
||||||
|
@ -441,6 +442,21 @@ static void UpdateInterrupts()
|
||||||
bool ints_set = (((g_dspState.DSPControl.Hex >> 1) & g_dspState.DSPControl.Hex & (INT_DSP | INT_ARAM | INT_AID)) != 0);
|
bool ints_set = (((g_dspState.DSPControl.Hex >> 1) & g_dspState.DSPControl.Hex & (INT_DSP | INT_ARAM | INT_AID)) != 0);
|
||||||
|
|
||||||
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, ints_set);
|
ProcessorInterface::SetInterrupt(ProcessorInterface::INT_CAUSE_DSP, ints_set);
|
||||||
|
|
||||||
|
if ((g_dspState.DSPControl.Hex >> 1) & g_dspState.DSPControl.Hex & (INT_DSP | INT_ARAM | INT_AID))
|
||||||
|
{
|
||||||
|
if (jit && PC != 0 && (jit->js.dspARAMAddresses.find(PC)) == (jit->js.dspARAMAddresses.end()) && (g_dspState.DSPControl.ARAM & g_dspState.DSPControl.ARAM_mask))
|
||||||
|
{
|
||||||
|
int type = GetOpInfo(Memory::ReadUnchecked_U32(PC))->type;
|
||||||
|
if (type == OPTYPE_STORE || type == OPTYPE_STOREFP || (type == OPTYPE_PS && GetOpInfo(Memory::ReadUnchecked_U32(PC))->opname == "psq_st"))
|
||||||
|
{
|
||||||
|
jit->js.dspARAMAddresses.insert(PC);
|
||||||
|
|
||||||
|
// Invalidate the JIT block so that it gets recompiled with the external exception check included.
|
||||||
|
jit->GetBlockCache()->InvalidateICache(PC, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateDSPInterrupt(u64 DSPIntType, int cyclesLate)
|
static void GenerateDSPInterrupt(u64 DSPIntType, int cyclesLate)
|
||||||
|
@ -518,25 +534,11 @@ static void Do_ARAM_DMA()
|
||||||
g_dspState.DSPControl.DMAState = 1;
|
g_dspState.DSPControl.DMAState = 1;
|
||||||
if (g_arDMA.Cnt.count == 32)
|
if (g_arDMA.Cnt.count == 32)
|
||||||
{
|
{
|
||||||
// Beyond Good and Evil (GGEE41) sends count 32
|
|
||||||
// Lost Kingdoms 2 needs the exception check here in DSP HLE mode
|
|
||||||
CompleteARAM(0, 0);
|
CompleteARAM(0, 0);
|
||||||
CoreTiming::ForceExceptionCheck(100);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CoreTiming::ScheduleEvent_Threadsafe(0, et_CompleteARAM);
|
CoreTiming::ScheduleEvent_Threadsafe(0, et_CompleteARAM);
|
||||||
|
|
||||||
// Force an early exception check on large transfers. Fixes RE2 audio.
|
|
||||||
// NFS:HP2 (<= 6144)
|
|
||||||
// Viewtiful Joe (<= 6144)
|
|
||||||
// Sonic Mega Collection (> 2048)
|
|
||||||
// Paper Mario battles (> 32)
|
|
||||||
// Mario Super Baseball (> 32)
|
|
||||||
// Knockout Kings 2003 loading (> 32)
|
|
||||||
// WWE DOR (> 32)
|
|
||||||
if (g_arDMA.Cnt.count > 2048 && g_arDMA.Cnt.count <= 6144)
|
|
||||||
CoreTiming::ForceExceptionCheck(100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks
|
// Real hardware DMAs in 32byte chunks, but we can get by with 8byte chunks
|
||||||
|
|
|
@ -697,7 +697,8 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add an external exception check if the instruction writes to the FIFO.
|
// Add an external exception check if the instruction writes to the FIFO.
|
||||||
if (jit->js.fifoWriteAddresses.find(ops[i].address) != jit->js.fifoWriteAddresses.end())
|
if (jit->js.fifoWriteAddresses.find(ops[i].address) != jit->js.fifoWriteAddresses.end() ||
|
||||||
|
jit->js.dspARAMAddresses.find(ops[i].address) != jit->js.dspARAMAddresses.end())
|
||||||
{
|
{
|
||||||
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_ISI | EXCEPTION_PROGRAM | EXCEPTION_SYSCALL | EXCEPTION_FPU_UNAVAILABLE | EXCEPTION_DSI | EXCEPTION_ALIGNMENT));
|
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_ISI | EXCEPTION_PROGRAM | EXCEPTION_SYSCALL | EXCEPTION_FPU_UNAVAILABLE | EXCEPTION_DSI | EXCEPTION_ALIGNMENT));
|
||||||
FixupBranch clearInt = J_CC(CC_NZ);
|
FixupBranch clearInt = J_CC(CC_NZ);
|
||||||
|
@ -707,7 +708,14 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||||
SetJumpTarget(extException);
|
SetJumpTarget(extException);
|
||||||
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
||||||
FixupBranch noExtIntEnable = J_CC(CC_Z, true);
|
FixupBranch noExtIntEnable = J_CC(CC_Z, true);
|
||||||
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
|
if (jit->js.fifoWriteAddresses.find(ops[i].address) != jit->js.fifoWriteAddresses.end())
|
||||||
|
{
|
||||||
|
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_CP | ProcessorInterface::INT_CAUSE_PE_TOKEN | ProcessorInterface::INT_CAUSE_PE_FINISH));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TEST(32, M((void *)&ProcessorInterface::m_InterruptCause), Imm32(ProcessorInterface::INT_CAUSE_DSP));
|
||||||
|
}
|
||||||
FixupBranch noCPInt = J_CC(CC_Z, true);
|
FixupBranch noCPInt = J_CC(CC_Z, true);
|
||||||
|
|
||||||
gpr.Flush(FLUSH_MAINTAIN_STATE);
|
gpr.Flush(FLUSH_MAINTAIN_STATE);
|
||||||
|
|
|
@ -97,6 +97,7 @@ protected:
|
||||||
JitBlock *curBlock;
|
JitBlock *curBlock;
|
||||||
|
|
||||||
std::unordered_set<u32> fifoWriteAddresses;
|
std::unordered_set<u32> fifoWriteAddresses;
|
||||||
|
std::unordered_set<u32> dspARAMAddresses;
|
||||||
};
|
};
|
||||||
|
|
||||||
PPCAnalyst::CodeBlock code_block;
|
PPCAnalyst::CodeBlock code_block;
|
||||||
|
|
Loading…
Reference in New Issue