From d3b8908a7cec54dc638564cbf40576dfc1a3fb93 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Mon, 24 Jan 2011 21:54:19 +0000 Subject: [PATCH] Make CDolLoader a bit more c++ish, make wii dols be detected by the presence of a mfspr x, HID4. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6909 8ced0084-cf51-0410-be5f-012b33b47a6e --- Externals/Bochs_disasm/PowerPCDisasm.cpp | 1 + Source/Core/Core/Src/Boot/Boot.cpp | 5 +- Source/Core/Core/Src/Boot/Boot_DOL.cpp | 103 ++++++++++++++--------- Source/Core/Core/Src/Boot/Boot_DOL.h | 39 +++++---- Source/Core/Core/Src/CoreParameter.cpp | 3 +- 5 files changed, 95 insertions(+), 56 deletions(-) diff --git a/Externals/Bochs_disasm/PowerPCDisasm.cpp b/Externals/Bochs_disasm/PowerPCDisasm.cpp index 22c4324654..16f4afd865 100644 --- a/Externals/Bochs_disasm/PowerPCDisasm.cpp +++ b/Externals/Bochs_disasm/PowerPCDisasm.cpp @@ -243,6 +243,7 @@ typedef unsigned int ppc_word; case 1008: return "HID0"; case 1009: return "HID1"; case 1010: return "IABR"; + case 1011: return "HID4"; case 1013: return "DABR"; case 1017: return "L2CR"; case 1019: return "ICTC"; diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp index 3516dd85bf..e7e89c2ccb 100644 --- a/Source/Core/Core/Src/Boot/Boot.cpp +++ b/Source/Core/Core/Src/Boot/Boot.cpp @@ -231,8 +231,9 @@ bool CBoot::BootUp() // DOL case SCoreStartupParameter::BOOT_DOL: { + CDolLoader dolLoader(_StartupPara.m_strFilename.c_str()); // Check if we have gotten a Wii file or not - bool dolWii = CDolLoader::IsDolWii(_StartupPara.m_strFilename.c_str()); + bool dolWii = dolLoader.IsWii(); if (dolWii != _StartupPara.bWii) { PanicAlertT("Warning - starting DOL in wrong console mode!"); @@ -261,7 +262,7 @@ bool CBoot::BootUp() if (!BS2Success) { - CDolLoader dolLoader(_StartupPara.m_strFilename.c_str()); + dolLoader.Load(); PC = dolLoader.GetEntryPoint(); } diff --git a/Source/Core/Core/Src/Boot/Boot_DOL.cpp b/Source/Core/Core/Src/Boot/Boot_DOL.cpp index 8c96bb70d6..3bb95905fa 100644 --- a/Source/Core/Core/Src/Boot/Boot_DOL.cpp +++ b/Source/Core/Core/Src/Boot/Boot_DOL.cpp @@ -17,18 +17,17 @@ #include "Boot_DOL.h" #include "FileUtil.h" - #include "../HW/Memmap.h" - +#include "CommonFuncs.h" CDolLoader::CDolLoader(u8* _pBuffer, u32 _Size) - : m_bInit(false) + : m_isWii(false) { - m_bInit = Initialize(_pBuffer, _Size); + Initialize(_pBuffer, _Size); } -CDolLoader::CDolLoader(const char* _szFilename) - : m_bInit(false) +CDolLoader::CDolLoader(const char* _szFilename) + : m_isWii(false) { u64 size = File::GetSize(_szFilename); u8* tmpBuffer = new u8[(size_t)size]; @@ -37,27 +36,79 @@ CDolLoader::CDolLoader(const char* _szFilename) fread(tmpBuffer, (size_t)size, 1, pStream); fclose(pStream); - m_bInit = Initialize(tmpBuffer, (u32)size); - delete[] tmpBuffer; + Initialize(tmpBuffer, (u32)size); + delete [] tmpBuffer; } -bool CDolLoader::Initialize(u8* _pBuffer, u32 _Size) +CDolLoader::~CDolLoader() +{ + for (int i = 0; i < DOL_NUM_TEXT; i++) + { + delete [] text_section[i]; + text_section[i] = NULL; + } + + for (int i = 0; i < DOL_NUM_DATA; i++) + { + delete [] data_section[i]; + data_section[i] = NULL; + } +} + +void CDolLoader::Initialize(u8* _pBuffer, u32 _Size) { memcpy(&m_dolheader, _pBuffer, sizeof(SDolHeader)); // swap memory u32* p = (u32*)&m_dolheader; - for (size_t i=0; i<(sizeof(SDolHeader)>>2); i++) + for (size_t i = 0; i < (sizeof(SDolHeader)/sizeof(u32)); i++) p[i] = Common::swap32(p[i]); + for (int i = 0; i < DOL_NUM_TEXT; i++) + text_section[i] = NULL; + for (int i = 0; i < DOL_NUM_DATA; i++) + data_section[i] = NULL; + + u32 HID4_pattern = 0x7c13fba6; + u32 HID4_mask = 0xfc1fffff; + + for (int i = 0; i < DOL_NUM_TEXT; i++) + { + if (m_dolheader.textOffset[i] != 0) + { + text_section[i] = new u8[m_dolheader.textSize[i]]; + memcpy(text_section[i], _pBuffer + m_dolheader.textOffset[i], m_dolheader.textSize[i]); + for (int j = 0; j < (m_dolheader.textSize[i]/sizeof(u32)); j++) + { + u32 word = Common::swap32(((u32*)text_section[i])[j]); + if ((word & HID4_mask) == HID4_pattern) + { + m_isWii = true; + break; + } + } + } + } + + for (int i = 0; i < DOL_NUM_DATA; i++) + { + if (m_dolheader.dataOffset[i] != 0) + { + data_section[i] = new u8[m_dolheader.dataSize[i]]; + memcpy(data_section[i], _pBuffer + m_dolheader.dataOffset[i], m_dolheader.dataSize[i]); + } + } +} + +void CDolLoader::Load() +{ // load all text (code) sections for (int i = 0; i < DOL_NUM_TEXT; i++) { if (m_dolheader.textOffset[i] != 0) { - u8* pTemp = &_pBuffer[m_dolheader.textOffset[i]]; for (u32 num = 0; num < m_dolheader.textSize[i]; num++) - Memory::Write_U8(pTemp[num], m_dolheader.textAddress[i] + num); + Memory::Write_U8(text_section[i][num], m_dolheader.textAddress[i] + num); } } @@ -66,32 +117,8 @@ bool CDolLoader::Initialize(u8* _pBuffer, u32 _Size) { if (m_dolheader.dataOffset[i] != 0) { - u8* pTemp = &_pBuffer[m_dolheader.dataOffset[i]]; for (u32 num = 0; num < m_dolheader.dataSize[i]; num++) - Memory::Write_U8(pTemp[num], m_dolheader.dataAddress[i] + num); + Memory::Write_U8(data_section[i][num], m_dolheader.dataAddress[i] + num); } } - - return true; -} - -u32 CDolLoader::GetEntryPoint() -{ - return m_dolheader.entryPoint; -} - -bool CDolLoader::IsDolWii(const char* filename) -{ - // try to open file - FILE* pStream = fopen(filename, "rb"); - if (pStream) - { - fseeko(pStream, 0xe0, SEEK_SET); - u32 entrypt = fgetc(pStream) << 24 | fgetc(pStream) << 16 | - fgetc(pStream) << 8 | fgetc(pStream); - - fclose(pStream); - return entrypt >= 0x80004000; - } - return 0; -} +} \ No newline at end of file diff --git a/Source/Core/Core/Src/Boot/Boot_DOL.h b/Source/Core/Core/Src/Boot/Boot_DOL.h index be617ffbb3..76a8c6d17b 100644 --- a/Source/Core/Core/Src/Boot/Boot_DOL.h +++ b/Source/Core/Core/Src/Boot/Boot_DOL.h @@ -25,10 +25,13 @@ class CDolLoader public: CDolLoader(const char* _szFilename); CDolLoader(u8* _pBuffer, u32 _Size); + ~CDolLoader(); - u32 GetEntryPoint(); - - static bool IsDolWii(const char* filename); + bool IsWii() { return m_isWii; } + u32 GetEntryPoint() { return m_dolheader.entryPoint; } + + // Load into emulated memory + void Load(); private: enum @@ -36,26 +39,32 @@ private: DOL_NUM_TEXT = 7, DOL_NUM_DATA = 11 }; + struct SDolHeader { - u32 textOffset[DOL_NUM_TEXT]; - u32 dataOffset[DOL_NUM_DATA]; + u32 textOffset[DOL_NUM_TEXT]; + u32 dataOffset[DOL_NUM_DATA]; - u32 textAddress[DOL_NUM_TEXT]; - u32 dataAddress[DOL_NUM_DATA]; + u32 textAddress[DOL_NUM_TEXT]; + u32 dataAddress[DOL_NUM_DATA]; - u32 textSize[DOL_NUM_TEXT]; - u32 dataSize[DOL_NUM_DATA]; + u32 textSize[DOL_NUM_TEXT]; + u32 dataSize[DOL_NUM_DATA]; - u32 bssAddress; - u32 bssSize; - u32 entryPoint; - u32 padd[7]; + u32 bssAddress; + u32 bssSize; + u32 entryPoint; + u32 padd[7]; }; SDolHeader m_dolheader; - bool m_bInit; - bool Initialize(u8* _pBuffer, u32 _Size); + u8 *data_section[DOL_NUM_DATA]; + u8 *text_section[DOL_NUM_TEXT]; + + bool m_isWii; + + // Copy sections to internal buffers + void Initialize(u8* _pBuffer, u32 _Size); }; #endif diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 90dce8c4e3..0f43597463 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -189,7 +189,8 @@ bool SCoreStartupParameter::AutoSetup(EBootBS2 _BootBS2) } else if (!strcasecmp(Extension.c_str(), ".dol")) { - bWii = CDolLoader::IsDolWii(m_strFilename.c_str()); + CDolLoader dolfile(m_strFilename.c_str()); + bWii = dolfile.IsWii(); Region = USA_DIR; m_BootType = BOOT_DOL; bNTSC = true;