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
This commit is contained in:
Shawn Hoffman 2011-01-24 21:54:19 +00:00
parent 470ed118f5
commit d3b8908a7c
5 changed files with 95 additions and 56 deletions

View File

@ -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";

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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;