diff --git a/pcsx2/DebugTools/BiosDebugData.cpp b/pcsx2/DebugTools/BiosDebugData.cpp index 8d240e6a1a..b0f381290d 100644 --- a/pcsx2/DebugTools/BiosDebugData.cpp +++ b/pcsx2/DebugTools/BiosDebugData.cpp @@ -21,10 +21,11 @@ std::vector getEEThreads() { std::vector threads; - if (CurrentBiosInformation == NULL) + if (CurrentBiosInformation.threadListAddr <= 0) return threads; - u32 start = CurrentBiosInformation->threadListAddr & 0x3fffff; + const u32 start = CurrentBiosInformation.threadListAddr & 0x3fffff; + for (int tid = 0; tid < 256; tid++) { EEThread thread; @@ -40,4 +41,3 @@ std::vector getEEThreads() return threads; } - diff --git a/pcsx2/R5900OpcodeImpl.cpp b/pcsx2/R5900OpcodeImpl.cpp index 53cb2533ac..4bf4c1e801 100644 --- a/pcsx2/R5900OpcodeImpl.cpp +++ b/pcsx2/R5900OpcodeImpl.cpp @@ -982,8 +982,43 @@ void SYSCALL() case Syscall::SetVTLBRefillHandler: DevCon.Warning("A tlb refill handler is set. New handler %x", (u32*)PSM(cpuRegs.GPR.n.a1.UL[0])); break; + case Syscall::StartThread: + case Syscall::ChangeThreadPriority: + { + if (CurrentBiosInformation.threadListAddr == 0) + { + u32 offset = 0x0; + // Suprisingly not that slow :) + while (offset < 0x5000) // I find that the instructions are in between 0x4000 -> 0x5000 + { + u32 addr = 0x80000000 + offset; + const u32 inst1 = memRead32(addr); + const u32 inst2 = memRead32(addr += 4); + const u32 inst3 = memRead32(addr += 4); - + if (ThreadListInstructions[0] == inst1 && // sw v0,0x0(v0) + ThreadListInstructions[1] == inst2 && // no-op + ThreadListInstructions[2] == inst3) // no-op + { + // We've found the instruction pattern! + // We (well, I) know that the thread address is always 0x8001 + the immediate of the 6th instruction from here + const u32 op = memRead32(0x80000000 + offset + (sizeof(u32) * 6)); + CurrentBiosInformation.threadListAddr = 0x80010000 + static_cast(op) - 8; // Subtract 8 because the address here is offset by 8. + DevCon.WriteLn("BIOS: Successfully found the instruction pattern. Assuming the thread list is here: %0x", CurrentBiosInformation.threadListAddr); + break; + } + offset += 4; + } + if (!CurrentBiosInformation.threadListAddr) + { + // We couldn't find the address + CurrentBiosInformation.threadListAddr = -1; + // If you're here because a user has reported this message, this means that the instruction pattern is not present on their bios, or it is aligned weirdly. + Console.Warning("BIOS Warning: Unable to get a thread list offset. The debugger thread and stack frame views will not be functional."); + } + } + } + break; case Syscall::sceSifSetDma: // The only thing this code is used for is the one log message, so don't execute it if we aren't logging bios messages. if (SysTraceActive(EE.Bios)) diff --git a/pcsx2/R5900OpcodeTables.h b/pcsx2/R5900OpcodeTables.h index 35c0e8b35e..eb46577853 100644 --- a/pcsx2/R5900OpcodeTables.h +++ b/pcsx2/R5900OpcodeTables.h @@ -21,6 +21,8 @@ enum Syscall : u8 { SetGsCrt = 2, SetVTLBRefillHandler = 13, + StartThread = 34, + ChangeThreadPriority = 41, GetOsdConfigParam = 75, GetOsdConfigParam2 = 111, sysPrintOut = 117, diff --git a/pcsx2/ps2/BiosTools.cpp b/pcsx2/ps2/BiosTools.cpp index 08074cfc20..a72d10a5c5 100644 --- a/pcsx2/ps2/BiosTools.cpp +++ b/pcsx2/ps2/BiosTools.cpp @@ -54,57 +54,7 @@ u32 BiosChecksum; u32 BiosRegion; bool NoOSD; wxString BiosDescription; -const BiosDebugInformation* CurrentBiosInformation; - -const BiosDebugInformation biosVersions[] = { - // Notes: The SCPH versions have not been verified - - // USA v02.00(14/06/2004) SCPH70012 - { 0x00000200, 0xD778DB8D, 0x8001A640 }, - // USA v01.60(19/03/2002) SCPH39004 - { 0x0000013C, 0x0B51A16F, 0x8001A280 }, - // USA v01.60(07/02/2002) SCPH39001 - { 0x0000013C, 0x3A75B059, 0x8001A480 }, - // Europe v02.20(10/02/2006) SCPH77008 - { 0x00000214, 0xD7EDD771, 0x8001AC00 }, - // Europe v02.20(20/06/2005) SCPH75004 - { 0x00000214, 0x0E9C22D3, 0x8001AC00 }, - // Europe v02.00(16/06/2004) SCPH70008 - { 0x00000200, 0x3C6AA4F4, 0x8001A640 }, - // Europe v02.00(14/06/2004) SCPH70004 - { 0x00000200, 0x9C7B59D3, 0x8001A640 }, - { 0x00000200, 0x8C7B49D3, 0x8001A640 }, // Russian variant - // Europe v02.00(04/11/2004) SCPH50003 - { 0x00000200, 0xBDE56F8E, 0x8001A580 }, - // Europe v01.90(23/06/2003) SCPH50004 - { 0x0000015A, 0xE36776DC, 0x8001A640 }, - // Europe v01.70(27/02/2003) SCPH50004 - { 0x00000146 ,0x4954F4A2, 0x8001A640 }, - // Europe v01.60(19/03/2002) SCPH39004 - { 0x0000013C, 0xFA3F9E90, 0x8001A280 }, - // Europe v01.60(04/10/2001) SCPH30004 - { 0x0000013C, 0xB8E26E89, 0x8001A580 }, - // Europe v01.60(04/10/2001) SCPH30004R - { 0x0000013C, 0xEC9058f6, 0x8001A580 }, - // Europe v01.20(02/09/2000) SCPH30003 - { 0x00000114, 0xCF83F17A, 0x80017B40 }, - // Japan v02.20(05/09/2006) SCPH90006 - { 0x00000214, 0x098047D7, 0x8001AC00 }, - // Japan v02.20(20/06/2005) SCPH75004 - { 0x00000214, 0x0E9C22DC, 0x8001AC00 }, - // Japan v02.00(14/06/2004) SCPH70000 - { 0x00000200, 0xC9B61306, 0x8001A640 }, - // Japan v01.70(06/02/2003) SCPH50000 - { 0x00000146, 0x71C7C144, 0x8001A640 }, - // Japan v01.50(18/01/2001) SCPH30000 - { 0x00000132, 0x4FA83C78, 0x80019A00 }, - // Japan v01.00(17/01/2000) SCPH10000 - { 0x00000100, 0x22B99C77, 0x80017400 }, - // China v01.90(23/06/2003) SCPH50009 - { 0x0000015A, 0xE9D87F1F, 0x8001A640 }, - // HK v02.00(14/06/2004) SCPH70006 - { 0x00000200, 0x2E5D0C98, 0x8001A640 } -}; +BiosDebugInformation CurrentBiosInformation; // -------------------------------------------------------------------------------------- // Exception::BiosLoadFailed (implementations) @@ -354,18 +304,7 @@ void LoadBIOS() if (g_Conf->CurrentIRX.Length() > 3) LoadIrx(g_Conf->CurrentIRX, &eeMem->ROM[0x3C0000]); - CurrentBiosInformation = NULL; - for (size_t i = 0; i < sizeof(biosVersions)/sizeof(biosVersions[0]); i++) - { - if (biosVersions[i].biosChecksum == BiosChecksum && biosVersions[i].biosVersion == BiosVersion) - { - CurrentBiosInformation = &biosVersions[i]; - break; - } - } - - if (CurrentBiosInformation == NULL) - Console.Warning("BIOS Warning: Unknown BIOS version. The debugger thread and stack frame views will not be functional."); + CurrentBiosInformation.threadListAddr = 0; } catch (Exception::BadStream& ex) { diff --git a/pcsx2/ps2/BiosTools.h b/pcsx2/ps2/BiosTools.h index cac9251a16..a2f374bc9b 100644 --- a/pcsx2/ps2/BiosTools.h +++ b/pcsx2/ps2/BiosTools.h @@ -28,19 +28,23 @@ namespace Exception }; } +const u32 ThreadListInstructions[3] = +{ + 0xac420000, // sw v0,0x0(v0) + 0x00000000, // no-op + 0x00000000, // no-op +}; + struct BiosDebugInformation { - u32 biosVersion; - u32 biosChecksum; u32 threadListAddr; }; +extern BiosDebugInformation CurrentBiosInformation; extern u32 BiosVersion; // Used by CDVD extern u32 BiosRegion; // Used by CDVD extern bool NoOSD; // Used for HLE OSD Config Params extern u32 BiosChecksum; extern wxString BiosDescription; -extern const BiosDebugInformation* CurrentBiosInformation; - extern void LoadBIOS(); extern bool IsBIOS(const wxString& filename, wxString& description);