mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
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/ProcessorInterface.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/PowerPC/JitCommon/JitBase.h"
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
@ -518,25 +534,11 @@ static void Do_ARAM_DMA()
|
||||
g_dspState.DSPControl.DMAState = 1;
|
||||
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);
|
||||
CoreTiming::ForceExceptionCheck(100);
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
|
@ -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.
|
||||
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));
|
||||
FixupBranch clearInt = J_CC(CC_NZ);
|
||||
@ -707,7 +708,14 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc
|
||||
SetJumpTarget(extException);
|
||||
TEST(32, PPCSTATE(msr), Imm32(0x0008000));
|
||||
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);
|
||||
|
||||
gpr.Flush(FLUSH_MAINTAIN_STATE);
|
||||
|
@ -97,6 +97,7 @@ protected:
|
||||
JitBlock *curBlock;
|
||||
|
||||
std::unordered_set<u32> fifoWriteAddresses;
|
||||
std::unordered_set<u32> dspARAMAddresses;
|
||||
};
|
||||
|
||||
PPCAnalyst::CodeBlock code_block;
|
||||
|
Loading…
Reference in New Issue
Block a user