*EXPERIMENTAL* Switched the code over to a new method of exception handling which should be more efficient and easier to debug and, most importantly, fixes a lot of the weird errors we've been getting since r488.

*NOTE: THIS IS REVISION WORKS ON VTLB ONLY -- VM BUILDS ARE CURRENTLY BROKEN*  If you like VM, do not try to compile or use this revision.  The VM build will crash anytime you try to load a savestate or exit/resume emulation.

(Interpreters and some other stuff are also broken too, but will be fixed shortly)

git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@578 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
Jake.Stine 2009-01-12 22:23:43 +00:00 committed by Gregory Hainaut
parent 7488e930d4
commit 7b2a5f068f
15 changed files with 143 additions and 138 deletions

View File

@ -497,10 +497,10 @@ __forceinline void rcntUpdate_hScanline()
}
}
__forceinline void rcntUpdate_vSync()
__forceinline bool rcntUpdate_vSync()
{
s32 diff = (cpuRegs.cycle - counters[5].sCycle);
if( diff < counters[5].CycleT ) return;
if( diff < counters[5].CycleT ) return false;
//iopBranchAction = 1;
if (counters[5].modeval == MODE_VSYNC)
@ -510,8 +510,9 @@ __forceinline void rcntUpdate_vSync()
counters[5].sCycle += vSyncInfo.Blank;
counters[5].CycleT = vSyncInfo.Render;
counters[5].modeval = MODE_VRENDER;
SysUpdate(); // check for and handle keyevents
return true;
// SysUpdate(); // check for and handle keyevents
}
else // VSYNC end / VRENDER begin
{
@ -534,8 +535,8 @@ __forceinline void rcntUpdate_vSync()
vblankinc = 0;
}
# endif
}
return false;
}
static __forceinline void __fastcall _cpuTestTarget( int i )
@ -576,15 +577,13 @@ static __forceinline void _cpuTestOverflow( int i )
// forceinline note: this method is called from two locations, but one
// of them is the interpreter, which doesn't count. ;) So might as
// well forceinline it!
__forceinline void rcntUpdate()
__forceinline bool rcntUpdate()
{
int i;
rcntUpdate_vSync();
bool retval = rcntUpdate_vSync();
// Update counters so that we can perform overflow and target tests.
for (i=0; i<=3; i++) {
for (int i=0; i<=3; i++) {
// We want to count gated counters (except the hblank which exclude below, and are
// counted by the hblank timer instead)
@ -609,8 +608,8 @@ __forceinline void rcntUpdate()
else counters[i].sCycleT = cpuRegs.cycle;
}
cpuRcntSet();
return retval;
}
static void _rcntSetGate( int index )

View File

@ -131,8 +131,8 @@ extern s32 nextCounter; // delta until the next counter event (must be signed)
extern u32 nextsCounter;
extern void rcntUpdate_hScanline();
extern void rcntUpdate_vSync();
extern void rcntUpdate();
extern bool rcntUpdate_vSync();
extern bool rcntUpdate();
void rcntInit();
void rcntStartGate(unsigned int mode, u32 sCycle);

View File

@ -779,7 +779,7 @@ int __Deci2Call(int call, u32 *addr) {
else pdeciaddr += (deci2addr[4]+0xc)%16;
memcpy(deci2buffer, pdeciaddr, deci2addr[1]-0xc);
deci2buffer[deci2addr[1]-0xc>=255?255:deci2addr[1]-0xc]='\0';
SysPrintf(deci2buffer);
Console::Write( Color_Cyan, deci2buffer );
}
deci2addr[3] = 0;
return 1;

View File

@ -157,9 +157,8 @@ static void ReserveExtraMem( void* base, uint size )
throw vm_alloc_failed_exception( base, size, pExtraMem);
}
void memAlloc() {
int i;
void memAlloc()
{
LPVOID pExtraMem = NULL;
// release the previous reserved mem
@ -411,7 +410,6 @@ OtherException:
if( ExceptionRecord->ExceptionInformation[0] ) {
//SKIP_WRITE();
// shouldn't be writing
SysPrintf("Exception: Write\n"); // Naruto Ultimate Ninja 3 crashes right after a write!
}
else {
SysPrintf("vmhack ");
@ -2607,8 +2605,6 @@ static u8* m_psAllMem = NULL;
void memAlloc()
{
#ifdef __LINUX__
InstallLinuxExceptionHandler();
// For Linux we need to use the system virtual memory mapper so that we
// can coerce an allocation below the 2GB line.
@ -2710,14 +2706,8 @@ void loadBiosRom( const char *ext, u8 *dest, long maxSize )
void memReset()
{
#ifdef PCSX2_VIRTUAL_MEM
DWORD OldProtect;
memset(PS2MEM_BASE, 0, Ps2MemSize::Base);
memset(PS2MEM_SCRATCH, 0, Ps2MemSize::Scratch);
vm_Reset();
# ifdef _WIN32
DWORD OldProtect;
// make sure can write
VirtualProtect(PS2MEM_ROM, Ps2MemSize::Rom, PAGE_READWRITE, &OldProtect);
VirtualProtect(PS2MEM_ROM1, Ps2MemSize::Rom1, PAGE_READWRITE, &OldProtect);
@ -2730,8 +2720,22 @@ void memReset()
mprotect(PS2EMEM_EROM, Ps2MemSize::ERom, PROT_READ|PROT_WRITE);
# endif
memset(PS2MEM_BASE, 0, Ps2MemSize::Base);
memset(PS2MEM_SCRATCH, 0, Ps2MemSize::Scratch);
vm_Reset();
#else
// VTLB Protection Preparations.
# ifdef _WIN32
DWORD OldProtect;
// make sure can write
VirtualProtect(m_psAllMem, m_allMemSize, PAGE_READWRITE, &OldProtect);
# else
mprotect(m_psAllMem, m_allMemSize, PROT_READ|PROT_WRITE);
# endif
// Note!! Ideally the vtlb should only be initialized once, and then subsequent
// resets of the system hardware would only clear vtlb mappings, but since the
// rest of the emu is not really set up to support a "soft" reset of that sort

View File

@ -448,7 +448,7 @@ u32 g_nextBranchCycle = 0;
// Shared portion of the branch test, called from both the Interpreter
// and the recompiler. (moved here to help alleviate redundant code)
static __forceinline void _cpuBranchTest_Shared()
__forceinline bool _cpuBranchTest_Shared()
{
EventTestIsActive = true;
g_nextBranchCycle = cpuRegs.cycle + eeWaitCycles;
@ -460,12 +460,12 @@ static __forceinline void _cpuBranchTest_Shared()
iopBranchAction = true;
// ---- Counters -------------
bool vsyncEvent = false;
rcntUpdate_hScanline();
if( cpuTestCycle( nextsCounter, nextCounter ) )
{
rcntUpdate();
vsyncEvent = rcntUpdate();
_cpuTestPERF();
}
@ -577,31 +577,8 @@ static __forceinline void _cpuBranchTest_Shared()
TESTINT(30, intcInterrupt);
TESTINT(31, dmacInterrupt);
}
}
void cpuBranchTest()
{
// cpuBranchTest should be called from the recompiler only.
assert( Cpu == &recCpu );
#ifdef PCSX2_DEVBUILD
// dont' remove this check unless doing an official release
if( g_globalXMMSaved || g_globalMMXSaved)
DevCon::Error("Pcsx2 Foopah! Frozen regs have not been restored!!!");
assert( !g_globalXMMSaved && !g_globalMMXSaved);
#endif
// Don't need to freeze any regs during a BranchTest.
// Everything has been flushed already.
g_EEFreezeRegs = false;
// Perform counters, ints, and IOP updates:
_cpuBranchTest_Shared();
#ifdef PCSX2_DEVBUILD
assert( !g_globalXMMSaved && !g_globalMMXSaved);
#endif
g_EEFreezeRegs = true;
return vsyncEvent;
}
void cpuTestINTCInts()

View File

@ -224,8 +224,9 @@ void cpuException(u32 code, u32 bd);
void cpuTlbMissR(u32 addr, u32 bd);
void cpuTlbMissW(u32 addr, u32 bd);
void IntcpuBranchTest();
void cpuBranchTest();
void cpuTestHwInts();
extern void cpuTestHwInts();
extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:
extern void cpuTestINTCInts();
extern void cpuTestDMACInts();

View File

@ -52,12 +52,21 @@ void SysMunmap(uptr base, u32 size);
// *DEPRECIATED* Use Console namespace methods instead.
void SysPrintf(const char *fmt, ...); // *DEPRECIATED*
static __forceinline void SysMunmap( void* base, u32 size )
{
SysMunmap( (uptr)base, size );
}
#ifdef _MSC_VER
# define PCSX2_MEM_PROTECT_BEGIN() __try {
# define PCSX2_MEM_PROTECT_END() } __except(SysPageFaultExceptionFilter(GetExceptionInformation())) {}
#else
# define PCSX2_MEM_PROTECT_BEGIN() InstallLinuxExceptionHandler()
# define PCSX2_MEM_PROTECT_END() ReleaseLinuxExceptionHandler()
#endif
// Console Namespace -- Replacements for SysPrintf.
// SysPrintf is depreciated -- We should phase these in over time.
namespace Console

View File

@ -146,6 +146,8 @@ void vuMicroMemReset()
jASSUME( VU0.Mem != NULL );
jASSUME( VU1.Mem != NULL );
PCSX2_MEM_PROTECT_BEGIN();
// === VU0 Initialization ===
memset(&VU0.ACC, 0, sizeof(VECTOR));
memset(VU0.VF, 0, sizeof(VECTOR)*32);
@ -187,6 +189,8 @@ void vuMicroMemReset()
// VU1.VI = (REG_VI*)(VU0.Mem + 0x4200);
VU1.vuExec = vu1Exec;
VU1.vifRegs = vif1Regs;
PCSX2_MEM_PROTECT_END();
}
void SaveState::vuMicroFreeze()

View File

@ -87,8 +87,8 @@ BOOL CALLBACK CpuDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam)
SetDlgItemText(hW, IDC_FEATURESINPUT, features);
CheckDlgButton(hW, IDC_CPU_EEREC, !!(Config.Options&PCSX2_EEREC));
CheckDlgButton(hW, IDC_CPU_VU0REC, !!(Config.Options&CHECK_VU0REC));
CheckDlgButton(hW, IDC_CPU_VU1REC, !!(Config.Options&CHECK_VU1REC));
CheckDlgButton(hW, IDC_CPU_VU0REC, !!(Config.Options&PCSX2_VU0REC));
CheckDlgButton(hW, IDC_CPU_VU1REC, !!(Config.Options&PCSX2_VU1REC));
EnableDlgItem( hW, IDC_CPU_EEREC, !g_Session.ForceDisableEErec );
EnableDlgItem( hW, IDC_CPU_VU0REC, !g_Session.ForceDisableVU0rec );

View File

@ -56,6 +56,7 @@
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="$(SolutionDir)\common"
PreprocessorDefinitions="NDEBUG,WIN32_PTHREADS"
ExceptionHandling="2"
SmallerTypeCheck="false"
BufferSecurityCheck="false"
UsePrecompiledHeader="2"
@ -137,6 +138,7 @@
AdditionalIncludeDirectories="$(SolutionDir)\common"
PreprocessorDefinitions="WIN32_PTHREADS"
MinimalRebuild="true"
ExceptionHandling="2"
SmallerTypeCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
@ -220,6 +222,7 @@
AdditionalIncludeDirectories="$(SolutionDir)\common"
PreprocessorDefinitions="WIN32_PTHREADS"
MinimalRebuild="true"
ExceptionHandling="2"
SmallerTypeCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="2"
@ -311,6 +314,7 @@
AdditionalIncludeDirectories="$(SolutionDir)\common"
PreprocessorDefinitions="NDEBUG;WIN32_PTHREADS"
StringPooling="true"
ExceptionHandling="2"
SmallerTypeCheck="false"
RuntimeLibrary="0"
StructMemberAlignment="5"
@ -398,6 +402,7 @@
EnableFiberSafeOptimizations="true"
AdditionalIncludeDirectories="$(SolutionDir)\common"
PreprocessorDefinitions="NDEBUG,WIN32_PTHREADS"
ExceptionHandling="2"
SmallerTypeCheck="false"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="0"
@ -482,6 +487,7 @@
EnableFiberSafeOptimizations="true"
AdditionalIncludeDirectories="$(SolutionDir)\common"
PreprocessorDefinitions="NDEBUG,WIN32_PTHREADS"
ExceptionHandling="2"
SmallerTypeCheck="false"
BufferSecurityCheck="false"
EnableEnhancedInstructionSet="0"
@ -598,11 +604,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
ExceptionHandling="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -611,7 +613,6 @@
>
<Tool
Name="VCCLCompilerTool"
ExceptionHandling="0"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -620,7 +621,6 @@
>
<Tool
Name="VCCLCompilerTool"
ExceptionHandling="0"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -629,11 +629,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
ExceptionHandling="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -642,11 +638,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
ExceptionHandling="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -655,11 +647,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
ExceptionHandling="0"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -672,10 +660,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -684,10 +669,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -696,10 +678,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>
@ -708,10 +687,7 @@
>
<Tool
Name="VCCLCompilerTool"
Optimization="3"
FavorSizeOrSpeed="2"
OmitFramePointers="false"
EnableFiberSafeOptimizations="false"
BufferSecurityCheck="false"
UsePrecompiledHeader="0"
/>
</FileConfiguration>

View File

@ -44,7 +44,7 @@
AdditionalIncludeDirectories="&quot;$(InputDir)&quot;"
PreprocessorDefinitions="PTW32_STATIC_LIB;WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
ExceptionHandling="0"
ExceptionHandling="2"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
StructMemberAlignment="5"
@ -118,7 +118,7 @@
PreprocessorDefinitions="PTW32_STATIC_LIB;PTW32_BUILD_INLINED;WIN32;NDEBUG;_LIB"
StringPooling="true"
MinimalRebuild="true"
ExceptionHandling="0"
ExceptionHandling="2"
RuntimeLibrary="0"
StructMemberAlignment="5"
BufferSecurityCheck="false"

View File

@ -118,7 +118,6 @@ namespace Console
return false;
}
}
namespace Msgbox

View File

@ -22,8 +22,6 @@
// and it's usually user error, but in this case I'm pretty sure I found one.
// So put your c++ exception code in WinSysExec.cpp. It's better that way. :D (air)
// Disabled warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
#pragma warning(disable:4530)
#include "PrecompiledHeader.h"
#include "win32.h"
@ -201,6 +199,21 @@ void WinClose()
exit(0);
}
/*class SehException
{
public:
uint m_code;
const _EXCEPTION_POINTERS& m_info;
public:
SehException(uint code, const _EXCEPTION_POINTERS& eptr ) : m_code(code), m_info(eptr) { }
};
void SehTranslatorFunction( uint code, _EXCEPTION_POINTERS* eptr )
{
throw SehException( code, *eptr );
}*/
BOOL SysLoggedSetLockPagesPrivilege ( HANDLE hProcess, BOOL bEnable);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
@ -246,9 +259,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
_getcwd( g_WorkingFolder, g_MaxPath );
__try
{
int argc;
TCHAR *const *const argv = _CommandLineToArgv( lpCmdLine, &argc );
@ -389,10 +399,11 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
LoadPatch("default");
RunGui();
}
__except(SysPageFaultExceptionFilter(GetExceptionInformation()))
/*}
catch( SehException& ex )
{
}
SysPageFaultExceptionFilter( ex.m_info );
}*/
// Note : Because of how the GUI and recompiler function, this area of
// the code is effectively unreachable. Program termination is handled

View File

@ -16,11 +16,6 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
// NOTE : This file was created to separate code that uses C++ exceptions from the
// WinMain procedure in WinMain.cpp. Apparently MSVC handles not so well the idea
// of both __try/__except and try/catch in the same module. (yup, I ran into a
// dreaded compiler bug).
#include "PrecompiledHeader.h"
#include "win32.h"
@ -197,7 +192,11 @@ void ExecuteCpu()
g_GameInProgress = true;
if( !m_EmuStateActive )
{
Cpu->Execute();
while( true )
{
Cpu->Execute();
SysUpdate();
}
g_GameInProgress = false;
}
else
@ -214,9 +213,6 @@ void RunExecute( const char* elf_file, bool use_bios )
g_GameInProgress = false;
if (OpenPlugins(g_TestRun.ptitle) == -1)
return;
try
{
cpuReset();
@ -227,18 +223,15 @@ void RunExecute( const char* elf_file, bool use_bios )
return;
}
if (OpenPlugins(g_TestRun.ptitle) == -1)
return;
if( elf_file == NULL )
{
if(g_RecoveryState != NULL)
{
try
{
/*string Text;
SaveState::GetFilename( Text, 9 );
gzLoadingState joe( Text ); // throws exception on version mismatch
R5900::cpuReset();
joe.FreezeAll();*/
memLoadingState( *g_RecoveryState ).FreezeAll();
}
catch( std::runtime_error& ex )

View File

@ -639,7 +639,9 @@ static void execute( void )
__asm call pfn;
__asm pop ebp; // restore ebp for the reason above
#else
__asm__("push %%ebp\n");
((R5900FNPTR)pblock->pFnptr)();
__asm__("pop %%ebp\n");
#endif
#endif
@ -650,15 +652,41 @@ static void execute( void )
void recStep( void ) {
}
void recExecute( void ) {
if( Config.Options & PCSX2_EEREC ) Config.Options |= PCSX2_COP2REC;
static __forceinline bool recEventTest()
{
#ifdef PCSX2_DEVBUILD
// dont' remove this check unless doing an official release
if( g_globalXMMSaved || g_globalMMXSaved)
DevCon::Error("Pcsx2 Foopah! Frozen regs have not been restored!!!");
assert( !g_globalXMMSaved && !g_globalMMXSaved);
#endif
for (;;)
execute();
// Perform counters, ints, and IOP updates:
bool retval = ::R5900::_cpuBranchTest_Shared();
#ifdef PCSX2_DEVBUILD
assert( !g_globalXMMSaved && !g_globalMMXSaved);
#endif
return retval;
}
void recExecuteBlock( void ) {
execute();
static void recExecute( void )
{
PCSX2_MEM_PROTECT_BEGIN()
while( true )
{
if( recEventTest() ) break;
execute();
}
PCSX2_MEM_PROTECT_END()
}
static void recExecuteBlock( void )
{
PCSX2_MEM_PROTECT_BEGIN()
recEventTest();
execute();
PCSX2_MEM_PROTECT_END()
}
////////////////////////////////////////////////////
@ -710,8 +738,8 @@ CheckPtr:
// }
__asm {
and eax, 0x0fffffff
mov edx, eax
pop ecx // x86Ptr to mod
mov edx, eax
sub edx, ecx
sub edx, 4
mov dword ptr [ecx], edx
@ -735,8 +763,8 @@ __declspec(naked,noreturn) void DispatcherClear()
// already modded the code, jump to the new place
__asm {
pop edx
add esp, 4 // ignore stack
mov eax, s_pDispatchBlock
add esp, 4 // ignore stack
mov eax, dword ptr [eax]
and eax, 0x0fffffff
jmp eax
@ -987,14 +1015,12 @@ void SetBranchReg( u32 reg )
iFlushCall(FLUSH_EVERYTHING);
iBranchTest(0xffffffff, 1);
if( bExecBIOS ) CheckForBIOSEnd();
JMP32((u32)DispatcherReg - ( (u32)x86Ptr + 5 ));
}
void SetBranchImm( u32 imm )
{
u32* ptr;
branch = 1;
assert( imm );
@ -1004,10 +1030,9 @@ void SetBranchImm( u32 imm )
iFlushCall(FLUSH_EVERYTHING);
iBranchTest(imm, imm <= pc);
if( bExecBIOS ) CheckForBIOSEnd();
MOV32ItoR(EDX, 0);
ptr = (u32*)(x86Ptr-4);
u32* ptr = (u32*)(x86Ptr-4);
*ptr = (u32)JMP32((u32)Dispatcher - ( (u32)x86Ptr + 5 ));
}
@ -1161,17 +1186,25 @@ static void iBranchTest(u32 newpc, u32 cpuBranch)
// check if should branch
j8Ptr[0] = JS8( 0 );
RET();
/*if( newpc != 0xffffffff )
JNS32( (uptr)eventTestReg - ( (uptr)x86Ptr + 6 ) );
else
JNS32( (uptr)eventTest - ( (uptr)x86Ptr + 6 ) );*/
// has to be in the middle of Save/LoadBranchState
CALLFunc( (uptr)cpuBranchTest );
/*CALLFunc( (uptr)cpuBranchTest );
if( newpc != 0xffffffff )
{
CMP32ItoM((uptr)&cpuRegs.pc, newpc);
JNE32((uptr)DispatcherReg - ( (uptr)x86Ptr + 6 ));
}
}*/
x86SetJ8( j8Ptr[0] );
if( bExecBIOS ) CheckForBIOSEnd();
}
namespace OpcodeImpl
@ -2111,7 +2144,6 @@ StartRecomp:
iFlushCall(FLUSH_EVERYTHING);
iBranchTest(0xffffffff, 1);
if( bExecBIOS ) CheckForBIOSEnd();
JMP32((uptr)DispatcherReg - ( (uptr)x86Ptr + 5 ));
}