diff --git a/Data/User/GameConfig/GGSEA4.ini b/Data/User/GameConfig/GGSEA4.ini
new file mode 100644
index 0000000000..248f6c45eb
--- /dev/null
+++ b/Data/User/GameConfig/GGSEA4.ini
@@ -0,0 +1,8 @@
+# GGSEA4 - METAL GEAR SOLID THE TWIN SNAKES
+[Core]
+TLBHack=1
+[EmuState]
+#The Emulation State. 1 is worst, 5 is best, 0 is not set.
+EmulationStateId = 1
+[OnFrame]
+[ActionReplay]
diff --git a/Data/User/GameConfig/GGSPA4.ini b/Data/User/GameConfig/GGSPA4.ini
new file mode 100644
index 0000000000..58ac951e32
--- /dev/null
+++ b/Data/User/GameConfig/GGSPA4.ini
@@ -0,0 +1,9 @@
+# GGSPA4 - METAL GEAR SOLID THE TWIN SNAKES
+[Core]
+TLBHack = 1
+#Values set here will override the main dolphin settings.
+[EmuState]
+#The Emulation State. 1 is worst, 5 is best, 0 is not set.
+EmulationStateId = 1
+[OnFrame]
+[ActionReplay]
diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp
index cf99d1d4b3..0fb6678e18 100644
--- a/Source/Core/Core/Src/CoreParameter.cpp
+++ b/Source/Core/Core/Src/CoreParameter.cpp
@@ -40,6 +40,7 @@ void SCoreStartupParameter::LoadDefaults()
bLockThreads = true;
bWii = false;
SelectedLanguage = 0;
+ iTLBHack = 0;
bJITOff = false; // debugger only settings
bJITLoadStoreOff = false;
diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h
index 8e6b758c9f..4376f4f85e 100644
--- a/Source/Core/Core/Src/CoreParameter.h
+++ b/Source/Core/Core/Src/CoreParameter.h
@@ -59,6 +59,9 @@ struct SCoreStartupParameter
bool bRunCompareServer;
bool bRunCompareClient;
+
+ int iTLBHack;
+
int SelectedLanguage;
bool bWii; bool bWiiLeds; bool bWiiSpeakers; // Wii settings
diff --git a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp
index b2daa324ee..7a88f3a4a4 100644
--- a/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp
+++ b/Source/Core/Core/Src/Debugger/PPCDebugInterface.cpp
@@ -25,7 +25,6 @@
#include "../PowerPC/PowerPC.h"
#include "../PowerPC/SymbolDB.h"
-// Not thread safe.
void PPCDebugInterface::disasm(unsigned int address, char *dest, int max_size)
{
if (Core::GetState() != Core::CORE_UNINITIALIZED)
diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp
index 97aa9af4a6..b799da391a 100644
--- a/Source/Core/Core/Src/HW/Memmap.cpp
+++ b/Source/Core/Core/Src/HW/Memmap.cpp
@@ -49,7 +49,8 @@ namespace Memory
// #define NOCHECK
-static const bool bFakeVMEM = false;
+// TLBHack = 1 in a patch ini will set this to true.
+static bool bFakeVMEM = false;
#ifndef LOGGING
#define NOCHECK
@@ -293,7 +294,7 @@ void InitHWMemFuncsWii()
writeFn32 GetHWWriteFun32(const u32 _Address)
{
- return hwWrite32[(_Address>>HWSHIFT) & (NUMHWMEMFUN-1)];
+ return hwWrite32[(_Address >> HWSHIFT) & (NUMHWMEMFUN-1)];
}
@@ -342,10 +343,18 @@ bool ValidMemory(const u32 _Address)
return true;
else
return false;
+ case 0x7e:
+ case 0x7f:
+ if (bFakeVMEM)
+ return true;
+ else
+ return false;
case 0xE0:
if (_Address < (0xE0000000 + L1_CACHE_SIZE))
return true;
+ else
+ return false;
case 0xCC:
case 0xCD:
case 0xC8:
@@ -445,7 +454,7 @@ void CheckForBadAddresses64(u32 Address, u64 Data, bool Read)
hwReadWii##_type[(_Address>>HWSHIFT) & (NUMHWMEMFUN-1)](_var, _Address); \
else if (((_Address & 0xFFF00000) == 0xCD800000) && \
(_Address <= 0xCD809000)) \
- WII_IOBridge::Read##_type(_var,_Address); \
+ WII_IOBridge::Read##_type(_var, _Address); \
else \
{ \
/* Disabled because the debugger makes trouble with */ \
@@ -467,7 +476,7 @@ void CheckForBadAddresses64(u32 Address, u64 Data, bool Read)
PanicAlert("READ: Invalid address: %08x", _Address); \
else \
{ \
- if (bFakeVMEM && (_Address & 0xFE000000) == 0x7e000000) \
+ if (bFakeVMEM && ((_Address & 0xFE000000) == 0x7e000000) ) \
{ \
_var = bswap((*(u##_type*)&m_pFakeVMEM[_Address & FAKEVMEM_MASK])); \
} \
@@ -514,16 +523,6 @@ void CheckForBadAddresses64(u32 Address, u64 Data, bool Read)
_dbg_assert_msg_(MEMMAP,0,"Memory - Unknown HW address %08x", _Address); \
} \
} \
- else if ((_Address >= 0xE0000000) && (_Address < (0xE0000000+L1_CACHE_SIZE))) \
- { \
- *(u##_type*)&m_pL1Cache[_Address & L1_CACHE_MASK] = bswap(_Data); \
- return; \
- } \
- else if (_Address >= 0xE0000000) \
- { \
- LOG(MEMMAP,"WRITE: Cache address out of bounds (addr: %08x data: %08x)",_Address,_Data); \
-/* PanicAlert("WRITE: Cache address %08x out of bounds", _Address); */ \
- } \
else if (((_Address & 0xF0000000) == 0x80000000) || \
((_Address & 0xF0000000) == 0xC0000000) || \
((_Address & 0xF0000000) == 0x00000000)) \
@@ -538,9 +537,19 @@ void CheckForBadAddresses64(u32 Address, u64 Data, bool Read)
*(u##_type*)&m_pEXRAM[_Address & EXRAM_MASK] = bswap(_Data); \
return; \
} \
+ else if ((_Address >= 0xE0000000) && (_Address < (0xE0000000+L1_CACHE_SIZE))) \
+ { \
+ *(u##_type*)&m_pL1Cache[_Address & L1_CACHE_MASK] = bswap(_Data); \
+ return; \
+ } \
+ else if (_Address >= 0xE0000000) \
+ { \
+ LOG(MEMMAP,"WRITE: Cache address out of bounds (addr: %08x data: %08x)",_Address,_Data); \
+/* PanicAlert("WRITE: Cache address %08x out of bounds", _Address); */ \
+ } \
else \
{ \
- if (bFakeVMEM && (_Address & 0xFE000000) == 0x7e000000) \
+ if (bFakeVMEM && ((_Address & 0xFE000000) == 0x7e000000)) \
{ \
*(u##_type*)&m_pFakeVMEM[_Address & FAKEVMEM_MASK] = bswap(_Data); \
return; \
@@ -564,6 +573,7 @@ bool IsInitialized()
bool Init()
{
bool wii = Core::GetStartupParameter().bWii;
+ bFakeVMEM = Core::GetStartupParameter().iTLBHack == 1;
int totalMemSize = RAM_SIZE + EFB_SIZE + L1_CACHE_SIZE + IO_SIZE;
if (bFakeVMEM)
@@ -1027,7 +1037,7 @@ u8 *GetPointer(const u32 _Address)
case 0x81:
case 0xC0:
case 0xC1:
- return (u8*)(((char*)m_pRAM) + (_Address&RAM_MASK));
+ return (u8*)(((char*)m_pRAM) + (_Address & RAM_MASK));
case 0x10:
case 0x11:
@@ -1042,20 +1052,25 @@ u8 *GetPointer(const u32 _Address)
case 0xD2:
case 0xD3:
if (Core::GetStartupParameter().bWii)
- return (u8*)(((char*)m_pEXRAM) + (_Address&EXRAM_MASK));
+ return (u8*)(((char*)m_pEXRAM) + (_Address & EXRAM_MASK));
else
return 0;
case 0xE0:
if (_Address < (0xE0000000 + L1_CACHE_SIZE))
return GetCachePtr() + (_Address & L1_CACHE_MASK);
+ else
+ return 0;
case 0xC8:
return m_pEFB + (_Address & 0xFFFFFF);
case 0xCC:
case 0xCD:
- _dbg_assert_msg_(MEMMAP, 0,"Memory", "GetPointer from IO Bridge doesnt work");
+ _dbg_assert_msg_(MEMMAP, 0, "Memory", "GetPointer from IO Bridge doesnt work");
return NULL;
+ default:
+ PanicAlert("Tried to get pointer for unknown address %08x", _Address);
+ break;
}
return NULL;
}
@@ -1083,6 +1098,12 @@ bool IsRAMAddress(const u32 addr, bool allow_locked_cache)
return true;
else
return false;
+ case 0x7C:
+ if (bFakeVMEM && addr >= 0x7e000000)
+ return true;
+ else
+ return false;
+
default:
return false;
}
diff --git a/Source/Core/Core/Src/MemTools.cpp b/Source/Core/Core/Src/MemTools.cpp
index 052c8aed4b..f810de1b15 100644
--- a/Source/Core/Core/Src/MemTools.cpp
+++ b/Source/Core/Core/Src/MemTools.cpp
@@ -63,17 +63,22 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
//Figure out what address was hit
u64 badAddress = (u64)pPtrs->ExceptionRecord->ExceptionInformation[1];
+
//TODO: First examine the address, make sure it's within the emulated memory space
u64 memspaceBottom = (u64)Memory::base;
- if (badAddress < memspaceBottom) {
- PanicAlert("Exception handler - access below memory space. %08x%08x",
+#ifdef _M_X64
+ u64 memspaceTop = memspaceBottom + 0x100000000ULL;
+#else
+ u64 memspaceTop = memspaceBottom + 0x40000000;
+#endif
+ if (badAddress < memspaceBottom || badAddress >= memspaceTop) {
+ PanicAlert("Exception handler - access outside memory space. %08x%08x",
badAddress >> 32, badAddress);
}
+
u32 emAddress = (u32)(badAddress - memspaceBottom);
//Now we have the emulated address.
- //Let's notify everyone who wants to be notified
- //Notify(emAddress, accessType == 0 ? Read : Write);
CONTEXT *ctx = pPtrs->ContextRecord;
//opportunity to play with the context - we can change the debug regs!
@@ -81,9 +86,8 @@ LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
//We could emulate the memory accesses here, but then they would still be around to take up
//execution resources. Instead, we backpatch into a generic memory call and retry.
u8 *new_rip = Jit64::BackPatch(codePtr, accessType, emAddress, ctx);
-
- // We no longer touch Rip, since we return back to the instruction, after overwriting it with a
- // trampoline jump and some nops
+
+ // Rip/Eip needs to be updated.
if (new_rip)
#ifdef _M_X64
ctx->Rip = (DWORD_PTR)new_rip;
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
index 58759ba621..ae1efb1a8e 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.cpp
@@ -106,7 +106,8 @@ u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx)
{
// It's a read. Easy.
ABI_PushAllCallerSavedRegsAndAdjustStack();
- MOV(32, R(ABI_PARAM1), R((X64Reg)addrReg));
+ if (addrReg != ABI_PARAM1)
+ MOV(32, R(ABI_PARAM1), R((X64Reg)addrReg));
if (info.displacement) {
ADD(32, R(ABI_PARAM1), Imm32(info.displacement));
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h
index 649c119511..f30836fc79 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h
+++ b/Source/Core/Core/Src/PowerPC/Jit64/JitBackpatch.h
@@ -27,6 +27,7 @@
namespace Jit64 {
// Returns the new RIP value
u8 *BackPatch(u8 *codePtr, int accessType, u32 emAddress, CONTEXT *ctx);
-}
+
+} // namespace
#endif
diff --git a/Source/Core/DolphinWX/DolphinWX.vcproj b/Source/Core/DolphinWX/DolphinWX.vcproj
index 1a1ac4c035..5c009bdf16 100644
--- a/Source/Core/DolphinWX/DolphinWX.vcproj
+++ b/Source/Core/DolphinWX/DolphinWX.vcproj
@@ -921,6 +921,58 @@
RelativePath=".\src\main.h"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Core/DolphinWX/Src/BootManager.cpp b/Source/Core/DolphinWX/Src/BootManager.cpp
index f83004cff9..0597c2d74a 100644
--- a/Source/Core/DolphinWX/Src/BootManager.cpp
+++ b/Source/Core/DolphinWX/Src/BootManager.cpp
@@ -123,7 +123,7 @@ bool BootCore(const std::string& _rFilename)
ini.Get("Core", "UseDualCore", &StartUp.bUseDualCore, StartUp.bUseDualCore);
ini.Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
ini.Get("Core", "OptimizeQuantizers", &StartUp.bOptimizeQuantizers, StartUp.bOptimizeQuantizers);
-
+ ini.Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
// ------------------------------------------------
// Update SYSCONF with game specific settings
@@ -194,7 +194,7 @@ bool BootCore(const std::string& _rFilename)
if (!Core::Init(StartUp))
{
PanicAlert("Couldn't init the core.\nCheck your configuration.");
- return(false);
+ return false;
}
#if defined(HAVE_WX) && HAVE_WX
@@ -204,13 +204,12 @@ bool BootCore(const std::string& _rFilename)
#else
Core::SetState(Core::CORE_RUN);
#endif
- return(true);
+ return true;
}
-
void Stop()
{
Core::Stop();
}
-} // namespace
+} // namespace
diff --git a/Source/Core/VideoCommon/Src/TextureDecoder.cpp b/Source/Core/VideoCommon/Src/TextureDecoder.cpp
index e20b5368d6..f9d943ffbf 100644
--- a/Source/Core/VideoCommon/Src/TextureDecoder.cpp
+++ b/Source/Core/VideoCommon/Src/TextureDecoder.cpp
@@ -390,7 +390,7 @@ PC_TexFormat TexDecoder_Decode(u8 *dst, const u8 *src, int width, int height, in
#if (defined(_WIN32) || (defined (_M_X64) && !defined(_WIN32)))
__m128i Lmask = _mm_set1_epi8 (0x0F);
__m128i Hmask = _mm_set1_epi8 (0xF0);
- __m128i* sseSrc = (__m128i *)src;
+ const __m128i* sseSrc = (const __m128i *)src;
__m128i* sseDst = (__m128i *)dst;
for (int y = 0; y < height; y += 8)
for (int x = 0; x < width; x += 8)
diff --git a/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj b/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj
index 94e0c4940d..1129c7b594 100644
--- a/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj
+++ b/Source/Plugins/Plugin_DSP_HLE/Plugin_DSP_HLE.vcproj
@@ -55,7 +55,6 @@
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
- Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
ForcedIncludeFiles="stdafx.h"
/>
@@ -141,7 +140,6 @@
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
- Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
@@ -230,7 +228,6 @@
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
- Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
@@ -320,7 +317,6 @@
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
- Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
@@ -410,7 +406,6 @@
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
- Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
@@ -500,7 +495,6 @@
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
- Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>