@@ -1984,37 +1984,17 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
19841984bool __KernelLoadGEDump (const std::string &base_filename, std::string *error_string) {
19851985 __KernelLoadReset ();
19861986
1987- mipsr4k.pc = PSP_GetUserMemoryBase ();
1988-
1989- const static u32_le runDumpCode[] = {
1990- // Save the filename.
1991- MIPS_MAKE_ORI (MIPS_REG_S0, MIPS_REG_A0, 0 ),
1992- MIPS_MAKE_ORI (MIPS_REG_S1, MIPS_REG_A1, 0 ),
1993- // Call the actual render.
1994- MIPS_MAKE_SYSCALL (" FakeSysCalls" , " __KernelGPUReplay" ),
1995- // Make sure we don't get out of sync.
1996- MIPS_MAKE_LUI (MIPS_REG_A0, 0 ),
1997- MIPS_MAKE_SYSCALL (" sceGe_user" , " sceGeDrawSync" ),
1998- // Set the return address after the entry which saved the filename.
1999- MIPS_MAKE_LUI (MIPS_REG_RA, mipsr4k.pc >> 16 ),
2000- MIPS_MAKE_ADDIU (MIPS_REG_RA, MIPS_REG_RA, 8 ),
2001- // Wait for the next vblank to render again.
2002- MIPS_MAKE_JR_RA (),
2003- MIPS_MAKE_SYSCALL (" sceDisplay" , " sceDisplayWaitVblankStart" ),
2004- // This never gets reached, just here to be safe.
2005- MIPS_MAKE_BREAK (0 ),
2006- };
1987+ const u32 codeStartAddr = PSP_GetUserMemoryBase ();
1988+ mipsr4k.pc = codeStartAddr;
20071989
2008- for (size_t i = 0 ; i < ARRAY_SIZE (runDumpCode); ++i) {
2009- Memory::WriteUnchecked_U32 (runDumpCode[i], mipsr4k.pc + (u32 )i * sizeof (u32_le));
2010- }
1990+ GPURecord::WriteRunDumpCode (codeStartAddr);
20111991
20121992 PSPModule *module = new PSPModule ();
20131993 kernelObjects.Create (module );
20141994 loadedModules.insert (module ->GetUID ());
20151995 memset (&module ->nm , 0 , sizeof (module ->nm ));
20161996 module ->isFake = true ;
2017- module ->nm .entry_addr = mipsr4k. pc ;
1997+ module ->nm .entry_addr = codeStartAddr ;
20181998 module ->nm .gp_value = -1 ;
20191999
20202000 SceUID threadID = __KernelSetupRootThread (module ->GetUID (), (int )base_filename.size (), base_filename.data (), 0x20 , 0x1000 , 0 );
@@ -2024,17 +2004,20 @@ bool __KernelLoadGEDump(const std::string &base_filename, std::string *error_str
20242004 return true ;
20252005}
20262006
2027- void __KernelGPUReplay () {
2007+ int __KernelGPUReplay () {
20282008 // Special ABI: s0 and s1 are the "args". Not null terminated.
20292009 const char *filenamep = Memory::GetCharPointer (currentMIPS->r [MIPS_REG_S1]);
20302010 if (!filenamep) {
2031- ERROR_LOG (Log::G3D, " Failed to load dump filename" );
2011+ ERROR_LOG (Log::G3D, " __KernelGPUReplay: Failed to load dump filename" );
20322012 Core_Stop ();
2033- return ;
2013+ return 0 ;
20342014 }
20352015
20362016 std::string filename (filenamep, currentMIPS->r [MIPS_REG_S0]);
2037- if (!GPURecord::RunMountedReplay (filename)) {
2017+ GPURecord::ReplayResult result = GPURecord::RunMountedReplay (filename);
2018+
2019+ if (result == GPURecord::ReplayResult::Error) {
2020+ ERROR_LOG (Log::G3D, " __KernelGPUReplay: Failed running replay." );
20382021 Core_Stop ();
20392022 }
20402023
@@ -2045,6 +2028,9 @@ void __KernelGPUReplay() {
20452028 System_SendDebugScreenshot (std::string ((const char *)&topaddr[0 ], linesize * 272 ), 272 );
20462029 Core_Stop ();
20472030 }
2031+
2032+ // Return 0 for normal looping, 1 for break.
2033+ return result == GPURecord::ReplayResult::Break ? 1 : 0 ;
20482034}
20492035
20502036int sceKernelLoadExec (const char *filename, u32 paramPtr)
0 commit comments