From bf7d37953741e8dad0c0159801e05960fdf33912 Mon Sep 17 00:00:00 2001 From: "fires.gc" Date: Tue, 24 Feb 2009 21:45:36 +0000 Subject: [PATCH] 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 --- Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp | 21 +++ Source/Core/Core/Src/Boot/Boot_WiiWAD.h | 1 + Source/Core/Core/Src/HW/WII_IOB.cpp | 10 ++ Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 6 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h | 126 +++++++++++++++--- 5 files changed, 145 insertions(+), 19 deletions(-) diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp index 596a549a0e..d807108300 100644 --- a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp @@ -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 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); // ================ diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.h b/Source/Core/Core/Src/Boot/Boot_WiiWAD.h index 9054276a0d..3f2066e497 100644 --- a/Source/Core/Core/Src/Boot/Boot_WiiWAD.h +++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.h @@ -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 m_TileMetaContent; +extern u64 m_TitleID; diff --git a/Source/Core/Core/Src/HW/WII_IOB.cpp b/Source/Core/Core/Src/HW/WII_IOB.cpp index 2cfb29b247..218a05f9bc 100644 --- a/Source/Core/Core/Src/HW/WII_IOB.cpp +++ b/Source/Core/Core/Src/HW/WII_IOB.cpp @@ -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; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp index 13984e885c..f19a6c4313 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -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(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(_Address, "unknown")); } - if (erased > 0 && erased == DeviceID) + if (ClosedDeviceID > 0 && ClosedDeviceID == DeviceID) DeleteDeviceByID(DeviceID); } else { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h index 70deaaf53a..e607d70e5f 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h @@ -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 -