From 9d9c2fc983a7e54ea659c99a8ada1542f7fba0cf Mon Sep 17 00:00:00 2001 From: John Peterson Date: Sun, 7 Dec 2008 10:15:36 +0000 Subject: [PATCH] Wii IOS: Some comments, logging changes and other small changes, no noticeable effects except that the MP3 WiiConnect24 error message has changed git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1422 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/Common.h | 1 + Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp | 77 ++++--- .../Core/Src/Debugger/Debugger_SymbolMap.cpp | 4 +- Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 5 +- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device.h | 44 ++-- .../Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp | 5 + .../Src/IPC_HLE/WII_IPC_HLE_Device_Error.h | 1 + .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h | 193 ++++++++++-------- .../Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp | 79 ++++--- .../Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp | 86 ++++---- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h | 79 +++---- .../IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp | 53 +++-- .../Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h | 124 ++++++----- Source/Core/Core/Src/LogManager.cpp | 1 + Source/Core/DebuggerWX/Src/CodeWindow.cpp | 5 +- Source/Core/DebuggerWX/Src/LogWindow.cpp | 22 +- 16 files changed, 459 insertions(+), 320 deletions(-) diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h index ae7a193af4..c8ef3c8092 100644 --- a/Source/Core/Common/Src/Common.h +++ b/Source/Core/Common/Src/Common.h @@ -227,6 +227,7 @@ class LogTypes WII_IPC_DVD, WII_IPC_ES, WII_IPC_FILEIO, + WII_IPC_SD, WII_IPC_NET, WII_IPC_WIIMOTE, ACTIONREPLAY, diff --git a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp index 0b68218aa4..cc74df1a5b 100644 --- a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp @@ -67,11 +67,9 @@ void CBoot::EmulatedBIOS(bool _bDebug) // ======================================================================================= // Write necessary values // --------------------------------------------------------------------------------------- - /* - Here we write values to memory that the apploader does not take care of. Game iso info goes - to 0x80000000 according to yagcd 4.2. I'm not sure what bytes 8-10 does (version and streaming), - but I include them anyway because it seems like they are supposed to be there. - */ + /* Here we write values to memory that the apploader does not take care of. Game iso info goes + to 0x80000000 according to yagcd 4.2. I'm not sure what bytes 8-10 does (version and + streaming), but I include them anyway because it seems like they are supposed to be there. */ // --------------------------------------------------------------------------------------- DVDInterface::DVDRead(0x00000000, 0x80000000, 10); // write boot info needed for multidisc games @@ -124,10 +122,9 @@ void CBoot::EmulatedBIOS(bool _bDebug) // ======================================================================================= - /* - iAppLoaderMain - Here we load the apploader, the DOL (the exe) and the FST (filesystem). - To give you an idea about where the stuff is located on the disc take a look at yagcd chap 13. - */ + /* iAppLoaderMain - Here we load the apploader, the DOL (the exe) and the FST (filesystem). + To give you an idea about where the stuff is located on the disc take a look at yagcd + ch 13. */ // --------------------------------------------------------------------------------------- LOG(MASTER_LOG, "Call iAppLoaderMain"); do @@ -195,7 +192,13 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug) } else { - // load settings.txt + // ======================================================= + /* Write the 256 byte setting.txt to memory. This may not be needed as + most or all games read the setting.txt file from \title\00000001\00000002\ + data\setting.txt directly after the read the SYSCONF file. The games also + read it to 0x3800, what is a little strange however is that it only reads + the first 100 bytes of it. */ + // ------------- { std::string filename(WII_EUR_SETTING_FILE); if (VolumeHandler::IsValid()) @@ -231,21 +234,42 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug) fread(Memory::GetPointer(0x3800), 256, 1, pTmp); fclose(pTmp); } + // ============= - // int global vars + + // ======================================================= + /* Set hardcoded global variables to Wii memory. These are partly collected from + Wiibrew. These values are needed for the games to function correctly. A few + values in this region will also be placed here by the game as it boots. + They are: + + // Strange values that I don't know the meaning of, all games write these + 0x00 to 0x18: 0x029f0010 + 0x029f0033 + 0x029f0034 + 0x029f0035 + 0x029f0036 + 0x029f0037 + 0x029f0038 + 0x029f0039 // Replaces the previous 0x5d1c9ea3 magic word + + 0x80000038 Start of FST + 0x8000003c Size of FST Size + 0x80000060 Copyright code */ + // ------------- { - // 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); + DVDInterface::DVDRead(0x00000000, 0x00000000, 6); // Game Code + Memory::Write_U32(0x5d1c9ea3, 0x00000018); // Magic word it is a wii disc + Memory::Write_U32(0x0D15EA5E, 0x00000020); // Another magic word + Memory::Write_U32(0x00000001, 0x00000024); // Unknown + Memory::Write_U32(0x01800000, 0x00000028); // MEM1 size 24MB + Memory::Write_U32(0x00000023, 0x0000002c); // Production Board Model 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(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 @@ -254,12 +278,12 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug) 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(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, 0x00003118); // Unknown Memory::Write_U32(0x04000000, 0x0000311c); // BAT Memory::Write_U32(0x93400000, 0x00003120); // BAT Memory::Write_U32(0x90000800, 0x00003124); // Init - MEM2 low @@ -267,23 +291,28 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug) 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_U64(0x0009020400062507, 0x00003140); // IOS Version + 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 + // Fake the VI Init of the BIOS Memory::Write_U32(Core::g_CoreStartupParameter.bNTSC ? 0 : 1, 0x000000CC); - // clear exception handler + // Clear exception handler. Why? Don't we begin with only zeroes? for (int i = 0x3000; i <= 0x3038; i += 4) { Memory::Write_U32(0x00000000, 0x80000000 + i); } - // app + /* 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. */ VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4); Memory::Write_U8(0x80, 0x00003184); } diff --git a/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp b/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp index f03256d4bc..abfc9aa427 100644 --- a/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp +++ b/Source/Core/Core/Src/Debugger/Debugger_SymbolMap.cpp @@ -110,10 +110,10 @@ void PrintCallstack(LogTypes::LOG_TYPE _Log) { u32 addr = Memory::ReadUnchecked_U32(PowerPC::ppcState.gpr[1]); // SP - __Log(_Log, "\n == STACK TRACE - SP = %08x ==\n", PowerPC::ppcState.gpr[1]); + __Logv(_Log, 1, "\n == STACK TRACE - SP = %08x ==\n", PowerPC::ppcState.gpr[1]); if (LR == 0) { - __Log(_Log, " LR = 0 - this is bad\n"); + __Logv(_Log, 1, " LR = 0 - this is bad\n"); } int count = 1; if (g_symbolDB.GetDescription(PowerPC::ppcState.pc) != g_symbolDB.GetDescription(LR)) 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 7ea89e3633..537367bd57 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp @@ -62,7 +62,6 @@ #include "../HW/CPU.h" #include "../HW/Memmap.h" #include "../HW/WII_IPC.h" - #include "../Debugger/Debugger_SymbolMap.h" namespace WII_IPC_HLE_Interface @@ -202,7 +201,7 @@ IWII_IPC_HLE_Device* CreateDevice(u32 _DeviceID, const std::string& _rDeviceName bool AckCommand(u32 _Address) { Debugger::PrintCallstack(LogTypes::WII_IPC_HLE); - LOG(WII_IPC_HLE, "AckCommand: 0%08x", _Address); + LOGV(WII_IPC_HLE, 1, "AckCommand: 0%08x", _Address); std::list::iterator itr = g_Ack.begin(); while (itr != g_Ack.end()) @@ -437,7 +436,7 @@ void ExecuteCommand(u32 _Address) // This is called continuously and WII_IPCInterface::IsReady() is controlled from WII_IPC.cpp. void Update() -{ +{ if (WII_IPCInterface::IsReady()) { // check if an executed must be updated diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h index 80222d859a..3110636ea8 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device.h @@ -38,7 +38,7 @@ public: u32 GetDeviceID() const { return m_DeviceID; } virtual bool Open(u32 _CommandAddress, u32 _Mode) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Open()", m_Name.c_str()); return true; } - virtual bool Close(u32 _CommandAddress) { /*_dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Close()", m_Name.c_str()); */ return true; } + virtual bool Close(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Close()", m_Name.c_str()); return true; } virtual bool Seek(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Seek()", m_Name.c_str()); return true; } virtual bool Read(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Read()", m_Name.c_str()); return true; } virtual bool Write(u32 _CommandAddress) { _dbg_assert_msg_(WII_IPC_HLE, 0, "%s is not able to run Write()", m_Name.c_str()); return true; } @@ -48,7 +48,6 @@ public: virtual u32 Update() { return 0; } virtual bool ReturnFileHandle() { return false; } - //FILE* ReturnFileHandle() const { return m_pFileHandle; } private: @@ -71,11 +70,10 @@ protected: /* These are the Ioctlv parameters in the IOS communication. The BufferVector is a memory address offset at where the in and out buffer addresses are stored. */ - Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3 - NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4 - NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5 - BufferVector = Memory::Read_U32(m_Address + 0x18); // 6 - BufferSize = Memory::Read_U32(m_Address + 0x1C); // 7 + Parameter = Memory::Read_U32(m_Address + 0x0C); // command 3, arg0 + NumberInBuffer = Memory::Read_U32(m_Address + 0x10); // 4, arg1 + NumberPayloadBuffer = Memory::Read_U32(m_Address + 0x14); // 5, arg2 + BufferVector = Memory::Read_U32(m_Address + 0x18); // 6, arg3 // The start of the out buffer u32 BufferVectorOffset = BufferVector; @@ -87,9 +85,12 @@ protected: { SBuffer Buffer; Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); - // Restore cached address, mauled by emulatee's ioctl functions. - Memory::Write_U32(Buffer.m_Address | 0x80000000, BufferVectorOffset); - BufferVectorOffset += 4; + + /* Restore cached address, mauled by emulatee's ioctl functions. Why? + What is the purpose of this? After we have read the values, why would + anyone ned it */ + //Memory::Write_U32(Buffer.m_Address | 0x80000000, BufferVectorOffset); + BufferVectorOffset += 4; Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); BufferVectorOffset += 4; @@ -103,8 +104,9 @@ protected: { SBuffer Buffer; Buffer.m_Address = Memory::Read_U32(BufferVectorOffset); - Memory::Write_U32(Buffer.m_Address | 0x80000000, BufferVectorOffset); - BufferVectorOffset += 4; + + //Memory::Write_U32(Buffer.m_Address | 0x80000000, BufferVectorOffset); + BufferVectorOffset += 4; Buffer.m_Size = Memory::Read_U32(BufferVectorOffset); BufferVectorOffset += 4; @@ -128,28 +130,24 @@ protected: std::vector PayloadBuffer; }; + // =================================================== /* Write out the IPC struct from _CommandAddress to _NumberOfCommands numbers of 4 byte commands. */ // ---------------- - void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8) + void DumpCommands(u32 _CommandAddress, size_t _NumberOfCommands = 8, + int LogType = LogTypes::WII_IPC_HLE) { // Because I have to use __Logv here I add this #if #if defined(_DEBUG) || defined(DEBUGFAST) - // Select log type - int log; - if(GetDeviceName().find("dev/es") != std::string::npos) - log = LogTypes::WII_IPC_ES; - else - log = LogTypes::WII_IPC_HLE; - - __Logv(log, 0, "CommandDump of %s", GetDeviceName().c_str()); - for (u32 i=0; i<_NumberOfCommands; i++) + __Logv(LogType, 0, "CommandDump of %s", GetDeviceName().c_str()); + for (u32 i = 0; i < _NumberOfCommands; i++) { - __Logv(log, 0, " Command%02i: 0x%08x", i, Memory::Read_U32(_CommandAddress + i*4)); + __Logv(LogType, 0, " Command%02i: 0x%08x", i, Memory::Read_U32(_CommandAddress + i*4)); } #endif } + void DumpAsync( u32 BufferVector, u32 _CommandAddress, u32 NumberInBuffer, u32 NumberOutBuffer ) { diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index aacdb7ba1e..c2b6d14b11 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -83,6 +83,11 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress) u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) { u32 Command = Memory::Read_U32(_BufferIn) >> 24; + + /* Set out buffer to zeroes as a safety precaution to avoid answering + nonsense values */ + Memory::Memset(_BufferOut, 0, _BufferOutSize); + switch (Command) { // DVDLowInquiry diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h index 54793ca81c..1437289f9d 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_Error.h @@ -32,6 +32,7 @@ public: virtual bool Open(u32 _CommandAddress, u32 _Mode) { + PanicAlert("CWII_IPC_HLE_Device_Error"); Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; } 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 5e886136cb..47c62e75d3 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 @@ -14,6 +14,40 @@ // Official SVN repository and contact information can be found at // http://code.google.com/p/dolphin-emu/ + + + +// ======================================================= +// File description +// ------------- +/* Here we handle /dev/es requests. We have cases for these functions, the exact + DevKitPro name is en parenthesis: + + 0x20 GetTitleID (ES_GetTitleID) (Input: none, Output: 8 bytes) + 0x1d GetDataDir (ES_GetDataDir) (Input: 8 bytes, Output: 30 bytes) + + 0x1b DiGetTicketView (Input: none, Output: 216 bytes) + 0x16 GetConsumption (Input: 8 bytes, Output: 0 bytes, 4 bytes) // there are two output buffers + + 0x12 GetNumTicketViews (ES_GetNumTicketViews) (Input: 8 bytes, Output: 4 bytes) + 0x14 GetTMDViewSize (ES_GetTMDViewSize) (Input: ?, Output: ?) // I don't get this anymore, + it used to come after 0x12 + + but only the first two are correctly supported. For the other four we ignore any potential + input and only write zero to the out buffer. However, most games only use first two, + but some Nintendo developed games use the other ones to: + + 0x1b: Mario Galaxy, Mario Kart, SSBB + 0x16: Mario Galaxy, Mario Kart, SSBB + 0x12: Mario Kart + 0x14: Mario Kart: But only if we don't return a zeroed out buffer for the 0x12 question, + and instead answer for example 1 will this question appear. + +*/ +// ============= + + + #ifndef _WII_IPC_HLE_DEVICE_ES_H_ #define _WII_IPC_HLE_DEVICE_ES_H_ @@ -26,51 +60,59 @@ class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device { public: - enum - { - IOCTL_ES_ADDTICKET = 0x01, - IOCTL_ES_ADDTITLESTART = 0x02, - IOCTL_ES_ADDCONTENTSTART = 0x03, - IOCTL_ES_ADDCONTENTDATA = 0x04, - IOCTL_ES_ADDCONTENTFINISH = 0x05, - IOCTL_ES_ADDTITLEFINISH = 0x06, - IOCTL_ES_LAUNCH = 0x08, - IOCTL_ES_OPENCONTENT = 0x09, - IOCTL_ES_READCONTENT = 0x0A, - IOCTL_ES_CLOSECONTENT = 0x0B, - IOCTL_ES_GETTITLECOUNT = 0x0E, - IOCTL_ES_GETTITLES = 0x0F, - IOCTL_ES_GETVIEWCNT = 0x12, - IOCTL_ES_GETVIEWS = 0x13, + enum + { + IOCTL_ES_ADDTICKET = 0x01, + IOCTL_ES_ADDTITLESTART = 0x02, + IOCTL_ES_ADDCONTENTSTART = 0x03, + IOCTL_ES_ADDCONTENTDATA = 0x04, + IOCTL_ES_ADDCONTENTFINISH = 0x05, + IOCTL_ES_ADDTITLEFINISH = 0x06, + IOCTL_ES_LAUNCH = 0x08, + IOCTL_ES_OPENCONTENT = 0x09, + IOCTL_ES_READCONTENT = 0x0A, + IOCTL_ES_CLOSECONTENT = 0x0B, + IOCTL_ES_GETTITLECOUNT = 0x0E, + IOCTL_ES_GETTITLES = 0x0F, + IOCTL_ES_GETVIEWCNT = 0x12, + IOCTL_ES_GETVIEWS = 0x13, IOCTL_ES_GETTMDVIEWCNT = 0x14, - IOCTL_ES_DIVERIFY = 0x1C, - IOCTL_ES_GETTITLEDIR = 0x1D, - IOCTL_ES_GETTITLEID = 0x20, - IOCTL_ES_SEEKCONTENT = 0x23, - IOCTL_ES_ADDTMD = 0x2B, - IOCTL_ES_ADDTITLECANCEL = 0x2F, - IOCTL_ES_GETSTOREDCONTENTCNT = 0x32, - IOCTL_ES_GETSTOREDCONTENTS = 0x33, - IOCTL_ES_GETSTOREDTMDSIZE = 0x34, - IOCTL_ES_GETSTOREDTMD = 0x35, - IOCTL_ES_GETSHAREDCONTENTCNT = 0x36, - IOCTL_ES_GETSHAREDCONTENTS = 0x37, - }; + IOCTL_ES_GETCONSUMPTION = 0x16, + IOCTL_ES_DIGETTICKETVIEW = 0x1b, + IOCTL_ES_DIVERIFY = 0x1C, + IOCTL_ES_GETTITLEDIR = 0x1D, + IOCTL_ES_GETTITLEID = 0x20, + IOCTL_ES_SEEKCONTENT = 0x23, + IOCTL_ES_ADDTMD = 0x2B, + IOCTL_ES_ADDTITLECANCEL = 0x2F, + IOCTL_ES_GETSTOREDCONTENTCNT = 0x32, + IOCTL_ES_GETSTOREDCONTENTS = 0x33, + IOCTL_ES_GETSTOREDTMDSIZE = 0x34, + IOCTL_ES_GETSTOREDTMD = 0x35, + IOCTL_ES_GETSHAREDCONTENTCNT = 0x36, + IOCTL_ES_GETSHAREDCONTENTS = 0x37, + }; - CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName) : - IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) - {} + CWII_IPC_HLE_Device_es(u32 _DeviceID, const std::string& _rDeviceName) : + IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) + {} - virtual ~CWII_IPC_HLE_Device_es() - {} + virtual ~CWII_IPC_HLE_Device_es() + {} - virtual bool Open(u32 _CommandAddress, u32 _Mode) - { - Memory::Write_U32(GetDeviceID(), _CommandAddress+4); + virtual bool Open(u32 _CommandAddress, u32 _Mode) + { + Memory::Write_U32(GetDeviceID(), _CommandAddress+4); + return true; + } - return true; - } + virtual bool Close(u32 _CommandAddress) + { + LOG(WII_IPC_ES, "ES: Close"); + Memory::Write_U32(0, _CommandAddress + 4); + return true; + } virtual bool IOCtlV(u32 _CommandAddress) { @@ -78,69 +120,50 @@ public: LOG(WII_IPC_ES, "%s (0x%x)", GetDeviceName().c_str(), Buffer.Parameter); - /* Extended logs - //if(Buffer.Parameter == IOCTL_ES_GETTITLEDIR || Buffer.Parameter == IOCTL_ES_GETTITLEID || - // Buffer.Parameter == IOCTL_ES_GETVIEWCNT || Buffer.Parameter == IOCTL_ES_GETTMDVIEWCNT) - { - u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address | 0x80000000); - if(Buffer.NumberInBuffer > 0) - { - u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address | 0x80000000); - LOG(WII_IPC_ES, "ES Parameter: 0x%x (In: %i, Out:%i) (In 0x%08x = 0x%08x %i) (Out 0x%08x = 0x%08x %i)", - Buffer.Parameter, - Buffer.NumberInBuffer, Buffer.NumberPayloadBuffer, - Buffer.InBuffer[0].m_Address, InBuffer, Buffer.InBuffer[0].m_Size, - Buffer.PayloadBuffer[0].m_Address, OutBuffer, Buffer.PayloadBuffer[0].m_Size); - } - else - { - LOG(WII_IPC_ES, "ES Parameter: 0x%x (In: %i, Out:%i) (Out 0x%08x = 0x%08x %i)", - Buffer.Parameter, - Buffer.NumberInBuffer, Buffer.NumberPayloadBuffer, - Buffer.PayloadBuffer[0].m_Address, OutBuffer, Buffer.PayloadBuffer[0].m_Size); - } - //DumpCommands(_CommandAddress, 8); - }*/ + // Prepare the out buffer(s) with zeroes as a safety precaution + // to avoid returning bad values + for(int i = 0; i < Buffer.NumberPayloadBuffer; i++) + { + Memory::Memset(Buffer.PayloadBuffer[i].m_Address, 0, + Buffer.PayloadBuffer[i].m_Size); + } switch(Buffer.Parameter) { - case IOCTL_ES_GETTITLEDIR: // (0x1d) ES_GetDataDir in DevKitPro + case IOCTL_ES_GETTITLEDIR: // 0x1d { - u32 TitleID_ = Memory::Read_U32(Buffer.InBuffer[0].m_Address);; - u32 TitleID = VolumeHandler::Read32(0); - if (TitleID == 0) - TitleID = 0xF00DBEEF; + /* 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; char* pTitleID = (char*)&TitleID; - char* Path = (char*)Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); - sprintf(Path, "/00010000/%02x%02x%02x%02x/data", - (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]); + sprintf(Path, "/00010000/%08x/data", TitleID); - LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEDIR: %s (TitleID: %08x)", Path, TitleID_); + LOG(WII_IPC_ES, "ES: IOCTL_ES_GETTITLEDIR: %s)", Path); } break; - case IOCTL_ES_GETTITLEID: // (0x20) ES_GetTitleID in DevKitPro + case IOCTL_ES_GETTITLEID: // 0x20 { u32 TitleID = VolumeHandler::Read32(0); - if (TitleID == 0) - TitleID = 0xF00DBEEF; + if (TitleID == 0) TitleID = 0xF00DBEEF; /* 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 - that is called right after this. However, I have not seen that this - have any effect by itself, perhaps because it's really only - IOCTL_ES_GETTITLEDIR that matters, and since we ignore the InBuffer in - IOCTL_ES_GETTITLEDIR and read the title from the disc instead - this has no effect. */ + that is called right after this. I have not seen that this + have any effect by itself, it probably only matters as an input to + 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); } break; - // This and 0x14 are called by Mario Kart - case IOCTL_ES_GETVIEWCNT: // (0x12) ES_GetNumTicketViews in DevKitPro + case IOCTL_ES_GETVIEWCNT: // 0x12 (Input: 8 bytes, Output: 4 bytes) { if(Buffer.NumberPayloadBuffer) u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address); @@ -152,7 +175,7 @@ public: } break; - case IOCTL_ES_GETTMDVIEWCNT: // (0x14) ES_GetTMDViewSize in DevKitPro + case IOCTL_ES_GETTMDVIEWCNT: // 0x14 { if(Buffer.NumberPayloadBuffer) u32 OutBuffer = Memory::Read_U32(Buffer.PayloadBuffer[0].m_Address); @@ -164,10 +187,8 @@ public: } break; - case 0x16: // Consumption - case 0x1B: // ES_DiGetTicketView - - // Mario Galaxy + case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes) + case IOCTL_ES_DIGETTICKETVIEW: // (Input: none, Output: 216 bytes) break; case IOCTL_ES_GETTITLECOUNT: diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp index bb63fe6b4b..befd5f3b46 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_fs.cpp @@ -56,13 +56,13 @@ bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) // create home directory { u32 TitleID = VolumeHandler::Read32(0); - if (TitleID == 0) - TitleID = 0xF00DBEEF; + if (TitleID == 0) TitleID = 0xF00DBEEF; char* pTitleID = (char*)&TitleID; char Path[260+1]; - sprintf(Path, FULL_WII_USER_DIR "title/00010000/%02x%02x%02x%02x/data/nocopy/", (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]); + sprintf(Path, FULL_WII_USER_DIR "title/00010000/%02x%02x%02x%02x/data/nocopy/", + (u8)pTitleID[3], (u8)pTitleID[2], (u8)pTitleID[1], (u8)pTitleID[0]); File::CreateDirectoryStructure(Path); } @@ -71,35 +71,30 @@ bool CWII_IPC_HLE_Device_fs::Open(u32 _CommandAddress, u32 _Mode) return true; } -bool CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress) -{ - //u32 DeviceID = Memory::Read_U32(_CommandAddress + 8); - //LOG(WII_IPC_FILEIO, "FS: IOCtl (Device=%s, DeviceID=%08x)", GetDeviceName().c_str(), DeviceID); - - u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); - u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); - u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); - u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); - u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - - u32 ReturnValue = ExecuteCommand(Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); - Memory::Write_U32(ReturnValue, _CommandAddress+4); - - return true; -} +// ======================================================= +// IOCtlV calls begin here +// ------------- bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) { u32 ReturnValue = FS_RESULT_OK; - SIOCtlVBuffer CommandBuffer(_CommandAddress); + // Prepare the out buffer(s) with zeroes as a safety precaution + // to avoid returning bad values + for(int i = 0; i < CommandBuffer.NumberPayloadBuffer; i++) + { + Memory::Memset(CommandBuffer.PayloadBuffer[i].m_Address, 0, + CommandBuffer.PayloadBuffer[i].m_Size); + } + switch(CommandBuffer.Parameter) { case IOCTL_READ_DIR: { // the wii uses this function to define the type (dir or file) - std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer(CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size)); + std::string Filename(HLE_IPC_BuildFilename((const char*)Memory::GetPointer( + CommandBuffer.InBuffer[0].m_Address), CommandBuffer.InBuffer[0].m_Size)); LOG(WII_IPC_FILEIO, "FS: IOCTL_READ_DIR %s", Filename.c_str()); @@ -247,6 +242,36 @@ bool CWII_IPC_HLE_Device_fs::IOCtlV(u32 _CommandAddress) return true; } + +// ======================================================= +// IOCtl calls begin here +// ------------- +bool CWII_IPC_HLE_Device_fs::IOCtl(u32 _CommandAddress) +{ + //u32 DeviceID = Memory::Read_U32(_CommandAddress + 8); + //LOG(WII_IPC_FILEIO, "FS: IOCtl (Device=%s, DeviceID=%08x)", GetDeviceName().c_str(), DeviceID); + + u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); + u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); + u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); + u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); + u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); + + /* Prepare the out buffer(s) with zeroes as a safety precaution + to avoid returning bad values. */ + //LOG(WII_IPC_FILEIO, "Cleared %u bytes of the out buffer", _BufferOutSize); + Memory::Memset(BufferOut, 0, BufferOutSize); + + u32 ReturnValue = ExecuteCommand(Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize); + Memory::Write_U32(ReturnValue, _CommandAddress + 4); + + return true; +} + + +// ======================================================= +// Execute IOCtl commands +// ------------- s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) { switch(_Parameter) @@ -257,7 +282,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B LOG(WII_IPC_FILEIO, "FS: GET STATS - no idea what we have to return here, prolly the free memory etc:)"); LOG(WII_IPC_FILEIO, " InBufferSize: %i OutBufferSize: %i", _BufferInSize, _BufferOutSize); - + PanicAlert("GET_STATS"); /* Memory::Write_U32(Addr, a); Addr += 4; Memory::Write_U32(Addr, b); Addr += 4; @@ -266,8 +291,7 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B Memory::Write_U32(Addr, e); Addr += 4; Memory::Write_U32(Addr, f); Addr += 4; Memory::Write_U32(Addr, g); Addr += 4; -*/ - PanicAlert("GET_STATS"); +*/ return FS_RESULT_OK; } break; @@ -319,10 +343,9 @@ s32 CWII_IPC_HLE_Device_fs::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _B case GET_ATTR: { - _dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", _BufferOutSize); - - // first clear the whole output buffer - memset(Memory::GetPointer(_BufferOut), 0, _BufferOutSize); + _dbg_assert_msg_(WII_IPC_FILEIO, _BufferOutSize == 76, + " GET_ATTR needs an 76 bytes large output buffer but it is %i bytes large", + _BufferOutSize); u32 OwnerID = 0; u16 GroupID = 0; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp index 972921c40e..df5fe47452 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.cpp @@ -16,6 +16,42 @@ // http://code.google.com/p/dolphin-emu/ + +// ======================================================= +// File description +// ------------- +/* Here we handle /dev/net and /dev/net/ncd/manage requests. + + + // ----------------------- + The /dev/net/kd/request requests are part of what is called WiiConnect24, + it's used by for example SSBB, Mario Kart, Metroid Prime 3 + + 0x01 SuspendScheduler (Input: none, Output: 32 bytes) + 0x02 ExecTrySuspendScheduler (Input: 32 bytes, Output: 32 bytes) // Sounds like it will + check if it should suspend the updates scheduler or not. If I returned + (OutBuffer: 0, Ret: -1) to Metroid Prime 3 it got stuck in an endless loops of + requests, probably harmless but I changed it to (OutBuffer: 1, Ret: 0) to stop + the calls. However then it also calls 0x3 and then changes its error message + to a Wii Memory error message from just a general Error message. + + 0x03 ? (Input: none, Output: 32 bytes) // This is only called if 0x02 + does not return -1 + 0x0f NWC24iRequestGenerateUserId (Input: none, Output: 32 bytes) + + Requests are made in this order by these games + Mario Kart: 2, 1, f, 3 + SSBB: 2, 3 + + For Mario Kart I had to return -1 from at least 2, f and 3 to convince it that the network + was unavaliable and prevent if from looking for shared2/wc24 files (and do a PPCHalt when + it failed) + // ------- + +*/ +// ============= + + #include "WII_IPC_HLE_Device_net.h" @@ -34,11 +70,18 @@ CWII_IPC_HLE_Device_net_kd_request::~CWII_IPC_HLE_Device_net_kd_request() bool CWII_IPC_HLE_Device_net_kd_request::Open(u32 _CommandAddress, u32 _Mode) { - //LOG(WII_IPC_NET, "NET_KD_REQ: Open (Command: 0x%02x)", Memory::Read_U32(_CommandAddress)); + LOG(WII_IPC_NET, "NET_KD_REQ: Open"); Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); return true; } +bool CWII_IPC_HLE_Device_net_kd_request::Close(u32 _CommandAddress) +{ + LOG(WII_IPC_NET, "NET_KD_REQ: Close"); + Memory::Write_U32(0, _CommandAddress + 4); + return true; +} + bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC); @@ -58,35 +101,8 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress) s32 CWII_IPC_HLE_Device_net_kd_request::ExecuteCommand(u32 _Parameter, u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) { - // ----------------------- - /* Requests are made in this order by these games - Mario Kart: 2, 1, f, 3 - SSBB: 2, 3 - - For Mario Kart I had to return -1 from at least 2, f and 3 to convince it that the network - was unavaliable and prevent if from looking for shared2/wc24 files (and do a PPCHalt when - it failed) */ - // ------- - - /* Extended logs - //if(_Parameter == 2 || _Parameter == 3) - { - u32 OutBuffer = Memory::Read_U32(_BufferOut); - if(_BufferInSize > 0) - { - u32 InBuffer = Memory::Read_U32(_BufferIn); - LOG(WII_IPC_NET, "NET_KD_REQ: IOCtl Parameter: 0x%x (In 0x%08x = 0x%08x %i) (Out 0x%08x = 0x%08x %i)", - _Parameter, - _BufferIn, InBuffer, _BufferInSize, - _BufferOut, OutBuffer, _BufferOutSize); - } - else - { - LOG(WII_IPC_NET, "NET_KD_REQ: IOCtl Parameter: 0x%x (Out 0x%08x = 0x%08x %i)", - _Parameter, - _BufferOut, OutBuffer, _BufferOutSize); - } - }*/ + // Clean the location of the output buffer to zeroes as a safety precaution */ + Memory::Memset(_BufferOut, 0, _BufferOutSize); switch(_Parameter) { @@ -94,12 +110,12 @@ s32 CWII_IPC_HLE_Device_net_kd_request::ExecuteCommand(u32 _Parameter, u32 _Buff //Memory::Write_U32(0, _BufferOut); return -1; break; - case 2: /* ExecTrySuspendScheduler (Input: 32 bytes, Output: 32 bytes). Sounds like it will check - if it should suspend the updates scheduler or not. */ - //Memory::Write_U32(0, _BufferOut); - return -1; + case 2: // ExecTrySuspendScheduler (Input: 32 bytes, Output: 32 bytes). + DumpCommands(_BufferIn, _BufferInSize / 4, LogTypes::WII_IPC_NET); + Memory::Write_U32(1, _BufferOut); + return 0; break; - case 3: // ? + case 3: // ? (Input: none, Output: 32 bytes) //Memory::Write_U32(0, _BufferOut); return -1; break; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h index 756497c95a..c9f1ea5cc6 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_net.h @@ -29,7 +29,7 @@ public: virtual ~CWII_IPC_HLE_Device_net_kd_request(); virtual bool Open(u32 _CommandAddress, u32 _Mode); - + virtual bool Close(u32 _CommandAddress); virtual bool IOCtl(u32 _CommandAddress); private: @@ -43,42 +43,50 @@ class CWII_IPC_HLE_Device_net_kd_time : public IWII_IPC_HLE_Device { public: - CWII_IPC_HLE_Device_net_kd_time(u32 _DeviceID, const std::string& _rDeviceName) : - IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) - {} + CWII_IPC_HLE_Device_net_kd_time(u32 _DeviceID, const std::string& _rDeviceName) : + IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) + {} - virtual ~CWII_IPC_HLE_Device_net_kd_time() - {} + virtual ~CWII_IPC_HLE_Device_net_kd_time() + {} - virtual bool Open(u32 _CommandAddress, u32 _Mode) - { - Memory::Write_U32(GetDeviceID(), _CommandAddress+4); - return true; - } + virtual bool Open(u32 _CommandAddress, u32 _Mode) + { + LOG(WII_IPC_NET, "%s - IOCtl: Open", GetDeviceName().c_str()); + Memory::Write_U32(GetDeviceID(), _CommandAddress+4); + return true; + } - virtual bool IOCtl(u32 _CommandAddress) - { -#ifdef LOGGING - u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); - u32 Buffer1 = Memory::Read_U32(_CommandAddress +0x10); - u32 BufferSize1 = Memory::Read_U32(_CommandAddress +0x14); - u32 Buffer2 = Memory::Read_U32(_CommandAddress +0x18); - u32 BufferSize2 = Memory::Read_U32(_CommandAddress +0x1C); -#endif + virtual bool Close(u32 _CommandAddress, u32 _Mode) + { + LOG(WII_IPC_NET, "%s - IOCtl: Close", GetDeviceName().c_str()); + Memory::Write_U32(0, _CommandAddress + 4); + return true; + } - // write return value - Memory::Write_U32(0, _CommandAddress + 0x4); + virtual bool IOCtl(u32 _CommandAddress) + { + #ifdef LOGGING + u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); + u32 Buffer1 = Memory::Read_U32(_CommandAddress +0x10); + u32 BufferSize1 = Memory::Read_U32(_CommandAddress +0x14); + u32 Buffer2 = Memory::Read_U32(_CommandAddress +0x18); + u32 BufferSize2 = Memory::Read_U32(_CommandAddress +0x1C); + #endif - LOG(WII_IPC_HLE, "%s - IOCtl:\n" - " Parameter: 0x%x (0x17 could be some kind of Sync RTC) \n" - " Buffer1: 0x%08x\n" - " BufferSize1: 0x%08x\n" - " Buffer2: 0x%08x\n" - " BufferSize2: 0x%08x\n", - GetDeviceName().c_str(), Parameter, Buffer1, BufferSize1, Buffer2, BufferSize2); + // write return value + Memory::Write_U32(0, _CommandAddress + 0x4); - return true; - } + LOG(WII_IPC_NET, "%s - IOCtl:\n" + " Parameter: 0x%x (0x17 could be some kind of Sync RTC) \n" + " Buffer1: 0x%08x\n" + " BufferSize1: 0x%08x\n" + " Buffer2: 0x%08x\n" + " BufferSize2: 0x%08x\n", + GetDeviceName().c_str(), Parameter, Buffer1, BufferSize1, Buffer2, BufferSize2); + + return true; + } }; // ************************************************************************************** @@ -87,14 +95,14 @@ class CWII_IPC_HLE_Device_net_ip_top : public IWII_IPC_HLE_Device { public: CWII_IPC_HLE_Device_net_ip_top(u32 _DeviceID, const std::string& _rDeviceName) : - IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) - {} + IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) + {} - virtual ~CWII_IPC_HLE_Device_net_ip_top() { - } + virtual ~CWII_IPC_HLE_Device_net_ip_top() {} virtual bool Open(u32 _CommandAddress, u32 _Mode) { + LOG(WII_IPC_NET, "%s - IOCtl: Open", GetDeviceName().c_str()); Memory::Write_U32(GetDeviceID(), _CommandAddress+4); return true; } @@ -111,7 +119,6 @@ public: virtual ~CWII_IPC_HLE_Device_net_ncd_manage(); virtual bool Open(u32 _CommandAddress, u32 _Mode); - virtual bool IOCtlV(u32 _CommandAddress); }; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp index 28c5025a66..595b14b249 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_sdio_slot0.cpp @@ -43,8 +43,8 @@ CWII_IPC_HLE_Device_sdio_slot0::~CWII_IPC_HLE_Device_sdio_slot0() bool CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode) { + LOG(WII_IPC_SD, "SD: Open"); Memory::Write_U32(GetDeviceID(), _CommandAddress + 0x4); - return true; } @@ -53,9 +53,9 @@ CWII_IPC_HLE_Device_sdio_slot0::Open(u32 _CommandAddress, u32 _Mode) // The front SD slot bool CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) { - LOG(WII_IPC_FILEIO, "*************************************"); - LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_sdio_slot0::IOCtl"); - LOG(WII_IPC_FILEIO, "*************************************"); + //LOG(WII_IPC_FILEIO, "*************************************"); + //LOG(WII_IPC_FILEIO, "CWII_IPC_HLE_Device_sdio_slot0::IOCtl"); + //LOG(WII_IPC_FILEIO, "*************************************"); // DumpCommands(_CommandAddress); @@ -67,52 +67,61 @@ bool CWII_IPC_HLE_Device_sdio_slot0::IOCtl(u32 _CommandAddress) u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); - LOG(WII_IPC_FILEIO, "%s - BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)", GetDeviceName().c_str(), BufferIn, BufferInSize, BufferOut, BufferOutSize); + //LOG(WII_IPC_SD, "%s Cmd 0x%x - BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)", + // GetDeviceName().c_str(), Cmd, BufferIn, BufferInSize, BufferOut, BufferOutSize); + + /* As a safety precaution we fill the out buffer with zeroes to avoid + returning nonsense values */ + Memory::Memset(BufferOut, 0, BufferOutSize); u32 ReturnValue = 0; switch (Cmd) { - case 1: //set_hc_reg + case 1: // set_hc_reg + LOGV(WII_IPC_SD, 0, "SD: set_hc_reg"); break; - case 2: //get_hc_reg + case 2: // get_hc_reg + LOGV(WII_IPC_SD, 0, "SD: get_hc_reg"); break; - case 4: //reset - // do nothing ? + case 4: // reset, do nothing ? + LOGV(WII_IPC_SD, 0, "SD: reset"); break; - case 6: //sd_clock + case 6: // sd_clock + LOGV(WII_IPC_SD, 0, "SD: sd_clock"); break; - case 7: //sendcmd + case 7: // Send cmd (Input: 24 bytes, Output: 10 bytes) + LOGV(WII_IPC_SD, 0, "SD: sendcmd"); ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize); break; case 11: // sd_get_status - LOGV(WII_IPC_FILEIO, 0, "SD command: sd_get_status. Answer: SD card is inserted (write 1 to %08x).", BufferOut); - Memory::Write_U32(1, BufferOut); // SD card is inserted? + LOGV(WII_IPC_SD, 0, "SD: sd_get_status. Answer: SD card is not inserted", BufferOut); + Memory::Write_U32(2, BufferOut); // SD card is not inserted break; default: PanicAlert("Unknown SD command (0x%08x)", Cmd); break; } -/* DumpCommands(_CommandAddress); + //DumpCommands(_CommandAddress); - LOG(WII_IPC_HLE, "InBuffer"); - DumpCommands(BufferIn, BufferInSize); + //LOG(WII_IPC_SD, "InBuffer"); + //DumpCommands(BufferIn, BufferInSize / 4, LogTypes::WII_IPC_SD); -// LOG(WII_IPC_HLE, "OutBuffer"); - // DumpCommands(BufferOut, BufferOutSize); */ + //LOG(WII_IPC_SD, "OutBuffer"); + //DumpCommands(BufferOut, BufferOutSize); Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); - return true; + return true; } // __________________________________________________________________________________________________ // bool CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress) { - // PanicAlert("CWII_IPC_HLE_Device_sdio_slot0::IOCtlV() unknown"); + PanicAlert("CWII_IPC_HLE_Device_sdio_slot0::IOCtlV() unknown"); // SD_Read uses this DumpCommands(_CommandAddress); @@ -124,6 +133,8 @@ bool CWII_IPC_HLE_Device_sdio_slot0::IOCtlV(u32 _CommandAddress) // u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) { + /* The game will send us a SendCMD with this information. To be able to read and write + to a file we need to prepare a 10 byte output buffer as response. */ struct Request { u32 command; u32 type; @@ -143,5 +154,5 @@ u32 CWII_IPC_HLE_Device_sdio_slot0::ExecuteCommand(u32 _BufferIn, u32 _BufferInS //switch (req.command) { } - return 1; + return 0; } diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h index 8723fe9832..a80d62af67 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_stm.h @@ -37,68 +37,81 @@ enum IOCTL_STM_READDDRREG2 = 0x4002, }; + +// ======================================================= +// The /device/stm/immediate class +// ------------- class CWII_IPC_HLE_Device_stm_immediate : public IWII_IPC_HLE_Device { public: - CWII_IPC_HLE_Device_stm_immediate(u32 _DeviceID, const std::string& _rDeviceName) : - IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) - {} + CWII_IPC_HLE_Device_stm_immediate(u32 _DeviceID, const std::string& _rDeviceName) : + IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) + {} virtual ~CWII_IPC_HLE_Device_stm_immediate() - {} + {} - virtual bool Open(u32 _CommandAddress, u32 _Mode) - { - Memory::Write_U32(GetDeviceID(), _CommandAddress+4); - return true; - } + virtual bool Open(u32 _CommandAddress, u32 _Mode) + { + LOGV(WII_IPC_SD, 0, "STM: Open"); + Memory::Write_U32(GetDeviceID(), _CommandAddress+4); + return true; + } virtual bool IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); -#ifdef LOGGING - u32 Buffer1 = Memory::Read_U32(_CommandAddress +0x10); - u32 BufferSize1 = Memory::Read_U32(_CommandAddress +0x14); - u32 Buffer2 = Memory::Read_U32(_CommandAddress +0x18); - u32 BufferSize2 = Memory::Read_U32(_CommandAddress +0x1C); -#endif + u32 BufferIn = Memory::Read_U32(_CommandAddress +0x10); + u32 BufferInSize = Memory::Read_U32(_CommandAddress +0x14); + u32 BufferOut = Memory::Read_U32(_CommandAddress +0x18); + u32 BufferOutSize = Memory::Read_U32(_CommandAddress +0x1C); - // write return value - Memory::Write_U32(1, _CommandAddress + 0x4); + // Prepare the out buffer(s) with zeroes as a safety precaution + // to avoid returning bad values + Memory::Memset(BufferOut, 0, BufferOutSize); + u32 ReturnValue = 0; switch(Parameter) { - case IOCTL_STM_VIDIMMING: - LOG(WII_IPC_HLE, "%s - IOCtl: \n", GetDeviceName().c_str()); - LOG(WII_IPC_HLE, " IOCTL_STM_VIDIMMING"); + case IOCTL_STM_VIDIMMING: // (Input: 20 bytes, Output: 20 bytes) + LOG(WII_IPC_SD, "%s - IOCtl: \n", GetDeviceName().c_str()); + LOG(WII_IPC_SD, " IOCTL_STM_VIDIMMING"); + //Memory::Write_U32(1, BufferOut); + //ReturnValue = 1; break; - case IOCTL_STM_LEDMODE: - LOG(WII_IPC_HLE, "%s - IOCtl: \n", GetDeviceName().c_str()); - LOG(WII_IPC_HLE, " IOCTL_STM_LEDMODE"); + case IOCTL_STM_LEDMODE: // (Input: 20 bytes, Output: 20 bytes) + LOG(WII_IPC_SD, "%s - IOCtl: \n", GetDeviceName().c_str()); + LOG(WII_IPC_SD, " IOCTL_STM_LEDMODE"); break; default: { - _dbg_assert_msg_(WII_IPC_HLE, 0, "CWII_IPC_HLE_Device_stm_immediate: 0x%x", Parameter); + _dbg_assert_msg_(WII_IPC_SD, 0, "CWII_IPC_HLE_Device_stm_immediate: 0x%x", Parameter); - LOG(WII_IPC_HLE, "%s - IOCtl: \n", GetDeviceName().c_str()); - LOG(WII_IPC_HLE, " Parameter: 0x%x\n", Parameter); - LOG(WII_IPC_HLE, " Buffer1: 0x%08x\n", Buffer1); - LOG(WII_IPC_HLE, " BufferSize1: 0x%08x\n", BufferSize1); - LOG(WII_IPC_HLE, " Buffer2: 0x%08x\n", Buffer2); - LOG(WII_IPC_HLE, " BufferSize2: 0x%08x\n", BufferSize2); + LOG(WII_IPC_SD, "%s - IOCtl: \n", GetDeviceName().c_str()); + LOG(WII_IPC_SD, " Parameter: 0x%x\n", Parameter); + LOG(WII_IPC_SD, " InBuffer: 0x%08x\n", BufferIn); + LOG(WII_IPC_SD, " InBufferSize: 0x%08x\n", BufferInSize); + LOG(WII_IPC_SD, " OutBuffer: 0x%08x\n", BufferOut); + LOG(WII_IPC_SD, " OutBufferSize: 0x%08x\n", BufferOutSize); } break; } + // Write return value to the IPC call + Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); + // Generate true or false reply for the main UpdateInterrupts() function return true; } }; +// ======================================================= +// The /device/stm/eventhook class +// ------------- class CWII_IPC_HLE_Device_stm_eventhook : public IWII_IPC_HLE_Device { public: @@ -113,20 +126,22 @@ public: virtual bool Open(u32 _CommandAddress, u32 _Mode) { - Memory::Write_U32(GetDeviceID(), _CommandAddress+4); - + Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); return true; } virtual bool IOCtl(u32 _CommandAddress) { u32 Parameter = Memory::Read_U32(_CommandAddress +0x0C); - u32 Buffer1 = Memory::Read_U32(_CommandAddress +0x10); - u32 BufferSize1 = Memory::Read_U32(_CommandAddress +0x14); -#ifdef LOGGING - u32 Buffer2 = Memory::Read_U32(_CommandAddress +0x18); - u32 BufferSize2 = Memory::Read_U32(_CommandAddress +0x1C); -#endif + u32 BufferIn = Memory::Read_U32(_CommandAddress +0x10); + u32 BufferInSize = Memory::Read_U32(_CommandAddress +0x14); + u32 BufferOut = Memory::Read_U32(_CommandAddress +0x18); + u32 BufferOutSize = Memory::Read_U32(_CommandAddress +0x1C); + + // Prepare the out buffer(s) with zeroes as a safety precaution + // to avoid returning bad values + Memory::Memset(BufferOut, 0, BufferOutSize); + u32 ReturnValue = 0; // write return value switch (Parameter) @@ -135,14 +150,14 @@ public: { m_EventHookAddress = _CommandAddress; - LOG(WII_IPC_HLE, "%s registers event hook:\n", GetDeviceName().c_str()); - LOG(WII_IPC_HLE, " 0x1000 - IOCTL_STM_EVENTHOOK\n", Parameter); - LOG(WII_IPC_HLE, " Buffer1: 0x%08x\n", Buffer1); - LOG(WII_IPC_HLE, " BufferSize1: 0x%08x\n", BufferSize1); - LOG(WII_IPC_HLE, " Buffer2: 0x%08x\n", Buffer2); - LOG(WII_IPC_HLE, " BufferSize2: 0x%08x\n", BufferSize2); + LOG(WII_IPC_SD, "%s registers event hook:\n", GetDeviceName().c_str()); + LOG(WII_IPC_SD, " 0x1000 - IOCTL_STM_EVENTHOOK\n", Parameter); + LOG(WII_IPC_SD, " BufferIn: 0x%08x\n", BufferIn); + LOG(WII_IPC_SD, " BufferInSize: 0x%08x\n", BufferInSize); + LOG(WII_IPC_SD, " BufferOut: 0x%08x\n", BufferOut); + LOG(WII_IPC_SD, " BufferOutSize: 0x%08x\n", BufferOutSize); - DumpCommands(Buffer1, BufferSize1/4); + DumpCommands(BufferIn, BufferInSize/4, LogTypes::WII_IPC_SD); return false; } @@ -150,20 +165,21 @@ public: default: { - _dbg_assert_msg_(WII_IPC_HLE, 0, "CWII_IPC_HLE_Device_stm_eventhook: 0x%x", Parameter); - LOG(WII_IPC_HLE, "%s registers event hook:\n", GetDeviceName().c_str()); - LOG(WII_IPC_HLE, " Parameter: 0x%x\n", Parameter); - LOG(WII_IPC_HLE, " Buffer1: 0x%08x\n", Buffer1); - LOG(WII_IPC_HLE, " BufferSize1: 0x%08x\n", BufferSize1); - LOG(WII_IPC_HLE, " Buffer2: 0x%08x\n", Buffer2); - LOG(WII_IPC_HLE, " BufferSize2: 0x%08x\n", BufferSize2); + _dbg_assert_msg_(WII_IPC_SD, 0, "CWII_IPC_HLE_Device_stm_eventhook: 0x%x", Parameter); + LOG(WII_IPC_SD, "%s registers event hook:\n", GetDeviceName().c_str()); + LOG(WII_IPC_SD, " Parameter: 0x%x\n", Parameter); + LOG(WII_IPC_SD, " BufferIn: 0x%08x\n", BufferIn); + LOG(WII_IPC_SD, " BufferInSize: 0x%08x\n", BufferInSize); + LOG(WII_IPC_SD, " BufferOut: 0x%08x\n", BufferOut); + LOG(WII_IPC_SD, " BufferOutSize: 0x%08x\n", BufferOutSize); } break; } + // Write return value to the IPC call, 0 means success + Memory::Write_U32(0, _CommandAddress + 0x4); - Memory::Write_U32(0, _CommandAddress + 0x4); - + // Generate true or false reply for the main UpdateInterrupts() function return false; } diff --git a/Source/Core/Core/Src/LogManager.cpp b/Source/Core/Core/Src/LogManager.cpp index 7c0c0b7cc2..6b21c2f94b 100644 --- a/Source/Core/Core/Src/LogManager.cpp +++ b/Source/Core/Core/Src/LogManager.cpp @@ -137,6 +137,7 @@ void LogManager::Init() m_Log[LogTypes::WII_IPC_DVD + i*100] = new CDebugger_Log("WII_IPC_DVD", "WII IPC DVD", i); m_Log[LogTypes::WII_IPC_ES + i*100] = new CDebugger_Log("WII_IPC_ES", "WII IPC ES", i); m_Log[LogTypes::WII_IPC_FILEIO + i*100] = new CDebugger_Log("WII_IPC_FILEIO", "WII IPC FILEIO", i); + m_Log[LogTypes::WII_IPC_SD + i*100] = new CDebugger_Log("WII_IPC_SD", "WII IPC SD", i); m_Log[LogTypes::WII_IPC_NET + i*100] = new CDebugger_Log("WII_IPC_NET", "WII IPC NET", i); m_Log[LogTypes::WII_IPC_WIIMOTE + i*100] = new CDebugger_Log("WII_IPC_WIIMOTE", "WII IPC WIIMOTE", i); m_Log[LogTypes::ACTIONREPLAY + i*100] = new CDebugger_Log("ActionReplay", "ActionReplay", i); diff --git a/Source/Core/DebuggerWX/Src/CodeWindow.cpp b/Source/Core/DebuggerWX/Src/CodeWindow.cpp index 6adac00b83..c01b56688b 100644 --- a/Source/Core/DebuggerWX/Src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/Src/CodeWindow.cpp @@ -165,13 +165,13 @@ CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter wxKeyEventHandler(CCodeWindow::OnKeyDown), (wxObject*)0, this); - // load ini... + // Load ini... IniFile file; file.Load(DEBUGGER_CONFIG_FILE); + // Load settings for selectable windowses, but only if they have been created this->Load(file); if (m_BreakpointWindow) m_BreakpointWindow->Load(file); - if (m_LogWindow) m_LogWindow->Load(file); if (m_RegisterWindow) m_RegisterWindow->Load(file); if (m_MemoryWindow) m_MemoryWindow->Load(file); if (m_JitWindow) m_JitWindow->Load(file); @@ -402,6 +402,7 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam pSymbolsMenu->AppendSeparator(); pSymbolsMenu->Append(IDM_LOADMAPFILE, _T("&Load symbol map")); pSymbolsMenu->Append(IDM_SAVEMAPFILE, _T("&Save symbol map")); + pSymbolsMenu->AppendSeparator(); pSymbolsMenu->Append(IDM_SAVEMAPFILEWITHCODES, _T("Save code")); pSymbolsMenu->AppendSeparator(); pSymbolsMenu->Append(IDM_CREATESIGNATUREFILE, _T("&Create signature file...")); diff --git a/Source/Core/DebuggerWX/Src/LogWindow.cpp b/Source/Core/DebuggerWX/Src/LogWindow.cpp index 33c02fb34e..c6f57cf0e2 100644 --- a/Source/Core/DebuggerWX/Src/LogWindow.cpp +++ b/Source/Core/DebuggerWX/Src/LogWindow.cpp @@ -116,9 +116,18 @@ CLogWindow::CLogWindow(wxWindow* parent) UpdateChecks(); m_cmdline->SetFocus(); m_bCheckDirty = false; + + /* Load ini from here instead of from CodeWindow.cpp to make sure that + settings are loaded if the window is showing */ + IniFile file; + file.Load(DEBUGGER_CONFIG_FILE); + Load(file); } +// ======================================================= +// This is called from the CodeWindow deconstruction function. +// ------------- void CLogWindow::Save(IniFile& _IniFile) const { _IniFile.Set("LogWindow", "x", GetPosition().x); @@ -128,6 +137,9 @@ void CLogWindow::Save(IniFile& _IniFile) const } +// ======================================================= +// This is called from the class construction function. +// ------------- void CLogWindow::Load(IniFile& _IniFile) { int x,y,w,h; @@ -137,13 +149,13 @@ void CLogWindow::Load(IniFile& _IniFile) _IniFile.Get("LogWindow", "h", &h, GetSize().GetHeight()); SetSize(x, y, w, h); - // load verbosity setting + // Load verbosity setting int v; _IniFile.Get("LogWindow", "Verbosity", &v, m_RadioBox[0]->GetSelection()); m_RadioBox[0]->SetSelection(v); LogManager::m_LogSettings->m_iVerbosity = v; - // load options + // Load options _IniFile.Get("LogWindow", "Unify", &LogManager::m_LogSettings->bUnify, false); _IniFile.Get("LogWindow", "ResolveSymbols", &LogManager::m_LogSettings->bResolve, false); _IniFile.Get("LogWindow", "WriteMaster", &LogManager::m_LogSettings->bWriteMaster, false); @@ -153,6 +165,7 @@ void CLogWindow::Load(IniFile& _IniFile) m_options->Check(2, LogManager::m_LogSettings->bWriteMaster); m_options->Check(3, bOnlyUnique); + // If we use the Unify option if(LogManager::m_LogSettings->bUnify) { m_RadioBox[0]->SetSelection(LogManager::VERBOSITY_LEVELS); @@ -333,10 +346,7 @@ void CLogWindow::OnOptionsCheck(wxCommandEvent& event) // --------------- void CLogWindow::OnLogCheck(wxCommandEvent& event) { - if (!LogManager::m_bInitialized) - { - return; - } + if (!LogManager::m_bInitialized) return; IniFile ini; ini.Load(DEBUGGER_CONFIG_FILE);