diff --git a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp index dbd3673586..bfdb70dd7e 100644 --- a/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp +++ b/Source/Core/Core/Src/Boot/Boot_BIOSEmu.cpp @@ -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; } - diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp index 446fe9e617..cc44cfcf0c 100644 --- a/Source/Core/Core/Src/CoreParameter.cpp +++ b/Source/Core/Core/Src/CoreParameter.cpp @@ -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; } diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h index ed21630e8a..1011ed359c 100644 --- a/Source/Core/Core/Src/CoreParameter.h +++ b/Source/Core/Core/Src/CoreParameter.h @@ -71,7 +71,6 @@ struct SCoreStartupParameter bool bRunCompareClient; int iTLBHack; - bool bFix002; int SelectedLanguage; diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp index 906b0c5e18..c242a3e079 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.cpp @@ -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 diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h index f97e94e55a..378e5e1bb8 100644 --- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h +++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_DI.h @@ -45,6 +45,7 @@ private: DiscIO::IVolume* m_pVolume; DiscIO::IFileSystem* m_pFileSystem; + u32 m_ErrorStatus; }; #endif diff --git a/Source/Core/Core/Src/VolumeHandler.cpp b/Source/Core/Core/Src/VolumeHandler.cpp index 11b717807c..69052dc7bd 100644 --- a/Source/Core/Core/Src/VolumeHandler.cpp +++ b/Source/Core/Core/Src/VolumeHandler.cpp @@ -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 diff --git a/Source/Core/Core/Src/VolumeHandler.h b/Source/Core/Core/Src/VolumeHandler.h index 9f58917407..478ebcf90e 100644 --- a/Source/Core/Core/Src/VolumeHandler.h +++ b/Source/Core/Core/Src/VolumeHandler.h @@ -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(); diff --git a/Source/Core/DolphinWX/Src/BootManager.cpp b/Source/Core/DolphinWX/Src/BootManager.cpp index f5cdbc66d2..3ea75aae0d 100644 --- a/Source/Core/DolphinWX/Src/BootManager.cpp +++ b/Source/Core/DolphinWX/Src/BootManager.cpp @@ -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 diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp index 61c4d6bcdb..632fee18bd 100644 --- a/Source/Core/DolphinWX/Src/FrameTools.cpp +++ b/Source/Core/DolphinWX/Src/FrameTools.cpp @@ -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()); }