Merge pull request #5406 from JosJuice/refactor-emulatedbs2
Boot: Refactor EmulatedBS2
This commit is contained in:
commit
f4e115b322
|
@ -353,28 +353,9 @@ bool CBoot::BootUp()
|
|||
|
||||
if (!EmulatedBS2(dolWii))
|
||||
{
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
if (dolLoader.IsWii())
|
||||
HID4.SBE = 1;
|
||||
PowerPC::DBATUpdated();
|
||||
PowerPC::IBATUpdated();
|
||||
SetupBAT(/*is_wii*/ true);
|
||||
|
||||
// Because there is no TMD to get the requested system (IOS) version from,
|
||||
// we default to IOS58, which is the version used by the Homebrew Channel.
|
||||
|
|
|
@ -48,6 +48,8 @@ private:
|
|||
static bool Boot_ELF(const std::string& filename);
|
||||
static bool Boot_WiiWAD(const std::string& filename);
|
||||
|
||||
static void SetupBAT(bool is_wii);
|
||||
static bool RunApploader(bool is_wii);
|
||||
static bool EmulatedBS2_GC(bool skip_app_loader = false);
|
||||
static bool EmulatedBS2_Wii();
|
||||
static bool EmulatedBS2(bool is_wii);
|
||||
|
|
|
@ -52,15 +52,8 @@ void CBoot::RunFunction(u32 address)
|
|||
PowerPC::SingleStep();
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// GameCube Bootstrap 2 HLE:
|
||||
// copy the apploader to 0x81200000
|
||||
// execute the apploader, function by function, using the above utility.
|
||||
bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
||||
void CBoot::SetupBAT(bool is_wii)
|
||||
{
|
||||
INFO_LOG(BOOT, "Faking GC BS2...");
|
||||
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
|
@ -72,8 +65,99 @@ bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
|||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
|
||||
if (is_wii)
|
||||
{
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
}
|
||||
PowerPC::DBATUpdated();
|
||||
PowerPC::IBATUpdated();
|
||||
}
|
||||
|
||||
bool CBoot::RunApploader(bool is_wii)
|
||||
{
|
||||
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
|
||||
// but the size can differ between discs. Compare with YAGCD chap 13.
|
||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
||||
const u32 apploader_offset = 0x2440;
|
||||
u32 apploader_entry = 0;
|
||||
u32 apploader_size = 0;
|
||||
u32 apploader_trailer = 0;
|
||||
if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, is_wii) ||
|
||||
!volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, is_wii) ||
|
||||
!volume.ReadSwapped(apploader_offset + 0x18, &apploader_trailer, is_wii) ||
|
||||
apploader_entry == (u32)-1 || apploader_size + apploader_trailer == (u32)-1)
|
||||
{
|
||||
INFO_LOG(BOOT, "Invalid apploader. Your disc image is probably corrupted.");
|
||||
return false;
|
||||
}
|
||||
DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size + apploader_trailer, is_wii);
|
||||
|
||||
// TODO - Make Apploader(or just RunFunction()) debuggable!!!
|
||||
|
||||
// Call iAppLoaderEntry.
|
||||
DEBUG_LOG(MASTER_LOG, "Call iAppLoaderEntry");
|
||||
const u32 iAppLoaderFuncAddr = is_wii ? 0x80004000 : 0x80003100;
|
||||
PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0;
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(apploader_entry);
|
||||
const u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
const u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
const u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(MASTER_LOG, "Call iAppLoaderInit");
|
||||
HLE::Patch(0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader
|
||||
PowerPC::ppcState.gpr[3] = 0x81300000;
|
||||
RunFunction(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(MASTER_LOG, "Call iAppLoaderMain");
|
||||
do
|
||||
{
|
||||
PowerPC::ppcState.gpr[3] = 0x81300004;
|
||||
PowerPC::ppcState.gpr[4] = 0x81300008;
|
||||
PowerPC::ppcState.gpr[5] = 0x8130000c;
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c) << (is_wii ? 2 : 0);
|
||||
|
||||
INFO_LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset,
|
||||
iRamAddress, iLength);
|
||||
DVDRead(iDVDOffset, iRamAddress, iLength, is_wii);
|
||||
|
||||
} while (PowerPC::ppcState.gpr[3] != 0x00);
|
||||
|
||||
// iAppLoaderClose
|
||||
DEBUG_LOG(MASTER_LOG, "call iAppLoaderClose");
|
||||
RunFunction(iAppLoaderClose);
|
||||
HLE::UnPatch("AppLoaderReport");
|
||||
|
||||
// return
|
||||
PC = PowerPC::ppcState.gpr[3];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// __________________________________________________________________________________________________
|
||||
// GameCube Bootstrap 2 HLE:
|
||||
// copy the apploader to 0x81200000
|
||||
// execute the apploader, function by function, using the above utility.
|
||||
bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
||||
{
|
||||
INFO_LOG(BOOT, "Faking GC BS2...");
|
||||
|
||||
SetupBAT(/*is_wii*/ false);
|
||||
|
||||
// Write necessary values
|
||||
// Here we write values to memory that the apploader does not take care of. Game info goes
|
||||
|
@ -114,21 +198,6 @@ bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
|||
if (!DVDInterface::IsDiscInside())
|
||||
return false;
|
||||
|
||||
// Load Apploader to Memory - The apploader is hardcoded to begin at 0x2440 on the disc,
|
||||
// but the size can differ between discs. Compare with YAGCD chap 13.
|
||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
||||
const u32 apploader_offset = 0x2440;
|
||||
u32 apploader_entry, apploader_size, apploader_trailer;
|
||||
if (skip_app_loader || !volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, false) ||
|
||||
!volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, false) ||
|
||||
!volume.ReadSwapped(apploader_offset + 0x18, &apploader_trailer, false) ||
|
||||
apploader_entry == (u32)-1 || apploader_size + apploader_trailer == (u32)-1)
|
||||
{
|
||||
INFO_LOG(BOOT, "GC BS2: Not running apploader!");
|
||||
return false;
|
||||
}
|
||||
DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size + apploader_trailer, false);
|
||||
|
||||
// Setup pointers like real BS2 does
|
||||
if (ntsc)
|
||||
{
|
||||
|
@ -146,56 +215,10 @@ bool CBoot::EmulatedBS2_GC(bool skip_app_loader)
|
|||
PowerPC::ppcState.gpr[13] = 0x814b4fc0;
|
||||
}
|
||||
|
||||
// TODO - Make Apploader(or just RunFunction()) debuggable!!!
|
||||
if (skip_app_loader)
|
||||
return false;
|
||||
|
||||
// Call iAppLoaderEntry.
|
||||
DEBUG_LOG(MASTER_LOG, "Call iAppLoaderEntry");
|
||||
u32 iAppLoaderFuncAddr = 0x80003100;
|
||||
PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0;
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(apploader_entry);
|
||||
u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(MASTER_LOG, "Call iAppLoaderInit");
|
||||
HLE::Patch(0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader
|
||||
PowerPC::ppcState.gpr[3] = 0x81300000;
|
||||
RunFunction(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(MASTER_LOG, "Call iAppLoaderMain");
|
||||
do
|
||||
{
|
||||
PowerPC::ppcState.gpr[3] = 0x81300004;
|
||||
PowerPC::ppcState.gpr[4] = 0x81300008;
|
||||
PowerPC::ppcState.gpr[5] = 0x8130000c;
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c);
|
||||
|
||||
INFO_LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset,
|
||||
iRamAddress, iLength);
|
||||
DVDRead(iDVDOffset, iRamAddress, iLength, false);
|
||||
|
||||
} while (PowerPC::ppcState.gpr[3] != 0x00);
|
||||
|
||||
// iAppLoaderClose
|
||||
DEBUG_LOG(MASTER_LOG, "call iAppLoaderClose");
|
||||
RunFunction(iAppLoaderClose);
|
||||
HLE::UnPatch("AppLoaderReport");
|
||||
|
||||
// return
|
||||
PC = PowerPC::ppcState.gpr[3];
|
||||
|
||||
return true;
|
||||
return RunApploader(/*is_wii*/ false);
|
||||
}
|
||||
|
||||
bool CBoot::SetupWiiMemory(u64 ios_title_id)
|
||||
|
@ -333,26 +356,7 @@ bool CBoot::EmulatedBS2_Wii()
|
|||
// after this check during booting.
|
||||
DVDRead(0, 0x3180, 4, true);
|
||||
|
||||
// Set up MSR and the BAT SPR registers.
|
||||
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
|
||||
m_MSR.FP = 1;
|
||||
m_MSR.DR = 1;
|
||||
m_MSR.IR = 1;
|
||||
m_MSR.EE = 1;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_IBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0U] = 0x80001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT0L] = 0x00000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1U] = 0xc0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT1L] = 0x0000002a;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4U] = 0x90001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT4L] = 0x10000002;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5U] = 0xd0001fff;
|
||||
PowerPC::ppcState.spr[SPR_DBAT5L] = 0x1000002a;
|
||||
PowerPC::DBATUpdated();
|
||||
PowerPC::IBATUpdated();
|
||||
SetupBAT(/*is_wii*/ true);
|
||||
|
||||
Memory::Write_U32(0x4c000064, 0x00000300); // Write default DSI Handler: rfi
|
||||
Memory::Write_U32(0x4c000064, 0x00000800); // Write default FPU Handler: rfi
|
||||
|
@ -360,67 +364,11 @@ bool CBoot::EmulatedBS2_Wii()
|
|||
|
||||
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
|
||||
|
||||
// Execute the apploader
|
||||
const u32 apploader_offset = 0x2440; // 0x1c40;
|
||||
|
||||
// Load Apploader to Memory
|
||||
const DiscIO::IVolume& volume = DVDInterface::GetVolume();
|
||||
u32 apploader_entry, apploader_size;
|
||||
if (!volume.ReadSwapped(apploader_offset + 0x10, &apploader_entry, true) ||
|
||||
!volume.ReadSwapped(apploader_offset + 0x14, &apploader_size, true) ||
|
||||
apploader_entry == (u32)-1 || apploader_size == (u32)-1)
|
||||
{
|
||||
ERROR_LOG(BOOT, "Invalid apploader. Probably your image is corrupted.");
|
||||
if (!RunApploader(/*is_wii*/ true))
|
||||
return false;
|
||||
}
|
||||
DVDRead(apploader_offset + 0x20, 0x01200000, apploader_size, true);
|
||||
|
||||
// call iAppLoaderEntry
|
||||
DEBUG_LOG(BOOT, "Call iAppLoaderEntry");
|
||||
|
||||
u32 iAppLoaderFuncAddr = 0x80004000;
|
||||
PowerPC::ppcState.gpr[3] = iAppLoaderFuncAddr + 0;
|
||||
PowerPC::ppcState.gpr[4] = iAppLoaderFuncAddr + 4;
|
||||
PowerPC::ppcState.gpr[5] = iAppLoaderFuncAddr + 8;
|
||||
RunFunction(apploader_entry);
|
||||
u32 iAppLoaderInit = PowerPC::Read_U32(iAppLoaderFuncAddr + 0);
|
||||
u32 iAppLoaderMain = PowerPC::Read_U32(iAppLoaderFuncAddr + 4);
|
||||
u32 iAppLoaderClose = PowerPC::Read_U32(iAppLoaderFuncAddr + 8);
|
||||
|
||||
// iAppLoaderInit
|
||||
DEBUG_LOG(BOOT, "Run iAppLoaderInit");
|
||||
HLE::Patch(0x81300000, "AppLoaderReport"); // HLE OSReport for Apploader
|
||||
PowerPC::ppcState.gpr[3] = 0x81300000;
|
||||
RunFunction(iAppLoaderInit);
|
||||
|
||||
// Let the apploader load the exe to memory
|
||||
DEBUG_LOG(BOOT, "Run iAppLoaderMain");
|
||||
do
|
||||
{
|
||||
PowerPC::ppcState.gpr[3] = 0x81300004;
|
||||
PowerPC::ppcState.gpr[4] = 0x81300008;
|
||||
PowerPC::ppcState.gpr[5] = 0x8130000c;
|
||||
|
||||
RunFunction(iAppLoaderMain);
|
||||
|
||||
u32 iRamAddress = PowerPC::Read_U32(0x81300004);
|
||||
u32 iLength = PowerPC::Read_U32(0x81300008);
|
||||
u32 iDVDOffset = PowerPC::Read_U32(0x8130000c) << 2;
|
||||
|
||||
INFO_LOG(BOOT, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress,
|
||||
iLength);
|
||||
DVDRead(iDVDOffset, iRamAddress, iLength, true);
|
||||
} while (PowerPC::ppcState.gpr[3] != 0x00);
|
||||
|
||||
// iAppLoaderClose
|
||||
DEBUG_LOG(BOOT, "Run iAppLoaderClose");
|
||||
RunFunction(iAppLoaderClose);
|
||||
HLE::UnPatch("AppLoaderReport");
|
||||
|
||||
IOS::HLE::Device::ES::DIVerify(tmd, DVDInterface::GetVolume().GetTicket());
|
||||
|
||||
// return
|
||||
PC = PowerPC::ppcState.gpr[3];
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue