mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-17 07:31:01 +00:00
Add "slightly faster interpreter", optimizing the most common instrs. Not as helpful as I thought it would be on Android, really need a proper JIT.
This commit is contained in:
parent
f3aeadedfa
commit
a97f66766d
@ -45,11 +45,13 @@ void CConfig::Load(const char *iniFileName)
|
||||
general->Get("FirstRun", &bFirstRun, true);
|
||||
general->Get("AutoLoadLast", &bAutoLoadLast, false);
|
||||
general->Get("AutoRun", &bAutoRun, false);
|
||||
general->Get("Jit", &bJIT, false);
|
||||
general->Get("ConfirmOnQuit", &bConfirmOnQuit, false);
|
||||
general->Get("IgnoreBadMemAccess", &bIgnoreBadMemAccess, true);
|
||||
general->Get("CurrentDirectory", ¤tDirectory, "");
|
||||
|
||||
IniFile::Section *cpu = iniFile.GetOrCreateSection("CPU");
|
||||
cpu->Get("Core", &iCpuCore, 0);
|
||||
|
||||
IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics");
|
||||
graphics->Get("ShowFPSCounter", &bShowFPSCounter, false);
|
||||
graphics->Get("DisplayFramebuffer", &bDisplayFramebuffer, false);
|
||||
@ -74,11 +76,13 @@ void CConfig::Save()
|
||||
general->Set("FirstRun", bFirstRun);
|
||||
general->Set("AutoLoadLast", bAutoLoadLast);
|
||||
general->Set("AutoRun", bAutoRun);
|
||||
general->Set("Jit", bJIT);
|
||||
general->Set("ConfirmOnQuit", bConfirmOnQuit);
|
||||
general->Set("IgnoreBadMemAccess", bIgnoreBadMemAccess);
|
||||
general->Set("CurrentDirectory", currentDirectory);
|
||||
|
||||
IniFile::Section *cpu = iniFile.GetOrCreateSection("CPU");
|
||||
cpu->Set("Core", iCpuCore);
|
||||
|
||||
IniFile::Section *graphics = iniFile.GetOrCreateSection("Graphics");
|
||||
graphics->Set("ShowFPSCounter", bShowFPSCounter);
|
||||
graphics->Set("DisplayFramebuffer", bDisplayFramebuffer);
|
||||
|
@ -39,7 +39,6 @@ public:
|
||||
bool bFirstRun;
|
||||
bool bAutoRun;
|
||||
bool bSpeedLimit;
|
||||
bool bJIT;
|
||||
bool bConfirmOnQuit;
|
||||
bool bIgnoreBadMemAccess;
|
||||
bool bDisplayFramebuffer;
|
||||
@ -49,7 +48,7 @@ public:
|
||||
bool bShowFPSCounter;
|
||||
bool bShowDebugStats;
|
||||
int iWindowZoom; // for Windows
|
||||
|
||||
int iCpuCore;
|
||||
|
||||
std::string currentDirectory;
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
enum CPUCore {
|
||||
CPU_INTERPRETER,
|
||||
CPU_FASTINTERPRETER, // unsafe, a bit faster than INTERPRETER
|
||||
CPU_JIT,
|
||||
};
|
||||
|
||||
@ -31,7 +32,6 @@ enum GPUCore {
|
||||
GPU_SOFTWARE,
|
||||
};
|
||||
|
||||
|
||||
struct CoreParameter
|
||||
{
|
||||
// 0 = Interpreter
|
||||
|
@ -315,7 +315,7 @@ void sceAudioOutput2OutputBlocking()
|
||||
|
||||
u32 sceAudioOutput2ChangeLength(u32 sampleCount)
|
||||
{
|
||||
WARN_LOG(HLE,"sceAudioOutput2ChangeLength(%i)");
|
||||
WARN_LOG(HLE,"sceAudioOutput2ChangeLength(%i)", sampleCount);
|
||||
chans[0].sampleCount = sampleCount;
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include "MIPSDebugInterface.h"
|
||||
#include "MIPSVFPUUtils.h"
|
||||
#include "../System.h"
|
||||
#include "../Debugger/Breakpoints.h"
|
||||
#include "../HLE/sceDisplay.h"
|
||||
|
||||
#if defined(ANDROID) || defined(BLACKBERRY)
|
||||
@ -42,6 +41,7 @@ MIPSDebugInterface *currentDebugMIPS = &debugr4k;
|
||||
MIPSState::MIPSState()
|
||||
{
|
||||
cpuType = CPUTYPE_ALLEGREX;
|
||||
MIPSComp::jit = 0;
|
||||
}
|
||||
|
||||
MIPSState::~MIPSState()
|
||||
@ -109,85 +109,18 @@ void MIPSState::SingleStep()
|
||||
// returns 1 if reached ticks limit
|
||||
int MIPSState::RunLoopUntil(u64 globalTicks)
|
||||
{
|
||||
if (PSP_CoreParameter().cpuCore == CPU_JIT)
|
||||
switch (PSP_CoreParameter().cpuCore)
|
||||
{
|
||||
case CPU_JIT:
|
||||
MIPSComp::jit->RunLoopUntil(globalTicks);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
|
||||
case CPU_FASTINTERPRETER: // For jit-less platforms. Crashier than INTERPRETER.
|
||||
return MIPSInterpret_RunFastUntil(globalTicks);
|
||||
|
||||
case CPU_INTERPRETER:
|
||||
// INFO_LOG(CPU, "Entering run loop for %i ticks, pc=%08x", (int)globalTicks, mipsr4k.pc);
|
||||
while (coreState == CORE_RUNNING)
|
||||
{
|
||||
// NEVER stop in a delay slot!
|
||||
while (CoreTiming::downcount >= 0 && coreState == CORE_RUNNING)
|
||||
{
|
||||
// int cycles = 0;
|
||||
{
|
||||
again:
|
||||
u32 op = Memory::ReadUnchecked_U32(mipsr4k.pc);
|
||||
//u32 op = Memory::Read_Opcode_JIT(mipsr4k.pc);
|
||||
/*
|
||||
// Choke on VFPU
|
||||
u32 info = MIPSGetInfo(op);
|
||||
if (info & IS_VFPU)
|
||||
{
|
||||
if (!Core_IsStepping() && !GetAsyncKeyState(VK_LSHIFT))
|
||||
{
|
||||
Core_EnableStepping(true);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
//2: check for breakpoint (VERY SLOW)
|
||||
#if defined(_DEBUG)
|
||||
if (CBreakPoints::IsAddressBreakPoint(pc))
|
||||
{
|
||||
Core_EnableStepping(true);
|
||||
if (CBreakPoints::IsTempBreakPoint(pc))
|
||||
CBreakPoints::RemoveBreakPoint(pc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (inDelaySlot)
|
||||
{
|
||||
MIPSInterpret(op);
|
||||
if (inDelaySlot)
|
||||
{
|
||||
pc = nextPC;
|
||||
inDelaySlot = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MIPSInterpret(op);
|
||||
}
|
||||
|
||||
/*
|
||||
if (!Memory::IsValidAddress(pc))
|
||||
{
|
||||
pc = pc;
|
||||
}
|
||||
if (r[MIPS_REG_RA] != 0 && !Memory::IsValidAddress(r[MIPS_REG_RA]))
|
||||
{
|
||||
// pc = pc;
|
||||
}*/
|
||||
if (inDelaySlot)
|
||||
{
|
||||
CoreTiming::downcount -= 1;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
CoreTiming::downcount -= 1;
|
||||
if (CoreTiming::GetTicks() > globalTicks)
|
||||
{
|
||||
// DEBUG_LOG(CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
CoreTiming::Advance();
|
||||
}
|
||||
return MIPSInterpret_RunUntil(globalTicks);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ float round_ieee_754(float d) {
|
||||
return i + 1.0f;
|
||||
}
|
||||
|
||||
void DelayBranchTo(u32 where)
|
||||
static inline void DelayBranchTo(u32 where)
|
||||
{
|
||||
PC += 4;
|
||||
mipsr4k.nextPC = where;
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "MIPSInt.h"
|
||||
#include "MIPSIntVFPU.h"
|
||||
#include "MIPSCodeUtils.h"
|
||||
#include "../../Core/CoreTiming.h"
|
||||
#include "../Debugger/Breakpoints.h"
|
||||
|
||||
#if defined(ANDROID) || defined(BLACKBERRY)
|
||||
#include "ARM/Jit.h"
|
||||
@ -939,44 +941,197 @@ void MIPSInterpret(u32 op) //only for those rare ones
|
||||
#define _RS ((op>>21) & 0x1F)
|
||||
#define _RT ((op>>16) & 0x1F)
|
||||
#define _RD ((op>>11) & 0x1F)
|
||||
#define R(i) (currentMIPS->r[i])
|
||||
#define R(i) (curMips->r[i])
|
||||
|
||||
void MIPSInterpret_Fast(u32 op)
|
||||
|
||||
int MIPSInterpret_RunUntil(u64 globalTicks)
|
||||
{
|
||||
switch (op >> 29)
|
||||
MIPSState *curMips = currentMIPS;
|
||||
while (coreState == CORE_RUNNING)
|
||||
{
|
||||
case 0x1:
|
||||
// NEVER stop in a delay slot!
|
||||
while (CoreTiming::downcount >= 0 && coreState == CORE_RUNNING)
|
||||
{
|
||||
s32 simm = (s32)(s16)(op & 0xFFFF);
|
||||
u32 uimm = (u32)(u16)(op & 0xFFFF);
|
||||
u32 suimm = (u32)simm;
|
||||
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
|
||||
if (rt == 0) //destination register is zero register
|
||||
return; //nop
|
||||
|
||||
switch (op>>26)
|
||||
// int cycles = 0;
|
||||
{
|
||||
case 8: R(rt) = R(rs) + simm; break; //addi
|
||||
case 9: R(rt) = R(rs) + simm; break; //addiu
|
||||
case 10: R(rt) = (s32)R(rs) < simm; break; //slti
|
||||
case 11: R(rt) = R(rs) < suimm; break; //sltiu
|
||||
case 12: R(rt) = R(rs) & uimm; break; //andi
|
||||
case 13: R(rt) = R(rs) | uimm; break; //ori
|
||||
case 14: R(rt) = R(rs) ^ uimm; break; //xori
|
||||
case 15: R(rt) = uimm << 16; break; //lui
|
||||
default:
|
||||
break;
|
||||
}
|
||||
currentMIPS->pc += 4;
|
||||
}
|
||||
break;
|
||||
again:
|
||||
u32 op = Memory::ReadUnchecked_U32(curMips->pc);
|
||||
//u32 op = Memory::Read_Opcode_JIT(mipsr4k.pc);
|
||||
/*
|
||||
// Choke on VFPU
|
||||
u32 info = MIPSGetInfo(op);
|
||||
if (info & IS_VFPU)
|
||||
{
|
||||
if (!Core_IsStepping() && !GetAsyncKeyState(VK_LSHIFT))
|
||||
{
|
||||
Core_EnableStepping(true);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
default:
|
||||
MIPSInterpret(op);
|
||||
//2: check for breakpoint (VERY SLOW)
|
||||
#if defined(_DEBUG)
|
||||
if (CBreakPoints::IsAddressBreakPoint(curMips->pc))
|
||||
{
|
||||
Core_EnableStepping(true);
|
||||
if (CBreakPoints::IsTempBreakPoint(curMips->pc))
|
||||
CBreakPoints::RemoveBreakPoint(curMips->pc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool wasInDelaySlot = curMips->inDelaySlot;
|
||||
|
||||
MIPSInterpret(op);
|
||||
|
||||
if (curMips->inDelaySlot)
|
||||
{
|
||||
// The reason we have to check this is the delay slot hack in Int_Syscall.
|
||||
if (wasInDelaySlot)
|
||||
{
|
||||
curMips->pc = curMips->nextPC;
|
||||
curMips->inDelaySlot = false;
|
||||
}
|
||||
CoreTiming::downcount -= 1;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
if (CoreTiming::GetTicks() > globalTicks)
|
||||
{
|
||||
// DEBUG_LOG(CPU, "Hit the max ticks, bailing 1 : %llu, %llu", globalTicks, CoreTiming::GetTicks());
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
CoreTiming::Advance();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline void DelayBranchTo(MIPSState *curMips, u32 where)
|
||||
{
|
||||
curMips->pc += 4;
|
||||
curMips->nextPC = where;
|
||||
curMips->inDelaySlot = true;
|
||||
}
|
||||
|
||||
// Optimized interpreter loop that shortcuts the most common instructions.
|
||||
// For slow platforms without JITs.
|
||||
#define SIMM16 (s32)(s16)(op & 0xFFFF)
|
||||
#define UIMM16 (u32)(u16)(op & 0xFFFF)
|
||||
#define SUIMM16 (u32)(s32)(s16)(op & 0xFFFF)
|
||||
int MIPSInterpret_RunFastUntil(u64 globalTicks)
|
||||
{
|
||||
MIPSState *curMips = currentMIPS;
|
||||
while (coreState == CORE_RUNNING)
|
||||
{
|
||||
while (CoreTiming::downcount >= 0 && coreState == CORE_RUNNING) // TODO: Try to get rid of the latter check
|
||||
{
|
||||
again:
|
||||
bool wasInDelaySlot = curMips->inDelaySlot;
|
||||
u32 op = Memory::ReadUnchecked_U32(curMips->pc);
|
||||
switch (op >> 29)
|
||||
{
|
||||
case 0x0:
|
||||
{
|
||||
int imm = (s16)(op&0xFFFF) << 2;
|
||||
int rs = _RS;
|
||||
int rt = _RT;
|
||||
u32 addr = curMips->pc + imm + 4;
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 4: if (R(rt) == R(rs)) DelayBranchTo(curMips, addr); else curMips->pc += 4; break; //beq
|
||||
case 5: if (R(rt) != R(rs)) DelayBranchTo(curMips, addr); else curMips->pc += 4; break; //bne
|
||||
case 6: if ((s32)R(rs) <= 0) DelayBranchTo(curMips, addr); else curMips->pc += 4; break; //blez
|
||||
case 7: if ((s32)R(rs) > 0) DelayBranchTo(curMips, addr); else curMips->pc += 4; break; //bgtz
|
||||
default:
|
||||
goto interpret;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
{
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 8: R(rt) = R(rs) + SIMM16; break; //addi
|
||||
case 9: R(rt) = R(rs) + SIMM16; break; //addiu
|
||||
case 10: R(rt) = (s32)R(rs) < SIMM16; break; //slti
|
||||
case 11: R(rt) = R(rs) < SUIMM16; break; //sltiu
|
||||
case 12: R(rt) = R(rs) & UIMM16; break; //andi
|
||||
case 13: R(rt) = R(rs) | UIMM16; break; //ori
|
||||
case 14: R(rt) = R(rs) ^ UIMM16; break; //xori
|
||||
case 15: R(rt) = UIMM16 << 16; break; //lui
|
||||
default:
|
||||
goto interpret;
|
||||
}
|
||||
currentMIPS->pc += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
{
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
int imm = (s16)(op & 0xFFFF);
|
||||
u32 addr = R(rs) + imm;
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 32: R(rt) = (u32)(s32)(s8) Memory::ReadUnchecked_U8(addr); break; //lb
|
||||
case 33: R(rt) = (u32)(s32)(s16)Memory::ReadUnchecked_U16(addr); break; //lh
|
||||
case 35: R(rt) = Memory::ReadUnchecked_U32(addr); break; //lw
|
||||
case 36: R(rt) = Memory::ReadUnchecked_U8(addr); break; //lbu
|
||||
case 37: R(rt) = Memory::ReadUnchecked_U16(addr); break; //lhu
|
||||
default:
|
||||
goto interpret;
|
||||
}
|
||||
currentMIPS->pc += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
{
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
int imm = (s16)(op & 0xFFFF);
|
||||
u32 addr = R(rs) + imm;
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 40: Memory::WriteUnchecked_U8(R(rt), addr); break; //sb
|
||||
case 41: Memory::WriteUnchecked_U16(R(rt), addr); break; //sh
|
||||
case 43: Memory::WriteUnchecked_U32(R(rt), addr); break; //sw
|
||||
default:
|
||||
goto interpret;
|
||||
}
|
||||
currentMIPS->pc += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
interpret:
|
||||
MIPSInterpret(op);
|
||||
}
|
||||
|
||||
if (curMips->inDelaySlot)
|
||||
{
|
||||
// The reason we have to check this is the delay slot hack in Int_Syscall.
|
||||
if (wasInDelaySlot)
|
||||
{
|
||||
curMips->pc = curMips->nextPC;
|
||||
curMips->inDelaySlot = false;
|
||||
}
|
||||
CoreTiming::downcount -= 1;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
CoreTiming::Advance();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,6 +56,8 @@ void MIPSCompileOp(u32 op);
|
||||
void MIPSDisAsm(u32 op, u32 pc, char *out);
|
||||
u32 MIPSGetInfo(u32 op);
|
||||
void MIPSInterpret(u32 op); //only for those rare ones
|
||||
int MIPSInterpret_RunFastUntil(u64 globalTicks);
|
||||
int MIPSInterpret_RunUntil(u64 globalTicks);
|
||||
MIPSInterpretFunc MIPSGetInterpretFunc(u32 op);
|
||||
|
||||
int MIPSGetInstructionCycleEstimate(u32 op);
|
||||
|
@ -34,7 +34,7 @@
|
||||
// If safe memory is enabled and JIT is disabled, all memory access will go through the proper
|
||||
// memory access functions, and thus won't crash the emu when they go out of bounds.
|
||||
#if defined(_DEBUG)
|
||||
#define SAFE_MEMORY
|
||||
//#define SAFE_MEMORY
|
||||
#endif
|
||||
|
||||
|
||||
@ -114,13 +114,6 @@ void DoState(PointerWrap &p);
|
||||
void Clear();
|
||||
bool AreMemoryBreakpointsActivated();
|
||||
|
||||
// ONLY for use by GUI
|
||||
u8 ReadUnchecked_U8(const u32 _Address);
|
||||
u16 ReadUnchecked_U16(const u32 _Address);
|
||||
|
||||
void WriteUnchecked_U8(const u8 _Data, const u32 _Address);
|
||||
void WriteUnchecked_U32(const u32 _Data, const u32 _Address);
|
||||
|
||||
inline u8* GetMainRAMPtr() {return m_pRAM;}
|
||||
|
||||
// used by interpreter to read instructions, uses iCache
|
||||
@ -146,19 +139,69 @@ u16 Read_U16(const u32 _Address);
|
||||
u32 Read_U32(const u32 _Address);
|
||||
u64 Read_U64(const u32 _Address);
|
||||
|
||||
#if (defined(ARM) || defined(_ARM)) && !defined(_M_ARM)
|
||||
#define _M_ARM
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SAFE_MEMORY
|
||||
u32 ReadUnchecked_U32(const u32 _Address);
|
||||
// ONLY for use by GUI and fast interpreter
|
||||
u8 ReadUnchecked_U8(const u32 _Address);
|
||||
u16 ReadUnchecked_U16(const u32 _Address);
|
||||
void WriteUnchecked_U8(const u8 _Data, const u32 _Address);
|
||||
void WriteUnchecked_U16(const u16 _Data, const u32 _Address);
|
||||
void WriteUnchecked_U32(const u32 _Data, const u32 _Address);
|
||||
#else
|
||||
inline u32 ReadUnchecked_U32(const u32 _Address) {
|
||||
|
||||
inline u32 ReadUnchecked_U32(const u32 address) {
|
||||
#if defined(_M_IX86) || defined(_M_ARM32)
|
||||
return (*(u32 *)(base + (_Address & MEMVIEW32_MASK))); // ReadUnchecked_U32(_Address);
|
||||
#elif defined(_M_X64)
|
||||
return (*(u32 *)(base + _Address));
|
||||
return (*(u32 *)(base + (address & MEMVIEW32_MASK)));
|
||||
#else
|
||||
return (*(u32 *)(base + _Address));
|
||||
return (*(u32 *)(base + address));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u16 ReadUnchecked_U16(const u32 address) {
|
||||
#if defined(_M_IX86) || defined(_M_ARM32)
|
||||
return (*(u16 *)(base + (address & MEMVIEW32_MASK)));
|
||||
#else
|
||||
return (*(u16 *)(base + address));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline u8 ReadUnchecked_U8(const u32 address) {
|
||||
#if defined(_M_IX86) || defined(_M_ARM32)
|
||||
return (*(u8 *)(base + (address & MEMVIEW32_MASK)));
|
||||
#else
|
||||
return (*(u8 *)(base + address));
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void WriteUnchecked_U32(u32 data, u32 address) {
|
||||
#if defined(_M_IX86) || defined(_M_ARM32)
|
||||
(*(u32 *)(base + (address & MEMVIEW32_MASK))) = data;
|
||||
#else
|
||||
(*(u32 *)(base + address)) = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void WriteUnchecked_U16(u16 data, u32 address) {
|
||||
#if defined(_M_IX86) || defined(_M_ARM32)
|
||||
(*(u16 *)(base + (address & MEMVIEW32_MASK))) = data;
|
||||
#else
|
||||
(*(u16 *)(base + address)) = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void WriteUnchecked_U8(u8 data, u32 address) {
|
||||
#if defined(_M_IX86) || defined(_M_ARM32)
|
||||
(*(u8 *)(base + (address & MEMVIEW32_MASK))) = data;
|
||||
#else
|
||||
(*(u8 *)(base + address)) = data;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -275,6 +275,8 @@ void Write_U64(const u64 _Data, const u32 _Address)
|
||||
WriteToHardware<u64>(_Address, _Data);
|
||||
}
|
||||
|
||||
#ifdef SAFE_MEMORY
|
||||
|
||||
u8 ReadUnchecked_U8(const u32 _Address)
|
||||
{
|
||||
u8 _var = 0;
|
||||
@ -289,8 +291,6 @@ u16 ReadUnchecked_U16(const u32 _Address)
|
||||
return _var;
|
||||
}
|
||||
|
||||
#ifdef SAFE_MEMORY
|
||||
|
||||
u32 ReadUnchecked_U32(const u32 _Address)
|
||||
{
|
||||
u32 _var = 0;
|
||||
@ -298,16 +298,21 @@ u32 ReadUnchecked_U32(const u32 _Address)
|
||||
return _var;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void WriteUnchecked_U8(const u8 _iValue, const u32 _Address)
|
||||
{
|
||||
WriteToHardware<u8>(_Address, _iValue);
|
||||
}
|
||||
|
||||
void WriteUnchecked_U8(const u16 _iValue, const u32 _Address)
|
||||
{
|
||||
WriteToHardware<u16>(_Address, _iValue);
|
||||
}
|
||||
|
||||
void WriteUnchecked_U32(const u32 _iValue, const u32 _Address)
|
||||
{
|
||||
WriteToHardware<u32>(_Address, _iValue);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace Memory
|
||||
|
@ -67,7 +67,7 @@ DWORD TheThread(LPVOID x)
|
||||
coreParameter.fileToStart = fileToStart;
|
||||
coreParameter.enableSound = true;
|
||||
coreParameter.gpuCore = GPU_GLES;
|
||||
coreParameter.cpuCore = g_Config.bJIT ? CPU_JIT : CPU_INTERPRETER;
|
||||
coreParameter.cpuCore = (CPUCore)g_Config.iCpuCore;
|
||||
coreParameter.enableDebugging = true;
|
||||
coreParameter.printfEmuLog = false;
|
||||
coreParameter.headLess = false;
|
||||
|
@ -147,7 +147,7 @@ namespace MainWindow
|
||||
info.cyMax = 0;
|
||||
info.dwStyle = MNS_CHECKORBMP;
|
||||
info.fMask = MIM_STYLE;
|
||||
for (int i=0; i<GetMenuItemCount(menu); i++)
|
||||
for (int i = 0; i < GetMenuItemCount(menu); i++)
|
||||
{
|
||||
SetMenuInfo(GetSubMenu(menu,i),&info);
|
||||
}
|
||||
@ -350,11 +350,15 @@ namespace MainWindow
|
||||
//CPU menu
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
case ID_CPU_DYNAREC:
|
||||
g_Config.bJIT = true;
|
||||
g_Config.iCpuCore = CPU_JIT;
|
||||
UpdateMenus();
|
||||
break;
|
||||
case ID_CPU_INTERPRETER:
|
||||
g_Config.bJIT = false;
|
||||
g_Config.iCpuCore = CPU_INTERPRETER;
|
||||
UpdateMenus();
|
||||
break;
|
||||
case ID_CPU_FASTINTERPRETER:
|
||||
g_Config.iCpuCore = CPU_FASTINTERPRETER;
|
||||
UpdateMenus();
|
||||
break;
|
||||
|
||||
@ -597,9 +601,11 @@ namespace MainWindow
|
||||
// CHECK(ID_OPTIONS_EMULATESYSCALL,g_bEmulateSyscall);
|
||||
CHECKITEM(ID_OPTIONS_DISPLAYRAWFRAMEBUFFER, g_Config.bDisplayFramebuffer);
|
||||
CHECKITEM(ID_OPTIONS_IGNOREILLEGALREADS,g_Config.bIgnoreBadMemAccess);
|
||||
CHECKITEM(ID_CPU_INTERPRETER,!g_Config.bJIT);
|
||||
CHECKITEM(ID_CPU_DYNAREC,g_Config.bJIT);
|
||||
CHECKITEM(ID_CPU_INTERPRETER,g_Config.iCpuCore == CPU_INTERPRETER);
|
||||
CHECKITEM(ID_CPU_FASTINTERPRETER,g_Config.iCpuCore == CPU_FASTINTERPRETER);
|
||||
CHECKITEM(ID_CPU_DYNAREC,g_Config.iCpuCore == CPU_JIT);
|
||||
CHECKITEM(ID_OPTIONS_BUFFEREDRENDERING, g_Config.bBufferedRendering);
|
||||
|
||||
BOOL enable = !Core_IsStepping();
|
||||
EnableMenuItem(menu,ID_EMULATION_RUN,enable);
|
||||
EnableMenuItem(menu,ID_EMULATION_PAUSE,!enable);
|
||||
@ -610,6 +616,7 @@ namespace MainWindow
|
||||
//EnableMenuItem(menu,ID_FILE_LOAD_ELF,enable);
|
||||
EnableMenuItem(menu,ID_CPU_DYNAREC,enable);
|
||||
EnableMenuItem(menu,ID_CPU_INTERPRETER,enable);
|
||||
EnableMenuItem(menu,ID_CPU_FASTINTERPRETER,enable);
|
||||
EnableMenuItem(menu,ID_DVD_INSERTISO,enable);
|
||||
EnableMenuItem(menu,ID_FILE_BOOTBIOS,enable);
|
||||
EnableMenuItem(menu,ID_EMULATION_STOP,!enable);
|
||||
|
@ -197,6 +197,7 @@ BEGIN
|
||||
MENUITEM "R&eset", ID_EMULATION_RESET
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Interpreter", ID_CPU_INTERPRETER
|
||||
MENUITEM "&Slightly faster interpreter", ID_CPU_FASTINTERPRETER
|
||||
MENUITEM "&Dynarec", ID_CPU_DYNAREC, CHECKED
|
||||
END
|
||||
POPUP "Debu&g"
|
||||
|
@ -239,13 +239,16 @@
|
||||
#define ID_OPTIONS_SCREEN4X 40116
|
||||
#define ID_OPTIONS_SCREEN2X 40117
|
||||
#define ID_OPTIONS_BUFFEREDRENDERING 40118
|
||||
#define ID_EMULATION_FAST 40119
|
||||
#define ID_EMULATION_FASTINTERPRETER 40120
|
||||
#define ID_CPU_FASTINTERPRETER 40121
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 232
|
||||
#define _APS_NEXT_COMMAND_VALUE 40119
|
||||
#define _APS_NEXT_COMMAND_VALUE 40122
|
||||
#define _APS_NEXT_CONTROL_VALUE 1162
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
@ -48,10 +48,10 @@ EmuScreen::EmuScreen(const std::string &filename) : invalid_(true)
|
||||
INFO_LOG(BOOT, "Starting up hardware.");
|
||||
|
||||
CoreParameter coreParam;
|
||||
coreParam.cpuCore = (CPUCore)g_Config.iCpuCore;
|
||||
#if defined(ANDROID) || defined(BLACKBERRY)
|
||||
coreParam.cpuCore = CPU_INTERPRETER;
|
||||
#else
|
||||
coreParam.cpuCore = g_Config.bJIT ? CPU_JIT : CPU_INTERPRETER;
|
||||
if (coreParam.cpuCore == CPU_JIT)
|
||||
coreParam.cpuCore = CPU_FASTINTERPRETER;
|
||||
#endif
|
||||
coreParam.gpuCore = GPU_GLES;
|
||||
coreParam.enableSound = g_Config.bEnableSound;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "UIShader.h"
|
||||
|
||||
#include "../../Core/Config.h"
|
||||
#include "../../Core/CoreParameter.h"
|
||||
|
||||
#include "MenuScreens.h"
|
||||
#include "EmuScreen.h"
|
||||
@ -241,6 +242,11 @@ void SettingsScreen::render() {
|
||||
UICheckBox(GEN_ID, x, y += 50, "Enable Sound Emulation", ALIGN_TOPLEFT, &g_Config.bEnableSound);
|
||||
UICheckBox(GEN_ID, x, y += 50, "Show Analog Stick", ALIGN_TOPLEFT, &g_Config.bShowAnalogStick);
|
||||
UICheckBox(GEN_ID, x, y += 50, "Buffered Rendering (may fix flicker)", ALIGN_TOPLEFT, &g_Config.bBufferedRendering);
|
||||
|
||||
bool useFastInt = g_Config.iCpuCore == CPU_FASTINTERPRETER;
|
||||
UICheckBox(GEN_ID, x, y += 50, "Slightly faster interpreter (may crash)", ALIGN_TOPLEFT, &useFastInt);
|
||||
ui_draw2d.DrawText(UBUNTU48, "much faster JIT coming later", x += 50, 0xcFFFFFFF, ALIGN_LEFT);
|
||||
g_Config.iCpuCore = useFastInt ? CPU_FASTINTERPRETER : CPU_INTERPRETER;
|
||||
// UICheckBox(GEN_ID, x, y += 50, "Draw raw framebuffer (for some homebrew)", ALIGN_TOPLEFT, &g_Config.bDisplayFramebuffer);
|
||||
|
||||
if (UIButton(GEN_ID, Pos(dp_xres - 10, dp_yres-10), LARGE_BUTTON_WIDTH, "Back", ALIGN_RIGHT | ALIGN_BOTTOM)) {
|
||||
|
@ -80,6 +80,7 @@ int main(int argc, const char* argv[])
|
||||
{
|
||||
bool fullLog = false;
|
||||
bool useJit = false;
|
||||
bool fastInterpreter = false;
|
||||
bool autoCompare = false;
|
||||
|
||||
const char *bootFilename = argc > 1 ? argv[1] : 0;
|
||||
@ -100,6 +101,8 @@ int main(int argc, const char* argv[])
|
||||
fullLog = true;
|
||||
else if (!strcmp(argv[i], "-j"))
|
||||
useJit = true;
|
||||
else if (!strcmp(argv[i], "-f"))
|
||||
fastInterpreter = true;
|
||||
else if (!strcmp(argv[i], "-c"))
|
||||
autoCompare = true;
|
||||
}
|
||||
@ -129,7 +132,7 @@ int main(int argc, const char* argv[])
|
||||
coreParameter.fileToStart = bootFilename;
|
||||
coreParameter.mountIso = mountIso ? mountIso : "";
|
||||
coreParameter.startPaused = false;
|
||||
coreParameter.cpuCore = useJit ? CPU_JIT : CPU_INTERPRETER;
|
||||
coreParameter.cpuCore = useJit ? CPU_JIT : (fastInterpreter ? CPU_FASTINTERPRETER : CPU_INTERPRETER);
|
||||
coreParameter.gpuCore = GPU_NULL;
|
||||
coreParameter.enableSound = false;
|
||||
coreParameter.headLess = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user