From fbdf9ba153d6f409bd27ea1c160f9814a0e05393 Mon Sep 17 00:00:00 2001 From: skidau Date: Wed, 5 Oct 2011 00:22:51 +1100 Subject: [PATCH 1/9] Added preliminary support for ES_LAUNCH (Wii Multi-boot games) by using HLE to hijack the OSBootDol function. Metroid Prime Trilogy is working. Wii Sports+Wii Sports Resort is not working. Any games which can be played using the dol replacement trick should work here. Suspect that the DOL's are meant to receive an argument list which has not been catered for in this code. This probably also means that the Metroid Prime Trilogy games are locked in Veteran difficulty for the time-being. --- Data/Sys/totaldb.dsy | Bin 722980 -> 723252 bytes Source/Core/Core/Src/Boot/Boot.cpp | 13 ++++++++ Source/Core/Core/Src/HLE/HLE.cpp | 4 ++- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 44 ++++++++++++++++++++++++++ Source/Core/Core/Src/HLE/HLE_Misc.h | 1 + 5 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Data/Sys/totaldb.dsy b/Data/Sys/totaldb.dsy index 790a942eaefc071dfcad998bcc985dc239e2582f..a1c9683c9f57ca74ba2693c818d474dcb4761b2e 100644 GIT binary patch delta 93 zcmZ27L1)V(9mZpgjIE47#MH{j+{(z(%E;Qv$kxip-pa_)%E;Nu$hDP`TbV=Xjp3Gq hUlGetFileSize(dol.substr(1).c_str()); + u8* dolFile = new u8[fileSize]; + if (dolFile) + { + pFileSystem->ReadFile(dol.substr(1).c_str(), dolFile, fileSize); + CDolLoader dolLoader(dolFile, fileSize); + dolLoader.Load(); + PowerPC::ppcState.iCache.Reset(); + + static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); + for (unsigned int i = 0; i < 4; i++) + { + if (s_Usb->m_WiiMotes[i].IsConnected()) + { + s_Usb->m_WiiMotes[i].Activate(false); + s_Usb->m_WiiMotes[i].Activate(true); + } + else + { + s_Usb->m_WiiMotes[i].Activate(false); + } + } + + NPC = dolLoader.GetEntryPoint() | 0x80000000; + } +} + } diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.h b/Source/Core/Core/Src/HLE/HLE_Misc.h index 6c932258a7..f831e5b600 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.h +++ b/Source/Core/Core/Src/HLE/HLE_Misc.h @@ -39,6 +39,7 @@ namespace HLE_Misc void FZ_sqrt_internal(); void FZ_rsqrt_internal(); void HBReload(); + void OSBootDol(); } #endif From 651cedaac4526996bd5cc186736e66a0895798a3 Mon Sep 17 00:00:00 2001 From: skidau Date: Mon, 10 Oct 2011 20:32:24 +1100 Subject: [PATCH 2/9] Added argument detection and passing to the loaded dol. This fixes the Wii Sports+Wii Sports Resort bundle pack. --- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index bc625c9d2d..f9bab42f3c 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -292,10 +292,14 @@ void HBReload() void OSBootDol() { std::string dol; + std::string args; u32 r28 = GPR(28); Memory::GetString(dol, r28); + u32 argsPtr = Memory::Read_U32(GPR(5)); + Memory::GetString(args, argsPtr); + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); @@ -322,6 +326,22 @@ void OSBootDol() } } + if (argsPtr) + { + u32 args_base = Memory::Read_U32(0x800000f4); + u32 ptr_to_num_args = 0xc; + u32 num_args = 1; + u32 hi_ptr = args_base + ptr_to_num_args + 4; + u32 new_args_ptr = args_base + ptr_to_num_args + 8; + + Memory::Write_U32(ptr_to_num_args, args_base + 8); + Memory::Write_U32(num_args, args_base + ptr_to_num_args); + Memory::Write_U32(0x14, hi_ptr); + + for (int i = 0; i < args.length(); i++) + Memory::WriteUnchecked_U8(args[i], new_args_ptr+i); + } + NPC = dolLoader.GetEntryPoint() | 0x80000000; } } From 88e273fac13b6c3b95256fc083867c2b6553c9d6 Mon Sep 17 00:00:00 2001 From: skidau Date: Tue, 1 Nov 2011 23:00:12 +1100 Subject: [PATCH 3/9] Added an IOS check as games which use IOS older than IOS30 do not need to be HLE'd. Added some stubs for Reset to Menu and SSBB's load from disc partition. Fixed loading Fate of Atlantis from the Indiana Jones and the Staff of Kings game. --- Source/Core/Core/Src/Boot/Boot.cpp | 1 - Source/Core/Core/Src/HLE/HLE.cpp | 29 +++++++-- Source/Core/Core/Src/HLE/HLE.h | 1 + Source/Core/Core/Src/HLE/HLE_Misc.cpp | 92 +++++++++++++++++++++++---- 4 files changed, 103 insertions(+), 20 deletions(-) diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index 228d10b8a8..7711990e65 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -267,7 +267,6 @@ bool CBoot::BootUp() db.Apply(&g_symbolDB); } HLE::PatchFunctions(); - g_symbolDB.Clear(); } /* Try to load the symbol map if there is one, and then scan it for diff --git a/Source/Core/Core/Src/HLE/HLE.cpp b/Source/Core/Core/Src/HLE/HLE.cpp index 671a9e0a3a..0c42f7f4df 100644 --- a/Source/Core/Core/Src/HLE/HLE.cpp +++ b/Source/Core/Core/Src/HLE/HLE.cpp @@ -28,6 +28,7 @@ #include "HLE_OS.h" #include "HLE_Misc.h" #include "IPC_HLE/WII_IPC_HLE_Device_es.h" +#include "ConfigManager.h" namespace HLE { @@ -137,13 +138,16 @@ void PatchFunctions() } } - for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++) + if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) { - Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName); - if (symbol > 0) + for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++) { - PowerPC::breakpoints.Add(symbol->address, false); - INFO_LOG(OSHLE, "Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address); + Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName); + if (symbol > 0) + { + PowerPC::breakpoints.Add(symbol->address, false); + INFO_LOG(OSHLE, "Adding BP to %s %08x", OSBreakPoints[i].m_szPatchName, symbol->address); + } } } @@ -171,4 +175,19 @@ u32 GetOrigInstruction(u32 addr) return (iter != orig_instruction.end()) ? iter->second : 0; } +u32 UnPatch(std::string patchName) +{ + Symbol *symbol = g_symbolDB.GetSymbolFromName(patchName.c_str()); + if (symbol > 0) + { + for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) + { + Memory::WriteUnchecked_U32(orig_instruction[addr], addr); + PowerPC::ppcState.iCache.Invalidate(addr); + } + return symbol->address; + } + return 0; +} + } // end of namespace HLE diff --git a/Source/Core/Core/Src/HLE/HLE.h b/Source/Core/Core/Src/HLE/HLE.h index 04c3d35198..b81f347b9f 100644 --- a/Source/Core/Core/Src/HLE/HLE.h +++ b/Source/Core/Core/Src/HLE/HLE.h @@ -24,6 +24,7 @@ namespace HLE { void PatchFunctions(); void Patch(u32 pc, const char *func_name); + u32 UnPatch(std::string patchName); void Execute(u32 _CurrentPC, u32 _Instruction); u32 GetOrigInstruction(u32 em_address); diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index f9bab42f3c..67b2e84963 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -28,10 +28,17 @@ #include "Filesystem.h" #include "../Boot/Boot_DOL.h" #include "IPC_HLE/WII_IPC_HLE_Device_usb.h" +#include "HLE.h" namespace HLE_Misc { +std::string dol; +std::string args; +u32 argsPtr; +u32 bootType; +u16 IOSv; + // Helper to quickly read the floating point value at a memory location. inline float F(u32 addr) { @@ -288,26 +295,19 @@ void HBReload() Host_Message(WM_USER_STOP); } - -void OSBootDol() +void BootDOLFromDisc() { - std::string dol; - std::string args; - - u32 r28 = GPR(28); - Memory::GetString(dol, r28); - - u32 argsPtr = Memory::Read_U32(GPR(5)); - Memory::GetString(args, argsPtr); - DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); - size_t fileSize = (size_t) pFileSystem->GetFileSize(dol.substr(1).c_str()); + if (dol.substr(1, 1).compare("//")) + dol = dol.substr(1); + + u32 fileSize = (u32) pFileSystem->GetFileSize(dol.c_str()); u8* dolFile = new u8[fileSize]; - if (dolFile) + if (fileSize > 0) { - pFileSystem->ReadFile(dol.substr(1).c_str(), dolFile, fileSize); + pFileSystem->ReadFile(dol.c_str(), dolFile, fileSize); CDolLoader dolLoader(dolFile, fileSize); dolLoader.Load(); PowerPC::ppcState.iCache.Reset(); @@ -346,4 +346,68 @@ void OSBootDol() } } +u32 GetDolFileSize() +{ + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); + DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); + + std::string dolFile; + + if (dol.substr(1, 1).compare("//")) + dolFile = dol.substr(1); + + return (u32)pFileSystem->GetFileSize(dolFile.c_str()); +} + +void OSBootDol() +{ + IOSv = Memory::Read_U16(0x00003140); + + if (IOSv >= 30) + { + bootType = GPR(4); + + if ((GPR(4) >> 28) == 0x8) + { + // Reset from menu + PanicAlert("Reset from menu"); + } + else if ((GPR(4) >> 28) == 0xA) + { + // Boot from disc partition + PanicAlert("Boot Partition: %08x", GPR(26)); + } + else if ((GPR(4) >> 28) == 0xC) + { + // Boot DOL from disc + u32 ptr = GPR(28); + Memory::GetString(dol, ptr); + + if (GetDolFileSize() == 0) + { + ptr = GPR(30); + Memory::GetString(dol, ptr); + if (GetDolFileSize() == 0) + { + // Cannot locate the dol file, exit. + HLE::UnPatch("__OSBootDol"); + NPC = PC; + return; + } + } + + argsPtr = Memory::Read_U32(GPR(5)); + Memory::GetString(args, argsPtr); + BootDOLFromDisc(); + return; + } + else + { + PanicAlert("Unknown boot type: %08x", GPR(4)); + } + } + HLE::UnPatch("__OSBootDol"); + NPC = PC; +} + } From 0c845728ccfc5f3a93c69aa09a924a0413e8d151 Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 5 May 2012 18:38:00 +1000 Subject: [PATCH 4/9] Added support for Reset (from menu). Fixes Sam & Max. --- Source/Core/Core/Src/Boot/Boot.cpp | 6 +- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 122 ++++++++++++------ Source/Core/Core/Src/HLE/HLE_Misc.h | 1 + .../Core/Core/Src/HW/ProcessorInterface.cpp | 1 + Source/Core/DiscIO/Src/FileSystemGCWii.cpp | 17 ++- Source/Core/DiscIO/Src/FileSystemGCWii.h | 2 + Source/Core/DiscIO/Src/Filesystem.h | 2 + 7 files changed, 108 insertions(+), 43 deletions(-) diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index 7711990e65..ef3ae2a4fb 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -260,13 +260,15 @@ bool CBoot::BootUp() // Scan for common HLE functions if (!_StartupPara.bEnableDebugging) { - PPCAnalyst::FindFunctions(0x80000000, 0x81800000, &g_symbolDB); + PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB); SignatureDB db; if (db.Load((File::GetSysDirectory() + TOTALDB).c_str())) { db.Apply(&g_symbolDB); + HLE::PatchFunctions(); + db.Clear(); + g_symbolDB.Clear(); } - HLE::PatchFunctions(); } /* Try to load the symbol map if there is one, and then scan it for diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index 67b2e84963..40073d401e 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -29,6 +29,10 @@ #include "../Boot/Boot_DOL.h" #include "IPC_HLE/WII_IPC_HLE_Device_usb.h" #include "HLE.h" +#include "PowerPC/PPCAnalyst.h" +#include "PowerPC/SignatureDB.h" +#include "PowerPC/PPCSymbolDB.h" +#include "CommonPaths.h" namespace HLE_Misc { @@ -295,7 +299,61 @@ void HBReload() Host_Message(WM_USER_STOP); } -void BootDOLFromDisc() +void ExecuteDOL(u8* dolFile, u32 fileSize) +{ + CDolLoader dolLoader(dolFile, fileSize); + dolLoader.Load(); + + // Scan for common HLE functions + if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) + { + PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB); + SignatureDB db; + if (db.Load((File::GetSysDirectory() + TOTALDB).c_str())) + { + db.Apply(&g_symbolDB); + HLE::PatchFunctions(); + db.Clear(); + g_symbolDB.Clear(); + } + } + + PowerPC::ppcState.iCache.Reset(); + + static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); + for (unsigned int i = 0; i < 4; i++) + { + if (s_Usb->m_WiiMotes[i].IsConnected()) + { + s_Usb->m_WiiMotes[i].Activate(false); + s_Usb->m_WiiMotes[i].Activate(true); + } + else + { + s_Usb->m_WiiMotes[i].Activate(false); + } + } + + if (argsPtr) + { + u32 args_base = Memory::Read_U32(0x800000f4); + u32 ptr_to_num_args = 0xc; + u32 num_args = 1; + u32 hi_ptr = args_base + ptr_to_num_args + 4; + u32 new_args_ptr = args_base + ptr_to_num_args + 8; + + Memory::Write_U32(ptr_to_num_args, args_base + 8); + Memory::Write_U32(num_args, args_base + ptr_to_num_args); + Memory::Write_U32(0x14, hi_ptr); + + for (int i = 0; i < args.length(); i++) + Memory::WriteUnchecked_U8(args[i], new_args_ptr+i); + } + + NPC = dolLoader.GetEntryPoint() | 0x80000000; +} + +void LoadDOLFromDisc() { DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); @@ -308,42 +366,23 @@ void BootDOLFromDisc() if (fileSize > 0) { pFileSystem->ReadFile(dol.c_str(), dolFile, fileSize); - CDolLoader dolLoader(dolFile, fileSize); - dolLoader.Load(); - PowerPC::ppcState.iCache.Reset(); - - static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); - for (unsigned int i = 0; i < 4; i++) - { - if (s_Usb->m_WiiMotes[i].IsConnected()) - { - s_Usb->m_WiiMotes[i].Activate(false); - s_Usb->m_WiiMotes[i].Activate(true); - } - else - { - s_Usb->m_WiiMotes[i].Activate(false); - } - } - - if (argsPtr) - { - u32 args_base = Memory::Read_U32(0x800000f4); - u32 ptr_to_num_args = 0xc; - u32 num_args = 1; - u32 hi_ptr = args_base + ptr_to_num_args + 4; - u32 new_args_ptr = args_base + ptr_to_num_args + 8; - - Memory::Write_U32(ptr_to_num_args, args_base + 8); - Memory::Write_U32(num_args, args_base + ptr_to_num_args); - Memory::Write_U32(0x14, hi_ptr); - - for (int i = 0; i < args.length(); i++) - Memory::WriteUnchecked_U8(args[i], new_args_ptr+i); - } - - NPC = dolLoader.GetEntryPoint() | 0x80000000; + ExecuteDOL(dolFile, fileSize); } + delete[] dolFile; +} + +void LoadBootDOLFromDisc() +{ + DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); + DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); + u32 fileSize = pFileSystem->GetBootDOLSize(); + u8* dolFile = new u8[fileSize]; + if (fileSize > 0) + { + pFileSystem->GetBootDOL(dolFile, fileSize); + ExecuteDOL(dolFile, fileSize); + } + delete[] dolFile; } u32 GetDolFileSize() @@ -369,8 +408,13 @@ void OSBootDol() if ((GPR(4) >> 28) == 0x8) { - // Reset from menu - PanicAlert("Reset from menu"); + u32 resetCode = GPR(30); + + // Reset game + Memory::Write_U32(resetCode << 3, 0xCC003024); + //Memory::Write_U32((resetCode << 3) | 0x80000000, 0x800030f0); // Warm reset + LoadBootDOLFromDisc(); + return; } else if ((GPR(4) >> 28) == 0xA) { @@ -398,7 +442,7 @@ void OSBootDol() argsPtr = Memory::Read_U32(GPR(5)); Memory::GetString(args, argsPtr); - BootDOLFromDisc(); + LoadDOLFromDisc(); return; } else diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.h b/Source/Core/Core/Src/HLE/HLE_Misc.h index f831e5b600..d39280831c 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.h +++ b/Source/Core/Core/Src/HLE/HLE_Misc.h @@ -40,6 +40,7 @@ namespace HLE_Misc void FZ_rsqrt_internal(); void HBReload(); void OSBootDol(); + void ExecuteDOL(u8* dolFile, u32 fileSize); } #endif diff --git a/Source/Core/Core/Src/HW/ProcessorInterface.cpp b/Source/Core/Core/Src/HW/ProcessorInterface.cpp index 4a18ce63b5..0e989d3f50 100644 --- a/Source/Core/Core/Src/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/Src/HW/ProcessorInterface.cpp @@ -199,6 +199,7 @@ void Write32(const u32 _uValue, const u32 _iAddress) case PI_RESET_CODE: DEBUG_LOG(PROCESSORINTERFACE, "Write %08x to PI_RESET_CODE", _uValue); + m_ResetCode = _uValue; break; case PI_FLIPPER_UNK: diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp index 8f40ab2f18..f1d5f20b6e 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.cpp +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.cpp @@ -159,7 +159,7 @@ bool CFileSystemGCWii::ExportApploader(const char* _rExportFolder) const return false; } -bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const +u32 CFileSystemGCWii::GetBootDOLSize() const { u32 DolOffset = Read32(0x420) << m_OffsetShift; u32 DolSize = 0, offset = 0, size = 0; @@ -181,9 +181,22 @@ bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const if (offset + size > DolSize) DolSize = offset + size; } + return DolSize; +} +bool CFileSystemGCWii::GetBootDOL(u8* &buffer, u32 DolSize) const +{ + u32 DolOffset = Read32(0x420) << m_OffsetShift; + return m_rVolume->Read(DolOffset, DolSize, buffer); +} + +bool CFileSystemGCWii::ExportDOL(const char* _rExportFolder) const +{ + u32 DolOffset = Read32(0x420) << m_OffsetShift; + u32 DolSize = GetBootDOLSize(); u8* buffer = new u8[DolSize]; - if (m_rVolume->Read(DolOffset, DolSize, buffer)) + + if (GetBootDOL(buffer, DolSize)) { char exportName[512]; sprintf(exportName, "%s/boot.dol", _rExportFolder); diff --git a/Source/Core/DiscIO/Src/FileSystemGCWii.h b/Source/Core/DiscIO/Src/FileSystemGCWii.h index 38e5f181f9..0e7d836d75 100644 --- a/Source/Core/DiscIO/Src/FileSystemGCWii.h +++ b/Source/Core/DiscIO/Src/FileSystemGCWii.h @@ -38,6 +38,8 @@ public: virtual bool ExportFile(const char* _rFullPath, const char* _rExportFilename); virtual bool ExportApploader(const char* _rExportFolder) const; virtual bool ExportDOL(const char* _rExportFolder) const; + virtual bool GetBootDOL(u8* &buffer, u32 DolSize) const; + virtual u32 GetBootDOLSize() const; private: bool m_Initialized; diff --git a/Source/Core/DiscIO/Src/Filesystem.h b/Source/Core/DiscIO/Src/Filesystem.h index 71be4293e3..8bc98e6a77 100644 --- a/Source/Core/DiscIO/Src/Filesystem.h +++ b/Source/Core/DiscIO/Src/Filesystem.h @@ -57,6 +57,8 @@ public: virtual bool ExportApploader(const char* _rExportFolder) const = 0; virtual bool ExportDOL(const char* _rExportFolder) const = 0; virtual const char* GetFileName(u64 _Address) = 0; + virtual bool GetBootDOL(u8* &buffer, u32 DolSize) const = 0; + virtual u32 GetBootDOLSize() const = 0; virtual const IVolume *GetVolume() const { return m_rVolume; } protected: From 05730af7244fc3ce98f7475f4ebe906234ef1789 Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 5 May 2012 22:55:24 +1000 Subject: [PATCH 5/9] Added some IOS version checks and code to clear memory before loading the dol. --- Source/Core/Core/Src/Boot/Boot.cpp | 2 +- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 6 ++++++ Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index ef3ae2a4fb..0fa89a28cc 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -258,7 +258,7 @@ bool CBoot::BootUp() } // Scan for common HLE functions - if (!_StartupPara.bEnableDebugging) + if (!_StartupPara.bEnableDebugging && Memory::Read_U16(0x00003140) >= 30) { PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB); SignatureDB db; diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index 40073d401e..b04e8004fd 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -301,6 +301,12 @@ void HBReload() void ExecuteDOL(u8* dolFile, u32 fileSize) { + // Clear memory before loading the dol + for (int i = 0x80004000; i < Memory::Read_U32(0x00000034); i += 4) + { + // TODO: Should not write over the "save region" + Memory::Write_U32(0x00000000, i); + } CDolLoader dolLoader(dolFile, fileSize); dolLoader.Load(); diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp index f409c88c83..f15dc81ce7 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.cpp @@ -780,7 +780,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress) // someone with an affected game should test IOSv = TitleID & 0xffff; } - if (!bSuccess) + if (!bSuccess && IOSv >= 30 && IOSv != 0xffff) { PanicAlertT("IOCTL_ES_LAUNCH: Game tried to reload ios or a title that is not available in your nand dump\n" "TitleID %016llx.\n Dolphin will likely hang now", TitleID); From 95f66859008fe3dd16f0232e0da5623857abbe44 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 28 Dec 2012 14:26:46 +1100 Subject: [PATCH 6/9] Changed the HLE system to allow it to hook the beginning, the end or replace the entire function without changing the GC memory. Fixes Kirby's Return to Dreamland. Added a way to categorise the type of HLE function. Currently, there are debug, floating point, memory and generic functions. Added a HLE function for OSGetResetCode (Warm reset). Fixes the CSI games. Added a switch to disable all of the HLE functions if the idle skipping option is disabled. --- Data/Sys/totaldb.dsy | Bin 723252 -> 723388 bytes Source/Core/Core/Src/Boot/Boot.cpp | 3 +- Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp | 2 +- Source/Core/Core/Src/HLE/HLE.cpp | 115 +++++++++++------- Source/Core/Core/Src/HLE/HLE.h | 26 +++- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 96 +++++++++++++-- Source/Core/Core/Src/HLE/HLE_Misc.h | 7 ++ Source/Core/Core/Src/HW/Memmap.cpp | 5 +- .../Core/Core/Src/HW/ProcessorInterface.cpp | 3 +- .../Src/PowerPC/Interpreter/Interpreter.cpp | 98 +++++++++------ Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp | 37 +++++- .../Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp | 39 +++++- .../Core/Src/PowerPC/JitCommon/JitCache.cpp | 6 +- .../Core/Src/PowerPC/JitCommon/Jit_Util.cpp | 25 ++-- 14 files changed, 339 insertions(+), 123 deletions(-) diff --git a/Data/Sys/totaldb.dsy b/Data/Sys/totaldb.dsy index a1c9683c9f57ca74ba2693c818d474dcb4761b2e..8eb9c28bf769b1b762c83b503d2733400a02e697 100644 GIT binary patch delta 56 zcmdloNoUVw9meC0jIE47#MH{j+{(z(%E;Qv$kxip-pa_)%E;Nu$hDP`+nAH}*sruk LgXu57u{8q#y~7ZL delta 45 zcmdlpS!c^69mZpgjIE47#MH{j+{(z(%E;Qv$kxip-pa_)%E;Nu$hDP`+n5soCFBaH diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index 0fa89a28cc..aaaa4dd39a 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -258,7 +258,7 @@ bool CBoot::BootUp() } // Scan for common HLE functions - if (!_StartupPara.bEnableDebugging && Memory::Read_U16(0x00003140) >= 30) + if (_StartupPara.bSkipIdle && !_StartupPara.bEnableDebugging) { PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB); SignatureDB db; @@ -267,7 +267,6 @@ bool CBoot::BootUp() db.Apply(&g_symbolDB); HLE::PatchFunctions(); db.Clear(); - g_symbolDB.Clear(); } } diff --git a/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp index bd789fa82b..5011543448 100644 --- a/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BS2Emu.cpp @@ -375,7 +375,7 @@ bool CBoot::EmulatedBS2_Wii() u32 iLength = Memory::ReadUnchecked_U32(0x81300008); u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2; - INFO_LOG(BOOT, "DVDRead: offset: %08x memOffse: %08x length: %i", iDVDOffset, iRamAddress, iLength); + INFO_LOG(BOOT, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength); DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength); } while(PowerPC::ppcState.gpr[3] != 0x00); diff --git a/Source/Core/Core/Src/HLE/HLE.cpp b/Source/Core/Core/Src/HLE/HLE.cpp index 0c42f7f4df..457870ba1d 100644 --- a/Source/Core/Core/Src/HLE/HLE.cpp +++ b/Source/Core/Core/Src/HLE/HLE.cpp @@ -15,7 +15,6 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ -#include #include "Common.h" #include "HLE.h" @@ -29,6 +28,7 @@ #include "HLE_Misc.h" #include "IPC_HLE/WII_IPC_HLE_Device_es.h" #include "ConfigManager.h" +#include "Core.h" namespace HLE { @@ -47,56 +47,72 @@ struct SPatch { char m_szPatchName[128]; TPatchFunction PatchFunction; + int type; + int flags; }; static const SPatch OSPatches[] = { - { "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction }, + { "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // speedup - //{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse }, - //{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState }, + //{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ "memcpy", HLE_Misc::memcpy, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memcmp", HLE_Misc::memcmp, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memset", HLE_Misc::memset, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memmove", HLE_Misc::memmove, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "__div2i", HLE_Misc::div2i, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower? + //{ "__div2u", HLE_Misc::div2u, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower? + + //{ "DCFlushRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ "DCInvalidateRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ "DCZeroRange", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // debug out is very nice ;) - { "OSReport", HLE_OS::HLE_GeneralDebugPrint }, - { "DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint }, - { "WUD_DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint }, - { "OSPanic", HLE_OS::HLE_OSPanic }, - { "vprintf", HLE_OS::HLE_GeneralDebugPrint }, - { "printf", HLE_OS::HLE_GeneralDebugPrint }, - { "puts", HLE_OS::HLE_GeneralDebugPrint }, // gcc-optimized printf? - { "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint }, // used for early init things (normally) - { "___blank", HLE_OS::HLE_GeneralDebugPrint }, - { "__write_console", HLE_OS::HLE_write_console }, // used by sysmenu (+more?) + { "OSReport", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "WUD_DEBUGPrint", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "OSPanic", HLE_OS::HLE_OSPanic, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "vprintf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "printf", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "puts", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // gcc-optimized printf? + { "___blank(char *,...)", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used for early init things (normally) + { "___blank", HLE_OS::HLE_GeneralDebugPrint, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + { "__write_console", HLE_OS::HLE_write_console, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, // used by sysmenu (+more?) // wii only - //{ "__OSInitAudioSystem", HLE_Misc::UnimplementedFunction }, + //{ "__OSInitAudioSystem", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Super Monkey Ball - no longer needed. - //{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine }, - //{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize }, - //{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength }, - //{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize }, - { "PanicAlert", HLE_Misc::HLEPanicAlert }, - //{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal }, - //{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal }, - //{ ".atan2", HLE_Misc::SMB_atan2}, - //{ ".sqrt_fz", HLE_Misc::FZ_sqrt}, + //{ ".evil_vec_cosine", HLE_Misc::SMB_EvilVecCosine, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".evil_normalize", HLE_Misc::SMB_EvilNormalize, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".evil_vec_setlength", HLE_Misc::SMB_evil_vec_setlength, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".evil_vec_something", HLE_Misc::FZero_evil_vec_normalize, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + { "PanicAlert", HLE_Misc::HLEPanicAlert, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG }, + //{ ".sqrt_internal_needs_cr1", HLE_Misc::SMB_sqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".rsqrt_internal_needs_cr1", HLE_Misc::SMB_rsqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".atan2", HLE_Misc::SMB_atan2HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".sqrt_fz", HLE_Misc::FZ_sqrtHLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // F-zero still isn't working correctly, but these aren't really helping. - //{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal }, - //{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal }, + //{ ".sqrt_internal_fz", HLE_Misc::FZ_sqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + //{ ".rsqrt_internal_fz", HLE_Misc::FZ_rsqrt_internal, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, - //{ ".kill_infinites", HLE_Misc::FZero_kill_infinites }, + //{ ".kill_infinites", HLE_Misc::FZero_kill_infinites, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // special - // { "GXPeekZ", HLE_Misc::GXPeekZ}, - // { "GXPeekARGB", HLE_Misc::GXPeekARGB}, + // { "GXPeekZ", HLE_Misc::GXPeekZHLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + // { "GXPeekARGB", HLE_Misc::GXPeekARGBHLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Name doesn't matter, installed in CBoot::BootUp() - { "HBReload", HLE_Misc::HBReload }, - { "__OSBootDol", HLE_Misc::OSBootDol }, + { "HBReload", HLE_Misc::HBReload, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + + // ES_LAUNCH + { "__OSBootDol", HLE_Misc::OSBootDol, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + { "OSGetResetCode", HLE_Misc::OSGetResetCode, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, + }; static const SPatch OSBreakPoints[] = @@ -104,17 +120,13 @@ static const SPatch OSBreakPoints[] = { "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction }, }; - -static std::map orig_instruction; - -void Patch(u32 address, const char *hle_func_name) +void Patch(u32 addr, const char *hle_func_name) { for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++) { if (!strcmp(OSPatches[i].m_szPatchName, hle_func_name)) { - u32 HLEPatchValue = (1 & 0x3f) << 26; - Memory::Write_U32(HLEPatchValue | i, address); + orig_instruction[addr] = i; return; } } @@ -128,11 +140,9 @@ void PatchFunctions() Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName); if (symbol > 0) { - u32 HLEPatchValue = (1 & 0x3f) << 26; for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) { - orig_instruction[addr] = Memory::ReadUnchecked_U32(addr); - Memory::Write_U32(HLEPatchValue | i, addr); + orig_instruction[addr] = i; } INFO_LOG(OSHLE, "Patching %s %08x", OSPatches[i].m_szPatchName, symbol->address); } @@ -169,12 +179,33 @@ void Execute(u32 _CurrentPC, u32 _Instruction) // _dbg_assert_msg_(HLE,NPC == LR, "Broken HLE function (doesn't set NPC)", OSPatches[pos].m_szPatchName); } -u32 GetOrigInstruction(u32 addr) +u32 GetFunctionIndex(u32 addr) { std::map::const_iterator iter = orig_instruction.find(addr); return (iter != orig_instruction.end()) ? iter->second : 0; } +int GetFunctionTypeByIndex(u32 index) +{ + return OSPatches[index].type; +} + +int GetFunctionFlagsByIndex(u32 index) +{ + return OSPatches[index].flags; +} + +bool IsEnabled(int flags) +{ + if (flags == HLE::HLE_TYPE_MEMORY && Core::g_CoreStartupParameter.bMMU) + return false; + + if (flags == HLE::HLE_TYPE_DEBUG && !Core::g_CoreStartupParameter.bEnableDebugging && PowerPC::GetMode() != MODE_INTERPRETER) + return false; + + return true; +} + u32 UnPatch(std::string patchName) { Symbol *symbol = g_symbolDB.GetSymbolFromName(patchName.c_str()); @@ -182,7 +213,7 @@ u32 UnPatch(std::string patchName) { for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4) { - Memory::WriteUnchecked_U32(orig_instruction[addr], addr); + orig_instruction[addr] = 0; PowerPC::ppcState.iCache.Invalidate(addr); } return symbol->address; diff --git a/Source/Core/Core/Src/HLE/HLE.h b/Source/Core/Core/Src/HLE/HLE.h index b81f347b9f..9318d34197 100644 --- a/Source/Core/Core/Src/HLE/HLE.h +++ b/Source/Core/Core/Src/HLE/HLE.h @@ -18,16 +18,40 @@ #ifndef _HLE_H #define _HLE_H +#include #include "Common.h" namespace HLE { + enum + { + HLE_HOOK_START = 0, // Hook the beginning of the function and execute the function afterwards + HLE_HOOK_END = 1, // Hook the end of the function, executing the function first before the hook + HLE_HOOK_REPLACE = 2, // Replace the function with the HLE version + HLE_HOOK_NONE = 3, // Do not hook the function + }; + + enum + { + HLE_TYPE_GENERIC = 0, // Miscellaneous function + HLE_TYPE_MEMORY = 1, // Memory operation + HLE_TYPE_FP = 2, // Floating Point operation + HLE_TYPE_DEBUG = 3, // Debug output function + }; + void PatchFunctions(); + void Patch(u32 pc, const char *func_name); u32 UnPatch(std::string patchName); void Execute(u32 _CurrentPC, u32 _Instruction); - u32 GetOrigInstruction(u32 em_address); + u32 GetFunctionIndex(u32 em_address); + int GetFunctionTypeByIndex(u32 index); + int GetFunctionFlagsByIndex(u32 index); + + bool IsEnabled(int flags); + + static std::map orig_instruction; } #endif diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index b04e8004fd..4a17ffd748 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -37,7 +37,6 @@ namespace HLE_Misc { -std::string dol; std::string args; u32 argsPtr; u32 bootType; @@ -302,7 +301,7 @@ void HBReload() void ExecuteDOL(u8* dolFile, u32 fileSize) { // Clear memory before loading the dol - for (int i = 0x80004000; i < Memory::Read_U32(0x00000034); i += 4) + for (u32 i = 0x80004000; i < Memory::Read_U32(0x00000034); i += 4) { // TODO: Should not write over the "save region" Memory::Write_U32(0x00000000, i); @@ -320,7 +319,6 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) db.Apply(&g_symbolDB); HLE::PatchFunctions(); db.Clear(); - g_symbolDB.Clear(); } } @@ -359,12 +357,12 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) NPC = dolLoader.GetEntryPoint() | 0x80000000; } -void LoadDOLFromDisc() +void LoadDOLFromDisc(std::string dol) { DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); - if (dol.substr(1, 1).compare("//")) + if (dol.length() > 1 && dol.compare(0, 1, "/") == 0) dol = dol.substr(1); u32 fileSize = (u32) pFileSystem->GetFileSize(dol.c_str()); @@ -391,19 +389,92 @@ void LoadBootDOLFromDisc() delete[] dolFile; } -u32 GetDolFileSize() +u32 GetDolFileSize(std::string dol) { DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str()); DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume); std::string dolFile; - if (dol.substr(1, 1).compare("//")) + if (dol.length() > 1 && dol.compare(0, 1, "/") == 0) dolFile = dol.substr(1); + else + dolFile = dol; return (u32)pFileSystem->GetFileSize(dolFile.c_str()); } +void memmove() +{ + u32 dest = GPR(3); + u32 src = GPR(4); + u32 count = GPR(5); + std::memmove((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); + NPC = LR; +} + +void memcpy() +{ + u32 dest = GPR(3); + u32 src = GPR(4); + u32 count = GPR(5); + std::memcpy((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); + NPC = LR; +} + +void memset() +{ + u32 dest = GPR(3); + u32 ch = GPR(4); + u32 count = GPR(5); + std::memset((u8*)(Memory::base + dest), ch, count); + NPC = LR; +} + +void memcmp() +{ + u32 dest = GPR(3); + u32 src = GPR(4); + u32 count = GPR(5); + GPR(3) = std::memcmp((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); + NPC = LR; +} + +void div2i() +{ + s64 num = (s64)(GPR(3)) << 32 | GPR(4); + s64 den = (s64)(GPR(5)) << 32 | GPR(6); + s64 quo = num / den; + GPR(3) = quo >> 32; + GPR(4) = quo & 0xffffffff; + NPC = LR; +} + +void div2u() +{ + u64 num = (u64)(GPR(3)) << 32 | GPR(4); + u64 den = (u64)(GPR(5)) << 32 | GPR(6); + u64 quo = num / den; + GPR(3) = quo >> 32; + GPR(4) = quo & 0xffffffff; + NPC = LR; +} + +void OSGetResetCode() +{ + u32 resetCode = Memory::Read_U32(0xCC003024); + if (resetCode != 0) + { + GPR(3) = resetCode | 0x80000000; + } + else + { + GPR(3) = 0; + } + + NPC = LR; +} + void OSBootDol() { IOSv = Memory::Read_U16(0x00003140); @@ -417,8 +488,7 @@ void OSBootDol() u32 resetCode = GPR(30); // Reset game - Memory::Write_U32(resetCode << 3, 0xCC003024); - //Memory::Write_U32((resetCode << 3) | 0x80000000, 0x800030f0); // Warm reset + Memory::Write_U32(resetCode, 0xCC003024); LoadBootDOLFromDisc(); return; } @@ -429,15 +499,17 @@ void OSBootDol() } else if ((GPR(4) >> 28) == 0xC) { + std::string dol; + // Boot DOL from disc u32 ptr = GPR(28); Memory::GetString(dol, ptr); - if (GetDolFileSize() == 0) + if (GetDolFileSize(dol) == 0) { ptr = GPR(30); Memory::GetString(dol, ptr); - if (GetDolFileSize() == 0) + if (GetDolFileSize(dol) == 0) { // Cannot locate the dol file, exit. HLE::UnPatch("__OSBootDol"); @@ -448,7 +520,7 @@ void OSBootDol() argsPtr = Memory::Read_U32(GPR(5)); Memory::GetString(args, argsPtr); - LoadDOLFromDisc(); + LoadDOLFromDisc(dol); return; } else diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.h b/Source/Core/Core/Src/HLE/HLE_Misc.h index d39280831c..d0d098835f 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.h +++ b/Source/Core/Core/Src/HLE/HLE_Misc.h @@ -40,6 +40,13 @@ namespace HLE_Misc void FZ_rsqrt_internal(); void HBReload(); void OSBootDol(); + void OSGetResetCode(); + void memcpy(); + void memset(); + void memmove(); + void memcmp(); + void div2i(); + void div2u(); void ExecuteDOL(u8* dolFile, u32 fileSize); } diff --git a/Source/Core/Core/Src/HW/Memmap.cpp b/Source/Core/Core/Src/HW/Memmap.cpp index 2da999eeac..88f6b2c358 100644 --- a/Source/Core/Core/Src/HW/Memmap.cpp +++ b/Source/Core/Core/Src/HW/Memmap.cpp @@ -416,10 +416,7 @@ bool AreMemoryBreakpointsActivated() u32 Read_Instruction(const u32 em_address) { UGeckoInstruction inst = ReadUnchecked_U32(em_address); - if (inst.OPCD == 1) - return HLE::GetOrigInstruction(em_address); - else - return inst.hex; + return inst.hex; } u32 Read_Opcode_JIT_Uncached(const u32 _Address) diff --git a/Source/Core/Core/Src/HW/ProcessorInterface.cpp b/Source/Core/Core/Src/HW/ProcessorInterface.cpp index 0e989d3f50..9e72cc2169 100644 --- a/Source/Core/Core/Src/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/Src/HW/ProcessorInterface.cpp @@ -96,8 +96,7 @@ void Init() m_FlipperRev = 0x246500B1; // revision C m_Unknown = 0; - // Bleh, why? - //m_ResetCode |= 0x80000000; + m_ResetCode = 0x80000000; // Cold reset m_InterruptCause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI; toggleResetButton = CoreTiming::RegisterEvent("ToggleResetButton", &ToggleResetButtonCallback); diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp index a8277d868a..be68d357a3 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp @@ -26,6 +26,7 @@ #include "PowerPCDisasm.h" #include "../../IPC_HLE/WII_IPC_HLE.h" #include "Atomic.h" +#include "HLE/HLE.h" namespace { @@ -79,57 +80,63 @@ int startTrace = 0; void Trace( UGeckoInstruction &instCode ) { - char regs[500]=""; + char reg[25]=""; + std::string regs = ""; for (int i=0; i<32; i++) { - sprintf(regs, "%sr%02d: %08x ", regs, i, PowerPC::ppcState.gpr[i]); + sprintf(reg, "r%02d: %08x ", i, PowerPC::ppcState.gpr[i]); + regs.append(reg); } - char fregs[500]=""; + char freg[25]=""; + std::string fregs = ""; for (int i=0; i<32; i++) { - sprintf(fregs, "%sf%02d: %08llx %08llx ", fregs, i, - PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]); + sprintf(freg, "f%02d: %08llx %08llx ", i, PowerPC::ppcState.ps[i][0], PowerPC::ppcState.ps[i][1]); + fregs.append(freg); } 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); + 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.c_str(), fregs.c_str(), instCode.hex, ppcInst); } int Interpreter::SingleStepInner(void) { static UGeckoInstruction instCode; - NPC = PC + sizeof(UGeckoInstruction); - 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) + u32 function = m_EndBlock ? HLE::GetFunctionIndex(PC) : 0; // Check for HLE functions after branches + if (function != 0) { - Trace(instCode); - } - - if (instCode.hex != 0) - { - UReg_MSR& msr = (UReg_MSR&)MSR; - if (msr.FP) //If FPU is enabled, just execute + int type = HLE::GetFunctionTypeByIndex(function); + if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE) { - m_opTable[instCode.OPCD](instCode); - if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + int flags = HLE::GetFunctionFlagsByIndex(function); + if (HLE::IsEnabled(flags)) { - PowerPC::CheckExceptions(); - m_EndBlock = true; + HLEFunction(function); } } - else + } + else + { + NPC = PC + sizeof(UGeckoInstruction); + 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) { - // check if we have to generate a FPU unavailable exception - if (!PPCTables::UsesFPU(instCode)) + Trace(instCode); + } + + if (instCode.hex != 0) + { + UReg_MSR& msr = (UReg_MSR&)MSR; + if (msr.FP) //If FPU is enabled, just execute { m_opTable[instCode.OPCD](instCode); if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) @@ -140,17 +147,30 @@ int Interpreter::SingleStepInner(void) } else { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE); - PowerPC::CheckExceptions(); - m_EndBlock = true; + // check if we have to generate a FPU unavailable exception + if (!PPCTables::UsesFPU(instCode)) + { + m_opTable[instCode.OPCD](instCode); + if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) + { + PowerPC::CheckExceptions(); + m_EndBlock = true; + } + } + else + { + Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE); + PowerPC::CheckExceptions(); + m_EndBlock = true; + } } } - } - else - { - // Memory exception on instruction fetch - PowerPC::CheckExceptions(); - m_EndBlock = true; + else + { + // Memory exception on instruction fetch + PowerPC::CheckExceptions(); + m_EndBlock = true; + } } last_pc = PC; PC = NPC; diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 357eeb7809..31caca0a43 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -252,8 +252,6 @@ void Jit64::HLEFunction(UGeckoInstruction _inst) gpr.Flush(FLUSH_ALL); fpr.Flush(FLUSH_ALL); ABI_CallFunctionCC((void*)&HLE::Execute, js.compilerPC, _inst.hex); - MOV(32, R(EAX), M(&NPC)); - WriteExitDestInEAX(); } void Jit64::DoNothing(UGeckoInstruction _inst) @@ -566,6 +564,27 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc ABI_CallFunction(thunks.ProtectFunction((void *)&GPFifo::CheckGatherPipe, 0)); } + u32 function = HLE::GetFunctionIndex(ops[i].address); + if (function != 0) + { + int type = HLE::GetFunctionTypeByIndex(function); + if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE) + { + int flags = HLE::GetFunctionFlagsByIndex(function); + if (HLE::IsEnabled(flags)) + { + HLEFunction(function); + if (type == HLE::HLE_HOOK_REPLACE) + { + MOV(32, R(EAX), M(&NPC)); + js.downcountAmount += js.st.numCycles; + WriteExitDestInEAX(); + break; + } + } + } + } + if (!ops[i].skip) { if ((opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound) @@ -668,6 +687,20 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc break; } + u32 function = HLE::GetFunctionIndex(js.blockStart); + if (function != 0) + { + int type = HLE::GetFunctionTypeByIndex(function); + if (type == HLE::HLE_HOOK_END) + { + int flags = HLE::GetFunctionFlagsByIndex(function); + if (HLE::IsEnabled(flags)) + { + HLEFunction(function); + } + } + } + if (memory_exception) { // Address of instruction could not be translated diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index c9d4e44e71..d56c9ffee8 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -199,7 +199,7 @@ namespace JitILProfiler static u64 beginTime; static Block& Add(u64 codeHash) { - const u32 _blockIndex = blocks.size(); + const u32 _blockIndex = (u32)blocks.size(); blocks.push_back(Block()); Block& block = blocks.back(); block.index = _blockIndex; @@ -649,6 +649,27 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc js.next_compilerPC = ops[i + 1].address; } + u32 function = HLE::GetFunctionIndex(ops[i].address); + if (function != 0) + { + int type = HLE::GetFunctionTypeByIndex(function); + if (type == HLE::HLE_HOOK_START || type == HLE::HLE_HOOK_REPLACE) + { + int flags = HLE::GetFunctionFlagsByIndex(function); + if (HLE::IsEnabled(flags)) + { + HLEFunction(function); + if (type == HLE::HLE_HOOK_REPLACE) + { + MOV(32, R(EAX), M(&NPC)); + jit->js.downcountAmount += jit->js.st.numCycles; + WriteExitDestInOpArg(R(EAX)); + break; + } + } + } + } + if (!ops[i].skip) { if (js.memcheck && (opinfo->flags & FL_USE_FPU)) @@ -665,7 +686,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { ibuild.EmitBreakPointCheck(ibuild.EmitIntConst(ops[i].address)); } - + JitILTables::CompileInstruction(ops[i]); if (js.memcheck && (opinfo->flags & FL_LOADSTORE)) @@ -681,6 +702,20 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } } + u32 function = HLE::GetFunctionIndex(jit->js.blockStart); + if (function != 0) + { + int type = HLE::GetFunctionTypeByIndex(function); + if (type == HLE::HLE_HOOK_END) + { + int flags = HLE::GetFunctionFlagsByIndex(function); + if (HLE::IsEnabled(flags)) + { + HLEFunction(function); + } + } + } + if (memory_exception) { ibuild.EmitISIException(ibuild.EmitIntConst(em_address)); diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index 496ddebf7a..57827ec662 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -135,7 +135,11 @@ bool JitBlock::ContainsAddress(u32 em_address) // is full and when saving and loading states. void JitBlockCache::Clear() { - Core::DisplayMessage("Clearing code cache.", 3000); + if (IsFull()) + Core::DisplayMessage("Clearing block cache.", 3000); + else + Core::DisplayMessage("Clearing code cache.", 3000); + for (int i = 0; i < num_blocks; i++) { DestroyBlock(i, false); diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp index 333f0cdc05..7ec780b336 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/Jit_Util.cpp @@ -269,23 +269,18 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce void EmuCodeBlock::SafeWriteFloatToReg(X64Reg xmm_value, X64Reg reg_addr) { - u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS; - - if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) - { - mem_mask |= Memory::ADDR_MASK_MEM1; - } - -#ifdef ENABLE_MEM_CHECK - if (Core::g_CoreStartupParameter.bEnableDebugging) - { - mem_mask |= Memory::EXRAM_MASK; - } -#endif - - TEST(32, R(reg_addr), Imm32(mem_mask)); if (false && cpu_info.bSSSE3) { // This path should be faster but for some reason it causes errors so I've disabled it. + u32 mem_mask = Memory::ADDR_MASK_HW_ACCESS; + + if (Core::g_CoreStartupParameter.bMMU || Core::g_CoreStartupParameter.iTLBHack) + mem_mask |= Memory::ADDR_MASK_MEM1; + +#ifdef ENABLE_MEM_CHECK + if (Core::g_CoreStartupParameter.bEnableDebugging) + mem_mask |= Memory::EXRAM_MASK; +#endif + TEST(32, R(reg_addr), Imm32(mem_mask)); FixupBranch argh = J_CC(CC_Z); MOVSS(M(&float_buffer), xmm_value); MOV(32, R(EAX), M(&float_buffer)); From 1c9c6052d5fb3264a3a687b1d6fb87b89f229e7e Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 5 Jan 2013 12:32:47 +1100 Subject: [PATCH 7/9] Corrected a state bug where newly loaded dols did not have their patches applied. --- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index 4a17ffd748..da39a71372 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -40,7 +40,6 @@ namespace HLE_Misc std::string args; u32 argsPtr; u32 bootType; -u16 IOSv; // Helper to quickly read the floating point value at a memory location. inline float F(u32 addr) @@ -312,6 +311,7 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) // Scan for common HLE functions if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging) { + g_symbolDB.Clear(); PPCAnalyst::FindFunctions(0x80004000, 0x811fffff, &g_symbolDB); SignatureDB db; if (db.Load((File::GetSysDirectory() + TOTALDB).c_str())) @@ -325,9 +325,15 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) PowerPC::ppcState.iCache.Reset(); static CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer(); - for (unsigned int i = 0; i < 4; i++) + bool* wiiMoteConnected = new bool[s_Usb->m_WiiMotes.size()]; + for(unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++) + wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected(); + + WII_IPC_HLE_Interface::Reset(true); + WII_IPC_HLE_Interface::Init(); + for (unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++) { - if (s_Usb->m_WiiMotes[i].IsConnected()) + if (wiiMoteConnected[i]) { s_Usb->m_WiiMotes[i].Activate(false); s_Usb->m_WiiMotes[i].Activate(true); @@ -338,6 +344,8 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) } } + delete[] wiiMoteConnected; + if (argsPtr) { u32 args_base = Memory::Read_U32(0x800000f4); @@ -475,11 +483,14 @@ void OSGetResetCode() NPC = LR; } +u16 GetIOSVersion() +{ + return Memory::Read_U16(0x00003140); +} + void OSBootDol() { - IOSv = Memory::Read_U16(0x00003140); - - if (IOSv >= 30) + if (GetIOSVersion() >= 30) { bootType = GPR(4); From c61b0c7fbaf2cb1f0ce80e825022f16d26a736c3 Mon Sep 17 00:00:00 2001 From: skidau Date: Sat, 5 Jan 2013 12:56:35 +1100 Subject: [PATCH 8/9] Build fix --- Source/Core/Core/Src/HLE/HLE.cpp | 8 ++++---- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Source/Core/Core/Src/HLE/HLE.cpp b/Source/Core/Core/Src/HLE/HLE.cpp index 457870ba1d..ae25060c64 100644 --- a/Source/Core/Core/Src/HLE/HLE.cpp +++ b/Source/Core/Core/Src/HLE/HLE.cpp @@ -58,10 +58,10 @@ static const SPatch OSPatches[] = // speedup //{ "OSProtectRange", HLE_Misc::UnimplementedFunctionFalse, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, //{ "THPPlayerGetState", HLE_Misc:THPPlayerGetState, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, - //{ "memcpy", HLE_Misc::memcpy, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, - //{ "memcmp", HLE_Misc::memcmp, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, - //{ "memset", HLE_Misc::memset, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, - //{ "memmove", HLE_Misc::memmove, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memcpy", HLE_Misc::gc_memcpy, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memcmp", HLE_Misc::gc_memcmp, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memset", HLE_Misc::gc_memset, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, + //{ "memmove", HLE_Misc::gc_memmove, HLE_HOOK_REPLACE, HLE_TYPE_MEMORY }, //{ "__div2i", HLE_Misc::div2i, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower? //{ "__div2u", HLE_Misc::div2u, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC }, // Slower? diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index da39a71372..e6d1fc5611 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -358,7 +358,7 @@ void ExecuteDOL(u8* dolFile, u32 fileSize) Memory::Write_U32(num_args, args_base + ptr_to_num_args); Memory::Write_U32(0x14, hi_ptr); - for (int i = 0; i < args.length(); i++) + for (unsigned int i = 0; i < args.length(); i++) Memory::WriteUnchecked_U8(args[i], new_args_ptr+i); } @@ -412,39 +412,39 @@ u32 GetDolFileSize(std::string dol) return (u32)pFileSystem->GetFileSize(dolFile.c_str()); } -void memmove() +void gc_memmove() { u32 dest = GPR(3); u32 src = GPR(4); u32 count = GPR(5); - std::memmove((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); + memmove((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); NPC = LR; } -void memcpy() +void gc_memcpy() { u32 dest = GPR(3); u32 src = GPR(4); u32 count = GPR(5); - std::memcpy((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); + memcpy((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); NPC = LR; } -void memset() +void gc_memset() { u32 dest = GPR(3); u32 ch = GPR(4); u32 count = GPR(5); - std::memset((u8*)(Memory::base + dest), ch, count); + memset((u8*)(Memory::base + dest), ch, count); NPC = LR; } -void memcmp() +void gc_memcmp() { u32 dest = GPR(3); u32 src = GPR(4); u32 count = GPR(5); - GPR(3) = std::memcmp((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); + GPR(3) = memcmp((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count); NPC = LR; } From 1d691d7de4d640c998daa060201740c63d11d22a Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 6 Jan 2013 14:36:38 +1100 Subject: [PATCH 9/9] Fixed SSBB from starting at the mini-games screen. --- Source/Core/Core/Src/HLE/HLE_Misc.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/Src/HLE/HLE_Misc.cpp b/Source/Core/Core/Src/HLE/HLE_Misc.cpp index e6d1fc5611..162cc4698d 100644 --- a/Source/Core/Core/Src/HLE/HLE_Misc.cpp +++ b/Source/Core/Core/Src/HLE/HLE_Misc.cpp @@ -471,7 +471,8 @@ void div2u() void OSGetResetCode() { u32 resetCode = Memory::Read_U32(0xCC003024); - if (resetCode != 0) + + if ((resetCode & 0x1fffffff) != 0) { GPR(3) = resetCode | 0x80000000; }