Try to pass the wii "001" and "002" checks correctly

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3094 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Shawn Hoffman 2009-04-27 16:57:12 +00:00
parent ae41086ec8
commit 989f4fb6da
9 changed files with 94 additions and 79 deletions

View File

@ -42,30 +42,6 @@ void CBoot::RunFunction(u32 _iAddr)
PowerPC::SingleStep();
}
// THIS IS UGLY. this should be figured out properly instead of patching the games.
bool Remove_002_Protection(u32 addr, int Size)
{
u32 SearchPattern[3] = { 0x2C000000, 0x40820214, 0x3C608000 };
u32 PatchData[3] = { 0x2C000000, 0x48000214, 0x3C608000 };
while (Size >= 12)
{
if (Memory::ReadUnchecked_U32(addr + 0) == SearchPattern[0] &&
Memory::ReadUnchecked_U32(addr + 4) == SearchPattern[1] &&
Memory::ReadUnchecked_U32(addr + 8) == SearchPattern[2])
{
Memory::WriteUnchecked_U32(PatchData[0], addr);
Memory::WriteUnchecked_U32(PatchData[1], addr + 4);
Memory::WriteUnchecked_U32(PatchData[2], addr + 8);
return true;
}
addr += 4;
Size -= 4;
}
return false;
}
// __________________________________________________________________________________________________
//
// GameCube BIOS HLE:
@ -271,8 +247,23 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
Memory::Write_U32(0x93ae0000, 0x00003130); // IOS MEM2 low
Memory::Write_U32(0x93b00000, 0x00003134); // IOS MEM2 high
Memory::Write_U32(0x00000011, 0x00003138); // Console type
Memory::Write_U64(0x0009020400062507ULL, 0x00003140); // IOS Version
Memory::Write_U16(0x0113, 0x0000315e); // Apploader
// Pass the "#002 check"
u64 TMDOffset = 0;
if (VolumeHandler::GetTMDOffset(1, TMDOffset))
{
// IOS Version from TMD
VolumeHandler::RAWReadToPtr(Memory::GetPointer(0x00003141), TMDOffset + 0x18B, 1);
Memory::Write_U16(0xffff, 0x00003142); // IOS revision
Memory::Write_U32(0x00062507, 0x00003144); // ???
}
else
{
// Use fake IOS Version
Memory::Write_U64(0x0009020400062507ULL, 0x00003140);
}
Memory::Write_U16(0x0113, 0x0000315e); // Apploader
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
Memory::Write_U8(0x80, 0x0000315c); // OSInit
@ -396,14 +387,5 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
PowerPC::ppcState.DebugCount = 0;
if (Core::GetStartupParameter().bFix002)
{
// UGLY UGLY UGLY
// TODO: Understand what this does and fix it properly..
// This "fixes" games that display "Error 002" instead of running.
Remove_002_Protection(0x80004000, 0x5000000);
}
return true;
}

View File

@ -44,7 +44,6 @@ void SCoreStartupParameter::LoadDefaults()
bDSPThread = true;
bLockThreads = true;
bWii = false;
bFix002 = false;
SelectedLanguage = 0;
iTLBHack = 0;
delete gameIni;
@ -196,11 +195,11 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, Region, false);
m_strSRAM = GC_SRAM_FILE;
m_strBios = FULL_GC_SYS_DIR + Region + DIR_SEP GC_IPL;
//if (!File::Exists(m_strBios.c_str())) {
// WARN_LOG(BOOT, "BIOS file %s not found - using HLE.", m_strBios.c_str());
// We always HLE the boot.
if (!File::Exists(m_strBios.c_str()) || SConfig::GetInstance().m_LocalCoreStartupParameter.bHLEBios)
{
//WARN_LOG(BOOT, "BIOS file %s not found - using HLE.", m_strBios.c_str());
bHLEBios = true;
//}
}
return true;
}

View File

@ -71,7 +71,6 @@ struct SCoreStartupParameter
bool bRunCompareClient;
int iTLBHack;
bool bFix002;
int SelectedLanguage;

View File

@ -40,6 +40,7 @@ CWII_IPC_HLE_Device_di::CWII_IPC_HLE_Device_di(u32 _DeviceID, const std::string&
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_pVolume(NULL)
, m_pFileSystem(NULL)
, m_ErrorStatus(0)
{
m_pVolume = VolumeHandler::GetVolume();
if (m_pVolume)
@ -61,13 +62,13 @@ CWII_IPC_HLE_Device_di::~CWII_IPC_HLE_Device_di()
bool CWII_IPC_HLE_Device_di::Open(u32 _CommandAddress, u32 _Mode)
{
Memory::Write_U32(GetDeviceID(), _CommandAddress+4);
Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
return true;
}
bool CWII_IPC_HLE_Device_di::Close(u32 _CommandAddress)
{
Memory::Write_U32(0, _CommandAddress+4);
Memory::Write_U32(0, _CommandAddress + 4);
return true;
}
@ -78,15 +79,18 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
INFO_LOG(WII_IPC_DVD, "*******************************");
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 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;
DEBUG_LOG(WII_IPC_DVD, "%s - Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)",
GetDeviceName().c_str(), Command, BufferIn, BufferInSize, BufferOut, BufferOutSize);
if (Command == 0x7a)
DumpCommands(_CommandAddress, 8, LogTypes::WII_IPC_DVD, LogTypes::LWARNING);
u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize);
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
@ -123,19 +127,12 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
bool readOK = false;
// Get the info table
u8 pInfoTableOffset[4];
readOK |= VolumeHandler::RAWReadToPtr(pInfoTableOffset, 0x40004, 4);
u64 InfoTableOffset = (u32)(pInfoTableOffset[3] | pInfoTableOffset[2] << 8 | pInfoTableOffset[1] << 16 | pInfoTableOffset[0] << 24) << 2;
// Get the offset of the partition
u8 pInfoTableEntryOffset[4];
readOK |= VolumeHandler::RAWReadToPtr(pInfoTableEntryOffset, InfoTableOffset + (partition << 2) + 4, 4);
u64 PartitionOffset = (u32)(pInfoTableEntryOffset[3] | pInfoTableEntryOffset[2] << 8 | pInfoTableEntryOffset[1] << 16 | pInfoTableEntryOffset[0] << 24) << 2;
u64 TMDOffset = 0;
readOK |= VolumeHandler::GetTMDOffset(partition, TMDOffset);
// Read TMD to the buffer
readOK |= VolumeHandler::RAWReadToPtr(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address),
PartitionOffset + 0x2c0, CommandBuffer.PayloadBuffer[0].m_Size);
TMDOffset, CommandBuffer.PayloadBuffer[0].m_Size);
// Second outbuffer is error, we can ignore it
@ -207,8 +204,8 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
{
VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), 0, _BufferOutSize);
DEBUG_LOG(WII_IPC_DVD, "%s executes DVDLowReadDiskID 0x%08x",
GetDeviceName().c_str(), Memory::Read_U64(_BufferOut));
DEBUG_LOG(WII_IPC_DVD, "DVDLowReadDiskID %s",
ArrayToString(Memory::GetPointer(_BufferOut), _BufferOutSize, 0, _BufferOutSize).c_str());
return 1;
}
@ -234,7 +231,7 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
else
{
INFO_LOG(WII_IPC_DVD, " DVDLowRead: file unkw - (DVDAddr: 0x%x, Size: 0x%x)",
GetDeviceName().c_str(), DVDAddress, Size);
DVDAddress, Size);
}
if (Size > _BufferOutSize)
@ -357,15 +354,37 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
// DVDLowUnencryptedRead
case 0x8d:
DEBUG_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead");
{
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;
// 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)
))
{
INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: trying to read out of bounds @ %x", DVDAddress32);
m_ErrorStatus = 0x52100; // Logical block address out of range
// Should cause software to call DVDLowRequestError
return 2;
}
u64 DVDAddress = (u64)(DVDAddress32 << 2);
INFO_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead: DVDAddr: 0x%08x, Size: 0x%x", DVDAddress, Size);
if (Size > _BufferOutSize)
{
@ -389,7 +408,10 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
// DVDLowReportKey
case 0xa4:
PanicAlert("DVDLowReportKey");
INFO_LOG(WII_IPC_DVD, "DVDLowReportKey");
// Does not work on commercial discs
m_ErrorStatus = 0x052000; // Invalid command operation code
return 2;
break;
// DVDLowSeek
@ -446,7 +468,8 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
// DVDLowRequestError
case 0xe0:
// Identical to the error codes found in yagcd section 5.7.3.5.1 (so far)
PanicAlert("DVDLowRequestError");
WARN_LOG(WII_IPC_DVD, "DVDLowRequestError status = 0x%08x", m_ErrorStatus);
Memory::Write_U32(m_ErrorStatus, _BufferOut);
break;
// Ex commands are immediate and respond with 4 bytes

View File

@ -45,6 +45,7 @@ private:
DiscIO::IVolume* m_pVolume;
DiscIO::IFileSystem* m_pFileSystem;
u32 m_ErrorStatus;
};
#endif

View File

@ -101,4 +101,27 @@ bool IsWii()
return false;
}
bool GetTMDOffset(u32 _Partition, u64& _Offset)
{
bool ret = false;
if (IsWii())
{
// Get the info table
u8 pInfoTableOffset[4];
ret |= RAWReadToPtr(pInfoTableOffset, 0x40004, 4);
u64 InfoTableOffset = (u32)(pInfoTableOffset[3] | pInfoTableOffset[2] << 8 | pInfoTableOffset[1] << 16 | pInfoTableOffset[0] << 24) << 2;
// Get the offset of the partition
u8 pInfoTableEntryOffset[4];
ret |= RAWReadToPtr(pInfoTableEntryOffset, InfoTableOffset + (_Partition << 2) + 4, 4);
u64 PartitionOffset = (u32)(pInfoTableEntryOffset[3] | pInfoTableEntryOffset[2] << 8 | pInfoTableEntryOffset[1] << 16 | pInfoTableEntryOffset[0] << 24) << 2;
_Offset = PartitionOffset + 0x2c0;
}
return ret;
}
} // namespace

View File

@ -35,6 +35,8 @@ u32 Read32(u64 _Offset);
bool ReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
bool RAWReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
bool GetTMDOffset(u32 _Partition, u64& _Offset);
bool IsValid();
bool IsWii();

View File

@ -135,7 +135,6 @@ bool BootCore(const std::string& _rFilename)
ini->Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
ini->Get("Core", "OptimizeQuantizers", &StartUp.bOptimizeQuantizers, StartUp.bOptimizeQuantizers);
ini->Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
ini->Get("Core", "Fix002", &StartUp.bFix002, false);
// ------------------------------------------------
// Wii settings

View File

@ -476,19 +476,6 @@ void CFrame::DoOpen(bool Boot)
// Yes it is a valid ISO file
else
{
std::string OldID = SConfig::GetInstance().m_LocalCoreStartupParameter.m_strUniqueID;
std::string NewID = VolumeHandler::GetVolume()->GetUniqueID();
// Warn the user if he's selecting a completely different game
if(OldID != NewID)
PanicAlert(
"The new game ID '%s' is not the same as the old game ID '%s'."
" It is not recommended that you change the disc to another game this way."
" It may crash your game. If you want to play another game you"
" have to Stop this game and Start a new game."
, NewID.c_str(), OldID.c_str()
);
// Save the new ISO file name
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strFilename = std::string(path.ToAscii());
}