Added an option "Alternate RFI" to the Game Properties to enable alternate interrupt timing. Try enabling this option if a game hangs, works only in the Interpreter or Dolphin crashes. This option fixes Die Hard: Vendetta and Medabots Infinity.
Fixed the interpreter to execute instructions in the right number of cycles. It used to execute all instructions in one cycle. Added a trace function to the interpreter making it easier to determine differences between the interpreter and the recompilers. Removed the "Enable self modifying code check" as it was not useful. Fixes issue 2407. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6183 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
3bdeb923ef
commit
34aebffff9
|
@ -293,6 +293,7 @@ void SConfig::LoadSettings()
|
||||||
ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false);
|
ini.Get("Core", "RunCompareClient", &m_LocalCoreStartupParameter.bRunCompareClient, false);
|
||||||
ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false);
|
ini.Get("Core", "MMU", &m_LocalCoreStartupParameter.bMMU, false);
|
||||||
ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0);
|
ini.Get("Core", "TLBHack", &m_LocalCoreStartupParameter.iTLBHack, 0);
|
||||||
|
ini.Get("Core", "AlternateRFI", &m_LocalCoreStartupParameter.bAlternateRFI, false);
|
||||||
ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default
|
ini.Get("Core", "FrameLimit", &m_Framelimit, 1); // auto frame limit by default
|
||||||
ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default
|
ini.Get("Core", "UseFPS", &b_UseFPS, false); // use vps as default
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ SCoreStartupParameter::SCoreStartupParameter()
|
||||||
bLockThreads(false),
|
bLockThreads(false),
|
||||||
bEnableCheats(false),
|
bEnableCheats(false),
|
||||||
bRunCompareServer(false), bRunCompareClient(false),
|
bRunCompareServer(false), bRunCompareClient(false),
|
||||||
bMMU(false), bSMC(false), iTLBHack(0), SelectedLanguage(0), bWii(false),
|
bMMU(false), bAlternateRFI(false), iTLBHack(0), SelectedLanguage(0), bWii(false),
|
||||||
bConfirmStop(false), bHideCursor(false),
|
bConfirmStop(false), bHideCursor(false),
|
||||||
bAutoHideCursor(false), bUsePanicHandlers(true),
|
bAutoHideCursor(false), bUsePanicHandlers(true),
|
||||||
iRenderWindowXPos(0), iRenderWindowYPos(0),
|
iRenderWindowXPos(0), iRenderWindowYPos(0),
|
||||||
|
@ -70,8 +70,8 @@ void SCoreStartupParameter::LoadDefaults()
|
||||||
bLockThreads = true;
|
bLockThreads = true;
|
||||||
bEnableFPRF = false;
|
bEnableFPRF = false;
|
||||||
bMMU = false;
|
bMMU = false;
|
||||||
bSMC = false;
|
|
||||||
iTLBHack = 0;
|
iTLBHack = 0;
|
||||||
|
bAlternateRFI = false;
|
||||||
SelectedLanguage = 0;
|
SelectedLanguage = 0;
|
||||||
bWii = false;
|
bWii = false;
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@ struct SCoreStartupParameter
|
||||||
bool bRunCompareClient;
|
bool bRunCompareClient;
|
||||||
|
|
||||||
bool bMMU;
|
bool bMMU;
|
||||||
bool bSMC;
|
|
||||||
int iTLBHack;
|
int iTLBHack;
|
||||||
|
bool bAlternateRFI;
|
||||||
|
|
||||||
int SelectedLanguage;
|
int SelectedLanguage;
|
||||||
|
|
||||||
|
|
|
@ -265,11 +265,6 @@ inline void WriteToHardware(u32 em_address, const T data, u32 effective_address,
|
||||||
((em_address & 0xF0000000) == 0x00000000))
|
((em_address & 0xF0000000) == 0x00000000))
|
||||||
{
|
{
|
||||||
*(T*)&m_pRAM[em_address & RAM_MASK] = bswap(data);
|
*(T*)&m_pRAM[em_address & RAM_MASK] = bswap(data);
|
||||||
|
|
||||||
// Required for games with self modifying code (e.g. Monster House)
|
|
||||||
if (Core::g_CoreStartupParameter.bSMC)
|
|
||||||
Write_Opcode_JIT(em_address, 0x14141414);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (((em_address & 0xF0000000) == 0x90000000) ||
|
else if (((em_address & 0xF0000000) == 0x90000000) ||
|
||||||
|
|
|
@ -2799,6 +2799,7 @@ DEFINE_LUA_FUNCTION(emulua_loadrom, "filename")
|
||||||
game_ini.Get("Core", "EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF);
|
game_ini.Get("Core", "EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF);
|
||||||
game_ini.Get("Core", "MMU", &StartUp.bMMU, StartUp.bMMU);
|
game_ini.Get("Core", "MMU", &StartUp.bMMU, StartUp.bMMU);
|
||||||
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
||||||
|
game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI);
|
||||||
// Wii settings
|
// Wii settings
|
||||||
if (StartUp.bWii)
|
if (StartUp.bWii)
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,13 +75,44 @@ static void patches()
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::SingleStepInner(void)
|
int startTrace = 0;
|
||||||
|
|
||||||
|
void Trace( UGeckoInstruction &instCode )
|
||||||
|
{
|
||||||
|
char regs[500]="";
|
||||||
|
for (int i=0; i<32; i++) {
|
||||||
|
sprintf(regs, "%sr%02d: %08x ", regs, i, PowerPC::ppcState.gpr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char fregs[500]="";
|
||||||
|
for (int i=0; i<32; i++) {
|
||||||
|
sprintf(fregs, "%sf%02d: %08x %08x ", fregs, i, PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char ppcInst[256];
|
||||||
|
DisassembleGekko(instCode.hex, PC, ppcInst, 256);
|
||||||
|
|
||||||
|
DEBUG_LOG(POWERPC, "INTER PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s %08x %s", PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3], PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr, PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs, instCode.hex, ppcInst);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Interpreter::SingleStepInner(void)
|
||||||
{
|
{
|
||||||
static UGeckoInstruction instCode;
|
static UGeckoInstruction instCode;
|
||||||
|
|
||||||
NPC = PC + sizeof(UGeckoInstruction);
|
NPC = PC + sizeof(UGeckoInstruction);
|
||||||
instCode.hex = Memory::Read_Opcode(PC);
|
instCode.hex = Memory::Read_Opcode(PC);
|
||||||
|
|
||||||
|
// Uncomment to trace the interpreter
|
||||||
|
//if ((PC & 0xffffff)>=0x0ab54c && (PC & 0xffffff)<=0x0ab624)
|
||||||
|
// startTrace = 1;
|
||||||
|
//else
|
||||||
|
// startTrace = 0;
|
||||||
|
|
||||||
|
if (startTrace)
|
||||||
|
{
|
||||||
|
Trace(instCode);
|
||||||
|
}
|
||||||
|
|
||||||
if (instCode.hex != 0)
|
if (instCode.hex != 0)
|
||||||
{
|
{
|
||||||
UReg_MSR& msr = (UReg_MSR&)MSR;
|
UReg_MSR& msr = (UReg_MSR&)MSR;
|
||||||
|
@ -131,6 +162,9 @@ void Interpreter::SingleStepInner(void)
|
||||||
PowerPC::ppcState.DebugCount++;
|
PowerPC::ppcState.DebugCount++;
|
||||||
#endif
|
#endif
|
||||||
patches();
|
patches();
|
||||||
|
|
||||||
|
GekkoOPInfo *opinfo = GetOpInfo(instCode);
|
||||||
|
return opinfo->numCyclesMinusOne + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::SingleStep()
|
void Interpreter::SingleStep()
|
||||||
|
@ -224,11 +258,12 @@ void Interpreter::Run()
|
||||||
{
|
{
|
||||||
m_EndBlock = false;
|
m_EndBlock = false;
|
||||||
int i;
|
int i;
|
||||||
|
int cycles = 0;
|
||||||
for (i = 0; !m_EndBlock; i++)
|
for (i = 0; !m_EndBlock; i++)
|
||||||
{
|
{
|
||||||
SingleStepInner();
|
cycles += SingleStepInner();
|
||||||
}
|
}
|
||||||
CoreTiming::downcount -= i;
|
CoreTiming::downcount -= cycles;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ public:
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Reset();
|
void Reset();
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
void SingleStepInner();
|
int SingleStepInner();
|
||||||
|
|
||||||
void Run();
|
void Run();
|
||||||
void ClearCache();
|
void ClearCache();
|
||||||
const char *GetName();
|
const char *GetName();
|
||||||
|
|
|
@ -255,7 +255,7 @@ void Jit64::HLEFunction(UGeckoInstruction _inst)
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
||||||
MOV(32, R(EAX), M(&NPC));
|
MOV(32, R(EAX), M(&NPC));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::DoNothing(UGeckoInstruction _inst)
|
void Jit64::DoNothing(UGeckoInstruction _inst)
|
||||||
|
@ -321,7 +321,7 @@ void Jit64::WriteExit(u32 destination, int exit_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::WriteExitDestInEAX(int exit_num)
|
void Jit64::WriteExitDestInEAX()
|
||||||
{
|
{
|
||||||
MOV(32, M(&PC), R(EAX));
|
MOV(32, M(&PC), R(EAX));
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
@ -379,7 +379,7 @@ void Jit64::Trace()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NOTICE_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s",
|
DEBUG_LOG(DYNA_REC, "JIT64 PC: %08x SRR0: %08x SRR1: %08x CRfast: %02x%02x%02x%02x%02x%02x%02x%02x FPSCR: %08x MSR: %08x LR: %08x %s %s",
|
||||||
PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3],
|
PC, SRR0, SRR1, PowerPC::ppcState.cr_fast[0], PowerPC::ppcState.cr_fast[1], PowerPC::ppcState.cr_fast[2], PowerPC::ppcState.cr_fast[3],
|
||||||
PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr,
|
PowerPC::ppcState.cr_fast[4], PowerPC::ppcState.cr_fast[5], PowerPC::ppcState.cr_fast[6], PowerPC::ppcState.cr_fast[7], PowerPC::ppcState.fpscr,
|
||||||
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs);
|
PowerPC::ppcState.msr, PowerPC::ppcState.spr[8], regs, fregs);
|
||||||
|
|
|
@ -141,7 +141,7 @@ public:
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
void WriteExit(u32 destination, int exit_num);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInEAX(int exit_num);
|
void WriteExitDestInEAX();
|
||||||
void WriteExceptionExit();
|
void WriteExceptionExit();
|
||||||
void WriteRfiExitDestInEAX();
|
void WriteRfiExitDestInEAX();
|
||||||
void WriteCallInterpreter(UGeckoInstruction _inst);
|
void WriteCallInterpreter(UGeckoInstruction _inst);
|
||||||
|
|
|
@ -70,7 +70,10 @@ void Jit64::rfi(UGeckoInstruction inst)
|
||||||
OR(32, M(&MSR), R(EAX));
|
OR(32, M(&MSR), R(EAX));
|
||||||
// NPC = SRR0;
|
// NPC = SRR0;
|
||||||
MOV(32, R(EAX), M(&SRR0));
|
MOV(32, R(EAX), M(&SRR0));
|
||||||
WriteRfiExitDestInEAX();
|
if (Core::g_CoreStartupParameter.bAlternateRFI)
|
||||||
|
WriteExitDestInEAX();
|
||||||
|
else
|
||||||
|
WriteRfiExitDestInEAX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Jit64::bx(UGeckoInstruction inst)
|
void Jit64::bx(UGeckoInstruction inst)
|
||||||
|
@ -92,7 +95,7 @@ void Jit64::bx(UGeckoInstruction inst)
|
||||||
destination = js.compilerPC + SignExt26(inst.LI << 2);
|
destination = js.compilerPC + SignExt26(inst.LI << 2);
|
||||||
#ifdef ACID_TEST
|
#ifdef ACID_TEST
|
||||||
if (inst.LK)
|
if (inst.LK)
|
||||||
AND(32, M(&CR), Imm32(~(0xFF000000)));
|
AND(32, M(&PowerPC::ppcState.cr), Imm32(~(0xFF000000)));
|
||||||
#endif
|
#endif
|
||||||
if (destination == js.compilerPC)
|
if (destination == js.compilerPC)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +184,7 @@ void Jit64::bcctrx(UGeckoInstruction inst)
|
||||||
if (inst.LK_3)
|
if (inst.LK_3)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -203,7 +206,7 @@ void Jit64::bcctrx(UGeckoInstruction inst)
|
||||||
//MOV(32, M(&PC), R(EAX)); => Already done in WriteExitDestInEAX()
|
//MOV(32, M(&PC), R(EAX)); => Already done in WriteExitDestInEAX()
|
||||||
if (inst.LK_3)
|
if (inst.LK_3)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4)); // LR = PC + 4;
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
// Would really like to continue the block here, but it ends. TODO.
|
// Would really like to continue the block here, but it ends. TODO.
|
||||||
SetJumpTarget(b);
|
SetJumpTarget(b);
|
||||||
WriteExit(js.compilerPC + 4, 1);
|
WriteExit(js.compilerPC + 4, 1);
|
||||||
|
@ -241,14 +244,14 @@ void Jit64::bclrx(UGeckoInstruction inst)
|
||||||
// This below line can be used to prove that blr "eats flags" in practice.
|
// This below line can be used to prove that blr "eats flags" in practice.
|
||||||
// This observation will let us do a lot of fun observations.
|
// This observation will let us do a lot of fun observations.
|
||||||
#ifdef ACID_TEST
|
#ifdef ACID_TEST
|
||||||
AND(32, M(&CR), Imm32(~(0xFF000000)));
|
AND(32, M(&PowerPC::ppcState.cr), Imm32(~(0xFF000000)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MOV(32, R(EAX), M(&LR));
|
MOV(32, R(EAX), M(&LR));
|
||||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||||
if (inst.LK)
|
if (inst.LK)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
|
|
||||||
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
|
if ((inst.BO & BO_DONT_CHECK_CONDITION) == 0)
|
||||||
SetJumpTarget( pConditionDontBranch );
|
SetJumpTarget( pConditionDontBranch );
|
||||||
|
|
|
@ -290,14 +290,14 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
||||||
MOV(32, R(EAX), M(&CTR));
|
MOV(32, R(EAX), M(&CTR));
|
||||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
}
|
}
|
||||||
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 16)) // bclrx
|
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 16)) // bclrx
|
||||||
{
|
{
|
||||||
MOV(32, R(EAX), M(&LR));
|
MOV(32, R(EAX), M(&LR));
|
||||||
if (js.next_inst.LK)
|
if (js.next_inst.LK)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -395,7 +395,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
||||||
MOV(32, R(EAX), M(&CTR));
|
MOV(32, R(EAX), M(&CTR));
|
||||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
}
|
}
|
||||||
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 16)) // bclrx
|
else if ((js.next_inst.OPCD == 19) && (js.next_inst.SUBOP10 == 16)) // bclrx
|
||||||
{
|
{
|
||||||
|
@ -403,7 +403,7 @@ void Jit64::cmpXX(UGeckoInstruction inst)
|
||||||
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
AND(32, R(EAX), Imm32(0xFFFFFFFC));
|
||||||
if (js.next_inst.LK)
|
if (js.next_inst.LK)
|
||||||
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
MOV(32, M(&LR), Imm32(js.compilerPC + 4));
|
||||||
WriteExitDestInEAX(0);
|
WriteExitDestInEAX();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -104,14 +104,11 @@ void Jit64::mfspr(UGeckoInstruction inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
|
||||||
// Don't interpret this, if we do we get thrown out
|
|
||||||
// --------------
|
|
||||||
void Jit64::mtmsr(UGeckoInstruction inst)
|
void Jit64::mtmsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
INSTRUCTION_START
|
INSTRUCTION_START
|
||||||
JITDISABLE(SystemRegisters)
|
// Don't interpret this, if we do we get thrown out
|
||||||
|
//JITDISABLE(SystemRegisters)
|
||||||
if (!gpr.R(inst.RS).IsImm())
|
if (!gpr.R(inst.RS).IsImm())
|
||||||
{
|
{
|
||||||
gpr.Lock(inst.RS);
|
gpr.Lock(inst.RS);
|
||||||
|
@ -123,8 +120,6 @@ void Jit64::mtmsr(UGeckoInstruction inst)
|
||||||
fpr.Flush(FLUSH_ALL);
|
fpr.Flush(FLUSH_ALL);
|
||||||
WriteExit(js.compilerPC + 4, 0);
|
WriteExit(js.compilerPC + 4, 0);
|
||||||
}
|
}
|
||||||
// ==============
|
|
||||||
|
|
||||||
|
|
||||||
void Jit64::mfmsr(UGeckoInstruction inst)
|
void Jit64::mfmsr(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
|
|
|
@ -717,7 +717,7 @@ static void regWriteExit(RegInfo& RI, InstLoc dest) {
|
||||||
if (isImm(*dest)) {
|
if (isImm(*dest)) {
|
||||||
RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++);
|
RI.Jit->WriteExit(RI.Build->GetImmValue(dest), RI.exitNumber++);
|
||||||
} else {
|
} else {
|
||||||
RI.Jit->WriteExitDestInOpArg(regLocForInst(RI, dest), RI.exitNumber++);
|
RI.Jit->WriteExitDestInOpArg(regLocForInst(RI, dest));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1831,7 +1831,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
||||||
}
|
}
|
||||||
case InterpreterBranch: {
|
case InterpreterBranch: {
|
||||||
Jit->MOV(32, R(EAX), M(&NPC));
|
Jit->MOV(32, R(EAX), M(&NPC));
|
||||||
Jit->WriteExitDestInOpArg(R(EAX), 0);
|
Jit->WriteExitDestInOpArg(R(EAX));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RFIExit: {
|
case RFIExit: {
|
||||||
|
@ -1848,7 +1848,10 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak
|
||||||
Jit->MOV(32, M(&MSR), R(EAX));
|
Jit->MOV(32, M(&MSR), R(EAX));
|
||||||
// NPC = SRR0;
|
// NPC = SRR0;
|
||||||
Jit->MOV(32, R(EAX), M(&SRR0));
|
Jit->MOV(32, R(EAX), M(&SRR0));
|
||||||
Jit->WriteRfiExitDestInOpArg(R(EAX));
|
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bAlternateRFI)
|
||||||
|
Jit->WriteExitDestInOpArg(R(EAX));
|
||||||
|
else
|
||||||
|
Jit->WriteRfiExitDestInOpArg(R(EAX));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FPExceptionCheckStart: {
|
case FPExceptionCheckStart: {
|
||||||
|
|
|
@ -246,7 +246,7 @@ void JitIL::HLEFunction(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex);
|
||||||
MOV(32, R(EAX), M(&NPC));
|
MOV(32, R(EAX), M(&NPC));
|
||||||
WriteExitDestInOpArg(R(EAX), 0);
|
WriteExitDestInOpArg(R(EAX));
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::DoNothing(UGeckoInstruction _inst)
|
void JitIL::DoNothing(UGeckoInstruction _inst)
|
||||||
|
@ -314,7 +314,7 @@ void JitIL::WriteExit(u32 destination, int exit_num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg, int exit_num)
|
void JitIL::WriteExitDestInOpArg(const Gen::OpArg& arg)
|
||||||
{
|
{
|
||||||
MOV(32, M(&PC), arg);
|
MOV(32, M(&PC), arg);
|
||||||
Cleanup();
|
Cleanup();
|
||||||
|
|
|
@ -110,7 +110,7 @@ public:
|
||||||
// Utilities for use by opcodes
|
// Utilities for use by opcodes
|
||||||
|
|
||||||
void WriteExit(u32 destination, int exit_num);
|
void WriteExit(u32 destination, int exit_num);
|
||||||
void WriteExitDestInOpArg(const Gen::OpArg& arg, int exit_num);
|
void WriteExitDestInOpArg(const Gen::OpArg& arg);
|
||||||
void WriteExceptionExit();
|
void WriteExceptionExit();
|
||||||
void WriteRfiExitDestInOpArg(const Gen::OpArg& arg);
|
void WriteRfiExitDestInOpArg(const Gen::OpArg& arg);
|
||||||
void WriteCallInterpreter(UGeckoInstruction _inst);
|
void WriteCallInterpreter(UGeckoInstruction _inst);
|
||||||
|
|
|
@ -106,9 +106,9 @@ bool BootCore(const std::string& _rFilename)
|
||||||
game_ini.Get("Core", "CPUThread", &StartUp.bCPUThread, StartUp.bCPUThread);
|
game_ini.Get("Core", "CPUThread", &StartUp.bCPUThread, StartUp.bCPUThread);
|
||||||
game_ini.Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
|
game_ini.Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
|
||||||
game_ini.Get("Core", "EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF);
|
game_ini.Get("Core", "EnableFPRF", &StartUp.bEnableFPRF, StartUp.bEnableFPRF);
|
||||||
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
|
||||||
game_ini.Get("Core", "MMU", &StartUp.bMMU, StartUp.bMMU);
|
game_ini.Get("Core", "MMU", &StartUp.bMMU, StartUp.bMMU);
|
||||||
game_ini.Get("Core", "SMC", &StartUp.bSMC, StartUp.bSMC);
|
game_ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
||||||
|
game_ini.Get("Core", "AlternateRFI", &StartUp.bAlternateRFI, StartUp.bAlternateRFI);
|
||||||
// Wii settings
|
// Wii settings
|
||||||
if (StartUp.bWii)
|
if (StartUp.bWii)
|
||||||
{
|
{
|
||||||
|
|
|
@ -291,8 +291,11 @@ void CISOProperties::CreateGUIControls(bool IsWad)
|
||||||
CPUThread = new wxCheckBox(m_GameConfig, ID_USEDUALCORE, _("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
CPUThread = new wxCheckBox(m_GameConfig, ID_USEDUALCORE, _("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||||
SkipIdle = new wxCheckBox(m_GameConfig, ID_IDLESKIP, _("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
SkipIdle = new wxCheckBox(m_GameConfig, ID_IDLESKIP, _("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||||
MMU = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable MMU"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
MMU = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable MMU"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||||
|
MMU->SetToolTip(wxT("Enables the Memory Management Unit, needed for some games (slow)."));
|
||||||
TLBHack = new wxCheckBox(m_GameConfig, ID_TLBHACK, _("MMU Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
TLBHack = new wxCheckBox(m_GameConfig, ID_TLBHACK, _("MMU Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||||
SMC = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable self modifying code check"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
TLBHack->SetToolTip(wxT("Fast version of the MMU. Does not work for every game."));
|
||||||
|
AlternateRFI = new wxCheckBox(m_GameConfig, ID_RFI, _("Alternate RFI"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||||
|
AlternateRFI->SetToolTip(wxT("If a game hangs, works only in the Interpreter or Dolphin crashes, this option may fix the game."));
|
||||||
// Wii Console
|
// Wii Console
|
||||||
sbWiiOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Wii Console"));
|
sbWiiOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Wii Console"));
|
||||||
EnableProgressiveScan = new wxCheckBox(m_GameConfig, ID_ENABLEPROGRESSIVESCAN, _("Enable Progressive Scan"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
EnableProgressiveScan = new wxCheckBox(m_GameConfig, ID_ENABLEPROGRESSIVESCAN, _("Enable Progressive Scan"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
|
||||||
|
@ -352,7 +355,7 @@ void CISOProperties::CreateGUIControls(bool IsWad)
|
||||||
sbCoreOverrides->Add(SkipIdle, 0, wxEXPAND|wxLEFT, 5);
|
sbCoreOverrides->Add(SkipIdle, 0, wxEXPAND|wxLEFT, 5);
|
||||||
sbCoreOverrides->Add(MMU, 0, wxEXPAND|wxLEFT, 5);
|
sbCoreOverrides->Add(MMU, 0, wxEXPAND|wxLEFT, 5);
|
||||||
sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5);
|
sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5);
|
||||||
sbCoreOverrides->Add(SMC, 0, wxEXPAND|wxLEFT, 5);
|
sbCoreOverrides->Add(AlternateRFI, 0, wxEXPAND|wxLEFT, 5);
|
||||||
sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5);
|
sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5);
|
||||||
sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5);
|
sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5);
|
||||||
sbVideoOverrides->Add(ForceFiltering, 0, wxEXPAND|wxLEFT, 5);
|
sbVideoOverrides->Add(ForceFiltering, 0, wxEXPAND|wxLEFT, 5);
|
||||||
|
@ -826,10 +829,10 @@ void CISOProperties::LoadGameConfig()
|
||||||
else
|
else
|
||||||
TLBHack->Set3StateValue(wxCHK_UNDETERMINED);
|
TLBHack->Set3StateValue(wxCHK_UNDETERMINED);
|
||||||
|
|
||||||
if (GameIni.Get("Core", "SMC", &bTemp))
|
if (GameIni.Get("Core", "AlternateRFI", &bTemp))
|
||||||
SMC->Set3StateValue((wxCheckBoxState)bTemp);
|
AlternateRFI->Set3StateValue((wxCheckBoxState)bTemp);
|
||||||
else
|
else
|
||||||
SMC->Set3StateValue(wxCHK_UNDETERMINED);
|
AlternateRFI->Set3StateValue(wxCHK_UNDETERMINED);
|
||||||
|
|
||||||
if (GameIni.Get("Wii", "ProgressiveScan", &bTemp))
|
if (GameIni.Get("Wii", "ProgressiveScan", &bTemp))
|
||||||
EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp);
|
EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp);
|
||||||
|
@ -922,10 +925,10 @@ bool CISOProperties::SaveGameConfig()
|
||||||
else
|
else
|
||||||
GameIni.Set("Core", "TLBHack", TLBHack->Get3StateValue());
|
GameIni.Set("Core", "TLBHack", TLBHack->Get3StateValue());
|
||||||
|
|
||||||
if (SMC->Get3StateValue() == wxCHK_UNDETERMINED)
|
if (AlternateRFI->Get3StateValue() == wxCHK_UNDETERMINED)
|
||||||
GameIni.DeleteKey("Core", "SMC");
|
GameIni.DeleteKey("Core", "AlternateRFI");
|
||||||
else
|
else
|
||||||
GameIni.Set("Core", "SMC", SMC->Get3StateValue());
|
GameIni.Set("Core", "AlternateRFI", AlternateRFI->Get3StateValue());
|
||||||
|
|
||||||
if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED)
|
if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED)
|
||||||
GameIni.DeleteKey("Wii", "ProgressiveScan");
|
GameIni.DeleteKey("Wii", "ProgressiveScan");
|
||||||
|
|
|
@ -84,7 +84,7 @@ class CISOProperties : public wxDialog
|
||||||
|
|
||||||
wxStaticText *OverrideText;
|
wxStaticText *OverrideText;
|
||||||
// Core
|
// Core
|
||||||
wxCheckBox *CPUThread, *SkipIdle, *MMU, *SMC, *TLBHack;
|
wxCheckBox *CPUThread, *SkipIdle, *MMU, *AlternateRFI, *TLBHack;
|
||||||
// Wii
|
// Wii
|
||||||
wxCheckBox *EnableProgressiveScan, *EnableWideScreen;
|
wxCheckBox *EnableProgressiveScan, *EnableWideScreen;
|
||||||
// Video
|
// Video
|
||||||
|
@ -166,7 +166,7 @@ class CISOProperties : public wxDialog
|
||||||
ID_IDLESKIP,
|
ID_IDLESKIP,
|
||||||
ID_MMU,
|
ID_MMU,
|
||||||
ID_TLBHACK,
|
ID_TLBHACK,
|
||||||
ID_SMC,
|
ID_RFI,
|
||||||
ID_FORCEFILTERING,
|
ID_FORCEFILTERING,
|
||||||
ID_EFBCOPYDISABLE,
|
ID_EFBCOPYDISABLE,
|
||||||
ID_EFBTOTEXTUREENABLE,
|
ID_EFBTOTEXTUREENABLE,
|
||||||
|
|
Loading…
Reference in New Issue