Break out BIOS emulation code into its own file. Remove BOOT_BIN support (who still uses that?). assorted warning fixes.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@674 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-09-24 21:14:23 +00:00
parent b6605213a1
commit f7b6298e77
15 changed files with 681 additions and 662 deletions

View File

@ -89,77 +89,6 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\Externals\LZO;..\Common\Src;..\DiscIO\Src;..\..\PluginSpecs;..\Debugger\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LOGGING;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
BufferSecurityCheck="true"
FloatingPointModel="0"
UsePrecompiledHeader="2"
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/Core.lib"
AdditionalLibraryDirectories="&quot;..\..\..\Externals\LZO\$(OutDir)\lzo.lib&quot;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)" OutputDirectory="$(PlatformName)\$(ConfigurationName)"
@ -235,6 +164,151 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="DebugFast|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="false"
AdditionalIncludeDirectories="..\Common\Src;..\DiscIO\Src;..\..\PluginSpecs;..\Debugger\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib;..\..\..\Externals\LZO"
PreprocessorDefinitions="NDEBUG;_LIB;LOGGING;DEBUGFAST;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
FloatingPointModel="0"
UsePrecompiledHeader="2"
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/Core.lib"
AdditionalLibraryDirectories="&quot;..\..\..\Externals\LZO\$(OutDir)\lzo.lib&quot;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\..\Externals\LZO;..\Common\Src;..\DiscIO\Src;..\..\PluginSpecs;..\Debugger\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LOGGING;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
BufferSecurityCheck="true"
FloatingPointModel="0"
UsePrecompiledHeader="2"
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/Core.lib"
AdditionalLibraryDirectories="&quot;..\..\..\Externals\LZO\$(OutDir)\lzo.lib&quot;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="Release|x64" Name="Release|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)" OutputDirectory="$(PlatformName)\$(ConfigurationName)"
@ -312,80 +386,6 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="DebugFast|Win32"
OutputDirectory="$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
CharacterSet="2"
WholeProgramOptimization="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
EnableIntrinsicFunctions="true"
FavorSizeOrSpeed="1"
OmitFramePointers="true"
EnableFiberSafeOptimizations="false"
AdditionalIncludeDirectories="..\Common\Src;..\DiscIO\Src;..\..\PluginSpecs;..\Debugger\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\zlib;..\..\..\Externals\LZO"
PreprocessorDefinitions="NDEBUG;_LIB;LOGGING;DEBUGFAST;_CRT_SECURE_NO_DEPRECATE;_SECURE_SCL=0"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="2"
FloatingPointModel="0"
UsePrecompiledHeader="2"
AssemblerListingLocation="$(IntDir)\"
WarningLevel="3"
WarnAsError="false"
DebugInformationFormat="3"
ForcedIncludeFiles="stdafx.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/Core.lib"
AdditionalLibraryDirectories="&quot;..\..\..\Externals\LZO\$(OutDir)\lzo.lib&quot;"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="DebugFast|x64" Name="DebugFast|x64"
OutputDirectory="$(PlatformName)\$(ConfigurationName)" OutputDirectory="$(PlatformName)\$(ConfigurationName)"
@ -1151,6 +1151,10 @@
RelativePath=".\Src\Boot\Boot.h" RelativePath=".\Src\Boot\Boot.h"
> >
</File> </File>
<File
RelativePath=".\Src\Boot\Boot_BIOSEmu.cpp"
>
</File>
<File <File
RelativePath=".\Src\Boot\Boot_DOL.cpp" RelativePath=".\Src\Boot\Boot_DOL.cpp"
> >
@ -1263,14 +1267,6 @@
UsePrecompiledHeader="1" UsePrecompiledHeader="1"
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release|Win32" Name="Release|Win32"
> >
@ -1280,7 +1276,7 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="Release|x64" Name="DebugFast|Win32"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
@ -1288,7 +1284,15 @@
/> />
</FileConfiguration> </FileConfiguration>
<FileConfiguration <FileConfiguration
Name="DebugFast|Win32" Name="Debug|x64"
>
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
> >
<Tool <Tool
Name="VCCLCompilerTool" Name="VCCLCompilerTool"

View File

@ -47,394 +47,6 @@
#include "VolumeCreator.h" #include "VolumeCreator.h"
bool CBoot::Boot_BIN(const std::string& _rFilename)
{
Common::IMappedFile* pFile = Common::IMappedFile::CreateMappedFileDEPRECATED();
if (pFile->Open(_rFilename.c_str()))
{
u8* pData = pFile->Lock(0, pFile->GetSize());
Memory::WriteBigEData(pData, 0x80000000, (u32)pFile->GetSize());
pFile->Unlock(pData);
pFile->Close();
}
delete pFile;
return true;
}
void WrapRunFunction(void*)
{
while (PC != 0x00)
{
CCPU::SingleStep();
}
}
void WrapRunFunction2(void*)
{
while (PC != 0x00)
{
PowerPC::SingleStep();
}
}
void CBoot::RunFunction(u32 _iAddr, bool _bUseDebugger)
{
PC = _iAddr;
LR = 0x00;
if (_bUseDebugger)
{
CCPU::Break();
//EMM::Wrap(WrapRunFunction,0);
WrapRunFunction(0);
}
else
{
//EMM::Wrap(WrapRunFunction2,0);
WrapRunFunction2(0);
}
}
// __________________________________________________________________________________________________
//
// BIOS HLE:
// copy the apploader to 0x81200000
// execute the apploader
//
void CBoot::EmulatedBIOS(bool _bDebug)
{
LOG(BOOT, "Faking GC BIOS...");
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
m_MSR.FP = 1;
Memory::Clear();
// =======================================================================================
// Write necessary values
// ---------------------------------------------------------------------------------------
/*
"TODO: Game iso info to 0x80000000 according to yagcd - or does apploader do this?" - Answer, no
apparently it doesn't, at least not in some games (by Namco). In these cases we need to set these
manually. But I guess there's no reason that the Apploader couldn't do this by itself. So I guess we
could do this for only these Namco games that need this by detecting GetUniqueID, but that wouldn't
look pretty, and I think it's likely that this is actually how the GameCube works, it reads these values
by itself. So this is very unlikely to break anything. However, if somebody find a game that has an
apploader that automatically copies the first bytes of the disc to memory that could indicate that
the apploader procedure to load the first bytes fails for some reason in some games... I hope I'm not
being long-winded here :). The yagcd page for this is http://hitmen.c02.at/files/yagcd/yagcd/chap4.ht
ml#sec4.2 by the way. I'm not sure what the bytes 8-10 does (version and streaming), but I include
those to.
*/
// ---------------------------------------------------------------------------------------
DVDInterface::DVDRead(0x00000000, 0x80000000, 10); // write boot info needed for multidisc games
Memory::Write_U32(0x4c000064, 0x80000300); // write default DFI Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000800); // write default FPU Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000C00); // write default Syscall Handler: rfi
//
Memory::Write_U32(0xc2339f3d, 0x8000001C); //game disc
Memory::Write_U32(0x0D15EA5E, 0x80000020); //funny magic word for normal boot
Memory::Write_U32(0x01800000, 0x80000028); // Physical Memory Size
// Memory::Write_U32(0x00000003, 0x8000002C); // Console type - retail
Memory::Write_U32(0x10000006, 0x8000002C); // DevKit
Memory::Write_U32(((1 & 0x3f) << 26) | 2, 0x81300000); // HLE OSReport for Apploader
// =======================================================================================
// =======================================================================================
// Load Apploader to Memory - The apploader is hardcoded to begin at 9 280 on the disc, but
// it seems like the size can be variable.
// ---------------------------------------------------------------------------------------
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
u32 iAppLoaderOffset = 0x2440; // 0x1c40 (old value perhaps?, I don't know why it's here)
// ---------------------------------------------------------------------------------------
u32 iAppLoaderEntry = VolumeHandler::Read32(iAppLoaderOffset + 0x10);
u32 iAppLoaderSize = VolumeHandler::Read32(iAppLoaderOffset + 0x14);
if ((iAppLoaderEntry == (u32)-1) || (iAppLoaderSize == (u32)-1))
return;
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize);
// =======================================================================================
//call iAppLoaderEntry
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(iAppLoaderEntry, _bDebug);
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+0);
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+4);
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
// iAppLoaderInit
LOG(MASTER_LOG, "Call iAppLoaderInit");
PowerPC::ppcState.gpr[3] = 0x81300000;
RunFunction(iAppLoaderInit, _bDebug);
// =======================================================================================
// iAppLoaderMain - This let's the apploader load the DOL (the exe) and the TOC (filesystem)
// and I guess anything else it wishes. To give you an idea about where the stuff is on the disc
// here's an example of the disc structure of these things from Baten Kaitos - Wings. The values
// are given as non hexadecimal (ie normal numbers with base 10 instead of base 16) and they
// are only approximately right. I don't know what's in the gaps or why there are gaps between
// the different things.
// Data From To Size
// Header 0 1 072 1 072
// AppLoader 9 280 121 408 112 128
// DOL (exe) 128 768 2 204 416 2 075 648
// TOC 2 204 160 2 309 120 104 960
// For some reason this game loaded these things in 16 rounds in the loop below. The third and
// last of these were double reads of things it had already copied to memory. But hey, we're
// all human :)
// ---------------------------------------------------------------------------------------
LOG(MASTER_LOG, "Call iAppLoaderMain");
do
{
PowerPC::ppcState.gpr[3] = 0x81300004;
PowerPC::ppcState.gpr[4] = 0x81300008;
PowerPC::ppcState.gpr[5] = 0x8130000c;
RunFunction(iAppLoaderMain, _bDebug);
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c);
LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength);
} while(PowerPC::ppcState.gpr[3] != 0x00);
// =======================================================================================
// iAppLoaderClose
LOG(MASTER_LOG, "call iAppLoaderClose");
RunFunction(iAppLoaderClose, _bDebug);
// Load patches and run startup patches
std::string gameID = VolumeHandler::GetVolume()->GetUniqueID();
PatchEngine_LoadPatches(gameID.c_str());
PatchEngine_ApplyLoadPatches();
PowerPC::ppcState.DebugCount = 0;
// return
PC = PowerPC::ppcState.gpr[3];
// --- preinit some stuff from bios ---
// Bus Clock Speed
Memory::Write_U32(0x09a7ec80, 0x800000F8);
Memory::Write_U32(0x1cf7c580, 0x800000FC);
// fake the VI Init of the BIOS
Memory::Write_U32(Core::g_CoreStartupParameter.bNTSC ? 0 : 1, 0x800000CC);
// preset time
Memory::Write_U32(CEXIIPL::GetGCTime(), 0x800030D8);
}
// __________________________________________________________________________________________________
//
// BIOS HLE:
// copy the apploader to 0x81200000
// execute the apploader
//
bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
{
LOG(BOOT, "Faking Wii BIOS...");
FILE* pDump = fopen("WII/dump_0x0000_0x4000.bin", "rb");
if (pDump != NULL)
{
LOG(MASTER_LOG, "Init from memory dump.");
fread(Memory::GetMainRAMPtr(), 1, 16384, pDump);
fclose(pDump);
pDump = NULL;
}
else
{
// load settings.txt
{
std::string filename("WII/setting-eur.txt");
if (VolumeHandler::IsValid())
{
switch(VolumeHandler::GetVolume()->GetCountry())
{
case DiscIO::IVolume::COUNTRY_JAP:
filename = "WII/setting-jpn.txt";
break;
case DiscIO::IVolume::COUNTRY_USA:
filename = "WII/setting-usa.txt";
break;
case DiscIO::IVolume::COUNTRY_EUROPE:
filename = "WII/setting-eur.txt";
break;
default:
PanicAlert("Unknown country. Wii boot process will be switched to European settings.");
filename = "WII/setting-eur.txt";
break;
}
}
FILE* pTmp = fopen(filename.c_str(), "rb");
if (!pTmp)
{
LOG(MASTER_LOG, "Cant find setting file");
return false;
}
fread(Memory::GetPointer(0x3800), 256, 1, pTmp);
fclose(pTmp);
}
// int global vars
{
// updated with info from wiibrew.org
Memory::Write_U32(0x5d1c9ea3, 0x00000018); // magic word it is a wii disc
Memory::Write_U32(0x0D15EA5E, 0x00000020);
Memory::Write_U32(0x00000001, 0x00000024);
Memory::Write_U32(0x01800000, 0x00000028);
Memory::Write_U32(0x00000023, 0x0000002c);
Memory::Write_U32(0x00000000, 0x00000030); // Init
Memory::Write_U32(0x817FEC60, 0x00000034); // Init
// 38, 3C should get start, size of FST through apploader
Memory::Write_U32(0x38a00040, 0x00000060); // Exception init
Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init
Memory::Write_U32(0x01800000, 0x000000f0); // "simulated memory size" (debug mode?)
Memory::Write_U32(0x8179b500, 0x000000f4); // __start
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed
Memory::Write_U16(0x0000, 0x000030e6); // Console type
Memory::Write_U32(0x00000000, 0x000030c0); // EXI
Memory::Write_U32(0x00000000, 0x000030c4); // EXI
Memory::Write_U32(0x00000000, 0x000030dc); // Time
Memory::Write_U32(0x00000000, 0x000030d8); // Time
Memory::Write_U32(0x00000000, 0x000030f0); // apploader
Memory::Write_U32(0x01800000, 0x00003100); // BAT
Memory::Write_U32(0x01800000, 0x00003104); // BAT
Memory::Write_U32(0x00000000, 0x0000310c); // Init
Memory::Write_U32(0x8179d500, 0x00003110); // Init
Memory::Write_U32(0x04000000, 0x00003118);
Memory::Write_U32(0x04000000, 0x0000311c); // BAT
Memory::Write_U32(0x93400000, 0x00003120); // BAT
Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low
Memory::Write_U32(0x933e0000, 0x00003128); // Init - MEM2 high
Memory::Write_U32(0x933e0000, 0x00003130); // IOS MEM2 low
Memory::Write_U32(0x93400000, 0x00003134); // IOS MEM2 high
Memory::Write_U32(0x00000011, 0x00003138); // Console type
Memory::Write_U16(0x0113, 0x0000315e); // apploader
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
Memory::Write_U8(0x80, 0x0000315c); // OSInit
Memory::Write_U8(0x00, 0x00000006); // DVDInit
Memory::Write_U8(0x00, 0x00000007); // DVDInit
Memory::Write_U16(0x0000, 0x000030e0); // PADInit
// fake the VI Init of the BIOS
Memory::Write_U32(Core::g_CoreStartupParameter.bNTSC ? 0 : 1, 0x000000CC);
// clear exception handler
for (int i = 0x3000; i <= 0x3038; i += 4)
{
Memory::Write_U32(0x00000000, 0x80000000 + i);
}
// app
VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4);
Memory::Write_U8(0x80, 0x00003184);
}
}
// apploader
if (VolumeHandler::IsValid() && VolumeHandler::IsWii())
{
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
m_MSR.FP = 1;
//TODO: Game iso info to 0x80000000 according to yagcd - or does apploader do this?
Memory::Write_U32(0x4c000064, 0x80000300); // write default DFI Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000800); // write default FPU Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000C00); // write default Syscall Handler: rfi
Memory::Write_U32(((1 & 0x3f) << 26) | 2, 0x81300000); // HLE OSReport for Apploader
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
u32 iAppLoaderOffset = 0x2440; // 0x1c40;
// Load Apploader to Memory
u32 iAppLoaderEntry = VolumeHandler::Read32(iAppLoaderOffset + 0x10);
u32 iAppLoaderSize = VolumeHandler::Read32(iAppLoaderOffset + 0x14);
if ((iAppLoaderEntry == (u32)-1) || (iAppLoaderSize == (u32)-1))
{
LOG(BOOT, "Invalid apploader. Probably your image is corrupted.");
return false;
}
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize);
//call iAppLoaderEntry
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(iAppLoaderEntry, _bDebug);
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+0);
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+4);
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
// iAppLoaderInit
LOG(BOOT, "Call iAppLoaderInit");
PowerPC::ppcState.gpr[3] = 0x81300000;
RunFunction(iAppLoaderInit, _bDebug);
// iAppLoaderMain
LOG(BOOT, "Call iAppLoaderMain");
do
{
PowerPC::ppcState.gpr[3] = 0x81300004;
PowerPC::ppcState.gpr[4] = 0x81300008;
PowerPC::ppcState.gpr[5] = 0x8130000c;
RunFunction(iAppLoaderMain, _bDebug);
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2;
LOG(BOOT, "DVDRead: offset: %08x memOffse: %08x length: %i", iDVDOffset, iRamAddress, iLength);
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength);
} while(PowerPC::ppcState.gpr[3] != 0x00);
// iAppLoaderClose
LOG(BOOT, "call iAppLoaderClose");
RunFunction(iAppLoaderClose, _bDebug);
// Load patches and run startup patches
std::string gameID = VolumeHandler::GetVolume()->GetUniqueID();
PatchEngine_LoadPatches(gameID.c_str());
// return
PC = PowerPC::ppcState.gpr[3];
}
PowerPC::ppcState.DebugCount = 0;
return true;
}
void CBoot::Load_FST(bool _bIsWii) void CBoot::Load_FST(bool _bIsWii)
{ {
if(VolumeHandler::IsValid()) if(VolumeHandler::IsValid())
@ -655,22 +267,6 @@ bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
} }
break; break;
// BIN
// ===================================================================================
case SCoreStartupParameter::BOOT_BIN:
{
if (!_StartupPara.m_strDefaultGCM.empty())
{
VolumeHandler::SetVolumeName(_StartupPara.m_strDefaultGCM.c_str());
EmulatedBIOS(false);
}
Boot_BIN(_StartupPara.m_strFilename);
if (LoadMapFromFilename(_StartupPara.m_strFilename))
HLE::PatchFunctions();
}
break;
// BIOS // BIOS
// =================================================================================== // ===================================================================================
case SCoreStartupParameter::BOOT_BIOS: case SCoreStartupParameter::BOOT_BIOS:

View File

@ -32,7 +32,6 @@ public:
BOOT_ERROR, BOOT_ERROR,
BOOT_DOL, BOOT_DOL,
BOOT_ELF, BOOT_ELF,
BOOT_BIN,
BOOT_ISO, BOOT_ISO,
BOOT_BIOS BOOT_BIOS
}; };
@ -50,14 +49,11 @@ private:
static void UpdateDebugger_MapLoaded(const char* _gameID = NULL); static void UpdateDebugger_MapLoaded(const char* _gameID = NULL);
static bool LoadMapFromFilename(const std::string& _rFilename, const char* _gameID = NULL); static bool LoadMapFromFilename(const std::string& _rFilename, const char* _gameID = NULL);
static bool Boot_ELF(const char *filename); static bool Boot_ELF(const char *filename);
static bool Boot_BIN(const std::string& _rFilename);
static void EmulatedBIOS(bool _bDebug); static void EmulatedBIOS(bool _bDebug);
static bool EmulatedBIOS_Wii(bool _bDebug); static bool EmulatedBIOS_Wii(bool _bDebug);
static bool Load_BIOS(const std::string& _rBiosFilename); static bool Load_BIOS(const std::string& _rBiosFilename);
static void Load_FST(bool _bIsWii); static void Load_FST(bool _bIsWii);
}; };

View File

@ -0,0 +1,390 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "Common.h"
#include "../PowerPC/PowerPC.h"
#include "../Core.h"
#include "../HW/EXI_DeviceIPL.h"
#include "../HW/Memmap.h"
#include "../HW/DVDInterface.h"
#include "../HW/CPU.h"
#include "../Host.h"
#include "../VolumeHandler.h"
#include "../PatchEngine.h"
#include "../MemTools.h"
#include "VolumeCreator.h"
#include "Boot.h"
void CBoot::RunFunction(u32 _iAddr, bool _bUseDebugger)
{
PC = _iAddr;
LR = 0x00;
if (_bUseDebugger)
{
CCPU::Break();
while (PC != 0x00)
CCPU::SingleStep();
}
else
{
while (PC != 0x00)
PowerPC::SingleStep();
}
}
// __________________________________________________________________________________________________
//
// BIOS HLE:
// copy the apploader to 0x81200000
// execute the apploader
//
void CBoot::EmulatedBIOS(bool _bDebug)
{
LOG(BOOT, "Faking GC BIOS...");
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
m_MSR.FP = 1;
Memory::Clear();
// =======================================================================================
// Write necessary values
// ---------------------------------------------------------------------------------------
/*
"TODO: Game iso info to 0x80000000 according to yagcd - or does apploader do this?" - Answer, no
apparently it doesn't, at least not in some games (by Namco). In these cases we need to set these
manually. But I guess there's no reason that the Apploader couldn't do this by itself. So I guess we
could do this for only these Namco games that need this by detecting GetUniqueID, but that wouldn't
look pretty, and I think it's likely that this is actually how the GameCube works, it reads these values
by itself. So this is very unlikely to break anything. However, if somebody find a game that has an
apploader that automatically copies the first bytes of the disc to memory that could indicate that
the apploader procedure to load the first bytes fails for some reason in some games... I hope I'm not
being long-winded here :). The yagcd page for this is http://hitmen.c02.at/files/yagcd/yagcd/chap4.ht
ml#sec4.2 by the way. I'm not sure what the bytes 8-10 does (version and streaming), but I include
those to.
*/
// ---------------------------------------------------------------------------------------
DVDInterface::DVDRead(0x00000000, 0x80000000, 10); // write boot info needed for multidisc games
Memory::Write_U32(0x4c000064, 0x80000300); // write default DFI Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000800); // write default FPU Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000C00); // write default Syscall Handler: rfi
//
Memory::Write_U32(0xc2339f3d, 0x8000001C); //game disc
Memory::Write_U32(0x0D15EA5E, 0x80000020); //funny magic word for normal boot
Memory::Write_U32(0x01800000, 0x80000028); // Physical Memory Size
// Memory::Write_U32(0x00000003, 0x8000002C); // Console type - retail
Memory::Write_U32(0x10000006, 0x8000002C); // DevKit
Memory::Write_U32(((1 & 0x3f) << 26) | 2, 0x81300000); // HLE OSReport for Apploader
// =======================================================================================
// =======================================================================================
// Load Apploader to Memory - The apploader is hardcoded to begin at 9 280 on the disc, but
// it seems like the size can be variable.
// ---------------------------------------------------------------------------------------
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
u32 iAppLoaderOffset = 0x2440; // 0x1c40 (old value perhaps?, I don't know why it's here)
// ---------------------------------------------------------------------------------------
u32 iAppLoaderEntry = VolumeHandler::Read32(iAppLoaderOffset + 0x10);
u32 iAppLoaderSize = VolumeHandler::Read32(iAppLoaderOffset + 0x14);
if ((iAppLoaderEntry == (u32)-1) || (iAppLoaderSize == (u32)-1))
return;
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize);
// =======================================================================================
//call iAppLoaderEntry
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(iAppLoaderEntry, _bDebug);
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+0);
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+4);
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
// iAppLoaderInit
LOG(MASTER_LOG, "Call iAppLoaderInit");
PowerPC::ppcState.gpr[3] = 0x81300000;
RunFunction(iAppLoaderInit, _bDebug);
// =======================================================================================
// iAppLoaderMain - This let's the apploader load the DOL (the exe) and the TOC (filesystem)
// and I guess anything else it wishes. To give you an idea about where the stuff is on the disc
// here's an example of the disc structure of these things from Baten Kaitos - Wings. The values
// are given as non hexadecimal (ie normal numbers with base 10 instead of base 16) and they
// are only approximately right. I don't know what's in the gaps or why there are gaps between
// the different things.
// Data From To Size
// Header 0 1 072 1 072
// AppLoader 9 280 121 408 112 128
// DOL (exe) 128 768 2 204 416 2 075 648
// TOC 2 204 160 2 309 120 104 960
// For some reason this game loaded these things in 16 rounds in the loop below. The third and
// last of these were double reads of things it had already copied to memory. But hey, we're
// all human :)
// ---------------------------------------------------------------------------------------
LOG(MASTER_LOG, "Call iAppLoaderMain");
do
{
PowerPC::ppcState.gpr[3] = 0x81300004;
PowerPC::ppcState.gpr[4] = 0x81300008;
PowerPC::ppcState.gpr[5] = 0x8130000c;
RunFunction(iAppLoaderMain, _bDebug);
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c);
LOG(MASTER_LOG, "DVDRead: offset: %08x memOffset: %08x length: %i", iDVDOffset, iRamAddress, iLength);
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength);
} while(PowerPC::ppcState.gpr[3] != 0x00);
// =======================================================================================
// iAppLoaderClose
LOG(MASTER_LOG, "call iAppLoaderClose");
RunFunction(iAppLoaderClose, _bDebug);
// Load patches and run startup patches
std::string gameID = VolumeHandler::GetVolume()->GetUniqueID();
PatchEngine_LoadPatches(gameID.c_str());
PatchEngine_ApplyLoadPatches();
PowerPC::ppcState.DebugCount = 0;
// return
PC = PowerPC::ppcState.gpr[3];
// --- preinit some stuff from bios ---
// Bus Clock Speed
Memory::Write_U32(0x09a7ec80, 0x800000F8);
Memory::Write_U32(0x1cf7c580, 0x800000FC);
// fake the VI Init of the BIOS
Memory::Write_U32(Core::g_CoreStartupParameter.bNTSC ? 0 : 1, 0x800000CC);
// preset time
Memory::Write_U32(CEXIIPL::GetGCTime(), 0x800030D8);
}
// __________________________________________________________________________________________________
//
// BIOS HLE:
// copy the apploader to 0x81200000
// execute the apploader
//
bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
{
LOG(BOOT, "Faking Wii BIOS...");
FILE* pDump = fopen("WII/dump_0x0000_0x4000.bin", "rb");
if (pDump != NULL)
{
LOG(MASTER_LOG, "Init from memory dump.");
fread(Memory::GetMainRAMPtr(), 1, 16384, pDump);
fclose(pDump);
pDump = NULL;
}
else
{
// load settings.txt
{
std::string filename("WII/setting-eur.txt");
if (VolumeHandler::IsValid())
{
switch(VolumeHandler::GetVolume()->GetCountry())
{
case DiscIO::IVolume::COUNTRY_JAP:
filename = "WII/setting-jpn.txt";
break;
case DiscIO::IVolume::COUNTRY_USA:
filename = "WII/setting-usa.txt";
break;
case DiscIO::IVolume::COUNTRY_EUROPE:
filename = "WII/setting-eur.txt";
break;
default:
PanicAlert("Unknown country. Wii boot process will be switched to European settings.");
filename = "WII/setting-eur.txt";
break;
}
}
FILE* pTmp = fopen(filename.c_str(), "rb");
if (!pTmp)
{
LOG(MASTER_LOG, "Cant find setting file");
return false;
}
fread(Memory::GetPointer(0x3800), 256, 1, pTmp);
fclose(pTmp);
}
// int global vars
{
// updated with info from wiibrew.org
Memory::Write_U32(0x5d1c9ea3, 0x00000018); // magic word it is a wii disc
Memory::Write_U32(0x0D15EA5E, 0x00000020);
Memory::Write_U32(0x00000001, 0x00000024);
Memory::Write_U32(0x01800000, 0x00000028);
Memory::Write_U32(0x00000023, 0x0000002c);
Memory::Write_U32(0x00000000, 0x00000030); // Init
Memory::Write_U32(0x817FEC60, 0x00000034); // Init
// 38, 3C should get start, size of FST through apploader
Memory::Write_U32(0x38a00040, 0x00000060); // Exception init
Memory::Write_U32(0x8008f7b8, 0x000000e4); // Thread Init
Memory::Write_U32(0x01800000, 0x000000f0); // "simulated memory size" (debug mode?)
Memory::Write_U32(0x8179b500, 0x000000f4); // __start
Memory::Write_U32(0x0e7be2c0, 0x000000f8); // Bus speed
Memory::Write_U32(0x2B73A840, 0x000000fc); // CPU speed
Memory::Write_U16(0x0000, 0x000030e6); // Console type
Memory::Write_U32(0x00000000, 0x000030c0); // EXI
Memory::Write_U32(0x00000000, 0x000030c4); // EXI
Memory::Write_U32(0x00000000, 0x000030dc); // Time
Memory::Write_U32(0x00000000, 0x000030d8); // Time
Memory::Write_U32(0x00000000, 0x000030f0); // apploader
Memory::Write_U32(0x01800000, 0x00003100); // BAT
Memory::Write_U32(0x01800000, 0x00003104); // BAT
Memory::Write_U32(0x00000000, 0x0000310c); // Init
Memory::Write_U32(0x8179d500, 0x00003110); // Init
Memory::Write_U32(0x04000000, 0x00003118);
Memory::Write_U32(0x04000000, 0x0000311c); // BAT
Memory::Write_U32(0x93400000, 0x00003120); // BAT
Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low
Memory::Write_U32(0x933e0000, 0x00003128); // Init - MEM2 high
Memory::Write_U32(0x933e0000, 0x00003130); // IOS MEM2 low
Memory::Write_U32(0x93400000, 0x00003134); // IOS MEM2 high
Memory::Write_U32(0x00000011, 0x00003138); // Console type
Memory::Write_U16(0x0113, 0x0000315e); // apploader
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
Memory::Write_U8(0x80, 0x0000315c); // OSInit
Memory::Write_U8(0x00, 0x00000006); // DVDInit
Memory::Write_U8(0x00, 0x00000007); // DVDInit
Memory::Write_U16(0x0000, 0x000030e0); // PADInit
// fake the VI Init of the BIOS
Memory::Write_U32(Core::g_CoreStartupParameter.bNTSC ? 0 : 1, 0x000000CC);
// clear exception handler
for (int i = 0x3000; i <= 0x3038; i += 4)
{
Memory::Write_U32(0x00000000, 0x80000000 + i);
}
// app
VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4);
Memory::Write_U8(0x80, 0x00003184);
}
}
// apploader
if (VolumeHandler::IsValid() && VolumeHandler::IsWii())
{
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
m_MSR.FP = 1;
//TODO: Game iso info to 0x80000000 according to yagcd - or does apploader do this?
Memory::Write_U32(0x4c000064, 0x80000300); // write default DFI Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000800); // write default FPU Handler: rfi
Memory::Write_U32(0x4c000064, 0x80000C00); // write default Syscall Handler: rfi
Memory::Write_U32(((1 & 0x3f) << 26) | 2, 0x81300000); // HLE OSReport for Apploader
PowerPC::ppcState.gpr[1] = 0x816ffff0; // StackPointer
u32 iAppLoaderOffset = 0x2440; // 0x1c40;
// Load Apploader to Memory
u32 iAppLoaderEntry = VolumeHandler::Read32(iAppLoaderOffset + 0x10);
u32 iAppLoaderSize = VolumeHandler::Read32(iAppLoaderOffset + 0x14);
if ((iAppLoaderEntry == (u32)-1) || (iAppLoaderSize == (u32)-1))
{
LOG(BOOT, "Invalid apploader. Probably your image is corrupted.");
return false;
}
VolumeHandler::ReadToPtr(Memory::GetPointer(0x81200000), iAppLoaderOffset + 0x20, iAppLoaderSize);
//call iAppLoaderEntry
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(iAppLoaderEntry, _bDebug);
u32 iAppLoaderInit = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+0);
u32 iAppLoaderMain = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+4);
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
// iAppLoaderInit
LOG(BOOT, "Call iAppLoaderInit");
PowerPC::ppcState.gpr[3] = 0x81300000;
RunFunction(iAppLoaderInit, _bDebug);
// iAppLoaderMain
LOG(BOOT, "Call iAppLoaderMain");
do
{
PowerPC::ppcState.gpr[3] = 0x81300004;
PowerPC::ppcState.gpr[4] = 0x81300008;
PowerPC::ppcState.gpr[5] = 0x8130000c;
RunFunction(iAppLoaderMain, _bDebug);
u32 iRamAddress = Memory::ReadUnchecked_U32(0x81300004);
u32 iLength = Memory::ReadUnchecked_U32(0x81300008);
u32 iDVDOffset = Memory::ReadUnchecked_U32(0x8130000c) << 2;
LOG(BOOT, "DVDRead: offset: %08x memOffse: %08x length: %i", iDVDOffset, iRamAddress, iLength);
DVDInterface::DVDRead(iDVDOffset, iRamAddress, iLength);
} while(PowerPC::ppcState.gpr[3] != 0x00);
// iAppLoaderClose
LOG(BOOT, "call iAppLoaderClose");
RunFunction(iAppLoaderClose, _bDebug);
// Load patches and run startup patches
std::string gameID = VolumeHandler::GetVolume()->GetUniqueID();
PatchEngine_LoadPatches(gameID.c_str());
// return
PC = PowerPC::ppcState.gpr[3];
}
PowerPC::ppcState.DebugCount = 0;
return true;
}

View File

@ -14,6 +14,7 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifndef _BOOT_DOL_H #ifndef _BOOT_DOL_H
#define _BOOT_DOL_H #define _BOOT_DOL_H

View File

@ -1,3 +1,20 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include "../PowerPC/PowerPC.h" #include "../PowerPC/PowerPC.h"
#include "Boot.h" #include "Boot.h"
#include "../HLE/HLE.h" #include "../HLE/HLE.h"
@ -7,16 +24,13 @@
bool CBoot::IsElfWii(const char *filename) bool CBoot::IsElfWii(const char *filename)
{ {
Common::IMappedFile *mapfile = Common::IMappedFile::CreateMappedFileDEPRECATED(); FILE *f = fopen(filename, "rb");
bool ok = mapfile->Open(filename); fseek(f, 0, SEEK_END);
if (!ok) u64 filesize = ftell(f);
return false; fseek(f, 0, SEEK_SET);
size_t filesize = (size_t)mapfile->GetSize(); u8 *mem = new u8[(size_t)filesize];
u8 *ptr = mapfile->Lock(0, filesize); fread(mem, 1, filesize, f);
u8 *mem = new u8[filesize]; fclose(f);
memcpy(mem, ptr, filesize);
mapfile->Unlock(ptr);
mapfile->Close();
ElfReader reader(mem); ElfReader reader(mem);
@ -29,13 +43,13 @@ bool CBoot::IsElfWii(const char *filename)
bool CBoot::Boot_ELF(const char *filename) bool CBoot::Boot_ELF(const char *filename)
{ {
Common::IMappedFile *mapfile = Common::IMappedFile::CreateMappedFileDEPRECATED(); FILE *f = fopen(filename, "rb");
mapfile->Open(filename); fseek(f, 0, SEEK_END);
u8 *ptr = mapfile->Lock(0, mapfile->GetSize()); u64 filesize = ftell(f);
u8 *mem = new u8[(size_t)mapfile->GetSize()]; fseek(f, 0, SEEK_SET);
memcpy(mem, ptr, (size_t)mapfile->GetSize()); u8 *mem = new u8[(size_t)filesize];
mapfile->Unlock(ptr); fread(mem, 1, filesize, f);
mapfile->Close(); fclose(f);
ElfReader reader(mem); ElfReader reader(mem);
reader.LoadInto(0x80000000); reader.LoadInto(0x80000000);
@ -46,9 +60,9 @@ bool CBoot::Boot_ELF(const char *filename)
} else { } else {
HLE::PatchFunctions(); HLE::PatchFunctions();
} }
delete [] mem;
PC = reader.GetEntryPoint(); PC = reader.GetEntryPoint();
delete [] mem;
return true; return true;
} }

View File

@ -1 +1,18 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#pragma once #pragma once

View File

@ -1,3 +1,20 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#include <string> #include <string>
#include "Common.h" #include "Common.h"
@ -12,17 +29,17 @@ void bswap(Elf32_Half &w) {w = Common::swap16(w);}
void byteswapHeader(Elf32_Ehdr &ELF_H) void byteswapHeader(Elf32_Ehdr &ELF_H)
{ {
bswap(ELF_H.e_type); bswap(ELF_H.e_type);
bswap(ELF_H.e_machine);// = _byteswap_ushort(ELF_H.e_machine); bswap(ELF_H.e_machine);
bswap(ELF_H.e_ehsize);// = _byteswap_ushort(ELF_H.e_ehsize); bswap(ELF_H.e_ehsize);
bswap(ELF_H.e_phentsize);// = _byteswap_ushort(ELF_H.e_phentsize); bswap(ELF_H.e_phentsize);
bswap(ELF_H.e_phnum);// = _byteswap_ushort(ELF_H.e_phnum); bswap(ELF_H.e_phnum);
bswap(ELF_H.e_shentsize);// = _byteswap_ushort(ELF_H.e_shentsize); bswap(ELF_H.e_shentsize);
bswap(ELF_H.e_shnum);// = _byteswap_ushort(ELF_H.e_shnum); bswap(ELF_H.e_shnum);
bswap(ELF_H.e_shstrndx);//= _byteswap_ushort(ELF_H.e_shstrndx); bswap(ELF_H.e_shstrndx);
bswap(ELF_H.e_version);// = _byteswap_ulong(ELF_H.e_version ); bswap(ELF_H.e_version);
bswap(ELF_H.e_entry);// = _byteswap_ulong(ELF_H.e_entry ); bswap(ELF_H.e_entry);
bswap(ELF_H.e_phoff);// = _byteswap_ulong(ELF_H.e_phoff ); bswap(ELF_H.e_phoff);
bswap(ELF_H.e_shoff);// = _byteswap_ulong(ELF_H.e_shoff ); bswap(ELF_H.e_shoff);
bswap(ELF_H.e_flags); bswap(ELF_H.e_flags);
} }
@ -52,7 +69,6 @@ void byteswapSection(Elf32_Shdr &sec)
bswap(sec.sh_type); bswap(sec.sh_type);
} }
ElfReader::ElfReader(void *ptr) ElfReader::ElfReader(void *ptr)
{ {
base = (char*)ptr; base = (char*)ptr;
@ -75,8 +91,7 @@ ElfReader::ElfReader(void *ptr)
entryPoint = header->e_entry; entryPoint = header->e_entry;
} }
const char *ElfReader::GetSectionName(int section) const
const char *ElfReader::GetSectionName(int section)
{ {
if (sections[section].sh_type == SHT_NULL) if (sections[section].sh_type == SHT_NULL)
return 0; return 0;
@ -90,8 +105,6 @@ const char *ElfReader::GetSectionName(int section)
return 0; return 0;
} }
void addrToHiLo(u32 addr, u16 &hi, s16 &lo) void addrToHiLo(u32 addr, u16 &hi, s16 &lo)
{ {
lo = (addr & 0xFFFF); lo = (addr & 0xFFFF);
@ -143,7 +156,7 @@ bool ElfReader::LoadInto(u32 vaddr)
segmentVAddr[i] = baseAddress + p->p_vaddr; segmentVAddr[i] = baseAddress + p->p_vaddr;
u32 writeAddr = segmentVAddr[i]; u32 writeAddr = segmentVAddr[i];
u8 *src = GetSegmentPtr(i); const u8 *src = GetSegmentPtr(i);
u8 *dst = Memory::GetPointer(writeAddr); u8 *dst = Memory::GetPointer(writeAddr);
u32 srcSize = p->p_filesz; u32 srcSize = p->p_filesz;
u32 dstSize = p->p_memsz; u32 dstSize = p->p_memsz;
@ -188,17 +201,14 @@ bool ElfReader::LoadInto(u32 vaddr)
return true; return true;
} }
SectionID ElfReader::GetSectionByName(const char *name, int firstSection) const
SectionID ElfReader::GetSectionByName(const char *name, int firstSection)
{ {
for (int i = firstSection; i < header->e_shnum; i++) for (int i = firstSection; i < header->e_shnum; i++)
{ {
const char *secname = GetSectionName(i); const char *secname = GetSectionName(i);
if (secname != 0 && strcmp(name, secname) == 0) if (secname != 0 && strcmp(name, secname) == 0)
{
return i; return i;
}
} }
return -1; return -1;
} }
@ -210,15 +220,12 @@ bool ElfReader::LoadSymbols()
if (sec != -1) if (sec != -1)
{ {
int stringSection = sections[sec].sh_link; int stringSection = sections[sec].sh_link;
const char *stringBase = (const char *)GetSectionDataPtr(stringSection);
const char *stringBase = (const char*)GetSectionDataPtr(stringSection);
//We have a symbol table! //We have a symbol table!
Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec)); Elf32_Sym *symtab = (Elf32_Sym *)(GetSectionDataPtr(sec));
int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym); int numSymbols = sections[sec].sh_size / sizeof(Elf32_Sym);
for (int sym = 0; sym < numSymbols; sym++)
for (int sym = 0; sym<numSymbols; sym++)
{ {
int size = Common::swap32(symtab[sym].st_size); int size = Common::swap32(symtab[sym].st_size);
if (size == 0) if (size == 0)
@ -229,12 +236,10 @@ bool ElfReader::LoadSymbols()
int sectionIndex = Common::swap16(symtab[sym].st_shndx); int sectionIndex = Common::swap16(symtab[sym].st_shndx);
int value = Common::swap32(symtab[sym].st_value); int value = Common::swap32(symtab[sym].st_value);
const char *name = stringBase + Common::swap32(symtab[sym].st_name); const char *name = stringBase + Common::swap32(symtab[sym].st_name);
if (bRelocate) if (bRelocate)
value += sectionAddrs[sectionIndex]; value += sectionAddrs[sectionIndex];
int symtype = Symbol::SYMBOL_DATA; int symtype = Symbol::SYMBOL_DATA;
switch (type) switch (type)
{ {
case STT_OBJECT: case STT_OBJECT:
@ -251,4 +256,3 @@ bool ElfReader::LoadSymbols()
g_symbolDB.Index(); g_symbolDB.Index();
return hasSymbols; return hasSymbols;
} }

View File

@ -1,3 +1,20 @@
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
#ifndef _ELFREADER_H #ifndef _ELFREADER_H
#define _ELFREADER_H #define _ELFREADER_H
@ -29,31 +46,21 @@ class ElfReader
public: public:
ElfReader(void *ptr); ElfReader(void *ptr);
~ElfReader() { }
~ElfReader() u32 Read32(int off) const { return base32[off>>2]; }
{
}
u32 Read32(int off)
{
return base32[off>>2];
}
// Quick accessors // Quick accessors
ElfType GetType() { return (ElfType)(header->e_type); } ElfType GetType() const { return (ElfType)(header->e_type); }
ElfMachine GetMachine() { return (ElfMachine)(header->e_machine); } ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
u32 GetEntryPoint() { return entryPoint; } u32 GetEntryPoint() const { return entryPoint; }
u32 GetFlags() { return (u32)(header->e_flags); } u32 GetFlags() const { return (u32)(header->e_flags); }
int GetNumSegments() { return (int)(header->e_phnum); } int GetNumSegments() const { return (int)(header->e_phnum); }
int GetNumSections() { return (int)(header->e_shnum); } int GetNumSections() const { return (int)(header->e_shnum); }
const char *GetSectionName(int section); const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
u8 *GetPtr(int offset) const char *GetSectionName(int section) const;
{ const u8 *GetSectionDataPtr(int section) const
return (u8*)base + offset;
}
u8 *GetSectionDataPtr(int section)
{ {
if (section < 0 || section >= header->e_shnum) if (section < 0 || section >= header->e_shnum)
return 0; return 0;
@ -62,16 +69,13 @@ public:
else else
return 0; return 0;
} }
u8 *GetSegmentPtr(int segment) const u8 *GetSegmentPtr(int segment)
{ {
return GetPtr(segments[segment].p_offset); return GetPtr(segments[segment].p_offset);
} }
u32 GetSectionAddr(SectionID section) {return sectionAddrs[section];} u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
int GetSectionSize(SectionID section) int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
{ SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
return sections[section].sh_size;
}
SectionID GetSectionByName(const char *name, int firstSection=0); //-1 for not found
bool DidRelocate() { bool DidRelocate() {
return bRelocate; return bRelocate;

View File

@ -100,12 +100,6 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
m_BootType = BOOT_ELF; m_BootType = BOOT_ELF;
bNTSC = true; bNTSC = true;
} }
else if (!strcasecmp(Extension.c_str(), ".bin"))
{
BaseDataPath = s_DataBasePath_USA;
m_BootType = BOOT_BIN;
bNTSC = true;
}
else if (!strcasecmp(Extension.c_str(), ".dol")) else if (!strcasecmp(Extension.c_str(), ".dol"))
{ {
BaseDataPath = s_DataBasePath_USA; BaseDataPath = s_DataBasePath_USA;

View File

@ -62,13 +62,11 @@ struct SCoreStartupParameter
{ {
BOOT_ISO, BOOT_ISO,
BOOT_ELF, BOOT_ELF,
BOOT_BIN,
BOOT_DOL, BOOT_DOL,
BOOT_BIOS BOOT_BIOS
}; };
EBootType m_BootType; EBootType m_BootType;
// files // files
std::string m_strVideoPlugin; std::string m_strVideoPlugin;
std::string m_strPadPlugin; std::string m_strPadPlugin;

View File

@ -194,19 +194,19 @@ void ExecuteCommand(UDIDMAControlRegister& _DMAControlReg);
void Init() void Init()
{ {
dvdMem.StatusReg.Hex = 0; dvdMem.StatusReg.Hex = 0;
dvdMem.CoverReg.Hex = 0; dvdMem.CoverReg.Hex = 0;
dvdMem.Command[0] = 0; dvdMem.Command[0] = 0;
dvdMem.Command[1] = 0; dvdMem.Command[1] = 0;
dvdMem.Command[2] = 0; dvdMem.Command[2] = 0;
dvdMem.DMAAddress.Hex = 0; dvdMem.DMAAddress.Hex = 0;
dvdMem.DMALength.Hex = 0; dvdMem.DMALength.Hex = 0;
dvdMem.DMAControlReg.Hex = 0; dvdMem.DMAControlReg.Hex = 0;
dvdMem.Immediate = 0; dvdMem.Immediate = 0;
dvdMem.ConfigReg.Hex = 0; dvdMem.ConfigReg.Hex = 0;
dvdMem.AudioStart = 0; dvdMem.AudioStart = 0;
dvdMem.AudioPos = 0; dvdMem.AudioPos = 0;
dvdMem.AudioLength = 0; dvdMem.AudioLength = 0;
// SetLidOpen(true); // SetLidOpen(true);
} }

View File

@ -66,7 +66,7 @@ CEXIIPL::CEXIIPL() :
if (pStream != NULL) if (pStream != NULL)
{ {
fseek(pStream, 0, SEEK_END); fseek(pStream, 0, SEEK_END);
size_t filesize = ftell(pStream); size_t filesize = (size_t)ftell(pStream);
rewind(pStream); rewind(pStream);
fread(m_pIPL + 0x001fcf00, 1, filesize, pStream); fread(m_pIPL + 0x001fcf00, 1, filesize, pStream);
@ -81,7 +81,7 @@ CEXIIPL::CEXIIPL() :
if (pStream != NULL) if (pStream != NULL)
{ {
fseek(pStream, 0, SEEK_END); fseek(pStream, 0, SEEK_END);
size_t filesize = ftell(pStream); size_t filesize = (size_t)ftell(pStream);
rewind(pStream); rewind(pStream);
fread(m_pIPL + 0x001aff00, 1, filesize, pStream); fread(m_pIPL + 0x001aff00, 1, filesize, pStream);

View File

@ -14,6 +14,7 @@ files = ["Console.cpp",
"Tracer.cpp", "Tracer.cpp",
"VolumeHandler.cpp", "VolumeHandler.cpp",
"Boot/Boot.cpp", "Boot/Boot.cpp",
"Boot/Boot_BIOSEmu.cpp",
"Boot/Boot_DOL.cpp", "Boot/Boot_DOL.cpp",
"Boot/Boot_ELF.cpp", "Boot/Boot_ELF.cpp",
"Boot/ElfReader.cpp", "Boot/ElfReader.cpp",