Merge branch 'ES_LAUNCH'
Games that are now playable: Back to the Future: The Game CSI - Hard Evidence CSI - Deadly Intent CSI - Fatal Conspiracy Red Steel Metroid Prime: Trilogy Wii Sports + Wii Sports Resort pack Sam & Max: Season One Sam & Max: Beyond Time and Space Kirby's Dream Collection: Classic Collection Indiana Jones and the Staff of Kings: Fate of Atlantis * ES_LAUNCH: Fixed SSBB from starting at the mini-games screen. Build fix Corrected a state bug where newly loaded dols did not have their patches applied. 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. Added some IOS version checks and code to clear memory before loading the dol. Added support for Reset (from menu). Fixes Sam & Max. 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. Added argument detection and passing to the loaded dol. This fixes the Wii Sports+Wii Sports Resort bundle pack. Added preliminary support for ES_LAUNCH (Wii Multi-boot games) by using HLE to hijack the OSBootDol function. Conflicts: Source/Core/DiscIO/Src/FileSystemGCWii.cpp
This commit is contained in:
commit
7e5d877858
Binary file not shown.
|
@ -257,6 +257,19 @@ bool CBoot::BootUp()
|
|||
EmulatedBS2(_StartupPara.bWii);
|
||||
}
|
||||
|
||||
// Scan for common HLE functions
|
||||
if (_StartupPara.bSkipIdle && !_StartupPara.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();
|
||||
}
|
||||
}
|
||||
|
||||
/* Try to load the symbol map if there is one, and then scan it for
|
||||
and eventually replace code */
|
||||
if (LoadMapFromFilename(_StartupPara.m_strFilename, gameID))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
// Official SVN repository and contact information can be found at
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
#include <map>
|
||||
#include "Common.h"
|
||||
|
||||
#include "HLE.h"
|
||||
|
@ -27,6 +26,9 @@
|
|||
|
||||
#include "HLE_OS.h"
|
||||
#include "HLE_Misc.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_es.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "Core.h"
|
||||
|
||||
namespace HLE
|
||||
{
|
||||
|
@ -45,55 +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::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?
|
||||
|
||||
//{ "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 },
|
||||
{ "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[] =
|
||||
|
@ -101,17 +120,13 @@ static const SPatch OSBreakPoints[] =
|
|||
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
|
||||
};
|
||||
|
||||
|
||||
static std::map<u32, u32> 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;
|
||||
}
|
||||
}
|
||||
|
@ -125,23 +140,24 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,10 +179,46 @@ 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<u32, u32>::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());
|
||||
if (symbol > 0)
|
||||
{
|
||||
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
|
||||
{
|
||||
orig_instruction[addr] = 0;
|
||||
PowerPC::ppcState.iCache.Invalidate(addr);
|
||||
}
|
||||
return symbol->address;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // end of namespace HLE
|
||||
|
|
|
@ -18,15 +18,40 @@
|
|||
#ifndef _HLE_H
|
||||
#define _HLE_H
|
||||
|
||||
#include <map>
|
||||
#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<u32, u32> orig_instruction;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,10 +22,25 @@
|
|||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../Host.h"
|
||||
#include "IPC_HLE/WII_IPC_HLE_Device_DI.h"
|
||||
#include "ConfigManager.h"
|
||||
#include "VolumeCreator.h"
|
||||
#include "Filesystem.h"
|
||||
#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
|
||||
{
|
||||
|
||||
std::string args;
|
||||
u32 argsPtr;
|
||||
u32 bootType;
|
||||
|
||||
// Helper to quickly read the floating point value at a memory location.
|
||||
inline float F(u32 addr)
|
||||
{
|
||||
|
@ -282,4 +297,253 @@ void HBReload()
|
|||
Host_Message(WM_USER_STOP);
|
||||
}
|
||||
|
||||
void ExecuteDOL(u8* dolFile, u32 fileSize)
|
||||
{
|
||||
// Clear memory before loading the dol
|
||||
for (u32 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();
|
||||
|
||||
// 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()))
|
||||
{
|
||||
db.Apply(&g_symbolDB);
|
||||
HLE::PatchFunctions();
|
||||
db.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
PowerPC::ppcState.iCache.Reset();
|
||||
|
||||
CWII_IPC_HLE_Device_usb_oh1_57e_305* s_Usb = GetUsbPointer();
|
||||
size_t size = s_Usb->m_WiiMotes.size();
|
||||
bool* wiiMoteConnected = new bool[size];
|
||||
for (unsigned int i = 0; i < size; i++)
|
||||
wiiMoteConnected[i] = s_Usb->m_WiiMotes[i].IsConnected();
|
||||
|
||||
WII_IPC_HLE_Interface::Reset(true);
|
||||
WII_IPC_HLE_Interface::Init();
|
||||
s_Usb = GetUsbPointer();
|
||||
for (unsigned int i = 0; i < s_Usb->m_WiiMotes.size(); i++)
|
||||
{
|
||||
if (wiiMoteConnected[i])
|
||||
{
|
||||
s_Usb->m_WiiMotes[i].Activate(false);
|
||||
s_Usb->m_WiiMotes[i].Activate(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_Usb->m_WiiMotes[i].Activate(false);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] wiiMoteConnected;
|
||||
|
||||
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 (unsigned int i = 0; i < args.length(); i++)
|
||||
Memory::WriteUnchecked_U8(args[i], new_args_ptr+i);
|
||||
}
|
||||
|
||||
NPC = dolLoader.GetEntryPoint() | 0x80000000;
|
||||
}
|
||||
|
||||
void LoadDOLFromDisc(std::string dol)
|
||||
{
|
||||
DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(SConfig::GetInstance().m_LastFilename.c_str());
|
||||
DiscIO::IFileSystem* pFileSystem = DiscIO::CreateFileSystem(pVolume);
|
||||
|
||||
if (dol.length() > 1 && dol.compare(0, 1, "/") == 0)
|
||||
dol = dol.substr(1);
|
||||
|
||||
u32 fileSize = (u32) pFileSystem->GetFileSize(dol.c_str());
|
||||
u8* dolFile = new u8[fileSize];
|
||||
if (fileSize > 0)
|
||||
{
|
||||
pFileSystem->ReadFile(dol.c_str(), dolFile, fileSize);
|
||||
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(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.length() > 1 && dol.compare(0, 1, "/") == 0)
|
||||
dolFile = dol.substr(1);
|
||||
else
|
||||
dolFile = dol;
|
||||
|
||||
return (u32)pFileSystem->GetFileSize(dolFile.c_str());
|
||||
}
|
||||
|
||||
void gc_memmove()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 src = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
memmove((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void gc_memcpy()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 src = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
memcpy((u8*)(Memory::base + dest), (u8*)(Memory::base + src), count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void gc_memset()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 ch = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
memset((u8*)(Memory::base + dest), ch, count);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void gc_memcmp()
|
||||
{
|
||||
u32 dest = GPR(3);
|
||||
u32 src = GPR(4);
|
||||
u32 count = GPR(5);
|
||||
GPR(3) = 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 & 0x1fffffff) != 0)
|
||||
{
|
||||
GPR(3) = resetCode | 0x80000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPR(3) = 0;
|
||||
}
|
||||
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
u16 GetIOSVersion()
|
||||
{
|
||||
return Memory::Read_U16(0x00003140);
|
||||
}
|
||||
|
||||
void OSBootDol()
|
||||
{
|
||||
if (GetIOSVersion() >= 30)
|
||||
{
|
||||
bootType = GPR(4);
|
||||
|
||||
if ((GPR(4) >> 28) == 0x8)
|
||||
{
|
||||
u32 resetCode = GPR(30);
|
||||
|
||||
// Reset game
|
||||
Memory::Write_U32(resetCode, 0xCC003024);
|
||||
LoadBootDOLFromDisc();
|
||||
return;
|
||||
}
|
||||
else if ((GPR(4) >> 28) == 0xA)
|
||||
{
|
||||
// Boot from disc partition
|
||||
PanicAlert("Boot Partition: %08x", GPR(26));
|
||||
}
|
||||
else if ((GPR(4) >> 28) == 0xC)
|
||||
{
|
||||
std::string dol;
|
||||
|
||||
// Boot DOL from disc
|
||||
u32 ptr = GPR(28);
|
||||
Memory::GetString(dol, ptr);
|
||||
|
||||
if (GetDolFileSize(dol) == 0)
|
||||
{
|
||||
ptr = GPR(30);
|
||||
Memory::GetString(dol, ptr);
|
||||
if (GetDolFileSize(dol) == 0)
|
||||
{
|
||||
// Cannot locate the dol file, exit.
|
||||
HLE::UnPatch("__OSBootDol");
|
||||
NPC = PC;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
argsPtr = Memory::Read_U32(GPR(5));
|
||||
Memory::GetString(args, argsPtr);
|
||||
LoadDOLFromDisc(dol);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("Unknown boot type: %08x", GPR(4));
|
||||
}
|
||||
}
|
||||
HLE::UnPatch("__OSBootDol");
|
||||
NPC = PC;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,15 @@ namespace HLE_Misc
|
|||
void FZ_sqrt_internal();
|
||||
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);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
@ -199,6 +198,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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -153,7 +153,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;
|
||||
|
@ -175,6 +175,19 @@ 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();
|
||||
|
||||
std::vector<u8> buffer(DolSize);
|
||||
if (m_rVolume->Read(DolOffset, DolSize, &buffer[0]))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue