| File: | /home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp |
| Location: | line 77, column 6 |
| Description: | Value stored to 'Command' during its initialization is never read |
| 1 | // Copyright 2013 Dolphin Emulator Project |
| 2 | // Licensed under GPLv2 |
| 3 | // Refer to the license.txt file included. |
| 4 | |
| 5 | #include "Common.h" |
| 6 | |
| 7 | #include "WII_IPC_HLE_Device_DI.h" |
| 8 | #include "WII_IPC_HLE.h" |
| 9 | |
| 10 | #include "../HW/DVDInterface.h" |
| 11 | #include "../HW/CPU.h" |
| 12 | #include "../HW/Memmap.h" |
| 13 | #include "../Core.h" |
| 14 | #include "../VolumeHandler.h" |
| 15 | #include "VolumeCreator.h" |
| 16 | #include "Filesystem.h" |
| 17 | #include "LogManager.h" |
| 18 | #include "../HW/SystemTimers.h" |
| 19 | |
| 20 | #include "../../DiscIO/Src/FileMonitor.h" |
| 21 | |
| 22 | using namespace DVDInterface; |
| 23 | |
| 24 | |
| 25 | #define DI_COVER_REG_INITIALIZED0 0 // Should be 4, but doesn't work correctly... |
| 26 | #define DI_COVER_REG_NO_DISC1 1 |
| 27 | |
| 28 | CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName ) |
| 29 | : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName) |
| 30 | , m_pFileSystem(NULL__null) |
| 31 | , m_ErrorStatus(0) |
| 32 | , m_CoverStatus(DI_COVER_REG_NO_DISC1) |
| 33 | {} |
| 34 | |
| 35 | CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di() |
| 36 | { |
| 37 | if (m_pFileSystem) |
| 38 | { |
| 39 | delete m_pFileSystem; |
| 40 | m_pFileSystem = NULL__null; |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode) |
| 45 | { |
| 46 | if (VolumeHandler::IsValid()) |
| 47 | { |
| 48 | m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume()); |
| 49 | m_CoverStatus |= DI_COVER_REG_INITIALIZED0; |
| 50 | m_CoverStatus &= ~DI_COVER_REG_NO_DISC1; |
| 51 | } |
| 52 | Memory::Write_U32(GetDeviceID(), _CommandAddress + 4); |
| 53 | m_Active = true; |
| 54 | return true; |
| 55 | } |
| 56 | |
| 57 | bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress, bool _bForce) |
| 58 | { |
| 59 | if (m_pFileSystem) |
| 60 | { |
| 61 | delete m_pFileSystem; |
| 62 | m_pFileSystem = NULL__null; |
| 63 | } |
| 64 | m_ErrorStatus = 0; |
| 65 | if (!_bForce) |
| 66 | Memory::Write_U32(0, _CommandAddress + 4); |
| 67 | m_Active = false; |
| 68 | return true; |
| 69 | } |
| 70 | |
| 71 | bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress) |
| 72 | { |
| 73 | u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); |
| 74 | u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14); |
| 75 | u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18); |
| 76 | u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C); |
| 77 | u32 Command = Memory::Read_U32(BufferIn) >> 24; |
Value stored to 'Command' during its initialization is never read | |
| 78 | |
| 79 | DEBUG_LOG(WII_IPC_DVD, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)",do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 80, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)" , Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); } } while (0) |
| 80 | Command, BufferIn, BufferInSize, BufferOut, BufferOutSize)do { { if (LogTypes::LDEBUG <= 3) GenericLog(LogTypes::LDEBUG , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 80, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)" , Command, BufferIn, BufferInSize, BufferOut, BufferOutSize); } } while (0); |
| 81 | |
| 82 | u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize); |
| 83 | Memory::Write_U32(ReturnValue, _CommandAddress + 0x4); |
| 84 | |
| 85 | return true; |
| 86 | } |
| 87 | |
| 88 | bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress) |
| 89 | { |
| 90 | SIOCtlVBuffer CommandBuffer(_CommandAddress); |
| 91 | |
| 92 | // Prepare the out buffer(s) with zeros as a safety precaution |
| 93 | // to avoid returning bad values |
| 94 | for(u32 i = 0; i < CommandBuffer.NumberPayloadBuffer; i++) |
| 95 | { |
| 96 | Memory::Memset(CommandBuffer.PayloadBuffer[i].m_Address, 0, |
| 97 | CommandBuffer.PayloadBuffer[i].m_Size); |
| 98 | } |
| 99 | |
| 100 | u32 ReturnValue = 0; |
| 101 | switch (CommandBuffer.Parameter) |
| 102 | { |
| 103 | case DVDLowOpenPartition: |
| 104 | { |
| 105 | _dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[1].m_Address == 0, "DVDLowOpenPartition with ticket"){}; |
| 106 | _dbg_assert_msg_(WII_IPC_DVD, CommandBuffer.InBuffer[2].m_Address == 0, "DVDLowOpenPartition with cert chain"){}; |
| 107 | |
| 108 | // Get TMD offset for requested partition... |
| 109 | u64 const TMDOffset = ((u64)Memory::Read_U32(CommandBuffer.InBuffer[0].m_Address + 4) << 2 ) + 0x2c0; |
| 110 | |
| 111 | INFO_LOG(WII_IPC_DVD, "DVDLowOpenPartition: TMDOffset 0x%016llx", TMDOffset)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 111, "DVDLowOpenPartition: TMDOffset 0x%016llx", TMDOffset) ; } } while (0); |
| 112 | |
| 113 | static u32 const TMDsz = 0x208; //CommandBuffer.PayloadBuffer[0].m_Size; |
| 114 | u8 pTMD[TMDsz]; |
| 115 | |
| 116 | // Read TMD to the buffer |
| 117 | VolumeHandler::RAWReadToPtr(pTMD, TMDOffset, TMDsz); |
| 118 | |
| 119 | memcpy(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address), pTMD, TMDsz); |
| 120 | WII_IPC_HLE_Interface::ES_DIVerify(pTMD, TMDsz); |
| 121 | |
| 122 | ReturnValue = 1; |
| 123 | } |
| 124 | break; |
| 125 | |
| 126 | default: |
| 127 | ERROR_LOG(WII_IPC_DVD, "IOCtlV: %i", CommandBuffer.Parameter)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 127, "IOCtlV: %i", CommandBuffer.Parameter); } } while (0); |
| 128 | _dbg_assert_msg_(WII_IPC_DVD, 0, "IOCtlV: %i", CommandBuffer.Parameter){}; |
| 129 | break; |
| 130 | } |
| 131 | |
| 132 | Memory::Write_U32(ReturnValue, _CommandAddress + 4); |
| 133 | return true; |
| 134 | } |
| 135 | |
| 136 | u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize) |
| 137 | { |
| 138 | u32 Command = Memory::Read_U32(_BufferIn) >> 24; |
| 139 | |
| 140 | // TATSUNOKO VS CAPCOM: Gets here with _BufferOut == 0!!! |
| 141 | if (_BufferOut != 0) |
| 142 | { |
| 143 | // Set out buffer to zeroes as a safety precaution to avoid answering |
| 144 | // nonsense values |
| 145 | Memory::Memset(_BufferOut, 0, _BufferOutSize); |
| 146 | } |
| 147 | |
| 148 | // Initializing a filesystem if it was just loaded |
| 149 | if(!m_pFileSystem && VolumeHandler::IsValid()) |
| 150 | { |
| 151 | m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume()); |
| 152 | m_CoverStatus |= DI_COVER_REG_INITIALIZED0; |
| 153 | m_CoverStatus &= ~DI_COVER_REG_NO_DISC1; |
| 154 | } |
| 155 | |
| 156 | // De-initializing a filesystem if the volume was unmounted |
| 157 | if(m_pFileSystem && !VolumeHandler::IsValid()) |
| 158 | { |
| 159 | delete m_pFileSystem; |
| 160 | m_pFileSystem = NULL__null; |
| 161 | m_CoverStatus |= DI_COVER_REG_NO_DISC1; |
| 162 | } |
| 163 | |
| 164 | switch (Command) |
| 165 | { |
| 166 | case DVDLowInquiry: |
| 167 | { |
| 168 | // (shuffle2) Taken from my wii |
| 169 | Memory::Write_U32(0x00000002, _BufferOut); |
| 170 | Memory::Write_U32(0x20060526, _BufferOut + 4); |
| 171 | // This was in the oubuf even though this cmd is only supposed to reply with 64bits |
| 172 | // However, this and other tests strongly suggest that the buffer is static, and it's never - or rarely cleared. |
| 173 | Memory::Write_U32(0x41000000, _BufferOut + 8); |
| 174 | |
| 175 | INFO_LOG(WII_IPC_DVD, "DVDLowInquiry (Buffer 0x%08x, 0x%x)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 176, "DVDLowInquiry (Buffer 0x%08x, 0x%x)", _BufferOut, _BufferOutSize ); } } while (0) |
| 176 | _BufferOut, _BufferOutSize)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 176, "DVDLowInquiry (Buffer 0x%08x, 0x%x)", _BufferOut, _BufferOutSize ); } } while (0); |
| 177 | } |
| 178 | break; |
| 179 | |
| 180 | case DVDLowReadDiskID: |
| 181 | { |
| 182 | VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), 0, _BufferOutSize); |
| 183 | |
| 184 | INFO_LOG(WII_IPC_DVD, "DVDLowReadDiskID %s",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 185, "DVDLowReadDiskID %s", ArrayToString(Memory::GetPointer (_BufferOut), _BufferOutSize, _BufferOutSize).c_str()); } } while (0) |
| 185 | ArrayToString(Memory::GetPointer(_BufferOut), _BufferOutSize, _BufferOutSize).c_str())do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 185, "DVDLowReadDiskID %s", ArrayToString(Memory::GetPointer (_BufferOut), _BufferOutSize, _BufferOutSize).c_str()); } } while (0); |
| 186 | } |
| 187 | break; |
| 188 | |
| 189 | case DVDLowRead: |
| 190 | { |
| 191 | if (_BufferOut == 0) |
| 192 | { |
| 193 | PanicAlert("DVDLowRead : _BufferOut == 0")MsgAlert(false, WARNING, "DVDLowRead : _BufferOut == 0"); |
| 194 | return 0; |
| 195 | } |
| 196 | u32 Size = Memory::Read_U32(_BufferIn + 0x04); |
| 197 | u64 DVDAddress = (u64)Memory::Read_U32(_BufferIn + 0x08) << 2; |
| 198 | |
| 199 | // Don't do anything if the log is unselected |
| 200 | if (LogManager::GetInstance()->IsEnabled(LogTypes::FILEMON)) |
| 201 | { |
| 202 | const char *pFilename = NULL__null; |
| 203 | if (m_pFileSystem) |
| 204 | pFilename = m_pFileSystem->GetFileName(DVDAddress); |
| 205 | if (pFilename != NULL__null) |
| 206 | { |
| 207 | INFO_LOG(WII_IPC_DVD, "DVDLowRead: %s (0x%llx) - (DVDAddr: 0x%llx, Size: 0x%x)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 208, "DVDLowRead: %s (0x%llx) - (DVDAddr: 0x%llx, Size: 0x%x)" , pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress , Size); } } while (0) |
| 208 | pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress, Size)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 208, "DVDLowRead: %s (0x%llx) - (DVDAddr: 0x%llx, Size: 0x%x)" , pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress , Size); } } while (0); |
| 209 | FileMon::CheckFile(std::string(pFilename), (int)m_pFileSystem->GetFileSize(pFilename)); |
| 210 | } |
| 211 | else |
| 212 | { |
| 213 | INFO_LOG(WII_IPC_DVD, "DVDLowRead: file unknown - (DVDAddr: 0x%llx, Size: 0x%x)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 214, "DVDLowRead: file unknown - (DVDAddr: 0x%llx, Size: 0x%x)" , DVDAddress, Size); } } while (0) |
| 214 | DVDAddress, Size)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 214, "DVDLowRead: file unknown - (DVDAddr: 0x%llx, Size: 0x%x)" , DVDAddress, Size); } } while (0); |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | if (Size > _BufferOutSize) |
| 219 | { |
| 220 | PanicAlertT("Detected attempt to read more data from the DVD than fit inside the out buffer. Clamp.")MsgAlert(false, WARNING, "Detected attempt to read more data from the DVD than fit inside the out buffer. Clamp." ); |
| 221 | Size = _BufferOutSize; |
| 222 | } |
| 223 | |
| 224 | if (!VolumeHandler::ReadToPtr(Memory::GetPointer(_BufferOut), DVDAddress, Size)) |
| 225 | { |
| 226 | PanicAlertT("DVDLowRead - Fatal Error: failed to read from volume")MsgAlert(false, WARNING, "DVDLowRead - Fatal Error: failed to read from volume" ); |
| 227 | } |
| 228 | } |
| 229 | break; |
| 230 | |
| 231 | case DVDLowWaitForCoverClose: |
| 232 | { |
| 233 | INFO_LOG(WII_IPC_DVD, "DVDLowWaitForCoverClose (Buffer 0x%08x, 0x%x)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 234, "DVDLowWaitForCoverClose (Buffer 0x%08x, 0x%x)", _BufferOut , _BufferOutSize); } } while (0) |
| 234 | _BufferOut, _BufferOutSize)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 234, "DVDLowWaitForCoverClose (Buffer 0x%08x, 0x%x)", _BufferOut , _BufferOutSize); } } while (0); |
| 235 | return 4; // ??? |
| 236 | } |
| 237 | break; |
| 238 | |
| 239 | case DVDLowGetCoverReg: |
| 240 | Memory::Write_U32(m_CoverStatus, _BufferOut); |
| 241 | |
| 242 | INFO_LOG(WII_IPC_DVD, "DVDLowGetCoverReg 0x%08x", Memory::Read_U32(_BufferOut))do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 242, "DVDLowGetCoverReg 0x%08x", Memory::Read_U32(_BufferOut )); } } while (0); |
| 243 | break; |
| 244 | |
| 245 | case DVDLowNotifyReset: |
| 246 | PanicAlert("DVDLowNotifyReset")MsgAlert(false, WARNING, "DVDLowNotifyReset"); |
| 247 | break; |
| 248 | |
| 249 | case DVDLowReadDvdPhysical: |
| 250 | PanicAlert("DVDLowReadDvdPhysical")MsgAlert(false, WARNING, "DVDLowReadDvdPhysical"); |
| 251 | break; |
| 252 | |
| 253 | case DVDLowReadDvdCopyright: |
| 254 | PanicAlert("DVDLowReadDvdCopyright")MsgAlert(false, WARNING, "DVDLowReadDvdCopyright"); |
| 255 | break; |
| 256 | |
| 257 | case DVDLowReadDvdDiscKey: |
| 258 | PanicAlert("DVDLowReadDvdDiscKey")MsgAlert(false, WARNING, "DVDLowReadDvdDiscKey"); |
| 259 | break; |
| 260 | |
| 261 | case DVDLowClearCoverInterrupt: |
| 262 | // TODO: check (seems to work ok) |
| 263 | INFO_LOG(WII_IPC_DVD, "DVDLowClearCoverInterrupt")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 263, "DVDLowClearCoverInterrupt"); } } while (0); |
| 264 | ClearCoverInterrupt(); |
| 265 | break; |
| 266 | |
| 267 | case DVDLowGetCoverStatus: |
| 268 | Memory::Write_U32(IsDiscInside() ? 2 : 1, _BufferOut); |
| 269 | INFO_LOG(WII_IPC_DVD, "DVDLowGetCoverStatus: Disc %sInserted", IsDiscInside() ? "" : "Not ")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 269, "DVDLowGetCoverStatus: Disc %sInserted", IsDiscInside( ) ? "" : "Not "); } } while (0); |
| 270 | break; |
| 271 | |
| 272 | case DVDLowReset: |
| 273 | INFO_LOG(WII_IPC_DVD, "DVDLowReset")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 273, "DVDLowReset"); } } while (0); |
| 274 | break; |
| 275 | |
| 276 | case DVDLowClosePartition: |
| 277 | INFO_LOG(WII_IPC_DVD, "DVDLowClosePartition")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 277, "DVDLowClosePartition"); } } while (0); |
| 278 | break; |
| 279 | |
| 280 | case DVDLowUnencryptedRead: |
| 281 | { |
| 282 | if (_BufferOut == 0) |
| 283 | { |
| 284 | PanicAlert("DVDLowRead : _BufferOut == 0")MsgAlert(false, WARNING, "DVDLowRead : _BufferOut == 0"); |
| 285 | return 0; |
| 286 | } |
| 287 | |
| 288 | u32 Size = Memory::Read_U32(_BufferIn + 0x04); |
| 289 | |
| 290 | // We must make sure it is in a valid area! (#001 check) |
| 291 | // * 0x00000000 - 0x00014000 (limit of older IOS versions) |
| 292 | // * 0x460a0000 - 0x460a0008 |
| 293 | // * 0x7ed40000 - 0x7ed40008 |
| 294 | u32 DVDAddress32 = Memory::Read_U32(_BufferIn + 0x08); |
| 295 | if (!( (DVDAddress32 > 0x00000000 && DVDAddress32 < 0x00014000) |
| 296 | || (((DVDAddress32 + Size) > 0x00000000) && (DVDAddress32 + Size) < 0x00014000) |
| 297 | || (DVDAddress32 > 0x460a0000 && DVDAddress32 < 0x460a0008) |
| 298 | || (((DVDAddress32 + Size) > 0x460a0000) && (DVDAddress32 + Size) < 0x460a0008) |
| 299 | || (DVDAddress32 > 0x7ed40000 && DVDAddress32 < 0x7ed40008) |
| 300 | || (((DVDAddress32 + Size) > 0x7ed40000) && (DVDAddress32 + Size) < 0x7ed40008) |
| 301 | )) |
| 302 | { |
| 303 | WARN_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: trying to read out of bounds @ %x", DVDAddress32)do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 303, "DVDLowUnencryptedRead: trying to read out of bounds @ %x" , DVDAddress32); } } while (0); |
| 304 | m_ErrorStatus = ERROR_READY | ERROR_BLOCK_OOB; |
| 305 | // Should cause software to call DVDLowRequestError |
| 306 | return 2; |
| 307 | } |
| 308 | |
| 309 | u64 DVDAddress = (u64)DVDAddress32 << 2; |
| 310 | |
| 311 | INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: DVDAddr: 0x%08llx, Size: 0x%x", DVDAddress, Size)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 311, "DVDLowUnencryptedRead: DVDAddr: 0x%08llx, Size: 0x%x" , DVDAddress, Size); } } while (0); |
| 312 | |
| 313 | if (Size > _BufferOutSize) |
| 314 | { |
| 315 | PanicAlertT("Detected attempt to read more data from the DVD than fit inside the out buffer. Clamp.")MsgAlert(false, WARNING, "Detected attempt to read more data from the DVD than fit inside the out buffer. Clamp." ); |
| 316 | Size = _BufferOutSize; |
| 317 | } |
| 318 | if(!VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), DVDAddress, Size)) |
| 319 | { |
| 320 | PanicAlertT("DVDLowUnencryptedRead - Fatal Error: failed to read from volume")MsgAlert(false, WARNING, "DVDLowUnencryptedRead - Fatal Error: failed to read from volume" ); |
| 321 | } |
| 322 | } |
| 323 | break; |
| 324 | |
| 325 | case DVDLowEnableDvdVideo: |
| 326 | ERROR_LOG(WII_IPC_DVD, "DVDLowEnableDvdVideo")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 326, "DVDLowEnableDvdVideo"); } } while (0); |
| 327 | break; |
| 328 | |
| 329 | case DVDLowReportKey: |
| 330 | INFO_LOG(WII_IPC_DVD, "DVDLowReportKey")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 330, "DVDLowReportKey"); } } while (0); |
| 331 | // Does not work on retail discs/drives |
| 332 | // Retail games send this command to see if they are running on real retail hw |
| 333 | m_ErrorStatus = ERROR_READY | ERROR_INV_CMD; |
| 334 | return 2; |
| 335 | break; |
| 336 | |
| 337 | case DVDLowSeek: |
| 338 | { |
| 339 | u64 DVDAddress = Memory::Read_U32(_BufferIn + 0x4) << 2; |
| 340 | const char *pFilename = NULL__null; |
| 341 | if (m_pFileSystem) |
| 342 | pFilename = m_pFileSystem->GetFileName(DVDAddress); |
| 343 | if (pFilename != NULL__null) |
| 344 | { |
| 345 | INFO_LOG(WII_IPC_DVD, "DVDLowSeek: %s (0x%llx) - (DVDAddr: 0x%llx)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 346, "DVDLowSeek: %s (0x%llx) - (DVDAddr: 0x%llx)", pFilename , m_pFileSystem->GetFileSize(pFilename), DVDAddress); } } while (0) |
| 346 | pFilename, m_pFileSystem->GetFileSize(pFilename), DVDAddress)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 346, "DVDLowSeek: %s (0x%llx) - (DVDAddr: 0x%llx)", pFilename , m_pFileSystem->GetFileSize(pFilename), DVDAddress); } } while (0); |
| 347 | } |
| 348 | else |
| 349 | { |
| 350 | INFO_LOG(WII_IPC_DVD, "DVDLowSeek: file unknown - (DVDAddr: 0x%llx)",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 351, "DVDLowSeek: file unknown - (DVDAddr: 0x%llx)", DVDAddress ); } } while (0) |
| 351 | DVDAddress)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 351, "DVDLowSeek: file unknown - (DVDAddr: 0x%llx)", DVDAddress ); } } while (0); |
| 352 | } |
| 353 | } |
| 354 | break; |
| 355 | |
| 356 | case DVDLowReadDvd: |
| 357 | ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvd")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 357, "DVDLowReadDvd"); } } while (0); |
| 358 | break; |
| 359 | |
| 360 | case DVDLowReadDvdConfig: |
| 361 | ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvdConfig")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 361, "DVDLowReadDvdConfig"); } } while (0); |
| 362 | break; |
| 363 | |
| 364 | case DVDLowStopLaser: |
| 365 | ERROR_LOG(WII_IPC_DVD, "DVDLowStopLaser")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 365, "DVDLowStopLaser"); } } while (0); |
| 366 | break; |
| 367 | |
| 368 | case DVDLowOffset: |
| 369 | ERROR_LOG(WII_IPC_DVD, "DVDLowOffset")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 369, "DVDLowOffset"); } } while (0); |
| 370 | break; |
| 371 | |
| 372 | case DVDLowReadDiskBca: |
| 373 | WARN_LOG(WII_IPC_DVD, "DVDLowReadDiskBca")do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 373, "DVDLowReadDiskBca"); } } while (0); |
| 374 | Memory::Write_U32(1, _BufferOut + 0x30); |
| 375 | break; |
| 376 | |
| 377 | case DVDLowRequestDiscStatus: |
| 378 | ERROR_LOG(WII_IPC_DVD, "DVDLowRequestDiscStatus")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 378, "DVDLowRequestDiscStatus"); } } while (0); |
| 379 | break; |
| 380 | |
| 381 | case DVDLowRequestRetryNumber: |
| 382 | ERROR_LOG(WII_IPC_DVD, "DVDLowRequestRetryNumber")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 382, "DVDLowRequestRetryNumber"); } } while (0); |
| 383 | break; |
| 384 | |
| 385 | case DVDLowSetMaximumRotation: |
| 386 | ERROR_LOG(WII_IPC_DVD, "DVDLowSetMaximumRotation")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 386, "DVDLowSetMaximumRotation"); } } while (0); |
| 387 | break; |
| 388 | |
| 389 | case DVDLowSerMeasControl: |
| 390 | ERROR_LOG(WII_IPC_DVD, "DVDLowSerMeasControl")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 390, "DVDLowSerMeasControl"); } } while (0); |
| 391 | break; |
| 392 | |
| 393 | case DVDLowRequestError: |
| 394 | // Identical to the error codes found in yagcd section 5.7.3.5.1 (so far) |
| 395 | WARN_LOG(WII_IPC_DVD, "DVDLowRequestError status = 0x%08x", m_ErrorStatus)do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 395, "DVDLowRequestError status = 0x%08x", m_ErrorStatus); } } while (0); |
| 396 | Memory::Write_U32(m_ErrorStatus, _BufferOut); |
| 397 | // When does error status get reset? |
| 398 | break; |
| 399 | |
| 400 | // Ex commands are immediate and respond with 4 bytes |
| 401 | case DVDLowStopMotor: |
| 402 | { |
| 403 | u32 eject = Memory::Read_U32(_BufferIn + 4); |
| 404 | // Drive won't do anything till reset is issued. I think it replies like nothing is wrong though? |
| 405 | u32 kill = Memory::Read_U32(_BufferIn + 8); |
| 406 | |
| 407 | INFO_LOG(WII_IPC_DVD, "DVDLowStopMotor %s %s",do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 408, "DVDLowStopMotor %s %s", eject ? "eject" : "", kill ? "kill!" : ""); } } while (0) |
| 408 | eject ? "eject" : "", kill ? "kill!" : "")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 408, "DVDLowStopMotor %s %s", eject ? "eject" : "", kill ? "kill!" : ""); } } while (0); |
| 409 | |
| 410 | if (eject) |
| 411 | { |
| 412 | SetLidOpen(true); |
| 413 | SetDiscInside(false); |
| 414 | } |
| 415 | } |
| 416 | break; |
| 417 | |
| 418 | case DVDLowAudioBufferConfig: |
| 419 | /* |
| 420 | For more information: http://www.crazynation.org/GC/GC_DD_TECH/GCTech.htm |
| 421 | |
| 422 | Upon Power up or reset , 2 commands must be issued for proper use of audio streaming: |
| 423 | DVDReadDiskID A8000040,00000000,00000020 |
| 424 | DVDLowAudioBufferConfig E4xx00yy,00000000,00000020 |
| 425 | |
| 426 | xx=byte 8 [0 or 1] from the disk header retrieved from DVDReadDiskID |
| 427 | yy=0 (if xx=0) or 0xA (if xx=1) |
| 428 | */ |
| 429 | ERROR_LOG(WII_IPC_DVD, "DVDLowAudioBufferConfig")do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 429, "DVDLowAudioBufferConfig"); } } while (0); |
| 430 | break; |
| 431 | |
| 432 | // New Super Mario Bros.Wii sends these cmds |
| 433 | // but it seems we don't need to implement anything |
| 434 | case 0x95: |
| 435 | case 0x96: |
| 436 | WARN_LOG(WII_IPC_DVD, "Unimplemented command 0x%08x (Buffer 0x%08x, 0x%x)",do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 437, "Unimplemented command 0x%08x (Buffer 0x%08x, 0x%x)", Command , _BufferOut, _BufferOutSize); } } while (0) |
| 437 | Command, _BufferOut, _BufferOutSize)do { { if (LogTypes::LWARNING <= 3) GenericLog(LogTypes::LWARNING , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 437, "Unimplemented command 0x%08x (Buffer 0x%08x, 0x%x)", Command , _BufferOut, _BufferOutSize); } } while (0); |
| 438 | break; |
| 439 | |
| 440 | default: |
| 441 | ERROR_LOG(WII_IPC_DVD, "Unknown command 0x%08x (Buffer 0x%08x, 0x%x)",do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 442, "Unknown command 0x%08x (Buffer 0x%08x, 0x%x)", Command , _BufferOut, _BufferOutSize); } } while (0) |
| 442 | Command, _BufferOut, _BufferOutSize)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::WII_IPC_DVD, "/home/anal/dolphin-emu/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp" , 442, "Unknown command 0x%08x (Buffer 0x%08x, 0x%x)", Command , _BufferOut, _BufferOutSize); } } while (0); |
| 443 | |
| 444 | PanicAlertT("Unknown command 0x%08x", Command)MsgAlert(false, WARNING, "Unknown command 0x%08x", Command); |
| 445 | break; |
| 446 | } |
| 447 | |
| 448 | // i dunno but prolly 1 is okay all the time :) |
| 449 | return 1; |
| 450 | } |
| 451 | |
| 452 | int CWII_IPC_HLE_Device_di::GetCmdDelay(u32 _CommandAddress) |
| 453 | { |
| 454 | u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10); |
| 455 | u32 Command = Memory::Read_U32(BufferIn) >> 24; |
| 456 | |
| 457 | // Hacks below |
| 458 | |
| 459 | switch (Command) |
| 460 | { |
| 461 | case DVDLowRead: |
| 462 | case DVDLowUnencryptedRead: |
| 463 | { |
| 464 | u32 const Size = Memory::Read_U32(BufferIn + 0x04); |
| 465 | // Delay depends on size of read, that makes sense, right? |
| 466 | // More than ~1150K "bytes / sec" hangs NSMBWii on boot. |
| 467 | // Less than ~800K "bytes / sec" hangs DKCR randomly (ok, probably not true) |
| 468 | return SystemTimers::GetTicksPerSecond() / 975000 * Size; |
| 469 | break; |
| 470 | } |
| 471 | |
| 472 | case DVDLowClearCoverInterrupt: |
| 473 | // Less than ~1/155th of a second hangs Oregon Trail at "loading wheel". |
| 474 | // More than ~1/140th of a second hangs Resident Evil Archives: Resident Evil Zero. |
| 475 | return SystemTimers::GetTicksPerSecond() / 146; |
| 476 | break; |
| 477 | |
| 478 | // case DVDLowAudioBufferConfig: |
| 479 | // case DVDLowInquiry: |
| 480 | // case DVDLowReadDiskID: |
| 481 | // case DVDLowWaitForCoverClose: |
| 482 | // case DVDLowGetCoverReg: |
| 483 | // case DVDLowGetCoverStatus: |
| 484 | // case DVDLowReset: |
| 485 | // case DVDLowClosePartition: |
| 486 | default: |
| 487 | // random numbers here! |
| 488 | // More than ~1/2000th of a second hangs DKCR with DSP HLE, maybe. |
| 489 | return SystemTimers::GetTicksPerSecond() / 15000; |
| 490 | break; |
| 491 | } |
| 492 | } |