Fixed TLB games support for the iCache, games using the TLB Hack should now work as before (fixes issue 1218)
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4492 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
22a0864337
commit
6c0c97cffe
|
@ -50,7 +50,6 @@ may be redirected here (for example to Read_U32()).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Declarations and definitions
|
// Declarations and definitions
|
||||||
// ----------------
|
// ----------------
|
||||||
namespace Memory
|
namespace Memory
|
||||||
|
@ -539,6 +538,7 @@ u32 Read_Opcode_JIT(const u32 _Address)
|
||||||
{
|
{
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
if ((_Address & ~JIT_ICACHE_MASK) != 0x80000000 && (_Address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
if ((_Address & ~JIT_ICACHE_MASK) != 0x80000000 && (_Address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
||||||
|
(_Address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area
|
||||||
(_Address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (_Address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
(_Address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (_Address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
||||||
{
|
{
|
||||||
PanicAlert("iCacheJIT: Reading Opcode from %x. Please report.", _Address);
|
PanicAlert("iCacheJIT: Reading Opcode from %x. Please report.", _Address);
|
||||||
|
@ -546,10 +546,15 @@ u32 Read_Opcode_JIT(const u32 _Address)
|
||||||
}
|
}
|
||||||
u8* iCache;
|
u8* iCache;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
if (_Address & JIT_ICACHE_EXRAM_BIT)
|
if (_Address & JIT_ICACHE_VMEM_BIT)
|
||||||
|
{
|
||||||
|
iCache = jit.GetBlockCache()->GetICacheVMEM();
|
||||||
|
addr = _Address & JIT_ICACHE_MASK;
|
||||||
|
}
|
||||||
|
else if (_Address & JIT_ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
iCache = jit.GetBlockCache()->GetICacheEx();
|
iCache = jit.GetBlockCache()->GetICacheEx();
|
||||||
addr = _Address & JIT_ICACHEEX_MASK;
|
addr = _Address & JIT_ICACHEEX_MASK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -587,6 +592,7 @@ u32 Read_Opcode_JIT_LC(const u32 _Address)
|
||||||
{
|
{
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
if ((_Address & ~JIT_ICACHE_MASK) != 0x80000000 && (_Address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
if ((_Address & ~JIT_ICACHE_MASK) != 0x80000000 && (_Address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
||||||
|
(_Address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area
|
||||||
(_Address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (_Address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
(_Address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (_Address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
||||||
{
|
{
|
||||||
PanicAlert("iCacheJIT: Reading Opcode from %x. Please report.", _Address);
|
PanicAlert("iCacheJIT: Reading Opcode from %x. Please report.", _Address);
|
||||||
|
@ -594,10 +600,15 @@ u32 Read_Opcode_JIT_LC(const u32 _Address)
|
||||||
}
|
}
|
||||||
u8* iCache;
|
u8* iCache;
|
||||||
u32 addr;
|
u32 addr;
|
||||||
if (_Address & JIT_ICACHE_EXRAM_BIT)
|
if (_Address & JIT_ICACHE_VMEM_BIT)
|
||||||
|
{
|
||||||
|
iCache = jit.GetBlockCache()->GetICacheVMEM();
|
||||||
|
addr = _Address & JIT_ICACHE_MASK;
|
||||||
|
}
|
||||||
|
else if (_Address & JIT_ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
iCache = jit.GetBlockCache()->GetICacheEx();
|
iCache = jit.GetBlockCache()->GetICacheEx();
|
||||||
addr = _Address & JIT_ICACHEEX_MASK;
|
addr = _Address & JIT_ICACHEEX_MASK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -624,7 +635,11 @@ u32 Read_Opcode_JIT_LC(const u32 _Address)
|
||||||
void Write_Opcode_JIT(const u32 _Address, const u32 _Value)
|
void Write_Opcode_JIT(const u32 _Address, const u32 _Value)
|
||||||
{
|
{
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
if (_Address & JIT_ICACHE_EXRAM_BIT)
|
if (_Address & JIT_ICACHE_VMEM_BIT)
|
||||||
|
{
|
||||||
|
*(u32*)(jit.GetBlockCache()->GetICacheVMEM() + (_Address & JIT_ICACHE_MASK)) = Common::swap32(_Value);
|
||||||
|
}
|
||||||
|
else if (_Address & JIT_ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
*(u32*)(jit.GetBlockCache()->GetICacheEx() + (_Address & JIT_ICACHEEX_MASK)) = Common::swap32(_Value);
|
*(u32*)(jit.GetBlockCache()->GetICacheEx() + (_Address & JIT_ICACHEEX_MASK)) = Common::swap32(_Value);
|
||||||
}
|
}
|
||||||
|
@ -790,7 +805,7 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// (comment for old implementation) : F|RES: rouge squadron and other games use the TLB ... so this cant work
|
// (comment for old implementation) : F|RES: rogue squadron and other games use the TLB ... so this cant work
|
||||||
|
|
||||||
// fixed implementation:
|
// fixed implementation:
|
||||||
for (u32 i = 0; i < _iLength; i++)
|
for (u32 i = 0; i < _iLength; i++)
|
||||||
|
@ -894,6 +909,10 @@ u8 *GetPointer(const u32 _Address)
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case 0x7E:
|
||||||
|
case 0x7F:
|
||||||
|
return (u8*)(((char*)m_pFakeVMEM) + (_Address & RAM_MASK));
|
||||||
|
|
||||||
case 0xE0:
|
case 0xE0:
|
||||||
if (_Address < (0xE0000000 + L1_CACHE_SIZE))
|
if (_Address < (0xE0000000 + L1_CACHE_SIZE))
|
||||||
return GetCachePtr() + (_Address & L1_CACHE_MASK);
|
return GetCachePtr() + (_Address & L1_CACHE_MASK);
|
||||||
|
|
|
@ -45,6 +45,7 @@ namespace Interpreter
|
||||||
void UpdateSSEState();
|
void UpdateSSEState();
|
||||||
|
|
||||||
// Extremely rare - actually, never seen.
|
// Extremely rare - actually, never seen.
|
||||||
|
// Star Wars : Rogue Leader spams that at some point :|
|
||||||
void Helper_UpdateCR1(double _fValue)
|
void Helper_UpdateCR1(double _fValue)
|
||||||
{
|
{
|
||||||
// Should just update exception flags, not do any compares.
|
// Should just update exception flags, not do any compares.
|
||||||
|
|
|
@ -159,6 +159,8 @@ void AsmRoutineManager::Generate()
|
||||||
SetJumpTarget(needinst);
|
SetJumpTarget(needinst);
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
|
|
||||||
|
TEST(32, R(EAX), Imm32(JIT_ICACHE_VMEM_BIT));
|
||||||
|
FixupBranch vmem = J_CC(CC_NZ);
|
||||||
TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT));
|
TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT));
|
||||||
FixupBranch exram = J_CC(CC_NZ);
|
FixupBranch exram = J_CC(CC_NZ);
|
||||||
|
|
||||||
|
@ -179,9 +181,21 @@ void AsmRoutineManager::Generate()
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RSI), Imm64((u64)jit.GetBlockCache()->GetICacheEx()));
|
MOV(64, R(RSI), Imm64((u64)jit.GetBlockCache()->GetICacheEx()));
|
||||||
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FixupBranch getinst2 = J();
|
||||||
|
SetJumpTarget(vmem);
|
||||||
|
|
||||||
|
AND(32, R(EAX), Imm32(JIT_ICACHE_MASK));
|
||||||
|
#ifdef _M_IX86
|
||||||
|
MOV(32, R(EAX), MDisp(EAX, (u32)jit.GetBlockCache()->GetICacheVMEM()));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RSI), Imm64((u64)jit.GetBlockCache()->GetICacheVMEM()));
|
||||||
|
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
||||||
|
#endif
|
||||||
|
|
||||||
SetJumpTarget(getinst);
|
SetJumpTarget(getinst);
|
||||||
|
SetJumpTarget(getinst2);
|
||||||
#else
|
#else
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
||||||
|
|
|
@ -164,6 +164,8 @@ void AsmRoutineManager::Generate()
|
||||||
SetJumpTarget(needinst);
|
SetJumpTarget(needinst);
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
|
|
||||||
|
TEST(32, R(EAX), Imm32(JIT_ICACHE_VMEM_BIT));
|
||||||
|
FixupBranch vmem = J_CC(CC_NZ);
|
||||||
TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT));
|
TEST(32, R(EAX), Imm32(JIT_ICACHE_EXRAM_BIT));
|
||||||
FixupBranch exram = J_CC(CC_NZ);
|
FixupBranch exram = J_CC(CC_NZ);
|
||||||
|
|
||||||
|
@ -184,9 +186,21 @@ void AsmRoutineManager::Generate()
|
||||||
#else
|
#else
|
||||||
MOV(64, R(RSI), Imm64((u64)jit.GetBlockCache()->GetICacheEx()));
|
MOV(64, R(RSI), Imm64((u64)jit.GetBlockCache()->GetICacheEx()));
|
||||||
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FixupBranch getinst2 = J();
|
||||||
|
SetJumpTarget(vmem);
|
||||||
|
|
||||||
|
AND(32, R(EAX), Imm32(JIT_ICACHE_MASK));
|
||||||
|
#ifdef _M_IX86
|
||||||
|
MOV(32, R(EAX), MDisp(EAX, (u32)jit.GetBlockCache()->GetICacheVMEM()));
|
||||||
|
#else
|
||||||
|
MOV(64, R(RSI), Imm64((u64)jit.GetBlockCache()->GetICacheVMEM()));
|
||||||
|
MOV(32, R(EAX), MComplex(RSI, EAX, SCALE_1, 0));
|
||||||
|
#endif
|
||||||
|
|
||||||
SetJumpTarget(getinst);
|
SetJumpTarget(getinst);
|
||||||
|
SetJumpTarget(getinst2);
|
||||||
#else
|
#else
|
||||||
#ifdef _M_IX86
|
#ifdef _M_IX86
|
||||||
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
AND(32, R(EAX), Imm32(Memory::MEMVIEW32_MASK));
|
||||||
|
|
|
@ -86,21 +86,23 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
blocks = new JitBlock[MAX_NUM_BLOCKS];
|
blocks = new JitBlock[MAX_NUM_BLOCKS];
|
||||||
blockCodePointers = new const u8*[MAX_NUM_BLOCKS];
|
blockCodePointers = new const u8*[MAX_NUM_BLOCKS];
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
if (iCache == 0 && iCacheEx == 0)
|
if (iCache == 0 && iCacheEx == 0 && iCacheVMEM == 0)
|
||||||
{
|
{
|
||||||
iCache = new u8[JIT_ICACHE_SIZE];
|
iCache = new u8[JIT_ICACHE_SIZE];
|
||||||
iCacheEx = new u8[JIT_ICACHEEX_SIZE];
|
iCacheEx = new u8[JIT_ICACHEEX_SIZE];
|
||||||
|
iCacheVMEM = new u8[JIT_ICACHE_SIZE];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlert("JitBlockCache::Init() - iCache is already initialized");
|
PanicAlert("JitBlockCache::Init() - iCache is already initialized");
|
||||||
}
|
}
|
||||||
if (iCache == 0 || iCacheEx == 0)
|
if (iCache == 0 || iCacheEx == 0 || iCacheVMEM == 0)
|
||||||
{
|
{
|
||||||
PanicAlert("JitBlockCache::Init() - unable to allocate iCache");
|
PanicAlert("JitBlockCache::Init() - unable to allocate iCache");
|
||||||
}
|
}
|
||||||
memset(iCache, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE);
|
memset(iCache, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE);
|
||||||
memset(iCacheEx, JIT_ICACHE_INVALID_BYTE, JIT_ICACHEEX_SIZE);
|
memset(iCacheEx, JIT_ICACHE_INVALID_BYTE, JIT_ICACHEEX_SIZE);
|
||||||
|
memset(iCacheVMEM, JIT_ICACHE_INVALID_BYTE, JIT_ICACHE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
@ -116,6 +118,9 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
if (iCacheEx != 0)
|
if (iCacheEx != 0)
|
||||||
delete [] iCacheEx;
|
delete [] iCacheEx;
|
||||||
iCacheEx = 0;
|
iCacheEx = 0;
|
||||||
|
if (iCacheVMEM != 0)
|
||||||
|
delete [] iCacheVMEM;
|
||||||
|
iCacheVMEM = 0;
|
||||||
#endif
|
#endif
|
||||||
blocks = 0;
|
blocks = 0;
|
||||||
blockCodePointers = 0;
|
blockCodePointers = 0;
|
||||||
|
@ -238,6 +243,11 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
{
|
{
|
||||||
return iCacheEx;
|
return iCacheEx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8* JitBlockCache::GetICacheVMEM()
|
||||||
|
{
|
||||||
|
return iCacheVMEM;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr)
|
int JitBlockCache::GetBlockNumberFromStartAddress(u32 addr)
|
||||||
|
@ -246,7 +256,11 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
return -1;
|
return -1;
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
u32 inst;
|
u32 inst;
|
||||||
if (addr & JIT_ICACHE_EXRAM_BIT)
|
if (addr & JIT_ICACHE_VMEM_BIT)
|
||||||
|
{
|
||||||
|
inst = *(u32*)(iCacheVMEM + (addr & JIT_ICACHE_MASK));
|
||||||
|
}
|
||||||
|
else if (addr & JIT_ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
inst = *(u32*)(iCacheEx + (addr & JIT_ICACHEEX_MASK));
|
inst = *(u32*)(iCacheEx + (addr & JIT_ICACHEEX_MASK));
|
||||||
}
|
}
|
||||||
|
@ -394,11 +408,17 @@ bool JitBlock::ContainsAddress(u32 em_address)
|
||||||
// invalidate iCache.
|
// invalidate iCache.
|
||||||
// icbi can be called with any address, so we sholud check
|
// icbi can be called with any address, so we sholud check
|
||||||
if ((address & ~JIT_ICACHE_MASK) != 0x80000000 && (address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
if ((address & ~JIT_ICACHE_MASK) != 0x80000000 && (address & ~JIT_ICACHE_MASK) != 0x00000000 &&
|
||||||
|
(address & ~JIT_ICACHE_MASK) != 0x7e000000 && // TLB area
|
||||||
(address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
(address & ~JIT_ICACHEEX_MASK) != 0x90000000 && (address & ~JIT_ICACHEEX_MASK) != 0x10000000)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (address & JIT_ICACHE_EXRAM_BIT)
|
if (address & JIT_ICACHE_VMEM_BIT)
|
||||||
|
{
|
||||||
|
u32 cacheaddr = address & JIT_ICACHE_MASK;
|
||||||
|
memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
||||||
|
}
|
||||||
|
else if (address & JIT_ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
u32 cacheaddr = address & JIT_ICACHEEX_MASK;
|
u32 cacheaddr = address & JIT_ICACHEEX_MASK;
|
||||||
memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 32);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#define JIT_ICACHEEX_SIZE 0x4000000
|
#define JIT_ICACHEEX_SIZE 0x4000000
|
||||||
#define JIT_ICACHEEX_MASK 0x3ffffff
|
#define JIT_ICACHEEX_MASK 0x3ffffff
|
||||||
#define JIT_ICACHE_EXRAM_BIT 0x10000000
|
#define JIT_ICACHE_EXRAM_BIT 0x10000000
|
||||||
|
#define JIT_ICACHE_VMEM_BIT 0x20000000
|
||||||
// this corresponds to opcode 5 which is invalid in PowerPC
|
// this corresponds to opcode 5 which is invalid in PowerPC
|
||||||
#define JIT_ICACHE_INVALID_BYTE 0x14
|
#define JIT_ICACHE_INVALID_BYTE 0x14
|
||||||
#define JIT_ICACHE_INVALID_WORD 0x14141414
|
#define JIT_ICACHE_INVALID_WORD 0x14141414
|
||||||
|
@ -89,6 +90,7 @@ class JitBlockCache
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
u8 *iCache;
|
u8 *iCache;
|
||||||
u8 *iCacheEx;
|
u8 *iCacheEx;
|
||||||
|
u8 *iCacheVMEM;
|
||||||
#endif
|
#endif
|
||||||
int MAX_NUM_BLOCKS;
|
int MAX_NUM_BLOCKS;
|
||||||
|
|
||||||
|
@ -116,6 +118,7 @@ public:
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
u8 *GetICache();
|
u8 *GetICache();
|
||||||
u8 *GetICacheEx();
|
u8 *GetICacheEx();
|
||||||
|
u8 *GetICacheVMEM();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Fast way to get a block. Only works on the first ppc instruction of a block.
|
// Fast way to get a block. Only works on the first ppc instruction of a block.
|
||||||
|
|
|
@ -72,6 +72,7 @@ namespace PowerPC
|
||||||
#ifdef FAST_ICACHE
|
#ifdef FAST_ICACHE
|
||||||
memset(lookup_table, 0xff, sizeof(lookup_table));
|
memset(lookup_table, 0xff, sizeof(lookup_table));
|
||||||
memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex));
|
memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex));
|
||||||
|
memset(lookup_table_vmem, 0xff, sizeof(lookup_table_vmem));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +86,9 @@ namespace PowerPC
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
if (valid[set] & (1<<i))
|
if (valid[set] & (1<<i))
|
||||||
{
|
{
|
||||||
if (tags[set][i] & (ICACHE_EXRAM_BIT >> 12))
|
if (tags[set][i] & (ICACHE_VMEM_BIT >> 12))
|
||||||
|
lookup_table_vmem[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
|
||||||
|
else if (tags[set][i] & (ICACHE_EXRAM_BIT >> 12))
|
||||||
lookup_table_ex[((tags[set][i] << 7) | set) & 0x1fffff] = 0xff;
|
lookup_table_ex[((tags[set][i] << 7) | set) & 0x1fffff] = 0xff;
|
||||||
else
|
else
|
||||||
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
|
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
|
||||||
|
@ -102,7 +105,11 @@ namespace PowerPC
|
||||||
u32 tag = addr >> 12;
|
u32 tag = addr >> 12;
|
||||||
#ifdef FAST_ICACHE
|
#ifdef FAST_ICACHE
|
||||||
u32 t;
|
u32 t;
|
||||||
if (addr & ICACHE_EXRAM_BIT)
|
if (addr & ICACHE_VMEM_BIT)
|
||||||
|
{
|
||||||
|
t = lookup_table_vmem[(addr>>5) & 0xfffff];
|
||||||
|
}
|
||||||
|
else if (addr & ICACHE_EXRAM_BIT)
|
||||||
{
|
{
|
||||||
t = lookup_table_ex[(addr>>5) & 0x1fffff];
|
t = lookup_table_ex[(addr>>5) & 0x1fffff];
|
||||||
}
|
}
|
||||||
|
@ -134,12 +141,16 @@ namespace PowerPC
|
||||||
#ifdef FAST_ICACHE
|
#ifdef FAST_ICACHE
|
||||||
if (valid[set] & (1<<t))
|
if (valid[set] & (1<<t))
|
||||||
{
|
{
|
||||||
if (tags[set][t] & (ICACHE_EXRAM_BIT >> 12))
|
if (tags[set][t] & (ICACHE_VMEM_BIT >> 12))
|
||||||
|
lookup_table_vmem[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
|
||||||
|
else if (tags[set][t] & (ICACHE_EXRAM_BIT >> 12))
|
||||||
lookup_table_ex[((tags[set][t] << 7) | set) & 0x1fffff] = 0xff;
|
lookup_table_ex[((tags[set][t] << 7) | set) & 0x1fffff] = 0xff;
|
||||||
else
|
else
|
||||||
lookup_table[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
|
lookup_table[((tags[set][t] << 7) | set) & 0xfffff] = 0xff;
|
||||||
}
|
}
|
||||||
if (addr & ICACHE_EXRAM_BIT)
|
if (addr & ICACHE_VMEM_BIT)
|
||||||
|
lookup_table_vmem[(addr>>5) & 0xfffff] = t;
|
||||||
|
else if (addr & ICACHE_EXRAM_BIT)
|
||||||
lookup_table_ex[(addr>>5) & 0x1fffff] = t;
|
lookup_table_ex[(addr>>5) & 0x1fffff] = t;
|
||||||
else
|
else
|
||||||
lookup_table[(addr>>5) & 0xfffff] = t;
|
lookup_table[(addr>>5) & 0xfffff] = t;
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace PowerPC
|
||||||
const u32 ICACHE_BLOCK_SIZE = 8;
|
const u32 ICACHE_BLOCK_SIZE = 8;
|
||||||
|
|
||||||
const u32 ICACHE_EXRAM_BIT = 0x10000000;
|
const u32 ICACHE_EXRAM_BIT = 0x10000000;
|
||||||
|
const u32 ICACHE_VMEM_BIT = 0x20000000;
|
||||||
|
|
||||||
struct InstructionCache
|
struct InstructionCache
|
||||||
{
|
{
|
||||||
|
@ -45,6 +46,7 @@ namespace PowerPC
|
||||||
#ifdef FAST_ICACHE
|
#ifdef FAST_ICACHE
|
||||||
u8 lookup_table[1<<20];
|
u8 lookup_table[1<<20];
|
||||||
u8 lookup_table_ex[1<<21];
|
u8 lookup_table_ex[1<<21];
|
||||||
|
u8 lookup_table_vmem[1<<20];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
InstructionCache();
|
InstructionCache();
|
||||||
|
|
|
@ -72,7 +72,7 @@ static Common::Thread *saveThread = NULL;
|
||||||
|
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
#define STATE_VERSION 1
|
#define STATE_VERSION 2
|
||||||
|
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
void DoState(PointerWrap &p)
|
||||||
|
@ -81,7 +81,8 @@ void DoState(PointerWrap &p)
|
||||||
p.Do(cookie);
|
p.Do(cookie);
|
||||||
if (cookie != 0xBAADBABE + STATE_VERSION)
|
if (cookie != 0xBAADBABE + STATE_VERSION)
|
||||||
{
|
{
|
||||||
PanicAlert("Savestate version mismatch !\nSorry, you can't load states from other revisions.");
|
//PanicAlert("Savestate version mismatch !\nSorry, you can't load states from other revisions.");
|
||||||
|
p.SetMode(PointerWrap::MODE_MEASURE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Begin with video plugin, so that it gets a chance to clear it's caches and writeback modified things to RAM
|
// Begin with video plugin, so that it gets a chance to clear it's caches and writeback modified things to RAM
|
||||||
|
@ -97,6 +98,7 @@ void DoState(PointerWrap &p)
|
||||||
#ifdef JIT_UNLIMITED_ICACHE
|
#ifdef JIT_UNLIMITED_ICACHE
|
||||||
p.DoVoid(jit.GetBlockCache()->GetICache(), JIT_ICACHE_SIZE);
|
p.DoVoid(jit.GetBlockCache()->GetICache(), JIT_ICACHE_SIZE);
|
||||||
p.DoVoid(jit.GetBlockCache()->GetICacheEx(), JIT_ICACHEEX_SIZE);
|
p.DoVoid(jit.GetBlockCache()->GetICacheEx(), JIT_ICACHEEX_SIZE);
|
||||||
|
p.DoVoid(jit.GetBlockCache()->GetICacheVMEM(), JIT_ICACHE_SIZE);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,9 +347,13 @@ void LoadStateCallback(u64 userdata, int cyclesLate)
|
||||||
u8 *ptr = buffer;
|
u8 *ptr = buffer;
|
||||||
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
PointerWrap p(&ptr, PointerWrap::MODE_READ);
|
||||||
DoState(p);
|
DoState(p);
|
||||||
delete [] buffer;
|
|
||||||
|
|
||||||
Core::DisplayMessage(StringFromFormat("Loaded state from %s", cur_filename.c_str()).c_str(), 2000);
|
if (p.GetMode() == PointerWrap::MODE_READ)
|
||||||
|
Core::DisplayMessage(StringFromFormat("Loaded state from %s", cur_filename.c_str()).c_str(), 2000);
|
||||||
|
else
|
||||||
|
Core::DisplayMessage("Unable to Load : Can't load state from other revisions !", 4000);
|
||||||
|
|
||||||
|
delete [] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void State_Init()
|
void State_Init()
|
||||||
|
|
|
@ -659,7 +659,10 @@ void CFrame::OnKeyDown(wxKeyEvent& event)
|
||||||
// Toggle fullscreen
|
// Toggle fullscreen
|
||||||
if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == WXK_RETURN && event.GetModifiers() == wxMOD_ALT))
|
if (event.GetKeyCode() == WXK_ESCAPE || (event.GetKeyCode() == WXK_RETURN && event.GetModifiers() == wxMOD_ALT))
|
||||||
{
|
{
|
||||||
DoFullscreen(!IsFullScreen());
|
// If a modal dialog is open, this will still process the keyboard events, and may cause
|
||||||
|
// the main window to become unresponsive, so we have to avoid that.
|
||||||
|
if ((bRenderToMain || Core::GetState() != Core::CORE_RUN) && !m_bModalDialogOpen)
|
||||||
|
DoFullscreen(!IsFullScreen());
|
||||||
|
|
||||||
// We do that to avoid the event to be double processed (which would cause the window to be stuck in fullscreen)
|
// We do that to avoid the event to be double processed (which would cause the window to be stuck in fullscreen)
|
||||||
event.StopPropagation();
|
event.StopPropagation();
|
||||||
|
@ -832,9 +835,7 @@ wxAuiNotebook* CFrame::CreateEmptyNotebook()
|
||||||
void CFrame::DoFullscreen(bool bF)
|
void CFrame::DoFullscreen(bool bF)
|
||||||
{
|
{
|
||||||
// Only switch this to fullscreen if we're rendering to main OR if we're not running a game
|
// Only switch this to fullscreen if we're rendering to main OR if we're not running a game
|
||||||
// AND if this is the active window, as it could cause the main window to become unresponsive
|
if (bRenderToMain || Core::GetState() != Core::CORE_RUN)
|
||||||
// if we're switching to fullscreen while a modal dialog is open
|
|
||||||
if ((bRenderToMain || Core::GetState() != Core::CORE_RUN) && this->IsActive())
|
|
||||||
{
|
{
|
||||||
ShowFullScreen(bF);
|
ShowFullScreen(bF);
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,7 @@ class CFrame : public wxFrame
|
||||||
bool m_bEdit;
|
bool m_bEdit;
|
||||||
bool m_bTabSplit;
|
bool m_bTabSplit;
|
||||||
bool m_bNoDocking;
|
bool m_bNoDocking;
|
||||||
|
bool m_bModalDialogOpen;
|
||||||
|
|
||||||
char **drives;
|
char **drives;
|
||||||
|
|
||||||
|
|
|
@ -665,9 +665,11 @@ void CFrame::OnReset(wxCommandEvent& WXUNUSED (event))
|
||||||
|
|
||||||
void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event))
|
void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event))
|
||||||
{
|
{
|
||||||
|
m_bModalDialogOpen = true;
|
||||||
CConfigMain ConfigMain(this);
|
CConfigMain ConfigMain(this);
|
||||||
if (ConfigMain.ShowModal() == wxID_OK)
|
if (ConfigMain.ShowModal() == wxID_OK)
|
||||||
m_GameListCtrl->Update();
|
m_GameListCtrl->Update();
|
||||||
|
m_bModalDialogOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event))
|
void CFrame::OnPluginGFX(wxCommandEvent& WXUNUSED (event))
|
||||||
|
@ -712,8 +714,10 @@ void CFrame::OnHelp(wxCommandEvent& event)
|
||||||
{
|
{
|
||||||
case IDM_HELPABOUT:
|
case IDM_HELPABOUT:
|
||||||
{
|
{
|
||||||
AboutDolphin frame(this);
|
m_bModalDialogOpen = true;
|
||||||
frame.ShowModal();
|
AboutDolphin frame(this);
|
||||||
|
frame.ShowModal();
|
||||||
|
m_bModalDialogOpen = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IDM_HELPWEBSITE:
|
case IDM_HELPWEBSITE:
|
||||||
|
@ -756,8 +760,10 @@ void CFrame::OnNetPlay(wxCommandEvent& WXUNUSED (event))
|
||||||
|
|
||||||
void CFrame::OnMemcard(wxCommandEvent& WXUNUSED (event))
|
void CFrame::OnMemcard(wxCommandEvent& WXUNUSED (event))
|
||||||
{
|
{
|
||||||
|
m_bModalDialogOpen = true;
|
||||||
CMemcardManager MemcardManager(this);
|
CMemcardManager MemcardManager(this);
|
||||||
MemcardManager.ShowModal();
|
MemcardManager.ShowModal();
|
||||||
|
m_bModalDialogOpen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame::OnShow_CheatsWindow(wxCommandEvent& WXUNUSED (event))
|
void CFrame::OnShow_CheatsWindow(wxCommandEvent& WXUNUSED (event))
|
||||||
|
|
Loading…
Reference in New Issue