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:
parent
ae41086ec8
commit
989f4fb6da
|
@ -42,30 +42,6 @@ void CBoot::RunFunction(u32 _iAddr)
|
||||||
PowerPC::SingleStep();
|
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:
|
// GameCube BIOS HLE:
|
||||||
|
@ -271,7 +247,22 @@ bool CBoot::SetupWiiMemory(unsigned int _CountryCode)
|
||||||
Memory::Write_U32(0x93ae0000, 0x00003130); // IOS MEM2 low
|
Memory::Write_U32(0x93ae0000, 0x00003130); // IOS MEM2 low
|
||||||
Memory::Write_U32(0x93b00000, 0x00003134); // IOS MEM2 high
|
Memory::Write_U32(0x93b00000, 0x00003134); // IOS MEM2 high
|
||||||
Memory::Write_U32(0x00000011, 0x00003138); // Console type
|
Memory::Write_U32(0x00000011, 0x00003138); // Console type
|
||||||
Memory::Write_U64(0x0009020400062507ULL, 0x00003140); // IOS Version
|
|
||||||
|
// 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_U16(0x0113, 0x0000315e); // Apploader
|
||||||
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
|
Memory::Write_U32(0x0000FF16, 0x00003158); // DDR ram vendor code
|
||||||
|
|
||||||
|
@ -396,14 +387,5 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
|
||||||
|
|
||||||
PowerPC::ppcState.DebugCount = 0;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ void SCoreStartupParameter::LoadDefaults()
|
||||||
bDSPThread = true;
|
bDSPThread = true;
|
||||||
bLockThreads = true;
|
bLockThreads = true;
|
||||||
bWii = false;
|
bWii = false;
|
||||||
bFix002 = false;
|
|
||||||
SelectedLanguage = 0;
|
SelectedLanguage = 0;
|
||||||
iTLBHack = 0;
|
iTLBHack = 0;
|
||||||
delete gameIni;
|
delete gameIni;
|
||||||
|
@ -196,11 +195,11 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
|
||||||
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, Region, false);
|
CheckMemcardPath(SConfig::GetInstance().m_strMemoryCardB, Region, false);
|
||||||
m_strSRAM = GC_SRAM_FILE;
|
m_strSRAM = GC_SRAM_FILE;
|
||||||
m_strBios = FULL_GC_SYS_DIR + Region + DIR_SEP GC_IPL;
|
m_strBios = FULL_GC_SYS_DIR + Region + DIR_SEP GC_IPL;
|
||||||
//if (!File::Exists(m_strBios.c_str())) {
|
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());
|
//WARN_LOG(BOOT, "BIOS file %s not found - using HLE.", m_strBios.c_str());
|
||||||
// We always HLE the boot.
|
|
||||||
bHLEBios = true;
|
bHLEBios = true;
|
||||||
//}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@ struct SCoreStartupParameter
|
||||||
bool bRunCompareClient;
|
bool bRunCompareClient;
|
||||||
|
|
||||||
int iTLBHack;
|
int iTLBHack;
|
||||||
bool bFix002;
|
|
||||||
|
|
||||||
int SelectedLanguage;
|
int SelectedLanguage;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
|
||||||
, m_pVolume(NULL)
|
, m_pVolume(NULL)
|
||||||
, m_pFileSystem(NULL)
|
, m_pFileSystem(NULL)
|
||||||
|
, m_ErrorStatus(0)
|
||||||
{
|
{
|
||||||
m_pVolume = VolumeHandler::GetVolume();
|
m_pVolume = VolumeHandler::GetVolume();
|
||||||
if (m_pVolume)
|
if (m_pVolume)
|
||||||
|
@ -87,6 +88,9 @@ bool CWII_IPC_HLE_Device_di::IOCtl(u32 _CommandAddress)
|
||||||
DEBUG_LOG(WII_IPC_DVD, "%s - Command(0x%08x) BufferIn(0x%08x, 0x%x) BufferOut(0x%08x, 0x%x)",
|
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);
|
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);
|
u32 ReturnValue = ExecuteCommand(BufferIn, BufferInSize, BufferOut, BufferOutSize);
|
||||||
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
Memory::Write_U32(ReturnValue, _CommandAddress + 0x4);
|
||||||
|
|
||||||
|
@ -123,19 +127,12 @@ bool CWII_IPC_HLE_Device_di::IOCtlV(u32 _CommandAddress)
|
||||||
|
|
||||||
bool readOK = false;
|
bool readOK = false;
|
||||||
|
|
||||||
// Get the info table
|
u64 TMDOffset = 0;
|
||||||
u8 pInfoTableOffset[4];
|
readOK |= VolumeHandler::GetTMDOffset(partition, TMDOffset);
|
||||||
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;
|
|
||||||
|
|
||||||
// Read TMD to the buffer
|
// Read TMD to the buffer
|
||||||
readOK |= VolumeHandler::RAWReadToPtr(Memory::GetPointer(CommandBuffer.PayloadBuffer[0].m_Address),
|
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
|
// 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);
|
VolumeHandler::RAWReadToPtr(Memory::GetPointer(_BufferOut), 0, _BufferOutSize);
|
||||||
|
|
||||||
DEBUG_LOG(WII_IPC_DVD, "%s executes DVDLowReadDiskID 0x%08x",
|
DEBUG_LOG(WII_IPC_DVD, "DVDLowReadDiskID %s",
|
||||||
GetDeviceName().c_str(), Memory::Read_U64(_BufferOut));
|
ArrayToString(Memory::GetPointer(_BufferOut), _BufferOutSize, 0, _BufferOutSize).c_str());
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -234,7 +231,7 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
INFO_LOG(WII_IPC_DVD, " DVDLowRead: file unkw - (DVDAddr: 0x%x, Size: 0x%x)",
|
INFO_LOG(WII_IPC_DVD, " DVDLowRead: file unkw - (DVDAddr: 0x%x, Size: 0x%x)",
|
||||||
GetDeviceName().c_str(), DVDAddress, Size);
|
DVDAddress, Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Size > _BufferOutSize)
|
if (Size > _BufferOutSize)
|
||||||
|
@ -357,15 +354,37 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
||||||
|
|
||||||
// DVDLowUnencryptedRead
|
// DVDLowUnencryptedRead
|
||||||
case 0x8d:
|
case 0x8d:
|
||||||
DEBUG_LOG(WII_IPC_DVD, "DVDLowUnencryptedRead");
|
|
||||||
{
|
{
|
||||||
if (_BufferOut == 0)
|
if (_BufferOut == 0)
|
||||||
{
|
{
|
||||||
PanicAlert("DVDLowRead : _BufferOut == 0");
|
PanicAlert("DVDLowRead : _BufferOut == 0");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Size = Memory::Read_U32(_BufferIn + 0x04);
|
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)
|
if (Size > _BufferOutSize)
|
||||||
{
|
{
|
||||||
|
@ -389,7 +408,10 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
||||||
|
|
||||||
// DVDLowReportKey
|
// DVDLowReportKey
|
||||||
case 0xa4:
|
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;
|
break;
|
||||||
|
|
||||||
// DVDLowSeek
|
// DVDLowSeek
|
||||||
|
@ -446,7 +468,8 @@ u32 CWII_IPC_HLE_Device_di::ExecuteCommand(u32 _BufferIn, u32 _BufferInSize, u32
|
||||||
// DVDLowRequestError
|
// DVDLowRequestError
|
||||||
case 0xe0:
|
case 0xe0:
|
||||||
// Identical to the error codes found in yagcd section 5.7.3.5.1 (so far)
|
// 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;
|
break;
|
||||||
|
|
||||||
// Ex commands are immediate and respond with 4 bytes
|
// Ex commands are immediate and respond with 4 bytes
|
||||||
|
|
|
@ -45,6 +45,7 @@ private:
|
||||||
|
|
||||||
DiscIO::IVolume* m_pVolume;
|
DiscIO::IVolume* m_pVolume;
|
||||||
DiscIO::IFileSystem* m_pFileSystem;
|
DiscIO::IFileSystem* m_pFileSystem;
|
||||||
|
u32 m_ErrorStatus;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,4 +101,27 @@ bool IsWii()
|
||||||
return false;
|
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
|
} // namespace
|
||||||
|
|
|
@ -35,6 +35,8 @@ u32 Read32(u64 _Offset);
|
||||||
bool ReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
|
bool ReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
|
||||||
bool RAWReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
|
bool RAWReadToPtr(u8* ptr, u64 _dwOffset, u64 _dwLength);
|
||||||
|
|
||||||
|
bool GetTMDOffset(u32 _Partition, u64& _Offset);
|
||||||
|
|
||||||
bool IsValid();
|
bool IsValid();
|
||||||
bool IsWii();
|
bool IsWii();
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,6 @@ bool BootCore(const std::string& _rFilename)
|
||||||
ini->Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
|
ini->Get("Core", "SkipIdle", &StartUp.bSkipIdle, StartUp.bSkipIdle);
|
||||||
ini->Get("Core", "OptimizeQuantizers", &StartUp.bOptimizeQuantizers, StartUp.bOptimizeQuantizers);
|
ini->Get("Core", "OptimizeQuantizers", &StartUp.bOptimizeQuantizers, StartUp.bOptimizeQuantizers);
|
||||||
ini->Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
ini->Get("Core", "TLBHack", &StartUp.iTLBHack, StartUp.iTLBHack);
|
||||||
ini->Get("Core", "Fix002", &StartUp.bFix002, false);
|
|
||||||
|
|
||||||
// ------------------------------------------------
|
// ------------------------------------------------
|
||||||
// Wii settings
|
// Wii settings
|
||||||
|
|
|
@ -476,19 +476,6 @@ void CFrame::DoOpen(bool Boot)
|
||||||
// Yes it is a valid ISO file
|
// Yes it is a valid ISO file
|
||||||
else
|
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
|
// Save the new ISO file name
|
||||||
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strFilename = std::string(path.ToAscii());
|
SConfig::GetInstance().m_LocalCoreStartupParameter.m_strFilename = std::string(path.ToAscii());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue