* 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:
__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?
};

View File

@ -21,18 +21,15 @@
#include "SysThreads.h"
#include "SaveState.h"
#include "Elfheader.h"
#include "Plugins.h"
#include "R5900.h"
#include "R3000A.h"
#include "VUmicro.h"
#include "GS.h"
#ifdef __WXMSW__
# include <wx/msw/wrapwin.h>
#endif
#include <xmmintrin.h>
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
// effects).
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
cpuExecuteBios();
loadElfFile( elf_file );
}
@ -229,12 +227,14 @@ void SysCoreThread::StateCheckInThread()
void SysCoreThread::ExecuteTaskInThread()
{
Threading::EnableHiresScheduler();
tls_coreThread = this;
m_sem_event.WaitWithoutYield();
m_mxcsr_saved.bitmask = _mm_getcsr();
PCSX2_PAGEFAULT_PROTECT {
StateCheckInThread();
SetCPUState( EmuConfig.Cpu.sseMXCSR, EmuConfig.Cpu.sseVUMXCSR );
Cpu->Execute();
} PCSX2_PAGEFAULT_EXCEPT;
}
@ -260,6 +260,8 @@ void SysCoreThread::OnCleanupInThread()
{
m_hasValidState = false;
_mm_setcsr( m_mxcsr_saved.bitmask );
Threading::DisableHiresScheduler();
if( g_plugins != NULL )

View File

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

View File

@ -15,6 +15,7 @@
#include "PrecompiledHeader.h"
#include "MainFrame.h"
#include "ps2/BiosTools.h"
AppCoreThread CoreThread;
@ -191,52 +192,18 @@ void AppCoreThread::ApplySettings( const Pcsx2Config& src )
void AppCoreThread::ExecuteTaskInThread()
{
try
{
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.") );
_parent::ExecuteTaskInThread();
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();
Console.Error( ex.FormatDiagnosticMessage() );
Msgbox::Alert( ex.FormatDisplayMessage(), _("Plugin Open Error") );
/*if( HandlePluginError( ex ) )
if( HandlePluginError( ex ) )
{
// 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 "Plugins.h"
#include "SaveState.h"
#include "ps2/BiosTools.h"
#include "Dialogs/ModalPopups.h"
#include "Dialogs/ConfigurationDialog.h"
@ -139,6 +140,7 @@ void Pcsx2App::OnCoreThreadStatus( wxCommandEvent& evt )
{
m_evtsrc_CoreThreadStatus.Dispatch( evt );
ScopedBusyCursor::SetDefault( Cursor_NotBusy );
CoreThread.RethrowException();
}
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
{
try {
(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 )
{
Console.Warning( ex.FormatDiagnosticMessage() );

View File

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

View File

@ -93,6 +93,8 @@ public:
ConfButtons& Abort() { m_Abort = true; return *this; }
ConfButtons& Retry() { m_Retry = 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 HasCancel() const { return m_Cancel; }

View File

@ -44,16 +44,17 @@ struct romdir
u32 BiosVersion; // Used in Memory, Misc, CDVD
// 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()
Exception::BiosLoadFailed::BiosLoadFailed( const wxString& filename, const wxString& msg_diag, const wxString& msg_user )
{
return pxE( ".Popup:BiosDumpRequired",
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."
wxString diag( msg_user.IsEmpty() ?
L"BIOS has not been configured, or the configuration has been corrupted." : msg_user
);
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.
@ -146,27 +147,32 @@ static void loadBiosRom( const wxChar *ext, u8 *dest, s64 maxSize )
void LoadBIOS()
{
pxAssertDev( PS2MEM_ROM != NULL, "PS2 system memory has not been initialized yet." );
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 );
if( filesize > 0 )
if( filesize <= 0 )
{
wxFile fp( Bios.c_str() );
fp.Read( PS2MEM_ROM, min( (s64)Ps2MemSize::Rom, filesize ) );
}
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()
throw Exception::BiosLoadFailed( Bios,
L"Configured BIOS file does not exist.",
_("The configured BIOS file does not exist. Please re-configure.")
);
}
wxFile fp( Bios );
fp.Read( PS2MEM_ROM, min( (s64)Ps2MemSize::Rom, filesize ) );
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);
//injectIRX("host.irx"); //not fully tested; still buggy

View File

@ -15,8 +15,20 @@
#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 wxString BIOS_GetMsg_Required();
extern void LoadBIOS();
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
dbl_ps2_overflow, // overflow & clamp if above or equal
dbl_underflow; // underflow if below
u64 padding;
u64 dbl_s_pos[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,1151,0),
DOUBLE(0,1152,0),
DOUBLE(0,897,0),
DOUBLE(0,1151,0), // cvt_overflow
DOUBLE(0,1152,0), // ps2_overflow
DOUBLE(0,897,0), // underflow
0, // Padding!!
{0x7fffffffffffffffULL, 0},
//{0x8000000000000000ULL, 0},

View File

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

View File

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