summaryrefslogtreecommitdiff
path: root/Source/Core/DiscIO
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2009-12-10 09:16:10 +0000
committerShawn Hoffman <godisgovernment@gmail.com>2009-12-10 09:16:10 +0000
commit805bd8ec280ba19ce3d93cbc5698e6456e5c75ac (patch)
treecdc7dddac036d5325662e9b502265c5eb44727b0 /Source/Core/DiscIO
parentd4e35a1a975cad1a8b789754cc9a87bcb5a64719 (diff)
VolumeDirectory: allow loading of arbitrary apploader and dol. Code cleaning around the bootup logic.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4668 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DiscIO')
-rw-r--r--Source/Core/DiscIO/Src/VolumeCreator.cpp4
-rw-r--r--Source/Core/DiscIO/Src/VolumeCreator.h2
-rw-r--r--Source/Core/DiscIO/Src/VolumeDirectory.cpp111
-rw-r--r--Source/Core/DiscIO/Src/VolumeDirectory.h123
4 files changed, 185 insertions, 55 deletions
diff --git a/Source/Core/DiscIO/Src/VolumeCreator.cpp b/Source/Core/DiscIO/Src/VolumeCreator.cpp
index addc64874f..7d877d0c13 100644
--- a/Source/Core/DiscIO/Src/VolumeCreator.cpp
+++ b/Source/Core/DiscIO/Src/VolumeCreator.cpp
@@ -111,10 +111,10 @@ IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionG
return NULL;
}
-IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii)
+IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader, const std::string& _rDOL)
{
if (CVolumeDirectory::IsValidDirectory(_rDirectory))
- return new CVolumeDirectory(_rDirectory, _bIsWii);
+ return new CVolumeDirectory(_rDirectory, _bIsWii, _rApploader, _rDOL);
return NULL;
}
diff --git a/Source/Core/DiscIO/Src/VolumeCreator.h b/Source/Core/DiscIO/Src/VolumeCreator.h
index 24a9bb1c0e..732370307d 100644
--- a/Source/Core/DiscIO/Src/VolumeCreator.h
+++ b/Source/Core/DiscIO/Src/VolumeCreator.h
@@ -23,7 +23,7 @@
namespace DiscIO
{
IVolume* CreateVolumeFromFilename(const std::string& _rFilename, u32 _PartitionGroup = 0, u32 _VolumeNum = -1);
-IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii);
+IVolume* CreateVolumeFromDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader = "", const std::string& _rDOL = "");
bool IsVolumeWiiDisc(const IVolume *_rVolume);
bool IsVolumeWadFile(const IVolume *_rVolume);
} // namespace
diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.cpp b/Source/Core/DiscIO/Src/VolumeDirectory.cpp
index b7ab262ada..6e5ab9ac5d 100644
--- a/Source/Core/DiscIO/Src/VolumeDirectory.cpp
+++ b/Source/Core/DiscIO/Src/VolumeDirectory.cpp
@@ -25,11 +25,20 @@ namespace DiscIO
static const u8 ENTRY_SIZE = 0x0c;
static const u8 FILE_ENTRY = 0;
static const u8 DIRECTORY_ENTRY = 1;
-static const u64 FST_ADDRESS = 0x440;
+static const u64 DISKHEADER_ADDRESS = 0;
+static const u64 DISKHEADERINFO_ADDRESS = 0x440;
+static const u64 APPLOADER_ADDRESS = 0x2440;
static const u32 MAX_NAME_LENGTH = 0x3df;
-
-CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii)
- : m_totalNameSize(0)
+// relocatable
+static u64 FST_ADDRESS = 0x440;
+static u64 DOL_ADDRESS = 0;
+
+CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii, const std::string& _rApploader, const std::string& _rDOL)
+ : m_apploaderSize(0)
+ , m_apploader(NULL)
+ , m_DOLSize(0)
+ , m_DOL(NULL)
+ , m_totalNameSize(0)
, m_dataStartAddress(-1)
, m_fstSize(0)
, m_FSTData(NULL)
@@ -51,16 +60,31 @@ CVolumeDirectory::CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii)
SetDiskTypeGC();
}
+ m_diskHeaderInfo = new SDiskHeaderInfo();
+
+ // Don't load the dol if we've no apploader...
+ if (SetApploader(_rApploader))
+ SetDOL(_rDOL);
+
BuildFST();
}
CVolumeDirectory::~CVolumeDirectory()
{
- delete m_FSTData;
+ delete[] m_FSTData;
m_FSTData = NULL;
- delete m_diskHeader;
+ delete[] m_diskHeader;
m_diskHeader = NULL;
+
+ delete m_diskHeaderInfo;
+ m_diskHeaderInfo = NULL;
+
+ delete[] m_DOL;
+ m_DOL = NULL;
+
+ delete[] m_apploader;
+ m_apploader = NULL;
}
bool CVolumeDirectory::IsValidDirectory(const std::string& _rDirectory)
@@ -76,14 +100,35 @@ bool CVolumeDirectory::RAWRead( u64 _Offset, u64 _Length, u8* _pBuffer ) const
bool CVolumeDirectory::Read(u64 _Offset, u64 _Length, u8* _pBuffer) const
{
- if(_Offset < FST_ADDRESS)
+ // header
+ if(_Offset < DISKHEADERINFO_ADDRESS)
{
- WriteToBuffer(0, FST_ADDRESS, m_diskHeader, _Offset, _Length, _pBuffer);
+ WriteToBuffer(DISKHEADER_ADDRESS, DISKHEADERINFO_ADDRESS, m_diskHeader, _Offset, _Length, _pBuffer);
+ return true;
}
-
+ // header info
+ if(_Offset < APPLOADER_ADDRESS)
+ {
+ WriteToBuffer(DISKHEADERINFO_ADDRESS, sizeof(m_diskHeaderInfo), (u8*)m_diskHeaderInfo, _Offset, _Length, _pBuffer);
+ return true;
+ }
+ // apploader
+ if(_Offset >= APPLOADER_ADDRESS && _Offset <= APPLOADER_ADDRESS + m_apploaderSize)
+ {
+ WriteToBuffer(APPLOADER_ADDRESS, m_apploaderSize, m_apploader, _Offset, _Length, _pBuffer);
+ return true;
+ }
+ // dol
+ if(_Offset >= DOL_ADDRESS && _Offset <= DOL_ADDRESS + m_DOLSize)
+ {
+ WriteToBuffer(DOL_ADDRESS, m_DOLSize, m_DOL, _Offset, _Length, _pBuffer);
+ return true;
+ }
+ // fst
if(_Offset < m_dataStartAddress)
{
- WriteToBuffer(FST_ADDRESS, m_fstSize, m_FSTData, _Offset, _Length, _pBuffer);
+ WriteToBuffer(FST_ADDRESS, m_fstSize, m_FSTData, _Offset, _Length, _pBuffer);
+ return true;
}
if(m_virtualDisk.size() == 0)
@@ -257,6 +302,52 @@ void CVolumeDirectory::SetDiskTypeGC()
m_addressShift = 0;
}
+bool CVolumeDirectory::SetApploader(const std::string& _rApploader)
+{
+ if (!_rApploader.empty())
+ {
+ std::string data;
+ File::ReadFileToString(false, _rApploader.c_str(), data);
+ m_apploaderSize = 0x20 + Common::swap32(*(u32*)&data.data()[0x14]) + Common::swap32(*(u32*)&data.data()[0x18]);
+ if (m_apploaderSize != data.size())
+ {
+ PanicAlert("Apploader is the wrong size...is it really an apploader?");
+ return false;
+ }
+ m_apploader = new u8[m_apploaderSize];
+ copy(data.begin(), data.end(), m_apploader);
+
+ // 32byte aligned (plus 0x20 padding)
+ DOL_ADDRESS = (APPLOADER_ADDRESS + m_apploaderSize + 0x20 + 31) & ~31ULL;
+ return true;
+ }
+ else
+ {
+ m_apploaderSize = 0x20;
+ m_apploader = new u8[m_apploaderSize];
+ // Make sure BS2 HLE doesn't try to run the apploader
+ *(u32*)&m_apploader[0x10] = (u32)-1;
+ return false;
+ }
+}
+
+void CVolumeDirectory::SetDOL(const std::string& _rDOL)
+{
+ if (!_rDOL.empty())
+ {
+ std::string data;
+ File::ReadFileToString(false, _rDOL.c_str(), data);
+ m_DOLSize = data.size();
+ m_DOL = new u8[m_DOLSize];
+ copy(data.begin(), data.end(), m_DOL);
+
+ Write32((u32)(DOL_ADDRESS >> m_addressShift), 0x0420, m_diskHeader);
+
+ // 32byte aligned (plus 0x20 padding)
+ FST_ADDRESS = (DOL_ADDRESS + m_DOLSize + 0x20 + 31) & ~31ULL;
+ }
+}
+
void CVolumeDirectory::BuildFST()
{
if(m_FSTData)
diff --git a/Source/Core/DiscIO/Src/VolumeDirectory.h b/Source/Core/DiscIO/Src/VolumeDirectory.h
index 27fa2df43d..727974a417 100644
--- a/Source/Core/DiscIO/Src/VolumeDirectory.h
+++ b/Source/Core/DiscIO/Src/VolumeDirectory.h
@@ -33,75 +33,114 @@ namespace DiscIO
class CVolumeDirectory : public IVolume
{
- public:
+public:
- CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii);
+ CVolumeDirectory(const std::string& _rDirectory, bool _bIsWii,
+ const std::string& _rApploader = "", const std::string& _rDOL = "");
- ~CVolumeDirectory();
+ ~CVolumeDirectory();
- static bool IsValidDirectory(const std::string& _rDirectory);
+ static bool IsValidDirectory(const std::string& _rDirectory);
- bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
- bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const;
+ bool Read(u64 _Offset, u64 _Length, u8* _pBuffer) const;
+ bool RAWRead(u64 _Offset, u64 _Length, u8* _pBuffer) const;
- std::string GetUniqueID() const;
- void SetUniqueID(std::string _ID);
+ std::string GetUniqueID() const;
+ void SetUniqueID(std::string _ID);
- std::string GetMakerID() const;
+ std::string GetMakerID() const;
- std::string GetName() const;
- void SetName(std::string);
+ std::string GetName() const;
+ void SetName(std::string);
- u32 GetFSTSize() const;
+ u32 GetFSTSize() const;
- std::string GetApploaderDate() const;
+ std::string GetApploaderDate() const;
- ECountry GetCountry() const;
+ ECountry GetCountry() const;
- u64 GetSize() const;
+ u64 GetSize() const;
- void BuildFST();
+ void BuildFST();
- private:
- static std::string ExtractDirectoryName(const std::string& _rDirectory);
+private:
+ static std::string ExtractDirectoryName(const std::string& _rDirectory);
- void SetDiskTypeWii();
- void SetDiskTypeGC();
+ void SetDiskTypeWii();
+ void SetDiskTypeGC();
- // writing to read buffer
- void WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src,
- u64& _Address, u64& _Length, u8*& _pBuffer) const;
+ bool SetApploader(const std::string& _rApploader);
- void PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const;
+ void SetDOL(const std::string& _rDOL);
- void Write32(u32 data, u32 offset, u8* buffer);
+ // writing to read buffer
+ void WriteToBuffer(u64 _SrcStartAddress, u64 _SrcLength, u8* _Src,
+ u64& _Address, u64& _Length, u8*& _pBuffer) const;
- // FST creation
- void WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length);
- void WriteEntryName(u32& nameOffset, const std::string& name);
- void WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum);
+ void PadToAddress(u64 _StartAddress, u64& _Address, u64& _Length, u8*& _pBuffer) const;
- // returns number of entries found in _Directory
- u32 AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry);
+ void Write32(u32 data, u32 offset, u8* buffer);
- std::string m_rootDirectory;
+ // FST creation
+ void WriteEntryData(u32& entryOffset, u8 type, u32 nameOffset, u64 dataOffset, u32 length);
+ void WriteEntryName(u32& nameOffset, const std::string& name);
+ void WriteEntry(const File::FSTEntry& entry, u32& fstOffset, u32& nameOffset, u64& dataOffset, u32 parentEntryNum);
- std::map<u64, std::string> m_virtualDisk;
+ // returns number of entries found in _Directory
+ u32 AddDirectoryEntries(const std::string& _Directory, File::FSTEntry& parentEntry);
- u32 m_totalNameSize;
+ std::string m_rootDirectory;
- // gc has no shift, wii has 2 bit shift
- u32 m_addressShift;
+ std::map<u64, std::string> m_virtualDisk;
- // first address on disk containing file data
- u64 m_dataStartAddress;
+ u32 m_totalNameSize;
- u64 m_fstNameOffset;
+ // gc has no shift, wii has 2 bit shift
+ u32 m_addressShift;
- u64 m_fstSize;
+ // first address on disk containing file data
+ u64 m_dataStartAddress;
- u8* m_FSTData;
- u8* m_diskHeader;
+ u64 m_fstNameOffset;
+ u64 m_fstSize;
+ u8* m_FSTData;
+
+ u8* m_diskHeader;
+
+ #pragma pack(push, 1)
+ struct SDiskHeaderInfo
+ {
+ u32 debug_mntr_size;
+ u32 simulated_mem_size;
+ u32 arg_offset;
+ u32 debug_flag;
+ u32 track_location;
+ u32 track_size;
+ u32 countrycode;
+ u32 unknown;
+ u32 unknown2;
+
+ // All the data is byteswapped
+ SDiskHeaderInfo() {
+ debug_mntr_size = 0;
+ simulated_mem_size = 0;
+ arg_offset = 0;
+ debug_flag = 0;
+ track_location = 0;
+ track_size = 0;
+ countrycode = 0;
+ unknown = 0;
+ unknown2 = 0;
+ }
+ };
+ #pragma pack(pop)
+ SDiskHeaderInfo* m_diskHeaderInfo;
+
+ u64 m_apploaderSize;
+ u8* m_apploader;
+
+ u64 m_DOLSize;
+ u8* m_DOL;
};
} // namespace