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 "AES/aes.h"
#include "MathUtil.h"
#include "FileUtil.h"
class CBlobBigEndianReader
{
@ -45,6 +46,7 @@ private:
std::vector<STileMetaContent> m_TileMetaContent;
u16 m_BootIndex = -1;
u64 m_TitleID = -1;
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);
m_BootIndex = Common::swap16(pTMD + 0x01e0);
m_TitleID = Common::swap64(pTMD + 0x018C);
u8* p = pDataApp;
m_TileMetaContent.resize(numEntries);
@ -243,12 +247,29 @@ void SetupWiiMem()
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
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
after this check during booting. */
Memory::Write_U64(m_TitleID, 0x0000318c); // NAND Load Title ID
// VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4);
// 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
// but this is the easiest way atm
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)
{
// NAND Loader ... no idea
case 0x018:
LOGV(WII_IOB, 0, "IOP: Read32 from 0x18 = 0x%08x", _Address);
break;
case 0xc0: // __VISendI2CData
_rReturnValue = 0;
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)
{
// NAND Loader ... no idea
case 0x18:
LOGV(WII_IOB, 0, "IOP: Write32 0x%08x to 0x%08x", _Value, _Address);
break;
case 0xc0: // __VISendI2CData
LOGV(WII_IOB, 2, "IOP: Write32 to 0xc0 = 0x%08x (__VISendI2CData)", _Value);
break;

View File

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

View File

@ -56,6 +56,8 @@
#include "../Boot/Boot_WiiWAD.h"
#include "../PowerPC/PowerPC.h"
struct SContentAccess
{
@ -147,6 +149,25 @@ public:
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
{
u32 CFD = AccessIdentID++;
@ -245,12 +266,13 @@ public:
/* I changed reading the TitleID from disc to reading from the
InBuffer, if it fails it's because of some kind of memory error
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* 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);
}
@ -258,8 +280,8 @@ public:
case IOCTL_ES_GETTITLEID: // 0x20
{
u32 TitleID = VolumeHandler::Read32(0);
if (TitleID == 0) TitleID = 0xF00DBEEF;
_dbg_assert_msg_(WII_IPC_HLE, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTITLEID no in buffer");
/* 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
@ -268,28 +290,73 @@ public:
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
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;
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?
//Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
LOG(WII_IPC_ES, "ES: IOCTL_ES_GETVIEWCNT titleID: %08x/%08x", TitleID>>32, TitleID );
//DumpCommands(Buffer.InBuffer[0].m_Address, Buffer.InBuffer[0].m_Size / 4,
// LogTypes::WII_IPC_NET);
Memory::Write_U32(0, _CommandAddress + 0x4);
return true;
}
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
{
PanicAlert("IOCTL_ES_GETTMDVIEWCNT: this looks really wrong...");
if(Buffer.NumberInBuffer)
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
@ -299,14 +366,19 @@ public:
break;
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,
// LogTypes::WII_IPC_NET);
break;
case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes)
PanicAlert("IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
break;
case IOCTL_ES_GETTITLECOUNT:
{
PanicAlert("IOCTL_ES_GETTITLECOUNT: this looks really wrong...");
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
Memory::Write_U32(0, OutBuffer);
@ -318,6 +390,9 @@ public:
case IOCTL_ES_GETSTOREDTMDSIZE:
{
PanicAlert("IOCTL_ES_GETSTOREDTMDSIZE: this looks really wrong...");
u64 TitleId = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address);
@ -344,8 +419,27 @@ public:
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