diff options
| author | skidau <skidau@gmail.com> | 2012-05-12 21:43:39 +1000 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2012-05-12 21:43:39 +1000 |
| commit | 48bf5c739dfa577644dfe5e5dca7d8bac5c044d5 (patch) | |
| tree | ad7dcca901785b14601c2aa28e0995bbbbfaf494 /Source/Core | |
| parent | f567782b4732646c619fc9508cbd1cfa779914bb (diff) | |
Changed the block linker to work on physical addresses. Checked whether the code has changed before invalidating it. Fixes the cut-scenes in Tales of Graces.
Fixes issue 2933.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp | 75 |
1 files changed, 56 insertions, 19 deletions
diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index 8cc85e3284..303945e965 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -208,7 +208,25 @@ bool JitBlock::ContainsAddress(u32 em_address) JitBlock &b = blocks[block_num]; b.originalFirstOpcode = Memory::Read_Opcode_JIT(b.originalAddress); Memory::Write_Opcode_JIT(b.originalAddress, (JIT_OPCODE << 26) | block_num); - block_map[std::make_pair(b.originalAddress + 4 * b.originalSize - 1, b.originalAddress)] = block_num; + u32 pAddr = 0; + + // Convert the logical address to a physical address for the block map + switch ((b.originalAddress >> 24) & 0xFC) + { + case 0x00: + case 0x80: + case 0xC0: + pAddr = b.originalAddress & 0x0FFFFFFF; + case 0x10: + case 0x90: + case 0xD0: + pAddr = b.originalAddress & 0x1FFFFFFF; + default: + // Translate address? + pAddr = b.originalAddress & 0x0FFFFFFF; + } + + block_map[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num; if (block_link) { for (int i = 0; i < 2; i++) @@ -409,33 +427,52 @@ bool JitBlock::ContainsAddress(u32 em_address) */ } - void JitBlockCache::InvalidateICache(u32 address, const u32 length) { + // Convert the logical address to a physical address for the block map + u32 pAddr = 0; + switch ((address >> 24) & 0xFC) + { + case 0x00: + case 0x80: + case 0xC0: + pAddr = address & 0x0FFFFFFF; + case 0x10: + case 0x90: + case 0xD0: + pAddr = address & 0x1FFFFFFF; + default: + // Translate address? + pAddr = address & 0x0FFFFFFF; + } + // destroy JIT blocks // !! this works correctly under assumption that any two overlapping blocks end at the same address - std::map<pair<u32,u32>, u32>::iterator it1 = block_map.lower_bound(std::make_pair(address, 0)), it2 = it1, it; - while (it2 != block_map.end() && it2->first.second < address + length) + std::map<pair<u32,u32>, u32>::iterator it1 = block_map.lower_bound(std::make_pair(pAddr, 0)), it2 = it1, it; + while (it2 != block_map.end() && it2->first.second < pAddr + length) { #ifdef JIT_UNLIMITED_ICACHE JitBlock &b = blocks[it2->second]; - if (b.originalAddress & JIT_ICACHE_VMEM_BIT) - { - u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; - memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); - } - else if (b.originalAddress & JIT_ICACHE_EXRAM_BIT) + if (b.originalFirstOpcode != Memory::ReadUnchecked_U32(b.originalAddress)) { - u32 cacheaddr = b.originalAddress & JIT_ICACHEEX_MASK; - memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); - } - else - { - u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; - memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); - } + if (b.originalAddress & JIT_ICACHE_VMEM_BIT) + { + u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; + memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); + } + else if (b.originalAddress & JIT_ICACHE_EXRAM_BIT) + { + u32 cacheaddr = b.originalAddress & JIT_ICACHEEX_MASK; + memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); + } + else + { + u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; + memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, 4); + } #endif - DestroyBlock(it2->second, true); + DestroyBlock(it2->second, true); + } it2++; } if (it1 != it2) |
