added some more function for ES emulation and NANDLoader... but IOCTL_ES_LAUNCH so a lot of WADs aren't loaded completely

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2425 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
fires.gc 2009-02-24 21:45:36 +00:00
parent 1f029ab1b5
commit bf7d379537
5 changed files with 145 additions and 19 deletions

View File

@ -26,6 +26,7 @@
#include "Boot_WiiWAD.h" #include "Boot_WiiWAD.h"
#include "AES/aes.h" #include "AES/aes.h"
#include "MathUtil.h" #include "MathUtil.h"
#include "FileUtil.h"
class CBlobBigEndianReader class CBlobBigEndianReader
{ {
@ -45,6 +46,7 @@ private:
std::vector<STileMetaContent> m_TileMetaContent; std::vector<STileMetaContent> m_TileMetaContent;
u16 m_BootIndex = -1; u16 m_BootIndex = -1;
u64 m_TitleID = -1;
void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest) void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest)
{ {
@ -97,6 +99,8 @@ bool ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u8* pTMD)
u32 numEntries = Common::swap16(pTMD + 0x01de); u32 numEntries = Common::swap16(pTMD + 0x01de);
m_BootIndex = Common::swap16(pTMD + 0x01e0); m_BootIndex = Common::swap16(pTMD + 0x01e0);
m_TitleID = Common::swap64(pTMD + 0x018C);
u8* p = pDataApp; u8* p = pDataApp;
m_TileMetaContent.resize(numEntries); m_TileMetaContent.resize(numEntries);
@ -243,12 +247,29 @@ void SetupWiiMem()
Memory::Write_U32(0x00000000, 0x80000000 + i); Memory::Write_U32(0x00000000, 0x80000000 + i);
} }
// create Home directory
{
char Path[260+1];
char* pTitleID = (char*)&m_TitleID;
sprintf(Path, FULL_WII_USER_DIR "title//%02x%02x%02x%02x/%02x%02x%02x%02x/data/nocopy/",
(u8)pTitleID[7], (u8)pTitleID[6], (u8)pTitleID[5], (u8)pTitleID[4],
(u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]);
File::CreateDirectoryStructure(Path);
}
/* This is some kind of consistency check that is compared to the 0x00 /* This is some kind of consistency check that is compared to the 0x00
values as the game boots. This location keep the 4 byte ID for as long values as the game boots. This location keep the 4 byte ID for as long
as the game is running. The 6 byte ID at 0x00 is overwritten sometime as the game is running. The 6 byte ID at 0x00 is overwritten sometime
after this check during booting. */ after this check during booting. */
Memory::Write_U64(m_TitleID, 0x0000318c); // NAND Load Title ID
// VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4); // VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4);
// Memory::Write_U8(0x80, 0x00003184); // Memory::Write_U8(0x80, 0x00003184);
// ================ // ================

View File

@ -33,4 +33,5 @@ struct STileMetaContent
// [TODO]: this global internal stuff sux... the whole data should be inside the ES // [TODO]: this global internal stuff sux... the whole data should be inside the ES
// but this is the easiest way atm // but this is the easiest way atm
extern std::vector<STileMetaContent> m_TileMetaContent; extern std::vector<STileMetaContent> m_TileMetaContent;
extern u64 m_TitleID;

View File

@ -36,6 +36,11 @@ void HWCALL Read32(u32& _rReturnValue, const u32 _Address)
{ {
switch(_Address & 0xFFFF) switch(_Address & 0xFFFF)
{ {
// NAND Loader ... no idea
case 0x018:
LOGV(WII_IOB, 0, "IOP: Read32 from 0x18 = 0x%08x", _Address);
break;
case 0xc0: // __VISendI2CData case 0xc0: // __VISendI2CData
_rReturnValue = 0; _rReturnValue = 0;
LOGV(WII_IOB, 2, "IOP: Read32 from 0xc0 = 0x%08x (__VISendI2CData)", _rReturnValue); LOGV(WII_IOB, 2, "IOP: Read32 from 0xc0 = 0x%08x (__VISendI2CData)", _rReturnValue);
@ -91,6 +96,11 @@ void HWCALL Write32(const u32 _Value, const u32 _Address)
{ {
switch(_Address & 0xFFFF) switch(_Address & 0xFFFF)
{ {
// NAND Loader ... no idea
case 0x18:
LOGV(WII_IOB, 0, "IOP: Write32 0x%08x to 0x%08x", _Value, _Address);
break;
case 0xc0: // __VISendI2CData case 0xc0: // __VISendI2CData
LOGV(WII_IOB, 2, "IOP: Write32 to 0xc0 = 0x%08x (__VISendI2CData)", _Value); LOGV(WII_IOB, 2, "IOP: Write32 to 0xc0 = 0x%08x (__VISendI2CData)", _Value);
break; break;

View File

@ -274,7 +274,7 @@ void CopySettingsFile(std::string DeviceName)
void ExecuteCommand(u32 _Address) void ExecuteCommand(u32 _Address)
{ {
bool GenerateReply = false; bool GenerateReply = false;
u32 erased = 0; u32 ClosedDeviceID = 0;
ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address)); ECommandType Command = static_cast<ECommandType>(Memory::Read_U32(_Address));
switch (Command) switch (Command)
@ -368,7 +368,7 @@ void ExecuteCommand(u32 _Address)
// Delete the device when CLOSE is called, this does not effect // Delete the device when CLOSE is called, this does not effect
// GenerateReply() for any other purpose than the logging because // GenerateReply() for any other purpose than the logging because
// it's a true / false only function // // it's a true / false only function //
erased = DeviceID; ClosedDeviceID = DeviceID;
GenerateReply = true; GenerateReply = true;
} }
} }
@ -449,7 +449,7 @@ void ExecuteCommand(u32 _Address)
g_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown")); g_ReplyQueue.push(std::pair<u32, std::string>(_Address, "unknown"));
} }
if (erased > 0 && erased == DeviceID) if (ClosedDeviceID > 0 && ClosedDeviceID == DeviceID)
DeleteDeviceByID(DeviceID); DeleteDeviceByID(DeviceID);
} else { } else {

View File

@ -56,6 +56,8 @@
#include "../Boot/Boot_WiiWAD.h" #include "../Boot/Boot_WiiWAD.h"
#include "../PowerPC/PowerPC.h"
struct SContentAccess struct SContentAccess
{ {
@ -147,6 +149,25 @@ public:
switch(Buffer.Parameter) switch(Buffer.Parameter)
{ {
case IOCTL_ES_LAUNCH: // 0x08
{
_dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 2);
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 view = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
u64 ticketid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+4);
u32 devicetype =Memory::Read_U32(Buffer.InBuffer[1].m_Address+12);
u64 titleid = Memory::Read_U64(Buffer.InBuffer[1].m_Address+16);
u16 access = Memory::Read_U16(Buffer.InBuffer[1].m_Address+24);
PanicAlert("IOCTL_ES_LAUNCH: src titleID %08x/%08x -> start %08x/%08x", TitleID>>32, TitleID, titleid>>32, titleid );
Memory::Write_U32(0, _CommandAddress + 0x4);
return false;
}
break;
case IOCTL_ES_OPENCONTENT: // 0x09 case IOCTL_ES_OPENCONTENT: // 0x09
{ {
u32 CFD = AccessIdentID++; u32 CFD = AccessIdentID++;
@ -245,12 +266,13 @@ public:
/* I changed reading the TitleID from disc to reading from the /* I changed reading the TitleID from disc to reading from the
InBuffer, if it fails it's because of some kind of memory error InBuffer, if it fails it's because of some kind of memory error
that we would want to fix anyway */ that we would want to fix anyway */
u32 TitleID = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
if (TitleID == 0) TitleID = 0xF00DBEEF; u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
_dbg_assert_msg_(WII_IPC_HLE, TitleID == GetCurrentTitleID(), "Get Dir from unkw title dir?? this can be okay...");
char* pTitleID = (char*)&TitleID; char* pTitleID = (char*)&TitleID;
char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address);
sprintf(Path, "/00010000/%08x/data", TitleID); sprintf(Path, "/%08x/%08x/data", (TitleID >> 32) & 0xFFFFFFFF, TitleID & 0xFFFFFFFF);
LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEDIR: %s)", Path); LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEDIR: %s)", Path);
} }
@ -258,8 +280,8 @@ public:
case IOCTL_ES_GETTITLEID: // 0x20 case IOCTL_ES_GETTITLEID: // 0x20
{ {
u32 TitleID = VolumeHandler::Read32(0); _dbg_assert_msg_(WII_IPC_HLE, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTITLEID no in buffer");
if (TitleID == 0) TitleID = 0xF00DBEEF;
/* This seems to be the right address to write the Title ID to /* This seems to be the right address to write the Title ID to
because then it shows up in the InBuffer of IOCTL_ES_GETTITLEDIR because then it shows up in the InBuffer of IOCTL_ES_GETTITLEDIR
@ -268,28 +290,73 @@ public:
IOCTL_ES_GETTITLEDIR. This values is not stored in 0x3180 or anywhere IOCTL_ES_GETTITLEDIR. This values is not stored in 0x3180 or anywhere
else as I have seen, it's just used as an input buffer in the following else as I have seen, it's just used as an input buffer in the following
IOCTL_ES_GETTITLEDIR call and then forgotten. */ IOCTL_ES_GETTITLEDIR call and then forgotten. */
Memory::Write_U32(TitleID, Buffer.PayloadBuffer[0].m_Address);
LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEID: 0x%x", TitleID); u64 TitleID = GetCurrentTitleID();
Memory::Write_U64(TitleID, Buffer.PayloadBuffer[0].m_Address);
LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEID: 0x%x 0x%x", TitleID>>32, TitleID);
} }
break; break;
case IOCTL_ES_GETVIEWCNT: // 0x12 (Input: 8 bytes, Output: 4 bytes) case IOCTL_ES_GETVIEWCNT: // 0x12 (Input: 8 bytes, Output: 4 bytes)
{ {
if(Buffer.NumberInBuffer) _dbg_assert_msg_(WII_IPC_HLE, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETVIEWCNT no in buffer");
_dbg_assert_msg_(WII_IPC_HLE, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETVIEWCNT no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
// [TODO] here we should have a map from title id to tickets or something like that...
if (m_TileMetaContent.size() > 0)
{ {
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address); Memory::Write_U32(1, Buffer.PayloadBuffer[0].m_Address);
} }
// Should we write something here? LOG(WII_IPC_ES, "ES: IOCTL_ES_GETVIEWCNT titleID: %08x/%08x", TitleID>>32, TitleID );
//Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
//DumpCommands(Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size / 4, Memory::Write_U32(0, _CommandAddress + 0x4);
// LogTypes::WII_IPC_NET); return true;
} }
break; break;
case IOCTL_ES_GETVIEWS:
{
_dbg_assert_msg_(WII_IPC_HLE, Buffer.NumberInBuffer == 2, "IOCTL_ES_GETVIEWS no in buffer");
_dbg_assert_msg_(WII_IPC_HLE, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETVIEWS no out buffer");
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 Count = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
_dbg_assert_msg_(WII_IPC_HLE, TitleID==0x0000000100000002, "IOCTL_ES_GETVIEWS: TitleID != 00000001/00000002");
/* write ticket data... hmmm
typedef struct _tikview {
u32 view;
u64 ticketid;
u32 devicetype;
u64 titleid;
u16 access_mask;
u8 reserved[0x3c];
u8 cidx_mask[0x40];
u16 padding;
tiklimit limits[8];
} __attribute__((packed)) tikview;
*/
Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
Memory::Write_U64(m_TitleID, Buffer.PayloadBuffer[0].m_Address+4);
Memory::Write_U32(0x00010001, Buffer.PayloadBuffer[0].m_Address+12);
Memory::Write_U64(m_TitleID, Buffer.PayloadBuffer[0].m_Address+16);
Memory::Write_U16(0x777, Buffer.PayloadBuffer[0].m_Address+24);
Memory::Write_U32(0, _CommandAddress + 0x4);
return true;
}
break;
case IOCTL_ES_GETTMDVIEWCNT: // 0x14 case IOCTL_ES_GETTMDVIEWCNT: // 0x14
{ {
PanicAlert("IOCTL_ES_GETTMDVIEWCNT: this looks really wrong...");
if(Buffer.NumberInBuffer) if(Buffer.NumberInBuffer)
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address); u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
@ -299,14 +366,19 @@ public:
break; break;
case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes) case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes)
PanicAlert("IOCTL_ES_GETCONSUMPTION: this looks really wrong...");
//DumpCommands(Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size / 4, //DumpCommands(Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size / 4,
// LogTypes::WII_IPC_NET); // LogTypes::WII_IPC_NET);
break; break;
case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes) case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes)
PanicAlert("IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
break; break;
case IOCTL_ES_GETTITLECOUNT: case IOCTL_ES_GETTITLECOUNT:
{ {
PanicAlert("IOCTL_ES_GETTITLECOUNT: this looks really wrong...");
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address); u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
Memory::Write_U32(0, OutBuffer); Memory::Write_U32(0, OutBuffer);
@ -318,6 +390,9 @@ public:
case IOCTL_ES_GETSTOREDTMDSIZE: case IOCTL_ES_GETSTOREDTMDSIZE:
{ {
PanicAlert("IOCTL_ES_GETSTOREDTMDSIZE: this looks really wrong...");
u64 TitleId = Memory::Read_U64(Buffer.InBuffer[0].m_Address); u64 TitleId = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address); u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
@ -344,8 +419,27 @@ public:
return true; return true;
} }
u64 GetCurrentTitleID()
{
u64 TitleID = 0;
// check for cd ...
if (VolumeHandler::IsValid())
{
TitleID = ((u64)0x00010000 << 32) | VolumeHandler::Read32(0);
}
else
{
if (m_TileMetaContent.size() > 0)
{
TitleID = m_TitleID;
}
}
if (TitleID == -1)
TitleID = ((u64)0x00010000 << 32) | 0xF00DBEEF;
return TitleID;
}
}; };
#endif #endif