mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #1634 from JosJuice/disc-drive-unification-lite
Make WII_IPC_HLE_Device_DI call DVDInterface
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,84 @@ namespace MMIO { class Mapping; }
|
||||
namespace DVDInterface
|
||||
{
|
||||
|
||||
// Not sure about endianness here. I'll just name them like this...
|
||||
enum DIErrorLow
|
||||
{
|
||||
ERROR_READY = 0x00000000, // Ready.
|
||||
ERROR_COVER_L = 0x01000000, // Cover is opened.
|
||||
ERROR_CHANGE_DISK = 0x02000000, // Disk change.
|
||||
ERROR_NO_DISK = 0x03000000, // No disk.
|
||||
ERROR_MOTOR_STOP_L = 0x04000000, // Motor stop.
|
||||
ERROR_NO_DISKID_L = 0x05000000 // Disk ID not read.
|
||||
};
|
||||
enum DIErrorHigh
|
||||
{
|
||||
ERROR_NONE = 0x000000, // No error.
|
||||
ERROR_MOTOR_STOP_H = 0x020400, // Motor stopped.
|
||||
ERROR_NO_DISKID_H = 0x020401, // Disk ID not read.
|
||||
ERROR_COVER_H = 0x023a00, // Medium not present / Cover opened.
|
||||
ERROR_SEEK_NDONE = 0x030200, // No seek complete.
|
||||
ERROR_READ = 0x031100, // Unrecovered read error.
|
||||
ERROR_PROTOCOL = 0x040800, // Transfer protocol error.
|
||||
ERROR_INV_CMD = 0x052000, // Invalid command operation code.
|
||||
ERROR_AUDIO_BUF = 0x052001, // Audio Buffer not set.
|
||||
ERROR_BLOCK_OOB = 0x052100, // Logical block address out of bounds.
|
||||
ERROR_INV_FIELD = 0x052400, // Invalid field in command packet.
|
||||
ERROR_INV_AUDIO = 0x052401, // Invalid audio command.
|
||||
ERROR_INV_PERIOD = 0x052402, // Configuration out of permitted period.
|
||||
ERROR_END_USR_AREA = 0x056300, // End of user area encountered on this track.
|
||||
ERROR_MEDIUM = 0x062800, // Medium may have changed.
|
||||
ERROR_MEDIUM_REQ = 0x0b5a01 // Operator medium removal request.
|
||||
};
|
||||
|
||||
enum DICommand
|
||||
{
|
||||
DVDLowInquiry = 0x12,
|
||||
DVDLowReadDiskID = 0x70,
|
||||
DVDLowRead = 0x71,
|
||||
DVDLowWaitForCoverClose = 0x79,
|
||||
DVDLowGetCoverReg = 0x7a, // DVDLowPrepareCoverRegister?
|
||||
DVDLowNotifyReset = 0x7e,
|
||||
DVDLowReadDvdPhysical = 0x80,
|
||||
DVDLowReadDvdCopyright = 0x81,
|
||||
DVDLowReadDvdDiscKey = 0x82,
|
||||
DVDLowClearCoverInterrupt = 0x86,
|
||||
DVDLowGetCoverStatus = 0x88,
|
||||
DVDLowReset = 0x8a,
|
||||
DVDLowOpenPartition = 0x8b,
|
||||
DVDLowClosePartition = 0x8c,
|
||||
DVDLowUnencryptedRead = 0x8d,
|
||||
DVDLowEnableDvdVideo = 0x8e,
|
||||
DVDLowReportKey = 0xa4,
|
||||
DVDLowSeek = 0xab,
|
||||
DVDLowReadDvd = 0xd0,
|
||||
DVDLowReadDvdConfig = 0xd1,
|
||||
DVDLowStopLaser = 0xd2,
|
||||
DVDLowOffset = 0xd9,
|
||||
DVDLowReadDiskBca = 0xda,
|
||||
DVDLowRequestDiscStatus = 0xdb,
|
||||
DVDLowRequestRetryNumber = 0xdc,
|
||||
DVDLowSetMaximumRotation = 0xdd,
|
||||
DVDLowSerMeasControl = 0xdf,
|
||||
DVDLowRequestError = 0xe0,
|
||||
DVDLowStopMotor = 0xe3,
|
||||
DVDLowAudioBufferConfig = 0xe4
|
||||
};
|
||||
|
||||
enum DIInterruptType
|
||||
{
|
||||
INT_DEINT = 0,
|
||||
INT_TCINT = 1,
|
||||
INT_BRKINT = 2,
|
||||
INT_CVRINT = 3,
|
||||
};
|
||||
|
||||
struct DVDCommandResult
|
||||
{
|
||||
DIInterruptType interrupt_type;
|
||||
u64 ticks_until_completion;
|
||||
};
|
||||
|
||||
void Init();
|
||||
void Shutdown();
|
||||
void DoState(PointerWrap &p);
|
||||
@@ -28,75 +106,10 @@ void ChangeDisc(const std::string& fileName);
|
||||
void SetLidOpen(bool _bOpen = true);
|
||||
bool IsLidOpen();
|
||||
|
||||
// Used as low level control by WII_IPC_HLE_Device_DI
|
||||
void ClearCoverInterrupt();
|
||||
|
||||
// DVD Access Functions
|
||||
bool DVDRead(u32 _iDVDOffset, u32 _iRamAddress, u32 _iLength);
|
||||
bool DVDRead(u64 _iDVDOffset, u32 _iRamAddress, u32 _iLength, bool raw = false);
|
||||
extern bool g_bStream;
|
||||
|
||||
// Not sure about endianness here. I'll just name them like this...
|
||||
enum DIErrorLow
|
||||
{
|
||||
ERROR_READY = 0x00000000, // Ready.
|
||||
ERROR_COVER_L = 0x01000000, // Cover is opened.
|
||||
ERROR_CHANGE_DISK = 0x02000000, // Disk change.
|
||||
ERROR_NO_DISK = 0x03000000, // No Disk.
|
||||
ERROR_MOTOR_STOP_L = 0x04000000, // Motor stop.
|
||||
ERROR_NO_DISKID_L = 0x05000000 // Disk ID not read.
|
||||
};
|
||||
enum DIErrorHigh
|
||||
{
|
||||
ERROR_NONE = 0x000000, // No error.
|
||||
ERROR_MOTOR_STOP_H = 0x020400, // Motor stopped.
|
||||
ERROR_NO_DISKID_H = 0x020401, // Disk ID not read.
|
||||
ERROR_COVER_H = 0x023a00, // Medium not present / Cover opened.
|
||||
ERROR_SEEK_NDONE = 0x030200, // No Seek complete.
|
||||
ERROR_READ = 0x031100, // UnRecoverd read error.
|
||||
ERROR_PROTOCOL = 0x040800, // Transfer protocol error.
|
||||
ERROR_INV_CMD = 0x052000, // Invalid command operation code.
|
||||
ERROR_AUDIO_BUF = 0x052001, // Audio Buffer not set.
|
||||
ERROR_BLOCK_OOB = 0x052100, // Logical block address out of bounds.
|
||||
ERROR_INV_FIELD = 0x052400, // Invalid Field in command packet.
|
||||
ERROR_INV_AUDIO = 0x052401, // Invalid audio command.
|
||||
ERROR_INV_PERIOD = 0x052402, // Configuration out of permitted period.
|
||||
ERROR_END_USR_AREA = 0x056300, // End of user area encountered on this track.
|
||||
ERROR_MEDIUM = 0x062800, // Medium may have changed.
|
||||
ERROR_MEDIUM_REQ = 0x0b5a01 // Operator medium removal request.
|
||||
};
|
||||
|
||||
enum DICommand
|
||||
{
|
||||
DVDLowInquiry = 0x12,
|
||||
DVDLowReadDiskID = 0x70,
|
||||
DVDLowRead = 0x71,
|
||||
DVDLowWaitForCoverClose = 0x79,
|
||||
DVDLowGetCoverReg = 0x7a, // DVDLowPrepareCoverRegister?
|
||||
DVDLowNotifyReset = 0x7e,
|
||||
DVDLowReadDvdPhysical = 0x80,
|
||||
DVDLowReadDvdCopyright = 0x81,
|
||||
DVDLowReadDvdDiscKey = 0x82,
|
||||
DVDLowClearCoverInterrupt = 0x86,
|
||||
DVDLowGetCoverStatus = 0x88,
|
||||
DVDLowReset = 0x8a,
|
||||
DVDLowOpenPartition = 0x8b,
|
||||
DVDLowClosePartition = 0x8c,
|
||||
DVDLowUnencryptedRead = 0x8d,
|
||||
DVDLowEnableDvdVideo = 0x8e,
|
||||
DVDLowReportKey = 0xa4,
|
||||
DVDLowSeek = 0xab,
|
||||
DVDLowReadDvd = 0xd0,
|
||||
DVDLowReadDvdConfig = 0xd1,
|
||||
DVDLowStopLaser = 0xd2,
|
||||
DVDLowOffset = 0xd9,
|
||||
DVDLowReadDiskBca = 0xda,
|
||||
DVDLowRequestDiscStatus = 0xdb,
|
||||
DVDLowRequestRetryNumber = 0xdc,
|
||||
DVDLowSetMaximumRotation = 0xdd,
|
||||
DVDLowSerMeasControl = 0xdf,
|
||||
DVDLowRequestError = 0xe0,
|
||||
DVDLowStopMotor = 0xe3,
|
||||
DVDLowAudioBufferConfig = 0xe4
|
||||
};
|
||||
DVDCommandResult ExecuteCommand(u32 command_0, u32 command_1, u32 command_2,
|
||||
u32 output_address, u32 output_length, bool write_to_DIIMMBUF);
|
||||
|
||||
} // end of namespace DVDInterface
|
||||
|
||||
@@ -8,9 +8,7 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/LogManager.h"
|
||||
|
||||
#include "Core/Core.h"
|
||||
#include "Core/VolumeHandler.h"
|
||||
#include "Core/HW/CPU.h"
|
||||
#include "Core/HW/DVDInterface.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/HW/SystemTimers.h"
|
||||
@@ -18,40 +16,17 @@
|
||||
#include "Core/IPC_HLE/WII_IPC_HLE.h"
|
||||
#include "Core/IPC_HLE/WII_IPC_HLE_Device_DI.h"
|
||||
|
||||
#include "DiscIO/FileMonitor.h"
|
||||
#include "DiscIO/Filesystem.h"
|
||||
#include "DiscIO/VolumeCreator.h"
|
||||
|
||||
using namespace DVDInterface;
|
||||
|
||||
|
||||
#define DI_COVER_REG_INITIALIZED 0 // Should be 4, but doesn't work correctly...
|
||||
#define DI_COVER_REG_NO_DISC 1
|
||||
|
||||
CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string& _rDeviceName )
|
||||
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||
, m_pFileSystem(nullptr)
|
||||
, m_ErrorStatus(0)
|
||||
, m_CoverStatus(DI_COVER_REG_NO_DISC)
|
||||
{}
|
||||
|
||||
CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di()
|
||||
{
|
||||
if (m_pFileSystem)
|
||||
{
|
||||
delete m_pFileSystem;
|
||||
m_pFileSystem = nullptr;
|
||||
}
|
||||
}
|
||||
{}
|
||||
|
||||
bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode)
|
||||
{
|
||||
if (VolumeHandler::IsValid())
|
||||
{
|
||||
m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume());
|
||||
m_CoverStatus |= DI_COVER_REG_INITIALIZED;
|
||||
m_CoverStatus &= ~DI_COVER_REG_NO_DISC;
|
||||
}
|
||||
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
|
||||
m_Active = true;
|
||||
return true;
|
||||
@@ -59,12 +34,6 @@ bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode)
|
||||
|
||||
bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress, bool _bForce)
|
||||
{
|
||||
if (m_pFileSystem)
|
||||
{
|
||||
delete m_pFileSystem;
|
||||
m_pFileSystem = nullptr;
|
||||
}
|
||||
m_ErrorStatus = 0;
|
||||
if (!_bForce)
|
||||
Memory::Write_U32(0, _CommandAddress + 4);
|
||||
m_Active = false;
|
||||
@@ -73,18 +42,30 @@ bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress, bool _bForce)
|
||||
|
||||
bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
|
||||
{
|
||||
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
|
||||
u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
|
||||
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 Command = Memory::Read_U32(BufferIn) >> 24;
|
||||
|
||||
u32 command_0 = Memory::Read_U32(BufferIn);
|
||||
u32 command_1 = Memory::Read_U32(BufferIn + 4);
|
||||
u32 command_2 = Memory::Read_U32(BufferIn + 8);
|
||||
|
||||
DEBUG_LOG(WII_IPC_DVD, "IOCtl Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)",
|
||||
Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
||||
command_0, BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
||||
|
||||
u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||
// TATSUNOKO VS CAPCOM: Gets here with BufferOut == 0!!!
|
||||
if (BufferOut != 0)
|
||||
{
|
||||
// Set out buffer to zeroes as a safety precaution
|
||||
// to avoid answering nonsense values
|
||||
Memory::Memset(BufferOut, 0, BufferOutSize);
|
||||
}
|
||||
|
||||
DVDCommandResult result = ExecuteCommand(command_0, command_1, command_2,
|
||||
BufferOut, BufferOutSize, false);
|
||||
Memory::Write_U32(result.interrupt_type, _CommandAddress + 0x4);
|
||||
// TODO: Don't discard result.ticks_until_completion
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -133,318 +114,6 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32 _BufferOut, u32 _BufferOutSize)
|
||||
{
|
||||
u32 Command = Memory::Read_U32(_BufferIn) >> 24;
|
||||
|
||||
// TATSUNOKO VS CAPCOM: Gets here with _BufferOut == 0!!!
|
||||
if (_BufferOut != 0)
|
||||
{
|
||||
// Set out buffer to zeroes as a safety precaution to avoid answering
|
||||
// nonsense values
|
||||
Memory::Memset(_BufferOut, 0, _BufferOutSize);
|
||||
}
|
||||
|
||||
// Initializing a filesystem if it was just loaded
|
||||
if (!m_pFileSystem && VolumeHandler::IsValid())
|
||||
{
|
||||
m_pFileSystem = DiscIO::CreateFileSystem(VolumeHandler::GetVolume());
|
||||
m_CoverStatus |= DI_COVER_REG_INITIALIZED;
|
||||
m_CoverStatus &= ~DI_COVER_REG_NO_DISC;
|
||||
}
|
||||
|
||||
// De-initializing a filesystem if the volume was unmounted
|
||||
if (m_pFileSystem && !VolumeHandler::IsValid())
|
||||
{
|
||||
delete m_pFileSystem;
|
||||
m_pFileSystem = nullptr;
|
||||
m_CoverStatus |= DI_COVER_REG_NO_DISC;
|
||||
}
|
||||
|
||||
switch (Command)
|
||||
{
|
||||
case DVDLowInquiry:
|
||||
{
|
||||
// (shuffle2) Taken from my Wii
|
||||
Memory::Write_U32(0x00000002, _BufferOut);
|
||||
Memory::Write_U32(0x20060526, _BufferOut + 4);
|
||||
// This was in the oubuf even though this cmd is only supposed to reply with 64bits
|
||||
// However, this and other tests strongly suggest that the buffer is static, and it's never - or rarely cleared.
|
||||
Memory::Write_U32(0x41000000, _BufferOut + 8);
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowInquiry (Buffer 0x%08x, 0x%x)",
|
||||
_BufferOut, _BufferOutSize);
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowReadDiskID:
|
||||
{
|
||||
VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), 0, _BufferOutSize);
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowReadDiskID %s",
|
||||
ArrayToString(Memory::GetPointer(_BufferOut), _BufferOutSize, _BufferOutSize).c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowRead:
|
||||
{
|
||||
if (_BufferOut == 0)
|
||||
{
|
||||
PanicAlert("DVDLowRead : _BufferOut == 0");
|
||||
return 0;
|
||||
}
|
||||
u32 Size = Memory::Read_U32(_BufferIn + 0x04);
|
||||
u64 DVDAddress = (u64)Memory::Read_U32(_BufferIn + 0x08) << 2;
|
||||
|
||||
// Don't do anything if the log is unselected
|
||||
if (LogManager::GetInstance()->IsEnabled(LogTypes::FILEMON))
|
||||
{
|
||||
if (m_pFileSystem)
|
||||
{
|
||||
const std::string filename = m_pFileSystem->GetFileName(DVDAddress);
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowRead: %s (0x%" PRIx64 ") - (DVDAddr: 0x%" PRIx64 ", Size: 0x%x)",
|
||||
filename.c_str(), m_pFileSystem->GetFileSize(filename), DVDAddress, Size);
|
||||
FileMon::CheckFile(filename, (int)m_pFileSystem->GetFileSize(filename));
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(WII_IPC_DVD, "Filesystem is invalid.");
|
||||
}
|
||||
}
|
||||
|
||||
if (Size > _BufferOutSize)
|
||||
{
|
||||
PanicAlertT("Detected attempt to read more data from the DVD than fit inside the out buffer. Clamp.");
|
||||
Size = _BufferOutSize;
|
||||
}
|
||||
|
||||
if (!VolumeHandler::ReadToPtr(Memory::GetPointer(_BufferOut), DVDAddress, Size))
|
||||
{
|
||||
PanicAlertT("DVDLowRead - Fatal Error: failed to read from volume");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowWaitForCoverClose:
|
||||
{
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowWaitForCoverClose (Buffer 0x%08x, 0x%x)",
|
||||
_BufferOut, _BufferOutSize);
|
||||
return 4; // ???
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowGetCoverReg:
|
||||
Memory::Write_U32(m_CoverStatus, _BufferOut);
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowGetCoverReg 0x%08x", Memory::Read_U32(_BufferOut));
|
||||
break;
|
||||
|
||||
case DVDLowNotifyReset:
|
||||
PanicAlert("DVDLowNotifyReset");
|
||||
break;
|
||||
|
||||
case DVDLowReadDvdPhysical:
|
||||
PanicAlert("DVDLowReadDvdPhysical");
|
||||
break;
|
||||
|
||||
case DVDLowReadDvdCopyright:
|
||||
PanicAlert("DVDLowReadDvdCopyright");
|
||||
break;
|
||||
|
||||
case DVDLowReadDvdDiscKey:
|
||||
PanicAlert("DVDLowReadDvdDiscKey");
|
||||
break;
|
||||
|
||||
case DVDLowClearCoverInterrupt:
|
||||
// TODO: check (seems to work ok)
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowClearCoverInterrupt");
|
||||
ClearCoverInterrupt();
|
||||
break;
|
||||
|
||||
case DVDLowGetCoverStatus:
|
||||
Memory::Write_U32(IsDiscInside() ? 2 : 1, _BufferOut);
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowGetCoverStatus: Disc %sInserted", IsDiscInside() ? "" : "Not ");
|
||||
break;
|
||||
|
||||
case DVDLowReset:
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowReset");
|
||||
break;
|
||||
|
||||
case DVDLowClosePartition:
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowClosePartition");
|
||||
break;
|
||||
|
||||
case DVDLowUnencryptedRead:
|
||||
{
|
||||
if (_BufferOut == 0)
|
||||
{
|
||||
PanicAlert("DVDLowRead : _BufferOut == 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 Size = Memory::Read_U32(_BufferIn + 0x04);
|
||||
|
||||
// We must make sure it is in a valid area! (#001 check)
|
||||
// * 0x00000000 - 0x00014000 (limit of older IOS versions)
|
||||
// * 0x460a0000 - 0x460a0008
|
||||
// * 0x7ed40000 - 0x7ed40008
|
||||
u32 DVDAddress32 = Memory::Read_U32(_BufferIn + 0x08);
|
||||
if (!((DVDAddress32 > 0x00000000 && DVDAddress32 < 0x00014000) ||
|
||||
(((DVDAddress32 + Size) > 0x00000000) && (DVDAddress32 + Size) < 0x00014000) ||
|
||||
(DVDAddress32 > 0x460a0000 && DVDAddress32 < 0x460a0008) ||
|
||||
(((DVDAddress32 + Size) > 0x460a0000) && (DVDAddress32 + Size) < 0x460a0008) ||
|
||||
(DVDAddress32 > 0x7ed40000 && DVDAddress32 < 0x7ed40008) ||
|
||||
(((DVDAddress32 + Size) > 0x7ed40000) && (DVDAddress32 + Size) < 0x7ed40008)))
|
||||
{
|
||||
WARN_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: trying to read out of bounds @ %x", DVDAddress32);
|
||||
m_ErrorStatus = ERROR_READY | ERROR_BLOCK_OOB;
|
||||
// Should cause software to call DVDLowRequestError
|
||||
return 2;
|
||||
}
|
||||
|
||||
u64 DVDAddress = (u64)DVDAddress32 << 2;
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: DVDAddr: 0x%08" PRIx64 ", Size: 0x%x", DVDAddress, Size);
|
||||
|
||||
if (Size > _BufferOutSize)
|
||||
{
|
||||
PanicAlertT("Detected attempt to read more data from the DVD than fit inside the out buffer. Clamp.");
|
||||
Size = _BufferOutSize;
|
||||
}
|
||||
if (!VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), DVDAddress, Size))
|
||||
{
|
||||
PanicAlertT("DVDLowUnencryptedRead - Fatal Error: failed to read from volume");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowEnableDvdVideo:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowEnableDvdVideo");
|
||||
break;
|
||||
|
||||
case DVDLowReportKey:
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowReportKey");
|
||||
// Does not work on retail discs/drives
|
||||
// Retail games send this command to see if they are running on real retail hw
|
||||
m_ErrorStatus = ERROR_READY | ERROR_INV_CMD;
|
||||
return 2;
|
||||
break;
|
||||
|
||||
case DVDLowSeek:
|
||||
{
|
||||
u64 DVDAddress = Memory::Read_U32(_BufferIn + 0x4) << 2;
|
||||
|
||||
if (m_pFileSystem)
|
||||
{
|
||||
const std::string filename = m_pFileSystem->GetFileName(DVDAddress);
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowSeek: %s (0x%" PRIx64 ") - (DVDAddr: 0x%" PRIx64 ")",
|
||||
filename.c_str(), m_pFileSystem->GetFileSize(filename), DVDAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(WII_IPC_DVD, "Filesystem is invalid.");
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowReadDvd:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvd");
|
||||
break;
|
||||
|
||||
case DVDLowReadDvdConfig:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowReadDvdConfig");
|
||||
break;
|
||||
|
||||
case DVDLowStopLaser:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowStopLaser");
|
||||
break;
|
||||
|
||||
case DVDLowOffset:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowOffset");
|
||||
break;
|
||||
|
||||
case DVDLowReadDiskBca:
|
||||
WARN_LOG(WII_IPC_DVD, "DVDLowReadDiskBca");
|
||||
Memory::Write_U32(1, _BufferOut + 0x30);
|
||||
break;
|
||||
|
||||
case DVDLowRequestDiscStatus:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowRequestDiscStatus");
|
||||
break;
|
||||
|
||||
case DVDLowRequestRetryNumber:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowRequestRetryNumber");
|
||||
break;
|
||||
|
||||
case DVDLowSetMaximumRotation:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowSetMaximumRotation");
|
||||
break;
|
||||
|
||||
case DVDLowSerMeasControl:
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowSerMeasControl");
|
||||
break;
|
||||
|
||||
case DVDLowRequestError:
|
||||
// Identical to the error codes found in yagcd section 5.7.3.5.1 (so far)
|
||||
WARN_LOG(WII_IPC_DVD, "DVDLowRequestError status = 0x%08x", m_ErrorStatus);
|
||||
Memory::Write_U32(m_ErrorStatus, _BufferOut);
|
||||
// When does error status get reset?
|
||||
break;
|
||||
|
||||
// Ex commands are immediate and respond with 4 bytes
|
||||
case DVDLowStopMotor:
|
||||
{
|
||||
u32 eject = Memory::Read_U32(_BufferIn + 4);
|
||||
// Drive won't do anything till reset is issued. I think it replies like nothing is wrong though?
|
||||
u32 kill = Memory::Read_U32(_BufferIn + 8);
|
||||
|
||||
INFO_LOG(WII_IPC_DVD, "DVDLowStopMotor %s %s",
|
||||
eject ? "eject" : "", kill ? "kill!" : "");
|
||||
|
||||
if (eject)
|
||||
{
|
||||
SetLidOpen(true);
|
||||
SetDiscInside(false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DVDLowAudioBufferConfig:
|
||||
/*
|
||||
For more information: http://www.crazynation.org/GC/GC_DD_TECH/GCTech.htm
|
||||
|
||||
Upon Power up or reset , 2 commands must be issued for proper use of audio streaming:
|
||||
DVDReadDiskID A8000040,00000000,00000020
|
||||
DVDLowAudioBufferConfig E4xx00yy,00000000,00000020
|
||||
|
||||
xx=byte 8 [0 or 1] from the disk header retrieved from DVDReadDiskID
|
||||
yy=0 (if xx=0) or 0xA (if xx=1)
|
||||
*/
|
||||
ERROR_LOG(WII_IPC_DVD, "DVDLowAudioBufferConfig");
|
||||
break;
|
||||
|
||||
// New Super Mario Bros.Wii sends these cmds
|
||||
// but it seems we don't need to implement anything
|
||||
case 0x95:
|
||||
case 0x96:
|
||||
WARN_LOG(WII_IPC_DVD, "Unimplemented command 0x%08x (Buffer 0x%08x, 0x%x)",
|
||||
Command, _BufferOut, _BufferOutSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(WII_IPC_DVD, "Unknown command 0x%08x (Buffer 0x%08x, 0x%x)",
|
||||
Command, _BufferOut, _BufferOutSize);
|
||||
|
||||
PanicAlertT("Unknown command 0x%08x", Command);
|
||||
break;
|
||||
}
|
||||
|
||||
// i dunno but prolly 1 is okay all the time :)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CWII_IPC_HLE_Device_di::GetCmdDelay(u32 _CommandAddress)
|
||||
{
|
||||
u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
|
||||
|
||||
@@ -27,13 +27,4 @@ public:
|
||||
bool IOCtlV(u32 _CommandAddress) override;
|
||||
|
||||
int GetCmdDelay(u32) override;
|
||||
|
||||
private:
|
||||
|
||||
u32 ExecuteCommand(u32 BufferIn, u32 BufferInSize, u32 _BufferOut, u32 BufferOutSize);
|
||||
|
||||
DiscIO::IFileSystem* m_pFileSystem;
|
||||
u32 m_ErrorStatus;
|
||||
// This flag seems to only be reset with poweron/off, not sure
|
||||
u32 m_CoverStatus;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user