* More MXCSR fixes (roundmode / DaZ / FtZ).

* Fixed a bug in the Full-mode FPU recompiler.
 * Added some better error handling to the BIOS Rom loader.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2117 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-11-02 19:56:38 +00:00
parent 2468551994
commit 24d6221141
12 changed files with 111 additions and 82 deletions

View File

@ -27,7 +27,12 @@ class SimdImpl_DestRegSSE
{ {
public: public:
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const
{
bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty();
pxAssertDev( isReallyAligned, "Alignment check failed on SSE indirect load." );
xOpWrite0F( Prefix, Opcode, to, from );
}
SimdImpl_DestRegSSE() {} //GCWho? SimdImpl_DestRegSSE() {} //GCWho?
}; };

View File

@ -21,18 +21,15 @@
#include "SysThreads.h" #include "SysThreads.h"
#include "SaveState.h" #include "SaveState.h"
#include "Elfheader.h"
#include "Plugins.h"
#include "R5900.h"
#include "R3000A.h"
#include "VUmicro.h" #include "VUmicro.h"
#include "GS.h" #include "GS.h"
#ifdef __WXMSW__ #ifdef __WXMSW__
# include <wx/msw/wrapwin.h> # include <wx/msw/wrapwin.h>
#endif #endif
#include <xmmintrin.h>
static __threadlocal SysCoreThread* tls_coreThread = NULL; static __threadlocal SysCoreThread* tls_coreThread = NULL;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -203,6 +200,7 @@ void SysCoreThread::CpuInitializeMess()
// fast bott up option. (though not recommended for games because of rare ill side // fast bott up option. (though not recommended for games because of rare ill side
// effects). // effects).
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
cpuExecuteBios(); cpuExecuteBios();
loadElfFile( elf_file ); loadElfFile( elf_file );
} }
@ -229,12 +227,14 @@ void SysCoreThread::StateCheckInThread()
void SysCoreThread::ExecuteTaskInThread() void SysCoreThread::ExecuteTaskInThread()
{ {
Threading::EnableHiresScheduler(); Threading::EnableHiresScheduler();
tls_coreThread = this; tls_coreThread = this;
m_sem_event.WaitWithoutYield(); m_sem_event.WaitWithoutYield();
m_mxcsr_saved.bitmask = _mm_getcsr();
PCSX2_PAGEFAULT_PROTECT { PCSX2_PAGEFAULT_PROTECT {
StateCheckInThread(); StateCheckInThread();
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
Cpu->Execute(); Cpu->Execute();
} PCSX2_PAGEFAULT_EXCEPT; } PCSX2_PAGEFAULT_EXCEPT;
} }
@ -260,6 +260,8 @@ void SysCoreThread::OnCleanupInThread()
{ {
m_hasValidState = false; m_hasValidState = false;
_mm_setcsr( m_mxcsr_saved.bitmask );
Threading::DisableHiresScheduler(); Threading::DisableHiresScheduler();
if( g_plugins != NULL ) if( g_plugins != NULL )

View File

@ -16,6 +16,7 @@
#pragma once #pragma once
#include "Utilities/Threading.h" #include "Utilities/Threading.h"
#include "x86emitter/tools.h"
using namespace Threading; using namespace Threading;
@ -194,6 +195,8 @@ protected:
bool m_CoreCancelDamnit; bool m_CoreCancelDamnit;
wxString m_elf_override; wxString m_elf_override;
SSE_MXCSR m_mxcsr_saved;
public: public:
static SysCoreThread& Get(); static SysCoreThread& Get();

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "MainFrame.h" #include "MainFrame.h"
#include "ps2/BiosTools.h"
AppCoreThread CoreThread; AppCoreThread CoreThread;
@ -191,52 +192,18 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
void AppCoreThread::ExecuteTaskInThread() void AppCoreThread::ExecuteTaskInThread()
{ {
try _parent::ExecuteTaskInThread();
{
SysCoreThread::ExecuteTaskInThread();
}
// ----------------------------------------------------------------------------
catch( Exception::FileNotFound& ex )
{
if( g_plugins != NULL ) g_plugins->Close();
if( ex.StreamName == g_Conf->FullpathToBios() )
{
bool result = Msgbox::OkCancel( ex.FormatDisplayMessage() +
_("\n\nPress Ok to go to the BIOS Configuration Panel.") );
if( result )
{
if( wxGetApp().ThreadedModalDialog( DialogId_BiosSelector ) == wxID_CANCEL )
{
// fixme: handle case where user cancels the settings dialog. (should return FALSE).
}
else
{
// fixme: automatically re-try emu startup here...
}
}
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
catch( Exception::PluginError& ex ) /*catch( Exception::PluginError& ex )
{ {
if( g_plugins != NULL ) g_plugins->Close(); if( g_plugins != NULL ) g_plugins->Close();
Console.Error( ex.FormatDiagnosticMessage() ); Console.Error( ex.FormatDiagnosticMessage() );
Msgbox::Alert( ex.FormatDisplayMessage(), _("Plugin Open Error") ); Msgbox::Alert( ex.FormatDisplayMessage(), _("Plugin Open Error") );
/*if( HandlePluginError( ex ) ) if( HandlePluginError( ex ) )
{ {
// fixme: automatically re-try emu startup here... // fixme: automatically re-try emu startup here...
}*/ }
} }*/
// ----------------------------------------------------------------------------
// [TODO] : Add exception handling here for debuggable PS2 exceptions that allows
// invocation of the PCSX2 debugger and such.
//
catch( Exception::BaseException& ex )
{
// Sent the exception back to the main gui thread?
if( g_plugins != NULL ) g_plugins->Close();
Msgbox::Alert( ex.FormatDisplayMessage() );
}
} }

View File

@ -18,6 +18,7 @@
#include "MainFrame.h" #include "MainFrame.h"
#include "Plugins.h" #include "Plugins.h"
#include "SaveState.h" #include "SaveState.h"
#include "ps2/BiosTools.h"
#include "Dialogs/ModalPopups.h" #include "Dialogs/ModalPopups.h"
#include "Dialogs/ConfigurationDialog.h" #include "Dialogs/ConfigurationDialog.h"
@ -139,6 +140,7 @@ void Pcsx2App::OnCoreThreadStatus( wxCommandEvent& evt )
{ {
m_evtsrc_CoreThreadStatus.Dispatch( evt ); m_evtsrc_CoreThreadStatus.Dispatch( evt );
ScopedBusyCursor::SetDefault( Cursor_NotBusy ); ScopedBusyCursor::SetDefault( Cursor_NotBusy );
CoreThread.RethrowException();
} }
void Pcsx2App::OnSemaphorePing( wxCommandEvent& evt ) void Pcsx2App::OnSemaphorePing( wxCommandEvent& evt )
@ -218,12 +220,44 @@ void Pcsx2App::OnEmuKeyDown( wxKeyEvent& evt )
} }
// Returns a string message telling the user to consult guides for obtaining a legal BIOS.
// This message is in a function because it's used as part of several dialogs in PCSX2 (there
// are multiple variations on the BIOS and BIOS folder checks).
wxString BIOS_GetMsg_Required()
{
return pxE( ".Popup:BiosDumpRequired",
L"\n\n"
L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain \n"
L"a BIOS from an actual PS2 unit that you own (borrowing doesn't count).\n"
L"Please consult the FAQs and Guides for further instructions.\n"
);
}
void Pcsx2App::HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const void Pcsx2App::HandleEvent(wxEvtHandler *handler, wxEventFunction func, wxEvent& event) const
{ {
try { try {
(handler->*func)(event); (handler->*func)(event);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
catch( Exception::BiosLoadFailed& ex )
{
bool result = Dialogs::ExtensibleConfirmation( NULL, ConfButtons().OK().Cancel(),
L"PS2 BIOS Error",
ex.FormatDisplayMessage() + BIOS_GetMsg_Required() + _("\nPress Ok to go to the BIOS Configuration Panel.")
).ShowModal() != wxID_CANCEL;
if( !result )
Console.Warning( "User denied option to re-configure BIOS." );
if( (wxTheApp != NULL) && (Dialogs::BiosSelectorDialog().ShowModal() != wxID_CANCEL) )
{
sApp.SysExecute();
}
else
Console.Warning( "User canceled BIOS configuration." );
}
// ----------------------------------------------------------------------------
catch( Exception::CancelEvent& ex ) catch( Exception::CancelEvent& ex )
{ {
Console.Warning( ex.FormatDiagnosticMessage() ); Console.Warning( ex.FormatDiagnosticMessage() );

View File

@ -40,7 +40,7 @@ using namespace Panels;
static const int s_orient = wxBK_LEFT; static const int s_orient = wxBK_LEFT;
#endif #endif
static const int IdealWidth = 500; static const int IdealWidth = 575;
template< typename T > template< typename T >
void Dialogs::ConfigurationDialog::AddPage( const char* label, int iconid ) void Dialogs::ConfigurationDialog::AddPage( const char* label, int iconid )

View File

@ -93,6 +93,8 @@ public:
ConfButtons& Abort() { m_Abort = true; return *this; } ConfButtons& Abort() { m_Abort = true; return *this; }
ConfButtons& Retry() { m_Retry = true; return *this; } ConfButtons& Retry() { m_Retry = true; return *this; }
ConfButtons& Ignore() { m_Ignore = true; return *this; } ConfButtons& Ignore() { m_Ignore = true; return *this; }
ConfButtons& OKCancel() { m_OK = m_Cancel = true; return *this; }
bool HasOK() const { return m_OK; } bool HasOK() const { return m_OK; }
bool HasCancel() const { return m_Cancel; } bool HasCancel() const { return m_Cancel; }

View File

@ -44,16 +44,17 @@ struct romdir
u32 BiosVersion; // Used in Memory, Misc, CDVD u32 BiosVersion; // Used in Memory, Misc, CDVD
// Returns a string message telling the user to consult guides for obtaining a legal BIOS. Exception::BiosLoadFailed::BiosLoadFailed( const wxString& filename, const wxString& msg_diag, const wxString& msg_user )
// This message is in a function because it's used as part of several dialogs in PCSX2 (there
// are multiple variations on the BIOS and BIOS folder checks).
wxString BIOS_GetMsg_Required()
{ {
return pxE( ".Popup:BiosDumpRequired", wxString diag( msg_user.IsEmpty() ?
L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain \n" L"BIOS has not been configured, or the configuration has been corrupted." : msg_user
L"a BIOS from an actual PS2 unit that you own (borrowing doesn't count).\n"
L"Please consult the FAQs and Guides for further instructions."
); );
wxString user( msg_user.IsEmpty() ?
_("The PS2 BIOS has not been configured, or the configuration has been corrupted. Please re-configure.") : msg_user
);
BaseException::InitBaseEx( diag, user );
StreamName = filename;
} }
// Returns the version information of the bios currently loaded into memory. // Returns the version information of the bios currently loaded into memory.
@ -146,27 +147,32 @@ static void loadBiosRom( const wxChar *ext, u8 *dest, s64 maxSize )
void LoadBIOS() void LoadBIOS()
{ {
pxAssertDev( PS2MEM_ROM != NULL, "PS2 system memory has not been initialized yet." ); pxAssertDev( PS2MEM_ROM != NULL, "PS2 system memory has not been initialized yet." );
wxString Bios( g_Conf->FullpathToBios() ); wxString Bios( g_Conf->FullpathToBios() );
if( !g_Conf->BaseFilenames.Bios.IsOk() || g_Conf->BaseFilenames.Bios.IsDir() )
throw Exception::BiosLoadFailed( Bios );
s64 filesize = Path::GetFileSize( Bios ); s64 filesize = Path::GetFileSize( Bios );
if( filesize > 0 ) if( filesize <= 0 )
{ {
wxFile fp( Bios.c_str() ); throw Exception::BiosLoadFailed( Bios,
fp.Read( PS2MEM_ROM, min( (s64)Ps2MemSize::Rom, filesize ) ); L"Configured BIOS file does not exist.",
} _("The configured BIOS file does not exist. Please re-configure.")
else
{
// Translated: Bios file not found or not specified ... A bios is required for Pcsx2 to run!
throw Exception::FileNotFound( Bios,
L"Configured Bios file does not exist",
_("The configured BIOS file does not exist, or no BIOS has been configured.\n\n") +
BIOS_GetMsg_Required()
); );
} }
wxFile fp( Bios );
fp.Read( PS2MEM_ROM, min( (s64)Ps2MemSize::Rom, filesize ) );
BiosVersion = GetBiosVersion(); BiosVersion = GetBiosVersion();
if( BiosVersion == -1 )
{
throw Exception::BiosLoadFailed( Bios,
L"Configured BIOS file is not a valid PS2 BIOS.",
_("The configured BIOS file is not a valid PS2 BIOS. Please re-configure.")
);
}
Console.WriteLn("Bios Version %d.%d", BiosVersion >> 8, BiosVersion & 0xff); Console.WriteLn("Bios Version %d.%d", BiosVersion >> 8, BiosVersion & 0xff);
//injectIRX("host.irx"); //not fully tested; still buggy //injectIRX("host.irx"); //not fully tested; still buggy

View File

@ -15,8 +15,20 @@
#pragma once #pragma once
namespace Exception
{
class BiosLoadFailed : public FileNotFound
{
public:
DEFINE_EXCEPTION_COPYTORS( BiosLoadFailed )
explicit BiosLoadFailed( const wxString& filename,
const wxString& msg_diag=wxEmptyString,
const wxString& msg_user=wxEmptyString );
};
}
extern u32 BiosVersion; // Used by CDVD extern u32 BiosVersion; // Used by CDVD
extern wxString BIOS_GetMsg_Required();
extern void LoadBIOS(); extern void LoadBIOS();
extern bool IsBIOS(const wxString& filename, wxString& description); extern bool IsBIOS(const wxString& filename, wxString& description);

View File

@ -116,7 +116,9 @@ struct FPUd_Globals
u64 dbl_cvt_overflow, // needs special code if above or equal u64 dbl_cvt_overflow, // needs special code if above or equal
dbl_ps2_overflow, // overflow & clamp if above or equal dbl_ps2_overflow, // overflow & clamp if above or equal
dbl_underflow; // underflow if below dbl_underflow; // underflow if below
u64 padding;
u64 dbl_s_pos[2]; u64 dbl_s_pos[2];
//u64 dlb_s_neg[2]; //u64 dlb_s_neg[2];
}; };
@ -132,9 +134,11 @@ static const __aligned(32) FPUd_Globals s_const =
{DOUBLE(0,1,0), 0}, {DOUBLE(0,1,0), 0},
DOUBLE(0,1151,0), DOUBLE(0,1151,0), // cvt_overflow
DOUBLE(0,1152,0), DOUBLE(0,1152,0), // ps2_overflow
DOUBLE(0,897,0), DOUBLE(0,897,0), // underflow
0, // Padding!!
{0x7fffffffffffffffULL, 0}, {0x7fffffffffffffffULL, 0},
//{0x8000000000000000ULL, 0}, //{0x8000000000000000ULL, 0},

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include <xmmintrin.h>
SSE_MXCSR g_sseMXCSR = { DEFAULT_sseMXCSR }; SSE_MXCSR g_sseMXCSR = { DEFAULT_sseMXCSR };
SSE_MXCSR g_sseVUMXCSR = { DEFAULT_sseVUMXCSR }; SSE_MXCSR g_sseVUMXCSR = { DEFAULT_sseVUMXCSR };
@ -29,10 +30,6 @@ void SetCPUState(SSE_MXCSR sseMXCSR, SSE_MXCSR sseVUMXCSR)
g_sseMXCSR = sseMXCSR.ApplyReserveMask(); g_sseMXCSR = sseMXCSR.ApplyReserveMask();
g_sseVUMXCSR = sseVUMXCSR.ApplyReserveMask(); g_sseVUMXCSR = sseVUMXCSR.ApplyReserveMask();
#ifdef _MSC_VER _mm_setcsr( g_sseMXCSR.bitmask );
__asm ldmxcsr g_sseMXCSR; // set the new sse control
#else
__asm__ __volatile__("ldmxcsr %[g_sseMXCSR]" : : [g_sseMXCSR]"m"(g_sseMXCSR) );
#endif
} }

View File

@ -688,13 +688,11 @@ static void recExecute()
{ {
eeRecIsReset = false; eeRecIsReset = false;
g_EEFreezeRegs = true; g_EEFreezeRegs = true;
SetCPUState(g_sseMXCSR, g_sseVUMXCSR);
try { try {
EnterRecompiledCode(); EnterRecompiledCode();
} }
catch( Exception::ForceDispatcherReg& ) { } catch( Exception::ForceDispatcherReg& ) { }
} }
} }
catch( Exception::ExitRecExecute& ) {} catch( Exception::ExitRecExecute& ) {}
@ -719,7 +717,6 @@ static void recExecute()
pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate ); pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldstate );
eeRecIsReset = false; eeRecIsReset = false;
SetCPUState(g_sseMXCSR, g_sseVUMXCSR);
#ifdef _WIN32 #ifdef _WIN32
__try { __try {