Bug Summary

File:Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp
Location:line 405, column 8
Description:Value stored to 'kill' during its initialization is never read

Annotated Source Code

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
22using 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
28CWII_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
35CWII_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
44bool 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
57bool 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
71bool 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;
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
88bool 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
136u32 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);
Value stored to 'kill' during its initialization is never read
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
452int 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}