diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 2ad7eb270a..6c84307d2f 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -554,7 +554,7 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard, if (!EmulatedBS2(system, guard, system.IsWii(), *volume, riivolution_patches)) return false; - SConfig::OnTitleDirectlyBooted(guard); + // SConfig::OnTitleDirectlyBooted(guard) is called by apploader runner code return true; } diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index 100f1cfdfd..b7f5c1d9d4 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -172,12 +173,17 @@ public: static bool FindMapFile(std::string* existing_map_file, std::string* writable_map_file); static bool LoadMapFromFilename(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db); + static void HLEAppLoaderAfterEntry(const Core::CPUThreadGuard& guard); + static void HLEAppLoaderAfterInit(const Core::CPUThreadGuard& guard); + static void HLEAppLoaderAfterMain(const Core::CPUThreadGuard& guard); + static void HLEAppLoaderAfterClose(const Core::CPUThreadGuard& guard); + static void HLEAppLoaderReport(std::string_view message); + private: static bool DVDRead(Core::System& system, const DiscIO::VolumeDisc& disc, u64 dvd_offset, u32 output_address, u32 length, const DiscIO::Partition& partition); static bool DVDReadDiscID(Core::System& system, const DiscIO::VolumeDisc& disc, u32 output_address); - static void RunFunction(Core::System& system, u32 address); static bool Boot_WiiWAD(Core::System& system, const DiscIO::VolumeWAD& wad); static bool BootNANDTitle(Core::System& system, u64 title_id); diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 884a11bd87..c22be74e98 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -24,6 +24,7 @@ #include "Core/HW/DVD/DVDInterface.h" #include "Core/HW/EXI/EXI_DeviceIPL.h" #include "Core/HW/Memmap.h" +#include "Core/Host.h" #include "Core/IOS/DI/DI.h" #include "Core/IOS/ES/ES.h" #include "Core/IOS/ES/Formats.h" @@ -32,6 +33,7 @@ #include "Core/IOS/IOSC.h" #include "Core/IOS/Uids.h" #include "Core/PowerPC/MMU.h" +#include "Core/PowerPC/PPCSymbolDB.h" #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" @@ -56,18 +58,6 @@ void PresetTimeBaseTicks(Core::System& system, const Core::CPUThreadGuard& guard } } // Anonymous namespace -void CBoot::RunFunction(Core::System& system, u32 address) -{ - auto& power_pc = system.GetPowerPC(); - auto& ppc_state = power_pc.GetPPCState(); - - ppc_state.pc = address; - LR(ppc_state) = 0x00; - - while (ppc_state.pc != 0x00) - power_pc.SingleStep(); -} - void CBoot::SetupMSR(PowerPC::PowerPCState& ppc_state) { // 0x0002032 @@ -136,6 +126,135 @@ void CBoot::SetupBAT(Core::System& system, bool is_wii) mmu.IBATUpdated(); } +/* +#include + + .globl AppLoaderRunnerBase +AppLoaderRunnerBase: + b RunAppLoader + +// Variables that iAppLoaderMain stores into +AppLoaderMainRamAddress: +.4byte 0x00dead04 +AppLoaderMainLength: +.4byte 0x00dead08 +AppLoaderMainDiscOffset: +.4byte 0x00dead0c + +// Function pointers returned by iAppLoaderEntry +AppLoaderInitPointer: // pointer to: void iAppLoaderInit(void (*OSReport)(char *fmt, ...)) +.4byte 0x00dead10 +AppLoaderMainPointer: // pointer to: bool iAppLoaderMain(u32* ram_addr, u32* len, u32* disc_offset) +.4byte 0x00dead14 +AppLoaderClosePointer: // pointer to: void* iAppLoaderClose(void); +.4byte 0x00dead18 + +HLEAppLoaderAfterEntry: // void HLEAppLoaderAfterEntry(void), logging + blr +HLEAppLoaderAfterInit: // void HLEAppLoaderAfterInit(void), logging + blr +HLEAppLoaderAfterMain: // void HLEAppLoaderAfterMain(void), reads disc at AppLoaderMain* variables + blr +HLEAppLoaderAfterClose: // void HLEAppLoaderAfterClose(void), cleans up HLE state + blr +HLEAppLoaderReport: // void HLEAppLoaderReport(char *fmt, ...), passed to iAppLoaderInit + blr + +RunAppLoader: + // Entry point; call iAppLoaderEntry + // r31 is AppLoaderRunnerBase + // r30 is iAppLoaderEntry (later used as a scratch register for other mtctr + bctrl sequences) + // Note that the above registers are specific to Dolphin's apploader HLE. + addi r3, r31, (AppLoaderInitPointer - AppLoaderRunnerBase) + addi r4, r31, (AppLoaderMainPointer - AppLoaderRunnerBase) + addi r5, r31, (AppLoaderClosePointer - AppLoaderRunnerBase) + mtctr r30 + bctrl // Call iAppLoaderEntry, which looks like this: + // void iAppLoaderEntry(void** init, void** main, void** close) + // { + // *init = &iAppLoaderInit; + // *main = &iAppLoaderMain; + // *close = &iAppLoaderClose; + // } + bl HLEAppLoaderAfterEntry // Logging only + + // Call iAppLoaderInit, which sets up logging and any internal state. + addi r3, r31, (HLEAppLoaderReport - AppLoaderRunnerBase) + lwz r30, (AppLoaderInitPointer - AppLoaderRunnerBase)(r31) + mtctr r30 + bctrl // Call iAppLoaderInit + bl HLEAppLoaderAfterInit // Logging only + + // iAppLoaderMain - Here we load the apploader, the DOL (the exe) and the FST (filesystem). + // To give you an idea about where the stuff is located on the disc take a look at yagcd + // ch 13. + // iAppLoaderMain returns 1 if the pointers in R3/R4/R5 were filled with values for DVD copy + // Typical behaviour is doing it once for each section defined in the DOL header. Some unlicensed + // titles don't have a properly constructed DOL and maintain a table of these values in apploader. + // iAppLoaderMain returns 0 when there are no more sections to copy. +LoopMain: + addi r3, r31, (AppLoaderMainRamAddress - AppLoaderRunnerBase) + addi r4, r31, (AppLoaderMainLength - AppLoaderRunnerBase) + addi r5, r31, (AppLoaderMainDiscOffset - AppLoaderRunnerBase) + lwz r30, (AppLoaderMainPointer - AppLoaderRunnerBase)(r31) + mtctr r30 + bctrl // Call iAppLoaderMain + cmpwi r3,0 + beq LoopMainDone + bl HLEAppLoaderAfterMain // Reads the disc (and logs) + b LoopMain + + // Call iAppLoaderClose, which returns (in r3) the game's entry point +LoopMainDone: + lwz r30, (AppLoaderClosePointer - AppLoaderRunnerBase)(r31) + mtctr r30 + bctrl // Call iAppLoaderClose + mr r30, r3 + bl HLEAppLoaderAfterClose // Unpatches the HLE functions + mtlr r30 + blr // "Return" to the game's entry point; this allows using "step out" to skip the apploader +*/ +static constexpr u32 APPLOADER_RUNNER_BASE = 0x81300000; +static constexpr u32 APPLOADER_RUNNER_MAIN_RAM_ADDR = APPLOADER_RUNNER_BASE + 0x04; +static constexpr u32 APPLOADER_RUNNER_MAIN_LENGTH = APPLOADER_RUNNER_BASE + 0x08; +static constexpr u32 APPLOADER_RUNNER_MAIN_DISC_OFFSET = APPLOADER_RUNNER_BASE + 0x0c; +static constexpr u32 APPLOADER_RUNNER_INIT_POINTER = APPLOADER_RUNNER_BASE + 0x10; +static constexpr u32 APPLOADER_RUNNER_MAIN_POINTER = APPLOADER_RUNNER_BASE + 0x14; +static constexpr u32 APPLOADER_RUNNER_CLOSE_POINTER = APPLOADER_RUNNER_BASE + 0x18; +static constexpr u32 APPLOADER_RUNNER_HLE_AFTER_ENTRY = APPLOADER_RUNNER_BASE + 0x1c; +static constexpr u32 APPLOADER_RUNNER_HLE_AFTER_INIT = APPLOADER_RUNNER_BASE + 0x20; +static constexpr u32 APPLOADER_RUNNER_HLE_AFTER_MAIN = APPLOADER_RUNNER_BASE + 0x24; +static constexpr u32 APPLOADER_RUNNER_HLE_AFTER_CLOSE = APPLOADER_RUNNER_BASE + 0x28; +static constexpr u32 APPLOADER_RUNNER_HLE_REPORT = APPLOADER_RUNNER_BASE + 0x2c; +static constexpr u32 APPLOADER_RUNNER_RUN_ADDR = APPLOADER_RUNNER_BASE + 0x30; + +static constexpr std::array APPLOADER_RUNNER_ASM{ + 0x48000030, // Starting thunk + // Variables + 0x00dead04, 0x00dead08, 0x00dead0c, 0x00dead10, 0x00dead14, 0x00dead18, + // HLE'd functions + 0x4e800020, 0x4e800020, 0x4e800020, 0x4e800020, 0x4e800020, + // Actual code + 0x387f0010, 0x389f0014, 0x38bf0018, 0x7fc903a6, 0x4e800421, 0x4bffffd9, 0x387f002c, 0x83df0010, + 0x7fc903a6, 0x4e800421, 0x4bffffc9, 0x387f0004, 0x389f0008, 0x38bf000c, 0x83df0014, 0x7fc903a6, + 0x4e800421, 0x2c030000, 0x4182000c, 0x4bffffa9, 0x4bffffdc, 0x83df0018, 0x7fc903a6, 0x4e800421, + 0x7c7e1b78, 0x4bffff95, 0x7fc803a6, 0x4e800020}; + +struct ApploaderRunnerState +{ + constexpr ApploaderRunnerState( + bool is_wii_, const DiscIO::VolumeDisc& volume_, + const std::vector& riivolution_patches_) + : is_wii(is_wii_), volume(volume_), riivolution_patches(riivolution_patches_) + { + } + + bool is_wii; + const DiscIO::VolumeDisc& volume; + const std::vector& riivolution_patches; +}; +static std::unique_ptr s_apploader_runner_state; + bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard, bool is_wii, const DiscIO::VolumeDisc& volume, const std::vector& riivolution_patches) @@ -153,11 +272,13 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard INFO_LOG_FMT(BOOT, "Invalid apploader. Your disc image is probably corrupted."); return false; } + INFO_LOG_FMT(BOOT, + "Loading apploader ({}) from disc offset {:08x} to {:08x}, " + "size {:#x} ({:#x} + {:#x}), entry point {:08x}", + volume.GetApploaderDate(partition), offset + 0x20, 0x81200000, *size + *trailer, + *size, *trailer, *entry); DVDRead(system, volume, offset + 0x20, 0x01200000, *size + *trailer, partition); - // TODO - Make Apploader(or just RunFunction()) debuggable!!! - - auto& ppc_state = system.GetPPCState(); auto& mmu = system.GetMMU(); auto& branch_watch = system.GetPowerPC().GetBranchWatch(); @@ -165,66 +286,66 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard if (system.IsBranchWatchIgnoreApploader()) branch_watch.SetRecordingActive(guard, false); - // Call iAppLoaderEntry. - DEBUG_LOG_FMT(BOOT, "Call iAppLoaderEntry"); - const u32 iAppLoaderFuncAddr = is_wii ? 0x80004000 : 0x80003100; - ppc_state.gpr[3] = iAppLoaderFuncAddr + 0; - ppc_state.gpr[4] = iAppLoaderFuncAddr + 4; - ppc_state.gpr[5] = iAppLoaderFuncAddr + 8; - RunFunction(system, *entry); - const u32 iAppLoaderInit = mmu.Read_U32(iAppLoaderFuncAddr + 0); - const u32 iAppLoaderMain = mmu.Read_U32(iAppLoaderFuncAddr + 4); - const u32 iAppLoaderClose = mmu.Read_U32(iAppLoaderFuncAddr + 8); - - // iAppLoaderInit - DEBUG_LOG_FMT(BOOT, "Call iAppLoaderInit"); - PowerPC::MMU::HostWrite_U32(guard, 0x4E800020, 0x81300000); // Write BLR - HLE::Patch(system, 0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader - ppc_state.gpr[3] = 0x81300000; - RunFunction(system, iAppLoaderInit); - - // iAppLoaderMain - Here we load the apploader, the DOL (the exe) and the FST (filesystem). - // To give you an idea about where the stuff is located on the disc take a look at yagcd - // ch 13. - DEBUG_LOG_FMT(BOOT, "Call iAppLoaderMain"); - - ppc_state.gpr[3] = 0x81300004; - ppc_state.gpr[4] = 0x81300008; - ppc_state.gpr[5] = 0x8130000c; - - RunFunction(system, iAppLoaderMain); - - // iAppLoaderMain returns 1 if the pointers in R3/R4/R5 were filled with values for DVD copy - // Typical behaviour is doing it once for each section defined in the DOL header. Some unlicensed - // titles don't have a properly constructed DOL and maintain a table of these values in apploader. - // iAppLoaderMain returns 0 when there are no more sections to copy. - while (ppc_state.gpr[3] != 0x00) + for (u32 i = 0; i < APPLOADER_RUNNER_ASM.size(); i++) { - const u32 ram_address = mmu.Read_U32(0x81300004); - const u32 length = mmu.Read_U32(0x81300008); - const u32 dvd_offset = mmu.Read_U32(0x8130000c) << (is_wii ? 2 : 0); - - INFO_LOG_FMT(BOOT, "DVDRead: offset: {:08x} memOffset: {:08x} length: {}", dvd_offset, - ram_address, length); - DVDRead(system, volume, dvd_offset, ram_address, length, partition); - - DiscIO::Riivolution::ApplyApploaderMemoryPatches(guard, riivolution_patches, ram_address, - length); - - ppc_state.gpr[3] = 0x81300004; - ppc_state.gpr[4] = 0x81300008; - ppc_state.gpr[5] = 0x8130000c; - - RunFunction(system, iAppLoaderMain); + mmu.HostWrite_U32(guard, APPLOADER_RUNNER_ASM[i], APPLOADER_RUNNER_BASE + i * sizeof(u32)); } - // iAppLoaderClose - DEBUG_LOG_FMT(BOOT, "call iAppLoaderClose"); - RunFunction(system, iAppLoaderClose); - HLE::UnPatch(system, "AppLoaderReport"); + HLE::Patch(system, APPLOADER_RUNNER_HLE_AFTER_ENTRY, "HLEAppLoaderAfterEntry"); + HLE::Patch(system, APPLOADER_RUNNER_HLE_AFTER_INIT, "HLEAppLoaderAfterInit"); + HLE::Patch(system, APPLOADER_RUNNER_HLE_AFTER_MAIN, "HLEAppLoaderAfterMain"); + HLE::Patch(system, APPLOADER_RUNNER_HLE_AFTER_CLOSE, "HLEAppLoaderAfterClose"); + HLE::Patch(system, APPLOADER_RUNNER_HLE_REPORT, "HLEAppLoaderReport"); + s_apploader_runner_state = + std::make_unique(is_wii, volume, riivolution_patches); - // return - ppc_state.pc = ppc_state.gpr[3]; + system.GetPPCSymbolDB().AddKnownSymbol(guard, *entry, 0, "iAppLoaderEntry", "Apploader"); + + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_MAIN_RAM_ADDR, 4, + "AppLoaderMainRamAddress", "Apploader", + Common::Symbol::Type::Data); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_MAIN_LENGTH, 4, + "AppLoaderMainLength", "Apploader", + Common::Symbol::Type::Data); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_MAIN_DISC_OFFSET, 4, + "AppLoaderMainDiscOffset", "Apploader", + Common::Symbol::Type::Data); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_INIT_POINTER, 4, + "AppLoaderInitPointer", "Apploader", + Common::Symbol::Type::Data); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_MAIN_POINTER, 4, + "AppLoaderMainPointer", "Apploader", + Common::Symbol::Type::Data); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_CLOSE_POINTER, 4, + "AppLoaderClosePointer", "Apploader", + Common::Symbol::Type::Data); + + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_HLE_AFTER_ENTRY, 4, + "HLEAppLoaderAfterEntry", "Dolphin BS2 HLE"); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_HLE_AFTER_INIT, 4, + "HLEAppLoaderAfterInit", "Dolphin BS2 HLE"); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_HLE_AFTER_MAIN, 4, + "HLEAppLoaderAfterMain", "Dolphin BS2 HLE"); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_HLE_AFTER_CLOSE, 4, + "HLEAppLoaderAfterClose", "Dolphin BS2 HLE"); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_HLE_REPORT, 4, + "HLEAppLoaderReport", "Dolphin BS2 HLE"); + + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_BASE, 4, "DolphinApploaderRunner", + "Dolphin BS2 HLE"); + const u32 remainder_size = u32(APPLOADER_RUNNER_ASM.size() * sizeof(u32)) - + (APPLOADER_RUNNER_RUN_ADDR - APPLOADER_RUNNER_BASE); + system.GetPPCSymbolDB().AddKnownSymbol(guard, APPLOADER_RUNNER_RUN_ADDR, remainder_size, + "DolphinApploaderRunner", "Dolphin BS2 HLE"); + system.GetPPCSymbolDB().Index(); + Host_PPCSymbolsChanged(); + + auto& ppc_state = system.GetPPCState(); + ppc_state.gpr[31] = APPLOADER_RUNNER_BASE; + ppc_state.gpr[30] = *entry; + + // Run our apploader runner code + ppc_state.pc = APPLOADER_RUNNER_BASE; branch_watch.SetRecordingActive(guard, resume_branch_watch); // Blank out session key (https://debugmo.de/2008/05/part-2-dumping-the-media-board/) @@ -238,6 +359,69 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard return true; } +void CBoot::HLEAppLoaderAfterEntry(const Core::CPUThreadGuard& guard) +{ + auto& system = Core::System::GetInstance(); + auto& mmu = system.GetMMU(); + + const u32 init = mmu.HostRead_U32(guard, APPLOADER_RUNNER_INIT_POINTER); + const u32 main = mmu.HostRead_U32(guard, APPLOADER_RUNNER_MAIN_POINTER); + const u32 close = mmu.HostRead_U32(guard, APPLOADER_RUNNER_CLOSE_POINTER); + + system.GetPPCSymbolDB().AddKnownSymbol(guard, init, 0, "iAppLoaderInit", "Apploader"); + system.GetPPCSymbolDB().AddKnownSymbol(guard, main, 0, "iAppLoaderMain", "Apploader"); + system.GetPPCSymbolDB().AddKnownSymbol(guard, close, 0, "iAppLoaderClose", "Apploader"); + system.GetPPCSymbolDB().Index(); + Host_PPCSymbolsChanged(); + + INFO_LOG_FMT(BOOT, "Called iAppLoaderEntry; init at {:08x}, main at {:08x}, close at {:08x}", + init, main, close); +} + +void CBoot::HLEAppLoaderAfterInit(const Core::CPUThreadGuard& guard) +{ + INFO_LOG_FMT(BOOT, "Called iAppLoaderInit"); +} + +void CBoot::HLEAppLoaderAfterMain(const Core::CPUThreadGuard& guard) +{ + ASSERT(s_apploader_runner_state); + if (!s_apploader_runner_state) + return; + + auto& system = Core::System::GetInstance(); + auto& mmu = system.GetMMU(); + + const u32 ram_address = mmu.HostRead_U32(guard, APPLOADER_RUNNER_MAIN_RAM_ADDR); + const u32 length = mmu.HostRead_U32(guard, APPLOADER_RUNNER_MAIN_LENGTH); + const u32 dvd_shift = s_apploader_runner_state->is_wii ? 2 : 0; + const u32 dvd_offset = mmu.HostRead_U32(guard, APPLOADER_RUNNER_MAIN_DISC_OFFSET) << dvd_shift; + + INFO_LOG_FMT(BOOT, "Called iAppLoaderMain; reading {:#x} bytes from disc offset {:08x} to {:08x}", + length, dvd_offset, ram_address); + DVDRead(system, s_apploader_runner_state->volume, dvd_offset, ram_address, length, + s_apploader_runner_state->volume.GetGamePartition()); + DiscIO::Riivolution::ApplyApploaderMemoryPatches( + guard, s_apploader_runner_state->riivolution_patches, ram_address, length); +} + +void CBoot::HLEAppLoaderAfterClose(const Core::CPUThreadGuard& guard) +{ + auto& system = Core::System::GetInstance(); + auto& ppc_state = system.GetPPCState(); + + INFO_LOG_FMT(BOOT, "Called iAppLoaderClose; game entry point is {:08x}", ppc_state.gpr[30]); + SConfig::OnTitleDirectlyBooted(guard); // Clears the temporary patches and symbols +} + +void CBoot::HLEAppLoaderReport(std::string_view message) +{ + auto& system = Core::System::GetInstance(); + auto& ppc_state = system.GetPPCState(); + + INFO_LOG_FMT(BOOT, "AppLoader {:08x}->{:08x}| {}", LR(ppc_state), ppc_state.pc, message); +} + void CBoot::SetupGCMemory(Core::System& system, const Core::CPUThreadGuard& guard) { auto& memory = system.GetMemory(); diff --git a/Source/Core/Core/HLE/HLE.cpp b/Source/Core/Core/HLE/HLE.cpp index a0ca859371..cc082764ec 100644 --- a/Source/Core/Core/HLE/HLE.cpp +++ b/Source/Core/Core/HLE/HLE.cpp @@ -10,6 +10,7 @@ #include "Common/CommonTypes.h" #include "Common/Config/Config.h" +#include "Core/Boot/Boot.h" #include "Core/Config/MainSettings.h" #include "Core/Core.h" #include "Core/GeckoCode.h" @@ -28,7 +29,7 @@ namespace HLE static std::map s_hooked_addresses; // clang-format off -constexpr std::array os_patches{{ +constexpr std::array os_patches{{ // Placeholder, os_patches[0] is the "non-existent function" index {"FAKE_TO_SKIP_0", HLE_Misc::UnimplementedFunction, HookType::Replace, HookFlag::Generic}, @@ -60,7 +61,12 @@ constexpr std::array os_patches{{ {"GeckoCodehandler", HLE_Misc::GeckoCodeHandlerICacheFlush, HookType::Start, HookFlag::Fixed}, {"GeckoHandlerReturnTrampoline", HLE_Misc::GeckoReturnTrampoline, HookType::Replace, HookFlag::Fixed}, - {"AppLoaderReport", HLE_OS::HLE_GeneralDebugPrint, HookType::Start, HookFlag::Fixed} // apploader needs OSReport-like function + + {"HLEAppLoaderAfterEntry", CBoot::HLEAppLoaderAfterEntry, HookType::Start, HookFlag::Fixed}, + {"HLEAppLoaderAfterInit", CBoot::HLEAppLoaderAfterInit, HookType::Start, HookFlag::Fixed}, + {"HLEAppLoaderAfterMain", CBoot::HLEAppLoaderAfterMain, HookType::Start, HookFlag::Fixed}, + {"HLEAppLoaderAfterClose", CBoot::HLEAppLoaderAfterClose, HookType::Start, HookFlag::Fixed}, + {"HLEAppLoaderReport", HLE_OS::HLE_AppLoaderReport, HookType::Start, HookFlag::Fixed}, }}; // clang-format on diff --git a/Source/Core/Core/HLE/HLE_OS.cpp b/Source/Core/Core/HLE/HLE_OS.cpp index a81f294107..143276a978 100644 --- a/Source/Core/Core/HLE/HLE_OS.cpp +++ b/Source/Core/Core/HLE/HLE_OS.cpp @@ -16,6 +16,7 @@ #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" #include "Common/StringUtil.h" +#include "Core/Boot/Boot.h" #include "Core/Core.h" #include "Core/HLE/HLE_VarArgs.h" #include "Core/PowerPC/MMU.h" @@ -208,6 +209,14 @@ void HLE_LogVFPrint(const Core::CPUThreadGuard& guard) HLE_LogFPrint(guard, ParameterType::VariableArgumentList); } +// Version of OSReport used by Dolphin for running apploaders from BS2 HLE +void HLE_AppLoaderReport(const Core::CPUThreadGuard& guard) +{ + auto& system = Core::System::GetInstance(); + CBoot::HLEAppLoaderReport( + SHIFTJISToUTF8(GetStringVA(system, guard, 3, ParameterType::ParameterList))); +} + namespace { class HLEPrintArgsVAList final : public HLEPrintArgs diff --git a/Source/Core/Core/HLE/HLE_OS.h b/Source/Core/Core/HLE/HLE_OS.h index 4f7bcb8ed7..34d4a03790 100644 --- a/Source/Core/Core/HLE/HLE_OS.h +++ b/Source/Core/Core/HLE/HLE_OS.h @@ -35,4 +35,5 @@ void HLE_LogDPrint(const Core::CPUThreadGuard& guard); void HLE_LogVDPrint(const Core::CPUThreadGuard& guard); void HLE_LogFPrint(const Core::CPUThreadGuard& guard); void HLE_LogVFPrint(const Core::CPUThreadGuard& guard); +void HLE_AppLoaderReport(const Core::CPUThreadGuard& guard); } // namespace HLE_OS