mirror of https://github.com/PCSX2/pcsx2.git
* Fix for Issue 493 -- non-standard SYSTEM.CNF contents are handled better now.
* Some minor exception/error handling fixes and improvements. DevNote: the BOOT2 elf loader fix is still a hackfix. I documented the proper fix for mimicking PS2 BOOT2 parsing, but not in a mood to do the full proper implementation right now. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3442 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
9d5a1b44ba
commit
d36bb19612
|
@ -306,17 +306,34 @@ s32 cdvdWriteConfig(const u8* config)
|
||||||
static MutexRecursive Mutex_NewDiskCB;
|
static MutexRecursive Mutex_NewDiskCB;
|
||||||
|
|
||||||
// Sets ElfCRC to the CRC of the game bound to the CDVD plugin.
|
// Sets ElfCRC to the CRC of the game bound to the CDVD plugin.
|
||||||
static __forceinline ElfObject *loadElf( const wxString filename )
|
static __forceinline ElfObject* loadElf( const wxString filename )
|
||||||
{
|
{
|
||||||
if (filename.StartsWith(L"host"))
|
if (filename.StartsWith(L"host"))
|
||||||
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')));
|
return new ElfObject(filename.After(':'), Path::GetFileSize(filename.After(':')));
|
||||||
|
|
||||||
|
// Mimic PS2 behavior!
|
||||||
|
// Much trial-and-error with changing the ISOFS and BOOT2 contents of an image have shown that
|
||||||
|
// the PS2 BIOS performs the peculiar task of *ignoring* the version info from the parsed BOOT2
|
||||||
|
// filename *and* the ISOFS, when loading the game's ELF image. What this means is:
|
||||||
|
//
|
||||||
|
// 1. a valid PS2 ELF can have any version (ISOFS), and the version need not match the one in SYSTEM.CNF.
|
||||||
|
// 2. the version info on the file in the BOOT2 parameter of SYSTEM.CNF can be missing, 10 chars long,
|
||||||
|
// or anything else. Its all ignored.
|
||||||
|
// 3. Games loading their own files do *not* exhibit this behavior; likely due to using newer IOP modules
|
||||||
|
// or lower level filesystem APIs (fortunately that doesn't affect us).
|
||||||
|
//
|
||||||
|
// FIXME: Properly mimicing this behavior is troublesome since we need to add support for "ignoring"
|
||||||
|
// version information when doing file searches. I'll add this later. For now, assuming a ;1 should
|
||||||
|
// be sufficient (no known games have their ELF binary as anything but version ;1)
|
||||||
|
|
||||||
|
const wxString fixedname( wxStringTokenizer(filename, L';').GetNextToken() + L";1" );
|
||||||
|
|
||||||
|
if( fixedname != filename )
|
||||||
|
Console.WriteLn( Color_Blue, "(LoadELF) Non-conforming version suffix detected and replaced." );
|
||||||
|
|
||||||
IsoFSCDVD isofs;
|
IsoFSCDVD isofs;
|
||||||
IsoFile file(isofs, filename);
|
IsoFile file(isofs, filename);
|
||||||
ElfObject *elfptr;
|
return new ElfObject(filename, file);
|
||||||
|
|
||||||
elfptr = new ElfObject(filename, file);
|
|
||||||
return elfptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __forceinline void _reloadElfInfo(wxString elfpath)
|
static __forceinline void _reloadElfInfo(wxString elfpath)
|
||||||
|
@ -339,7 +356,6 @@ static __forceinline void _reloadElfInfo(wxString elfpath)
|
||||||
if (fname.Matches(L"????_???.??*"))
|
if (fname.Matches(L"????_???.??*"))
|
||||||
DiscSerial = fname(0,4) + L"-" + fname(5,3) + fname(9,2);
|
DiscSerial = fname(0,4) + L"-" + fname(5,3) + fname(9,2);
|
||||||
|
|
||||||
Console.WriteLn("Disc ID = %s", DiscSerial.ToUTF8().data());
|
|
||||||
elfptr = loadElf(elfpath);
|
elfptr = loadElf(elfpath);
|
||||||
|
|
||||||
ElfCRC = elfptr->getCRC();
|
ElfCRC = elfptr->getCRC();
|
||||||
|
@ -348,47 +364,54 @@ static __forceinline void _reloadElfInfo(wxString elfpath)
|
||||||
ElfEntry = elfptr->header.e_entry;
|
ElfEntry = elfptr->header.e_entry;
|
||||||
Console.WriteLn("Entry point = 0x%08x", ElfEntry);
|
Console.WriteLn("Entry point = 0x%08x", ElfEntry);
|
||||||
|
|
||||||
elfptr.Delete();
|
// Note: Do not load game database info here. This code is generic and called from
|
||||||
|
// BIOS key encryption as well as eeloadReplaceOSDSYS. The first is actually still executing
|
||||||
// Set the Game DataBase to the correct game based on Game Serial Code...
|
// BIOS code, and patches and cheats should not be applied yet. (they are applied when
|
||||||
if (IGameDatabase* GameDB = AppHost_GetGameDatabase()) {
|
// eeGameStarting is invoked, which is when the VM starts executing the actual game ELF
|
||||||
wxString gameSerial( SysGetDiscID() );
|
// binary).
|
||||||
wxString serialMsg;
|
|
||||||
if(!DiscSerial.IsEmpty())
|
|
||||||
serialMsg = L"serial=" + DiscSerial + L" ";
|
|
||||||
|
|
||||||
Game_Data game;
|
|
||||||
if (GameDB->findGame(game, gameSerial))
|
|
||||||
{
|
|
||||||
Console.WriteLn(L"(GameDB) Found Game! %s [CRC=%8.8x]", serialMsg.c_str(), ElfCRC );
|
|
||||||
// [TODO] Display lots of other info from the database here!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Console.Warning(L"(GameDB) Game not found! %s [CRC=%8.8x]", serialMsg.c_str(), ElfCRC );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdvdReloadElfInfo(wxString elfoverride)
|
void cdvdReloadElfInfo(wxString elfoverride)
|
||||||
{
|
{
|
||||||
if (!elfoverride.IsEmpty())
|
// called from context of executing VM code (recompilers), so we need to trap exceptions
|
||||||
|
// and route them through the VM's exception handler. (needed for non-SEH platforms, such
|
||||||
|
// as Linux/GCC)
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_reloadElfInfo(elfoverride);
|
if (!elfoverride.IsEmpty())
|
||||||
return;
|
{
|
||||||
|
_reloadElfInfo(elfoverride);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString elfpath;
|
||||||
|
u32 discType = GetPS2ElfName(elfpath);
|
||||||
|
|
||||||
|
if(discType==1)
|
||||||
|
{
|
||||||
|
// Is a PS1 disc.
|
||||||
|
if (!ENABLE_LOADING_PS1_GAMES)
|
||||||
|
Cpu->ThrowException( Exception::RuntimeError()
|
||||||
|
.SetDiagMsg(L"PSX game discs are not supported by PCSX2.")
|
||||||
|
.SetUserMsg(pxE( "Error:PsxDisc",
|
||||||
|
L"Playstation game discs are not supported by PCSX2. If you want to emulate PSX games "
|
||||||
|
L"then you'll have to download a PSX-specific emulator, such as ePSXe or PCSX.")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
//Console.Error( "Playstation1 game discs are not supported by PCSX2." );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Isn't a disc we recognize?
|
||||||
|
if(discType == 0) return;
|
||||||
|
|
||||||
|
// Recognized and PS2 (BOOT2). Good job, user.
|
||||||
|
_reloadElfInfo(elfpath);
|
||||||
}
|
}
|
||||||
|
catch (Exception::FileNotFound& e)
|
||||||
wxString elfpath;
|
{
|
||||||
u32 discType = GetPS2ElfName(elfpath);
|
pxFail( "Not in my back yard!" );
|
||||||
|
Cpu->ThrowException(e);
|
||||||
switch (discType)
|
|
||||||
{
|
|
||||||
case 2: // Is a PS2 disc.
|
|
||||||
_reloadElfInfo(elfpath);
|
|
||||||
break;
|
|
||||||
case 1: // Is a PS1 disc.
|
|
||||||
if (ENABLE_LOADING_PS1_GAMES) _reloadElfInfo(elfpath);
|
|
||||||
break;
|
|
||||||
default: // Isn't a disc we recognise.
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -434,13 +434,13 @@ int GetPS2ElfName( wxString& name )
|
||||||
|
|
||||||
while( !file.eof() )
|
while( !file.eof() )
|
||||||
{
|
{
|
||||||
wxString original( fromUTF8(file.readLine().c_str()) );
|
const wxString original( fromUTF8(file.readLine().c_str()) );
|
||||||
ParsedAssignmentString parts( original );
|
const ParsedAssignmentString parts( original );
|
||||||
|
|
||||||
if( parts.lvalue.IsEmpty() && parts.rvalue.IsEmpty() ) continue;
|
if( parts.lvalue.IsEmpty() && parts.rvalue.IsEmpty() ) continue;
|
||||||
if( parts.rvalue.IsEmpty() )
|
if( parts.rvalue.IsEmpty() )
|
||||||
{
|
{
|
||||||
Console.Error( "(GetElfName) Unusual or malformed entry in SYSTEM.CNF ignored:" );
|
Console.Warning( "(SYSTEM.CNF) Unusual or malformed entry in SYSTEM.CNF ignored:" );
|
||||||
Console.Indent().WriteLn( original );
|
Console.Indent().WriteLn( original );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -448,22 +448,22 @@ int GetPS2ElfName( wxString& name )
|
||||||
if( parts.lvalue == L"BOOT2" )
|
if( parts.lvalue == L"BOOT2" )
|
||||||
{
|
{
|
||||||
name = parts.rvalue;
|
name = parts.rvalue;
|
||||||
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Detected PS2 Disc = " + name );
|
Console.WriteLn( Color_StrongBlue, L"(SYSTEM.CNF) Detected PS2 Disc = " + name );
|
||||||
retype = 2;
|
retype = 2;
|
||||||
}
|
}
|
||||||
else if( parts.lvalue == L"BOOT" )
|
else if( parts.lvalue == L"BOOT" )
|
||||||
{
|
{
|
||||||
name = parts.rvalue;
|
name = parts.rvalue;
|
||||||
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Detected PSX/PSone Disc = " + name );
|
Console.WriteLn( Color_StrongBlue, L"(SYSTEM.CNF) Detected PSX/PSone Disc = " + name );
|
||||||
retype = 1;
|
retype = 1;
|
||||||
}
|
}
|
||||||
else if( parts.lvalue == L"VMODE" )
|
else if( parts.lvalue == L"VMODE" )
|
||||||
{
|
{
|
||||||
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Disc region type = " + parts.rvalue );
|
Console.WriteLn( Color_Blue, L"(SYSTEM.CNF) Disc region type = " + parts.rvalue );
|
||||||
}
|
}
|
||||||
else if( parts.lvalue == L"VER" )
|
else if( parts.lvalue == L"VER" )
|
||||||
{
|
{
|
||||||
Console.WriteLn( Color_StrongBlue, L"(GetElfName) Software version = " + parts.rvalue );
|
Console.WriteLn( Color_Blue, L"(SYSTEM.CNF) Software version = " + parts.rvalue );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,9 +478,9 @@ int GetPS2ElfName( wxString& name )
|
||||||
Console.Error(ex.FormatDiagnosticMessage());
|
Console.Error(ex.FormatDiagnosticMessage());
|
||||||
return 0; // ISO error
|
return 0; // ISO error
|
||||||
}
|
}
|
||||||
catch( Exception::FileNotFound& ex )
|
catch( Exception::FileNotFound& )
|
||||||
{
|
{
|
||||||
Console.Warning(ex.FormatDiagnosticMessage());
|
//Console.Warning(ex.FormatDiagnosticMessage());
|
||||||
return 0; // no SYSTEM.CNF, not a PS1/PS2 disc.
|
return 0; // no SYSTEM.CNF, not a PS1/PS2 disc.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -423,6 +423,12 @@ static void intThrowException( const BaseR5900Exception& ex )
|
||||||
ex.Rethrow();
|
ex.Rethrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void intThrowException( const BaseException& ex )
|
||||||
|
{
|
||||||
|
// No tricks needed; C++ stack unwnding shoud suffice for MSW and GCC alike.
|
||||||
|
ex.Rethrow();
|
||||||
|
}
|
||||||
|
|
||||||
R5900cpu intCpu =
|
R5900cpu intCpu =
|
||||||
{
|
{
|
||||||
intAlloc,
|
intAlloc,
|
||||||
|
@ -434,5 +440,6 @@ R5900cpu intCpu =
|
||||||
|
|
||||||
intCheckExecutionState,
|
intCheckExecutionState,
|
||||||
intThrowException,
|
intThrowException,
|
||||||
|
intThrowException,
|
||||||
intClear,
|
intClear,
|
||||||
};
|
};
|
||||||
|
|
|
@ -581,10 +581,10 @@ void __fastcall eeGameStarting()
|
||||||
{
|
{
|
||||||
if (!g_GameStarted)
|
if (!g_GameStarted)
|
||||||
{
|
{
|
||||||
Console.WriteLn( Color_Green, "(R5900) ELF Entry point! [addr=0x%08X]", ElfEntry );
|
//Console.WriteLn( Color_Green, "(R5900) ELF Entry point! [addr=0x%08X]", ElfEntry );
|
||||||
g_GameStarted = true;
|
g_GameStarted = true;
|
||||||
GetCoreThread().GameStartingInThread();
|
GetCoreThread().GameStartingInThread();
|
||||||
|
|
||||||
// GameStartingInThread may issue a reset of the cpu and/or recompilers. Check for and
|
// GameStartingInThread may issue a reset of the cpu and/or recompilers. Check for and
|
||||||
// handle such things here:
|
// handle such things here:
|
||||||
Cpu->CheckExecutionState();
|
Cpu->CheckExecutionState();
|
||||||
|
@ -607,7 +607,7 @@ void __fastcall eeloadReplaceOSDSYS()
|
||||||
else
|
else
|
||||||
cdvdReloadElfInfo();
|
cdvdReloadElfInfo();
|
||||||
|
|
||||||
// didn't recognise an ELF
|
// didn't recognize an ELF
|
||||||
if (ElfEntry == -1) {
|
if (ElfEntry == -1) {
|
||||||
eeGameStarting();
|
eeGameStarting();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -279,7 +279,7 @@ struct R5900cpu
|
||||||
// Can be called from any thread. Execute status must be suspended or stopped
|
// Can be called from any thread. Execute status must be suspended or stopped
|
||||||
// to prevent multi-thread race conditions.
|
// to prevent multi-thread race conditions.
|
||||||
//
|
//
|
||||||
// Notable Exception Throws:
|
// Exception Throws:
|
||||||
// OutOfMemory - Not enough memory, or the memory areas required were already
|
// OutOfMemory - Not enough memory, or the memory areas required were already
|
||||||
// reserved.
|
// reserved.
|
||||||
//
|
//
|
||||||
|
@ -303,7 +303,7 @@ struct R5900cpu
|
||||||
// Can be called from any thread. Execute status must be suspended or stopped
|
// Can be called from any thread. Execute status must be suspended or stopped
|
||||||
// to prevent multi-thread race conditions.
|
// to prevent multi-thread race conditions.
|
||||||
//
|
//
|
||||||
// Exception Throws: Emulator-defined. Common exception types to look for:
|
// Exception Throws: Emulator-defined. Common exception types to expect are
|
||||||
// OutOfMemory, Stream Exceptions
|
// OutOfMemory, Stream Exceptions
|
||||||
//
|
//
|
||||||
void (*Reset)();
|
void (*Reset)();
|
||||||
|
@ -322,7 +322,9 @@ struct R5900cpu
|
||||||
// call to return at the nearest state check (typically handled internally using
|
// call to return at the nearest state check (typically handled internally using
|
||||||
// either C++ exceptions or setjmp/longjmp).
|
// either C++ exceptions or setjmp/longjmp).
|
||||||
//
|
//
|
||||||
// Exception Throws: [TODO] (possible execution-related throws to be added)
|
// Exception Throws:
|
||||||
|
// Throws BaseR5900Exception and all derivatives.
|
||||||
|
// Throws FileNotFound or other Streaming errors (typically related to BIOS MEC/NVM)
|
||||||
//
|
//
|
||||||
void (*Execute)();
|
void (*Execute)();
|
||||||
|
|
||||||
|
@ -333,23 +335,28 @@ struct R5900cpu
|
||||||
//
|
//
|
||||||
// Implementation note: Because of the nuances of recompiled code execution, setjmp
|
// Implementation note: Because of the nuances of recompiled code execution, setjmp
|
||||||
// may be used in place of thread cancellation or C++ exceptions (non-SEH exceptions
|
// may be used in place of thread cancellation or C++ exceptions (non-SEH exceptions
|
||||||
// cannot unwind through the recompiled code stackframes).
|
// cannot unwind through the recompiled code stackframes, thus longjmp must be used).
|
||||||
//
|
//
|
||||||
// Thread Affinity:
|
// Thread Affinity:
|
||||||
// Must be called on the same thread as Execute only.
|
// Must be called on the same thread as Execute.
|
||||||
//
|
//
|
||||||
// Exception Throws:
|
// Exception Throws:
|
||||||
// May throw threading/Pthreads cancellations if the compiler supports SEH.
|
// May throw Execution/Pthreads cancellations if the compiler supports SEH.
|
||||||
// ThreadTimedOut - For canceling VM execution in response to MTGS deadlock. (if the
|
|
||||||
// core emulator does not support multithreaded GS then this will not be a throw
|
|
||||||
// exception).
|
|
||||||
//
|
//
|
||||||
void (*CheckExecutionState)();
|
void (*CheckExecutionState)();
|
||||||
|
|
||||||
// Safely throws host exceptions from executing code (either recompiled or interpreted).
|
// Safely throws host exceptions from executing code (either recompiled or interpreted).
|
||||||
// If this function is called outside the context of the CPU's code execution, then the
|
// If this function is called outside the context of the CPU's code execution, then the
|
||||||
// given exception will be re-thrown automatically.
|
// given exception will be re-thrown automatically.
|
||||||
void (*ThrowException)( const BaseR5900Exception& ex );
|
//
|
||||||
|
// Exception Throws:
|
||||||
|
// (SEH) Rethrows the given exception immediately.
|
||||||
|
// (setjmp) Re-throws immediately if called from outside the context of dynamically
|
||||||
|
// generated code (either non-executing contexts or interpreters). Does not throw
|
||||||
|
// otherwise.
|
||||||
|
//
|
||||||
|
void (*ThrowException)( const BaseException& ex );
|
||||||
|
void (*ThrowCpuException)( const BaseR5900Exception& ex );
|
||||||
|
|
||||||
// Manual recompiled code cache clear; typically useful to recompilers only. Size is
|
// Manual recompiled code cache clear; typically useful to recompilers only. Size is
|
||||||
// in MIPS words (32 bits). Dev note: this callback is nearly obsolete, and might be
|
// in MIPS words (32 bits). Dev note: this callback is nearly obsolete, and might be
|
||||||
|
|
|
@ -260,6 +260,8 @@ void SysCoreThread::OnResumeInThread( bool isSuspended )
|
||||||
// Invoked by the pthread_exit or pthread_cancel.
|
// Invoked by the pthread_exit or pthread_cancel.
|
||||||
void SysCoreThread::OnCleanupInThread()
|
void SysCoreThread::OnCleanupInThread()
|
||||||
{
|
{
|
||||||
|
m_ExecMode = ExecMode_Closing;
|
||||||
|
|
||||||
m_hasActiveMachine = false;
|
m_hasActiveMachine = false;
|
||||||
m_resetVirtualMachine = true;
|
m_resetVirtualMachine = true;
|
||||||
|
|
||||||
|
@ -269,5 +271,7 @@ void SysCoreThread::OnCleanupInThread()
|
||||||
_mm_setcsr( m_mxcsr_saved.bitmask );
|
_mm_setcsr( m_mxcsr_saved.bitmask );
|
||||||
Threading::DisableHiresScheduler();
|
Threading::DisableHiresScheduler();
|
||||||
_parent::OnCleanupInThread();
|
_parent::OnCleanupInThread();
|
||||||
|
|
||||||
|
m_ExecMode = ExecMode_NoThreadYet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -95,13 +95,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsClosed() const { return !IsOpen(); }
|
bool IsClosed() const { return !IsOpen(); }
|
||||||
|
|
||||||
bool IsPaused() const { return !IsRunning() || (m_ExecMode <= ExecMode_Paused); }
|
bool IsPaused() const { return !IsRunning() || (m_ExecMode <= ExecMode_Paused); }
|
||||||
|
|
||||||
|
bool IsClosing() const
|
||||||
|
{
|
||||||
|
return !IsRunning() || (m_ExecMode <= ExecMode_Closed) || (m_ExecMode == ExecMode_Closing);
|
||||||
|
}
|
||||||
|
|
||||||
bool HasPendingStateChangeRequest() const
|
bool HasPendingStateChangeRequest() const
|
||||||
{
|
{
|
||||||
ExecutionMode mode = m_ExecMode;
|
return m_ExecMode >= ExecMode_Closing;
|
||||||
return (mode == ExecMode_Closing) || (mode == ExecMode_Pausing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ExecutionMode GetExecutionMode() const { return m_ExecMode; }
|
ExecutionMode GetExecutionMode() const { return m_ExecMode; }
|
||||||
|
|
|
@ -384,6 +384,7 @@ void AppCoreThread::OnSuspendInThread()
|
||||||
// the new (lack of) thread status, so this posts a message to the App to do so.
|
// the new (lack of) thread status, so this posts a message to the App to do so.
|
||||||
void AppCoreThread::OnCleanupInThread()
|
void AppCoreThread::OnCleanupInThread()
|
||||||
{
|
{
|
||||||
|
m_ExecMode = ExecMode_Closing;
|
||||||
PostCoreStatus( CoreThread_Stopped );
|
PostCoreStatus( CoreThread_Stopped );
|
||||||
_parent::OnCleanupInThread();
|
_parent::OnCleanupInThread();
|
||||||
}
|
}
|
||||||
|
|
|
@ -541,7 +541,7 @@ void MainEmuFrame::ApplyCoreStatus()
|
||||||
|
|
||||||
if( susres )
|
if( susres )
|
||||||
{
|
{
|
||||||
if( CoreThread.IsOpen() )
|
if( !CoreThread.IsClosing() )
|
||||||
{
|
{
|
||||||
susres->Enable();
|
susres->Enable();
|
||||||
susres->SetText(_("Suspend"));
|
susres->SetText(_("Suspend"));
|
||||||
|
|
|
@ -233,7 +233,7 @@ void __fastcall vtlb_memWrite128(u32 mem, const mem128_t *value)
|
||||||
static __forceinline void vtlb_Miss(u32 addr,u32 mode)
|
static __forceinline void vtlb_Miss(u32 addr,u32 mode)
|
||||||
{
|
{
|
||||||
if( IsDevBuild )
|
if( IsDevBuild )
|
||||||
Cpu->ThrowException( R5900Exception::TLBMiss( addr, !!mode ) );
|
Cpu->ThrowCpuException( R5900Exception::TLBMiss( addr, !!mode ) );
|
||||||
else
|
else
|
||||||
Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
|
Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,7 @@ static __forceinline void vtlb_BusError(u32 addr,u32 mode)
|
||||||
// the PC prior to invoking the indirect handlers.
|
// the PC prior to invoking the indirect handlers.
|
||||||
|
|
||||||
if( IsDevBuild )
|
if( IsDevBuild )
|
||||||
Cpu->ThrowException( R5900Exception::BusError( addr, !!mode ) );
|
Cpu->ThrowCpuException( R5900Exception::BusError( addr, !!mode ) );
|
||||||
else
|
else
|
||||||
Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
|
Console.Error( R5900Exception::TLBMiss( addr, !!mode ).FormatMessage() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,8 +63,6 @@ bool g_cpuFlushedPC, g_cpuFlushedCode, g_recompilingDelaySlot, g_maySignalExcept
|
||||||
#define X86
|
#define X86
|
||||||
static const int RECCONSTBUF_SIZE = 16384 * 2; // 64 bit consts in 32 bit units
|
static const int RECCONSTBUF_SIZE = 16384 * 2; // 64 bit consts in 32 bit units
|
||||||
|
|
||||||
static ScopedPtr<BaseR5900Exception> m_vmException;
|
|
||||||
|
|
||||||
static u8 *recMem = NULL; // the recompiled blocks will be here
|
static u8 *recMem = NULL; // the recompiled blocks will be here
|
||||||
static u32* recConstBuf = NULL; // 64-bit pseudo-immediates
|
static u32* recConstBuf = NULL; // 64-bit pseudo-immediates
|
||||||
static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here
|
static BASEBLOCK *recRAM = NULL; // and the ptr to the blocks here
|
||||||
|
@ -714,7 +712,15 @@ void recStep( void )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static jmp_buf m_SetJmp_StateCheck;
|
#if !PCSX2_SEH
|
||||||
|
# define SETJMP_CODE(x) x
|
||||||
|
static jmp_buf m_SetJmp_StateCheck;
|
||||||
|
static ScopedPtr<BaseR5900Exception> m_cpuException;
|
||||||
|
static ScopedPtr<BaseException> m_Exception;
|
||||||
|
#else
|
||||||
|
# define SETJMP_CODE(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void recExitExecution()
|
static void recExitExecution()
|
||||||
{
|
{
|
||||||
|
@ -732,7 +738,7 @@ static void recExitExecution()
|
||||||
|
|
||||||
static void recCheckExecutionState()
|
static void recCheckExecutionState()
|
||||||
{
|
{
|
||||||
if( eeRecIsReset || m_vmException || GetCoreThread().HasPendingStateChangeRequest() )
|
if( SETJMP_CODE(m_cpuException || m_Exception ||) eeRecIsReset || GetCoreThread().HasPendingStateChangeRequest() )
|
||||||
{
|
{
|
||||||
recExitExecution();
|
recExitExecution();
|
||||||
}
|
}
|
||||||
|
@ -747,7 +753,6 @@ static void recExecute()
|
||||||
|
|
||||||
#if PCSX2_SEH
|
#if PCSX2_SEH
|
||||||
eeRecIsReset = false;
|
eeRecIsReset = false;
|
||||||
m_vmException = NULL;
|
|
||||||
ScopedBool executing(m_recExecutingCode);
|
ScopedBool executing(m_recExecutingCode);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -758,6 +763,8 @@ static void recExecute()
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int oldstate;
|
int oldstate;
|
||||||
|
m_cpuException = NULL;
|
||||||
|
m_Exception = NULL;
|
||||||
|
|
||||||
if( !setjmp( m_SetJmp_StateCheck ) )
|
if( !setjmp( m_SetJmp_StateCheck ) )
|
||||||
{
|
{
|
||||||
|
@ -777,9 +784,10 @@ static void recExecute()
|
||||||
{
|
{
|
||||||
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
|
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldstate );
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if(m_vmException) m_vmException->Rethrow();
|
if(m_cpuException) m_cpuException->Rethrow();
|
||||||
|
if(m_Exception) m_Exception->Rethrow();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
@ -1838,12 +1846,25 @@ StartRecomp:
|
||||||
// SEH unwind (MSW) or setjmp/longjmp (GCC).
|
// SEH unwind (MSW) or setjmp/longjmp (GCC).
|
||||||
static void recThrowException( const BaseR5900Exception& ex )
|
static void recThrowException( const BaseR5900Exception& ex )
|
||||||
{
|
{
|
||||||
|
#if PCSX2_SEH
|
||||||
|
ex.Rethrow();
|
||||||
|
#else
|
||||||
if (!m_recExecutingCode) ex.Rethrow();
|
if (!m_recExecutingCode) ex.Rethrow();
|
||||||
|
m_cpuException = ex.Clone();
|
||||||
m_vmException = ex.Clone();
|
|
||||||
recExitExecution();
|
recExitExecution();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void recThrowException( const BaseException& ex )
|
||||||
|
{
|
||||||
|
#if PCSX2_SEH
|
||||||
|
ex.Rethrow();
|
||||||
|
#else
|
||||||
|
if (!m_recExecutingCode) ex.Rethrow();
|
||||||
|
m_Exception = ex.Clone();
|
||||||
|
recExitExecution();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
R5900cpu recCpu =
|
R5900cpu recCpu =
|
||||||
{
|
{
|
||||||
|
@ -1856,5 +1877,6 @@ R5900cpu recCpu =
|
||||||
|
|
||||||
recCheckExecutionState,
|
recCheckExecutionState,
|
||||||
recThrowException,
|
recThrowException,
|
||||||
|
recThrowException,
|
||||||
recClear,
|
recClear,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue