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:
parent
b6605213a1
commit
f7b6298e77
|
@ -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=""..\..\..\Externals\LZO\$(OutDir)\lzo.lib""
|
|
||||||
/>
|
|
||||||
<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=""..\..\..\Externals\LZO\$(OutDir)\lzo.lib""
|
||||||
|
/>
|
||||||
|
<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=""..\..\..\Externals\LZO\$(OutDir)\lzo.lib""
|
||||||
|
/>
|
||||||
|
<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=""..\..\..\Externals\LZO\$(OutDir)\lzo.lib""
|
|
||||||
/>
|
|
||||||
<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"
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Reference in New Issue