mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Remove unnecessary Src/ folders
This commit is contained in:
175
Source/Core/Core/HLE/HLE.cpp
Normal file
175
Source/Core/Core/HLE/HLE.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "HLE.h"
|
||||
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../PowerPC/PPCSymbolDB.h"
|
||||
#include "../HW/Memmap.h"
|
||||
#include "../Debugger/Debugger_SymbolMap.h"
|
||||
|
||||
#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
|
||||
{
|
||||
|
||||
using namespace PowerPC;
|
||||
|
||||
typedef void (*TPatchFunction)();
|
||||
|
||||
enum
|
||||
{
|
||||
HLE_RETURNTYPE_BLR = 0,
|
||||
HLE_RETURNTYPE_RFI = 1,
|
||||
};
|
||||
|
||||
struct SPatch
|
||||
{
|
||||
char m_szPatchName[128];
|
||||
TPatchFunction PatchFunction;
|
||||
int type;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static const SPatch OSPatches[] =
|
||||
{
|
||||
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction, HLE_HOOK_REPLACE, HLE_TYPE_GENERIC },
|
||||
|
||||
{ "PanicAlert", HLE_Misc::HLEPanicAlert, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
|
||||
// Name doesn't matter, installed in CBoot::BootUp()
|
||||
{ "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 },
|
||||
|
||||
// Debug/OS Support
|
||||
{ "OSPanic", HLE_OS::HLE_OSPanic, HLE_HOOK_REPLACE, HLE_TYPE_DEBUG },
|
||||
|
||||
{ "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 },
|
||||
{ "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?)
|
||||
{ "GeckoCodehandler", HLE_Misc::HLEGeckoCodehandler, HLE_HOOK_START, HLE_TYPE_GENERIC },
|
||||
};
|
||||
|
||||
static const SPatch OSBreakPoints[] =
|
||||
{
|
||||
{ "FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction },
|
||||
};
|
||||
|
||||
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))
|
||||
{
|
||||
orig_instruction[addr] = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PatchFunctions()
|
||||
{
|
||||
orig_instruction.clear();
|
||||
for (u32 i = 0; i < sizeof(OSPatches) / sizeof(SPatch); i++)
|
||||
{
|
||||
Symbol *symbol = g_symbolDB.GetSymbolFromName(OSPatches[i].m_szPatchName);
|
||||
if (symbol > 0)
|
||||
{
|
||||
for (u32 addr = symbol->address; addr < symbol->address + symbol->size; addr += 4)
|
||||
{
|
||||
orig_instruction[addr] = i;
|
||||
}
|
||||
INFO_LOG(OSHLE, "Patching %s %08x", OSPatches[i].m_szPatchName, symbol->address);
|
||||
}
|
||||
}
|
||||
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bEnableDebugging)
|
||||
{
|
||||
for (size_t i = 1; i < sizeof(OSBreakPoints) / sizeof(SPatch); i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CBreakPoints::AddBreakPoint(0x8000D3D0, false);
|
||||
}
|
||||
|
||||
void Execute(u32 _CurrentPC, u32 _Instruction)
|
||||
{
|
||||
unsigned int FunctionIndex = _Instruction & 0xFFFFF;
|
||||
if ((FunctionIndex > 0) && (FunctionIndex < (sizeof(OSPatches) / sizeof(SPatch))))
|
||||
{
|
||||
OSPatches[FunctionIndex].PatchFunction();
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlert("HLE system tried to call an undefined HLE function %i.", FunctionIndex);
|
||||
}
|
||||
|
||||
// _dbg_assert_msg_(HLE,NPC == LR, "Broken HLE function (doesn't set NPC)", OSPatches[pos].m_szPatchName);
|
||||
}
|
||||
|
||||
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
|
45
Source/Core/Core/HLE/HLE.h
Normal file
45
Source/Core/Core/HLE/HLE.h
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef _HLE_H
|
||||
#define _HLE_H
|
||||
|
||||
#include <map>
|
||||
#include "CommonTypes.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 GetFunctionIndex(u32 em_address);
|
||||
int GetFunctionTypeByIndex(u32 index);
|
||||
int GetFunctionFlagsByIndex(u32 index);
|
||||
|
||||
bool IsEnabled(int flags);
|
||||
|
||||
static std::map<u32, u32> orig_instruction;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
276
Source/Core/Core/HLE/HLE_Misc.cpp
Normal file
276
Source/Core/Core/HLE/HLE_Misc.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cmath>
|
||||
#include "Common.h"
|
||||
#include "HLE_OS.h"
|
||||
|
||||
#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/PPCCache.h"
|
||||
#include "PowerPC/SignatureDB.h"
|
||||
#include "PowerPC/PPCSymbolDB.h"
|
||||
#include "CommonPaths.h"
|
||||
#include "TextureCacheBase.h"
|
||||
|
||||
namespace HLE_Misc
|
||||
{
|
||||
|
||||
std::string args;
|
||||
u32 argsPtr;
|
||||
|
||||
// If you just want to kill a function, one of the three following are usually appropriate.
|
||||
// According to the PPC ABI, the return value is always in r3.
|
||||
void UnimplementedFunction()
|
||||
{
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
// If you want a function to panic, you can rename it PanicAlert :p
|
||||
// Don't know if this is worth keeping.
|
||||
void HLEPanicAlert()
|
||||
{
|
||||
::PanicAlert("HLE: PanicAlert %08x", LR);
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
void HBReload()
|
||||
{
|
||||
// There isn't much we can do. Just stop cleanly.
|
||||
PowerPC::Pause();
|
||||
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();
|
||||
TextureCache::RequestInvalidateTextureCache();
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
u16 GetIOSVersion()
|
||||
{
|
||||
return Memory::Read_U16(0x00003140);
|
||||
}
|
||||
|
||||
void OSGetResetCode()
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii)
|
||||
{
|
||||
u32 resetCode = Memory::Read_U32(0xCC003024);
|
||||
|
||||
if ((resetCode & 0x1fffffff) != 0)
|
||||
{
|
||||
GPR(3) = resetCode | 0x80000000;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPR(3) = 0;
|
||||
}
|
||||
|
||||
NPC = LR;
|
||||
}
|
||||
else
|
||||
{
|
||||
HLE::UnPatch("OSGetResetCode");
|
||||
NPC = PC;
|
||||
}
|
||||
}
|
||||
|
||||
void OSBootDol()
|
||||
{
|
||||
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && GetIOSVersion() >= 30)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void HLEGeckoCodehandler()
|
||||
{
|
||||
// Work around the codehandler not properly invalidating the icache, but
|
||||
// only the first few frames.
|
||||
// (Project M uses a conditional to only apply patches after something has
|
||||
// been read into memory, or such, so we do the first 5 frames. More
|
||||
// robust alternative would be to actually detect memory writes, but that
|
||||
// would be even uglier.)
|
||||
u32 magic = 0xd01f1bad;
|
||||
u32 existing = Memory::Read_U32(0x80001800);
|
||||
if (existing - magic == 5)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if(existing - magic > 5)
|
||||
{
|
||||
existing = magic;
|
||||
}
|
||||
Memory::Write_U32(existing + 1, 0x80001800);
|
||||
PowerPC::ppcState.iCache.Reset();
|
||||
}
|
||||
|
||||
}
|
18
Source/Core/Core/HLE/HLE_Misc.h
Normal file
18
Source/Core/Core/HLE/HLE_Misc.h
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef HLE_MISC_H
|
||||
#define HLE_MISC_H
|
||||
|
||||
namespace HLE_Misc
|
||||
{
|
||||
void HLEPanicAlert();
|
||||
void UnimplementedFunction();
|
||||
void HBReload();
|
||||
void OSBootDol();
|
||||
void OSGetResetCode();
|
||||
void HLEGeckoCodehandler();
|
||||
}
|
||||
|
||||
#endif
|
177
Source/Core/Core/HLE/HLE_OS.cpp
Normal file
177
Source/Core/Core/HLE/HLE_OS.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "StringUtil.h"
|
||||
#include <string>
|
||||
|
||||
#include "Common.h"
|
||||
#include "HLE_OS.h"
|
||||
|
||||
#include "../PowerPC/PowerPC.h"
|
||||
#include "../HW/Memmap.h"
|
||||
|
||||
namespace HLE_OS
|
||||
{
|
||||
|
||||
void GetStringVA(std::string& _rOutBuffer, u32 strReg = 3);
|
||||
|
||||
void HLE_OSPanic()
|
||||
{
|
||||
std::string Error, Msg;
|
||||
GetStringVA(Error);
|
||||
GetStringVA(Msg, 5);
|
||||
|
||||
PanicAlert("OSPanic: %s: %s", Error.c_str(), Msg.c_str());
|
||||
ERROR_LOG(OSREPORT, "%08x->%08x| OSPanic: %s: %s", LR, PC, Error.c_str(), Msg.c_str());
|
||||
|
||||
NPC = LR;
|
||||
}
|
||||
|
||||
// Generalized func for just printing string pointed to by r3.
|
||||
void HLE_GeneralDebugPrint()
|
||||
{
|
||||
std::string ReportMessage;
|
||||
if(*(u32*)Memory::GetPointer(GPR(3)) > 0x80000000){
|
||||
GetStringVA(ReportMessage, 4);
|
||||
}else{
|
||||
GetStringVA(ReportMessage);
|
||||
}
|
||||
NPC = LR;
|
||||
|
||||
//PanicAlert("(%08x->%08x) %s", LR, PC, ReportMessage.c_str());
|
||||
NOTICE_LOG(OSREPORT, "%08x->%08x| %s", LR, PC, ReportMessage.c_str());
|
||||
}
|
||||
|
||||
void HLE_VPrintf()
|
||||
{
|
||||
std::string ReportMessage;
|
||||
u32 r4 = GPR(4);
|
||||
u32 offset = Memory::Read_U32(r4+8);
|
||||
u32 check = Memory::Read_U32(r4);
|
||||
//NOTICE_LOG(OSREPORT, "Offset: %08X, Check %08X", offset, check);
|
||||
for(int i = 4; i<= 10; i++){
|
||||
GPR(i) = Memory::Read_U32(offset+(i-(check == 0x01000000? 3 : 2))*4);
|
||||
//NOTICE_LOG(OSREPORT, "r%d: %08X",i, GPR(i));
|
||||
}
|
||||
|
||||
GetStringVA(ReportMessage);
|
||||
|
||||
NPC = LR;
|
||||
|
||||
NOTICE_LOG(OSREPORT, "%08x->%08x| %s", LR, PC, ReportMessage.c_str());
|
||||
}
|
||||
// Generalized func for just printing string pointed to by r3.
|
||||
void HLE_GeneralDebugPrintWithInt()
|
||||
{
|
||||
std::string ReportMessage;
|
||||
GetStringVA(ReportMessage, 5);
|
||||
NPC = LR;
|
||||
|
||||
//PanicAlert("(%08x->%08x) %s", LR, PC, ReportMessage.c_str());
|
||||
NOTICE_LOG(OSREPORT, "%08x->%08x| %s", LR, PC, ReportMessage.c_str());
|
||||
}
|
||||
|
||||
// __write_console is slightly abnormal
|
||||
void HLE_write_console()
|
||||
{
|
||||
std::string ReportMessage;
|
||||
GetStringVA(ReportMessage, 4);
|
||||
NPC = LR;
|
||||
|
||||
//PanicAlert("(%08x->%08x) %s", LR, PC, ReportMessage.c_str());
|
||||
NOTICE_LOG(OSREPORT, "%08x->%08x| %s", LR, PC, ReportMessage.c_str());
|
||||
}
|
||||
|
||||
void GetStringVA(std::string& _rOutBuffer, u32 strReg)
|
||||
{
|
||||
_rOutBuffer = "";
|
||||
char ArgumentBuffer[256];
|
||||
u32 ParameterCounter = strReg+1;
|
||||
u32 FloatingParameterCounter = 1;
|
||||
char *pString = (char*)Memory::GetPointer(GPR(strReg));
|
||||
if (!pString)
|
||||
{
|
||||
ERROR_LOG(OSREPORT, "r%i invalid", strReg);
|
||||
return;
|
||||
}
|
||||
|
||||
while(*pString)
|
||||
{
|
||||
if (*pString == '%')
|
||||
{
|
||||
char* pArgument = ArgumentBuffer;
|
||||
*pArgument++ = *pString++;
|
||||
if(*pString == '%') {
|
||||
_rOutBuffer += "%";
|
||||
pString++;
|
||||
continue;
|
||||
}
|
||||
while(*pString < 'A' || *pString > 'z' || *pString == 'l' || *pString == '-')
|
||||
*pArgument++ = *pString++;
|
||||
|
||||
*pArgument++ = *pString;
|
||||
*pArgument = 0;
|
||||
|
||||
u64 Parameter;
|
||||
if (ParameterCounter > 10)
|
||||
{
|
||||
Parameter = Memory::Read_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*(pString-2) == 'l') && (*(pString-1) == 'l')) // hax, just seen this on sysmenu osreport
|
||||
{
|
||||
Parameter = GPR(++ParameterCounter);
|
||||
Parameter = (Parameter<<32)|GPR(++ParameterCounter);
|
||||
}
|
||||
else // normal, 32bit
|
||||
Parameter = GPR(ParameterCounter);
|
||||
}
|
||||
ParameterCounter++;
|
||||
|
||||
switch(*pString)
|
||||
{
|
||||
case 's':
|
||||
_rOutBuffer += StringFromFormat(ArgumentBuffer, (char*)Memory::GetPointer((u32)Parameter));
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
{
|
||||
//u64 Double = Memory::Read_U64(Parameter);
|
||||
_rOutBuffer += StringFromFormat(ArgumentBuffer, Parameter);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
_rOutBuffer += StringFromFormat(ArgumentBuffer,
|
||||
rPS0(FloatingParameterCounter));
|
||||
FloatingParameterCounter++;
|
||||
ParameterCounter--;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
// Override, so 64bit dolphin prints 32bit pointers, since the ppc is 32bit :)
|
||||
_rOutBuffer += StringFromFormat("%x", Parameter);
|
||||
break;
|
||||
|
||||
default:
|
||||
_rOutBuffer += StringFromFormat(ArgumentBuffer, Parameter);
|
||||
break;
|
||||
}
|
||||
pString++;
|
||||
}
|
||||
else
|
||||
{
|
||||
_rOutBuffer += StringFromFormat("%c", *pString);
|
||||
pString++;
|
||||
}
|
||||
}
|
||||
if(_rOutBuffer[_rOutBuffer.length() - 1] == '\n')
|
||||
_rOutBuffer.resize(_rOutBuffer.length() - 1);
|
||||
}
|
||||
|
||||
} // end of namespace HLE_OS
|
17
Source/Core/Core/HLE/HLE_OS.h
Normal file
17
Source/Core/Core/HLE/HLE_OS.h
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2013 Dolphin Emulator Project
|
||||
// Licensed under GPLv2
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#ifndef HLE_OS_H
|
||||
#define HLE_OS_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
namespace HLE_OS
|
||||
{
|
||||
void HLE_GeneralDebugPrint();
|
||||
void HLE_write_console();
|
||||
void HLE_OSPanic();
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user