wxGui branch: Holy crap! I converted it to unicode! This was an absolutely maddening experience. [also: Merged with /trunk]

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1069 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-04-27 02:04:31 +00:00
commit 5d36fe3839
238 changed files with 17755 additions and 14481 deletions

View File

@ -26,6 +26,7 @@
InheritedPropertySheets="..\..\..\3rdparty.vsprops" InheritedPropertySheets="..\..\..\3rdparty.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
WholeProgramOptimization="1" WholeProgramOptimization="1"
> >
<Tool <Tool
@ -52,7 +53,7 @@
OmitFramePointers="true" OmitFramePointers="true"
WholeProgramOptimization="true" WholeProgramOptimization="true"
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib" AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib"
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_UNICODE=1;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
BufferSecurityCheck="false" BufferSecurityCheck="false"
@ -107,6 +108,7 @@
InheritedPropertySheets="..\..\..\3rdparty.vsprops" InheritedPropertySheets="..\..\..\3rdparty.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
> >
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
@ -128,7 +130,7 @@
AdditionalOptions="/EHsc " AdditionalOptions="/EHsc "
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib" AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib"
PreprocessorDefinitions="WIN32;_LIB;_DEBUG;__WXMSW__;__WXDEBUG__;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_LIB;_DEBUG;__WXMSW__;__WXDEBUG__;wxUSE_GUI=0;wxUSE_BASE=1;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -179,6 +181,7 @@
InheritedPropertySheets="..\..\..\3rdparty.vsprops" InheritedPropertySheets="..\..\..\3rdparty.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
<Tool <Tool
@ -204,7 +207,7 @@
FavorSizeOrSpeed="2" FavorSizeOrSpeed="2"
WholeProgramOptimization="false" WholeProgramOptimization="false"
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib" AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib"
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_UNICODE=1;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"

View File

@ -20,7 +20,7 @@
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="10" ConfigurationType="10"
CharacterSet="2" CharacterSet="1"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
<Tool <Tool
@ -41,7 +41,7 @@
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="10" ConfigurationType="10"
CharacterSet="2" CharacterSet="1"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
<Tool <Tool
@ -62,7 +62,7 @@
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="10" ConfigurationType="10"
CharacterSet="2" CharacterSet="1"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
<Tool <Tool
@ -102,7 +102,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h" Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
CommandLine="cl /EP /nologo &quot;$(InputPath)&quot; &gt; &quot;..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h&quot;" CommandLine="cl /EP /nologo &quot;$(InputPath)&quot; &gt; &quot;..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h&quot;&#x0D;&#x0A;"
Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h" Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
/> />
</FileConfiguration> </FileConfiguration>
@ -112,7 +112,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h" Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
CommandLine="cl /EP /nologo &quot;$(InputPath)&quot; &gt; &quot;..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h&quot;" CommandLine="cl /EP /nologo &quot;$(InputPath)&quot; &gt; &quot;..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h&quot;&#x0D;&#x0A;"
Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h" Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
/> />
</FileConfiguration> </FileConfiguration>
@ -122,7 +122,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h" Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
CommandLine="cl /EP /nologo &quot;$(InputPath)&quot; &gt; &quot;..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h&quot;" CommandLine="cl /EP /nologo &quot;$(InputPath)&quot; &gt; &quot;..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h&quot;&#x0D;&#x0A;"
Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h" Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
/> />
</FileConfiguration> </FileConfiguration>
@ -136,7 +136,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Creating ..\..\lib\vc_lib\mswd\wx\setup.h" Description="Creating ..\..\lib\vc_lib\mswd\wx\setup.h"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\lib\vc_lib\mswd\wx\setup.h" CommandLine="copy &quot;$(InputPath)&quot; ..\..\lib\vc_lib\mswd\wx\setup.h&#x0D;&#x0A;"
Outputs="..\..\lib\vc_lib\mswd\wx\setup.h" Outputs="..\..\lib\vc_lib\mswd\wx\setup.h"
/> />
</FileConfiguration> </FileConfiguration>
@ -146,7 +146,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Creating ..\..\lib\vc_lib\msw\wx\setup.h" Description="Creating ..\..\lib\vc_lib\msw\wx\setup.h"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\lib\vc_lib\msw\wx\setup.h" CommandLine="copy &quot;$(InputPath)&quot; ..\..\lib\vc_lib\msw\wx\setup.h&#x0D;&#x0A;"
Outputs="..\..\lib\vc_lib\msw\wx\setup.h" Outputs="..\..\lib\vc_lib\msw\wx\setup.h"
/> />
</FileConfiguration> </FileConfiguration>
@ -156,7 +156,7 @@
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
Description="Creating ..\..\lib\vc_lib\msw\wx\setup.h" Description="Creating ..\..\lib\vc_lib\msw\wx\setup.h"
CommandLine="copy &quot;$(InputPath)&quot; ..\..\lib\vc_lib\msw\wx\setup.h" CommandLine="copy &quot;$(InputPath)&quot; ..\..\lib\vc_lib\msw\wx\setup.h&#x0D;&#x0A;"
Outputs="..\..\lib\vc_lib\msw\wx\setup.h" Outputs="..\..\lib\vc_lib\msw\wx\setup.h"
/> />
</FileConfiguration> </FileConfiguration>

View File

@ -26,6 +26,7 @@
InheritedPropertySheets="..\..\..\3rdparty.vsprops" InheritedPropertySheets="..\..\..\3rdparty.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
> >
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
@ -47,7 +48,7 @@
AdditionalOptions="/EHsc " AdditionalOptions="/EHsc "
Optimization="0" Optimization="0"
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png" AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png"
PreprocessorDefinitions="WIN32;_LIB;_DEBUG;__WXMSW__;__WXDEBUG__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_LIB;_DEBUG;__WXMSW__;__WXDEBUG__;wxUSE_BASE=0;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true" MinimalRebuild="true"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="1"
@ -98,6 +99,7 @@
InheritedPropertySheets="..\..\..\3rdparty.vsprops" InheritedPropertySheets="..\..\..\3rdparty.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
WholeProgramOptimization="1" WholeProgramOptimization="1"
> >
<Tool <Tool
@ -124,7 +126,7 @@
OmitFramePointers="true" OmitFramePointers="true"
WholeProgramOptimization="true" WholeProgramOptimization="true"
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png" AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png"
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_BASE=0;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
BufferSecurityCheck="false" BufferSecurityCheck="false"
@ -178,6 +180,7 @@
InheritedPropertySheets="..\..\..\3rdparty.vsprops" InheritedPropertySheets="..\..\..\3rdparty.vsprops"
UseOfMFC="0" UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false" ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="1"
WholeProgramOptimization="0" WholeProgramOptimization="0"
> >
<Tool <Tool
@ -203,7 +206,7 @@
FavorSizeOrSpeed="2" FavorSizeOrSpeed="2"
WholeProgramOptimization="false" WholeProgramOptimization="false"
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png" AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png"
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_BASE=0;_CRT_SECURE_NO_WARNINGS" PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_BASE=0;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
StringPooling="true" StringPooling="true"
RuntimeLibrary="0" RuntimeLibrary="0"
EnableFunctionLevelLinking="true" EnableFunctionLevelLinking="true"

View File

@ -55,8 +55,6 @@
// disable the default case in a switch // disable the default case in a switch
#define jNO_DEFAULT \ #define jNO_DEFAULT \
{ \ { \
break; \
\
default: \ default: \
jASSUME(0); \ jASSUME(0); \
break; \ break; \
@ -88,6 +86,7 @@ typedef unsigned int uint;
#define __naked __declspec(naked) #define __naked __declspec(naked)
#define __unused /*unused*/ #define __unused /*unused*/
#define __noinline __declspec(noinline)
#define CALLBACK __stdcall #define CALLBACK __stdcall
#else // _MSC_VER #else // _MSC_VER
@ -136,6 +135,7 @@ typedef union _LARGE_INTEGER
#define __unused __attribute__((unused)) #define __unused __attribute__((unused))
#define _inline __inline__ __attribute__((unused)) #define _inline __inline__ __attribute__((unused))
#define __forceinline __attribute__((always_inline,unused)) #define __forceinline __attribute__((always_inline,unused))
#define __noinline __attribute__((noinline))
#define __naked // GCC lacks the naked specifier #define __naked // GCC lacks the naked specifier
#define CALLBACK // CALLBACK is win32-specific mess #define CALLBACK // CALLBACK is win32-specific mess

View File

@ -20,11 +20,11 @@
#define __PCSX2CONFIG_H__ #define __PCSX2CONFIG_H__
// Hack so that you can still use this file from C (not C++), or from a plugin without access to Paths.h. // Hack so that you can still use this file from C (not C++), or from a plugin without access to Paths.h.
#ifdef PLUGIN_ONLY // .. and removed in favor of a less hackish approach (air)
#ifndef g_MaxPath
#define g_MaxPath 255 #define g_MaxPath 255
#else #endif
#include "Paths.h"
#endif
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
// Session Configuration Override Flags // Session Configuration Override Flags
@ -44,7 +44,8 @@ extern SessionOverrideFlags g_Session;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Pcsx2 User Configuration Options! // Pcsx2 User Configuration Options!
//#define PCSX2_MICROVU // Use Micro VU recs instead of Zero VU Recs //#define PCSX2_MICROVU // Use Micro VU recs instead of Zero VU Recs
//#define PCSX2_MICROVU_ // Fully enable Micro VU recs (temporary option for now)
#define PCSX2_GSMULTITHREAD 1 // uses multi-threaded gs #define PCSX2_GSMULTITHREAD 1 // uses multi-threaded gs
#define PCSX2_EEREC 0x10 #define PCSX2_EEREC 0x10
#define PCSX2_VU0REC 0x20 #define PCSX2_VU0REC 0x20
@ -55,19 +56,20 @@ extern SessionOverrideFlags g_Session;
#define PCSX2_FRAMELIMIT_SKIP 0x800 #define PCSX2_FRAMELIMIT_SKIP 0x800
#define PCSX2_FRAMELIMIT_VUSKIP 0xc00 #define PCSX2_FRAMELIMIT_VUSKIP 0xc00
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK)
//------------ CPU Options!!! ---------------
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD) #define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
#define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC) #define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
//------------ SPEED/MISC HACKS!!! --------------- #define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC)
#define CHECK_EE_CYCLERATE (Config.Hacks & 0x03) #define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC))
#define CHECK_IOP_CYCLERATE (Config.Hacks & 0x08)
#define CHECK_WAITCYCLE_HACK (Config.Hacks & 0x10)
#define CHECK_INTC_STAT_HACK (Config.Hacks & 0x20)
#define CHECK_ESCAPE_HACK (Config.Hacks & 0x400)
//------------ SPECIAL GAME FIXES!!! --------------- //------------ SPECIAL GAME FIXES!!! ---------------
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate. #define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu. #define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x2) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again). #define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x2) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
#define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs. #define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs.
//------------ Advanced Options!!! --------------- //------------ Advanced Options!!! ---------------
#define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1) #define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1)
#define CHECK_VU_EXTRA_OVERFLOW (Config.vuOptions & 0x2) // If enabled, Operands are clamped before being used in the VU recs #define CHECK_VU_EXTRA_OVERFLOW (Config.vuOptions & 0x2) // If enabled, Operands are clamped before being used in the VU recs
@ -80,14 +82,40 @@ extern SessionOverrideFlags g_Session;
#define CHECK_FPU_FULL (Config.eeOptions & 0x4) #define CHECK_FPU_FULL (Config.eeOptions & 0x4)
#define DEFAULT_eeOptions 0x01 #define DEFAULT_eeOptions 0x01
#define DEFAULT_vuOptions 0x01 #define DEFAULT_vuOptions 0x01
//------------ DEFAULT sseMXCSR VALUES!!! --------------- //------------ DEFAULT sseMXCSR VALUES!!! ---------------
#define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop" #define DEFAULT_sseMXCSR 0xffc0 //FPU rounding > DaZ, FtZ, "chop"
#define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop" #define DEFAULT_sseVUMXCSR 0xffc0 //VU rounding > DaZ, FtZ, "chop"
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK) //------------ Recompiler defines - Comment to disable a recompiler ---------------
// Yay! These work now! (air) ... almost (air)
#define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC) #define SHIFT_RECOMPILE // Speed majorly reduced if disabled
#define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC)) #define BRANCH_RECOMPILE // Speed extremely reduced if disabled - more then shift
// Disabling all the recompilers in this block is interesting, as it still runs at a reasonable rate.
// It also adds a few glitches. Really reminds me of the old Linux 64-bit version. --arcum42
#define ARITHMETICIMM_RECOMPILE
#define ARITHMETIC_RECOMPILE
#define MULTDIV_RECOMPILE
#define JUMP_RECOMPILE
#define LOADSTORE_RECOMPILE
#define MOVE_RECOMPILE
#define MMI_RECOMPILE
#define MMI0_RECOMPILE
#define MMI1_RECOMPILE
#define MMI2_RECOMPILE
#define MMI3_RECOMPILE
#define FPU_RECOMPILE
#define CP0_RECOMPILE
#define CP2_RECOMPILE
// You can't recompile ARITHMETICIMM without ARITHMETIC.
#ifndef ARITHMETIC_RECOMPILE
#undef ARITHMETICIMM_RECOMPILE
#endif
#define EE_CONST_PROP // rec2 - enables constant propagation (faster)
// Memory Card configuration, per slot. // Memory Card configuration, per slot.
struct McdConfig struct McdConfig
@ -133,7 +161,15 @@ public:
int PsxType; int PsxType;
int Patch; int Patch;
int CustomFps; int CustomFps;
int Hacks; struct Hacks_t {
int EECycleRate;
bool IOPCycleDouble;
bool WaitCycleExt;
bool INTCSTATSlow;
int VUCycleSteal;
bool IdleLoopFF;
bool ESCExits; // this is a hack!?
} Hacks;
int GameFixes; int GameFixes;
int CustomFrameSkip; int CustomFrameSkip;
int CustomConsecutiveFrames; int CustomConsecutiveFrames;

251
pcsx2/AsciiString.cpp Normal file
View File

@ -0,0 +1,251 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "SafeArray.h"
#include "AsciiString.h"
using namespace Threading;
namespace AsciiStringAllocator
{
struct PrivateHandle
{
AsciiStringAllocatorHandle* PublicHandle;
};
static const uint UnitLength = 256;
static const uint UnitLengthMask = UnitLength-1;
static const uint AllocationCleanupThreshold = 256;
static const uint InitialBufferLength = 0x100000; // 1MB!
static const AsciiStringAllocatorHandle* PublicHandleAllocated = (AsciiStringAllocatorHandle*)1;
static uint m_release_counter( 0 );
static SafeArray<PrivateHandle> m_PrivateHandles( InitialBufferLength / UnitLength );
static SafeArray<char> m_StringBuffer( InitialBufferLength );
static int m_NextPrivateHandle;
static int m_NextBufferIndex;
static MutexLock m_Lock;
static char* GetPtr( const AsciiStringAllocatorHandle& handle )
{
return &m_StringBuffer[ m_PrivateHandles[ handle.Index ] ];
}
static void DoCompact()
{
if( m_release_counter < AllocationCleanupThreshold ) return;
ScopedLock locker( m_Lock );
int handlecount = m_PrivateHandles.GetLength();
int writepos = 0;
for( int readpos=0; readpos<handlecount; readpos++ )
{
PrivateHandle& curhandle = m_PrivateHandles[readpos];
if( curhandle.PublicHandle != NULL )
{
int cwpos = writepos;
writepos++;
if( cwpos == readpos ) continue;
if( curhandle.PublicHandle != PublicHandleAllocated )
curhandle.PublicHandle->Index = cwpos;
// todo: replace this with a hardcoded XMM inline copy of 256 bytes. :)
memcpy_fast(
m_StringBuffer.GetPtr(cwpos*UnitLength),
m_StringBuffer.GetPtr(readpos*UnitLength),
UnitLength
);
}
}
}
void New( AsciiStringAllocatorHandle& dest, int length )
{
int numblocks = (length / UnitLength)+1;
length = numblocks * UnitLength;
ScopedLock locker( m_Lock );
AsciiStringAllocatorHandle retval( m_NextPrivateHandle, length );
m_PrivateHandles[m_NextPrivateHandle++].PublicHandle = &dest;
for( int p=numblocks-1; p; --p, ++m_NextPrivateHandle )
m_PrivateHandles[m_NextPrivateHandle].PublicHandle = PublicHandleAllocated;
m_StringBuffer.MakeRoomFor( m_NextPrivateHandle * UnitLength );
return retval;
}
bool Grow( AsciiStringAllocatorHandle& dest )
{
ScopedLock locker( m_lock );
if( m_PrivateHandles[m_NextPrivateHandle].PublicHandle == NULL )
{
m_PrivateHandles[m_NextPrivateHandle].PublicHandle = PublicHandleAllocated;
return true;
}
return false;
}
// releases the block without clearing the handle structure information
// and without doing a block compact check.
static int _release( AsciiStringAllocatorHandle& handle )
{
const int numblocks = handle.Length / UnitLength;
const int endblock = handle.Index + numblocks;
ScopedLock locker( m_Lock );
for( int i=handle.Index; i<endblock; i++ )
m_PrivateHandles[i].PublicHandle = NULL;
// Rewind the NextPrivateHandle if we haven't allocated anything else
// since this allocation was made.
if( endblock == m_NextPrivateHandle )
m_NextPrivateHandle = handle.Index;
return numblocks;
}
void Release( AsciiStringAllocatorHandle& handle )
{
handle.Index = -1;
handle.Length = 0;
m_release_counter += _release( handle );
if( m_release_counter >= AllocationCleanupThreshold )
DoCleanup();
}
// Allocates a new handle and copies the old string contents to the new reserve.
void Reallocate( AsciiStringAllocatorHandle& handle, int newsize )
{
int newblocks = (newsize / UnitLength)+1;
newsize = newblocks * UnitLength;
ScopedLock locker( m_Lock );
_release( handle );
m_StringBuffer.MakeRoomFor( m_NextPrivateHandle + newblocks );
if( m_NextPrivateHandle != handle.Index )
{
memcpy_fast(
m_StringBuffer.GetPtr( m_NextPrivateHandle ),
m_StringBuffer(handle.Index),
handle.Length
);
handle.Index = m_NextPrivateHandle;
}
handle.Length = newsize;
}
};
AsciiStringAllocatorHandle::GetPtr() const
{
return AsciiStringAllocator::GetPtr( *this );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
AsciiString::AsciiString( int length_reserve )
{
AsciiStringAllocator::New( m_MemoryHandle, len )
}
const wxCharBuffer AsciiString::mb_str() const
{
// use wxCharBuffer here for sake of safety, since parallel string operations could
// result in the pointer to this string becoming invalid.
ScopedLock locker( AsciiStringAllocator::m_Lock );
return wxCharBuffer( AsciiStringAllocator::GetPtr( m_MemoryHandle ) );
}
AsciiStringLock::operator char*()
{
return m_buffer;
}
char& AsciiStringLock::operator[]( int idx )
{
return m_buffer[idx];
}
char AsciiStringLock::GetCharAt( int idx ) const
{
return m_buffer[idx];
}
char* AsciiStringLock::GetPtr()
{
return m_buffer;
}
AsciiStringLock::AsciiStringLock( AsciiString& str ) :
m_string( str )
{
m_string.Lock();
}
AsciiStringLock::~AsciiStringLock()
{
m_string.Unlock();
}
AsciiStringLock::operator char*()
{
AsciiStringAllocator::GetPtr( m_handle );
}
AsciiString AsciiString::operator+( const AsciiString& right )
{
int len = GetLength() + right.GetLength();
AsciiString dest( len+1 );
char* lockptr = m_MemoryHandle.GetPtr();
memcpy_fast( lockptr, GetBufferPtr(), GetLength() );
memcpy_fast( lockptr+GetLength(), right.GetBufferPtr(), right.GetLength() );
lockptr[dest.GetLength()] = 0;
}
AsciiString& AsciiString::Append( const AsciiString& src )
{
int needlen = src.GetLength() + GetLength()+1;
if( needlen >= m_MemoryHandle.Length )
{
// The new string is too large -- looks like we're going to need to allocate
// a larger block. We try and use Grow first, if the appending string is very
// short (it sometimes saves the need to copy the block to a new location)
if( src.GetLength() >= AsciiStringAllocator::UnitLength || !AsciiStringAllocator::Grow( m_MemoryHandle ) )
AsciiStringAllocator::Reallocate( m_MemoryHandle, needlen );
}
char* lockptr = m_MemoryHandle.GetPtr();
memcpy_fast( lockptr+GetLength(), src.GetBufferPtr(), src.GetLength() );
lockptr[GetLength()] = 0;
}

84
pcsx2/AsciiString.h Normal file
View File

@ -0,0 +1,84 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
class AsciiStringAllocatorHandle
{
public:
const int Index;
const int Length;
public:
AsciiStringAllocatorHandle( int handle, int len ) :
Index( handle ),
Length( len )
{
}
char* GetPtr() const;
void Lock();
void Unlock();
};
class AsciiString
{
protected:
AsciiStringAllocatorHandle m_MemoryHandle;
int m_Length;
public:
AsciiString();
AsciiString( AsciiString& copycat );
AsciiString( const char* src );
AsciiString( const char* src, int length );
AsciiString( const char* src, int startpos, int length );
AsciiString( int length_reserve );
const char* mb_str() const;
char mb_str_unsafe();
int GetLength() const
{
return m_Length;
}
AsciiString operator+( const AsciiString& right );
AsciiString& Append( const AsciiString& src );
void Lock();
void Unlock();
};
class AsciiStringLock
{
protected:
AsciiString& m_string;
char* m_buffer;
public:
AsciiStringLock( const AsciiStringAllocatorHandle& handle );
~AsciiStringLock();
char* GetPtr();
char GetCharAt( int idx ) const;
operator char*();
char& operator[]( int idx );
const char& operator[]( int idx ) const { return GetCharAt( idx ); }
};

View File

@ -19,6 +19,7 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include <ctype.h> #include <ctype.h>
#include <wx/datetime.h>
#include "IopCommon.h" #include "IopCommon.h"
#include "CDVDiso.h" #include "CDVDiso.h"
@ -240,12 +241,12 @@ FILE *_cdvdOpenMechaVer() {
FILE* fd; FILE* fd;
// get the name of the bios file // get the name of the bios file
string Bios( Path::Combine( Config.BiosDir, Config.Bios ) );
// use the bios filename to get the name of the mecha ver file // use the bios filename to get the name of the mecha ver file
// [TODO] : Upgrade this to use std::string! // [TODO] : Upgrade this to use wxString!
strcpy(file, Bios.c_str()); strcpy(file, g_Conf.Files.Bios().ToAscii().data() );
ptr = file; i = (int)strlen(file); ptr = file; i = (int)strlen(file);
while (i > 0) { if (ptr[i] == '.') break; i--; } while (i > 0) { if (ptr[i] == '.') break; i--; }
ptr[i+1] = '\0'; ptr[i+1] = '\0';
@ -254,11 +255,14 @@ FILE *_cdvdOpenMechaVer() {
// if file doesnt exist, create empty one // if file doesnt exist, create empty one
fd = fopen(file, "r+b"); fd = fopen(file, "r+b");
if (fd == NULL) { if (fd == NULL) {
Console::Notice("MEC File Not Found , Creating Blank File"); Console::Notice( "MEC File Not Found, Creating Blank File..." );
fd = fopen(file, "wb"); fd = fopen(file, "wb");
if (fd == NULL) { if (fd == NULL)
Msgbox::Alert("_cdvdOpenMechaVer: Error creating %s", params file); {
exit(1); Console::Error( "\tMEC File Creation failed!" );
throw Exception::CreateStream( file );
//Msgbox::Alert( "_cdvdOpenMechaVer: Error creating %s", params file);
//exit(1);
} }
fputc(0x03, fd); fputc(0x03, fd);
fputc(0x06, fd); fputc(0x06, fd);
@ -285,12 +289,11 @@ FILE *_cdvdOpenNVM() {
FILE* fd; FILE* fd;
// get the name of the bios file // get the name of the bios file
string Bios( Path::Combine( Config.BiosDir, Config.Bios ) );
// use the bios filename to get the name of the nvm file // use the bios filename to get the name of the nvm file
// [TODO] : Upgrade this to use std::string! // [TODO] : Upgrade this to use std::string!
strcpy( file, Bios.c_str() ); strcpy( file, g_Conf.Files.Bios().ToAscii().data() );
ptr = file; i = (int)strlen(file); ptr = file; i = (int)strlen(file);
while (i > 0) { if (ptr[i] == '.') break; i--; } while (i > 0) { if (ptr[i] == '.') break; i--; }
ptr[i+1] = '\0'; ptr[i+1] = '\0';
@ -301,9 +304,11 @@ FILE *_cdvdOpenNVM() {
if (fd == NULL) { if (fd == NULL) {
Console::Notice("NVM File Not Found , Creating Blank File"); Console::Notice("NVM File Not Found , Creating Blank File");
fd = fopen(file, "wb"); fd = fopen(file, "wb");
if (fd == NULL) { if (fd == NULL)
Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file); {
exit(1); throw Exception::CreateStream( file );
//Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file);
//exit(1);
} }
for (i=0; i<1024; i++) fputc(0, fd); for (i=0; i<1024; i++) fputc(0, fd);
} }
@ -470,7 +475,7 @@ s32 cdvdWriteConfig(const u8* config)
void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) { void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
char str[g_MaxPath]; wxString fname;
int numbers; int numbers;
int letters; int letters;
unsigned int key_0_3; unsigned int key_0_3;
@ -479,7 +484,9 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
char exeName[12]; char exeName[12];
// get main elf name // get main elf name
GetPS2ElfName(str); GetPS2ElfName(fname);
const wxCharBuffer crap( fname.ToAscii() );
const char* str = crap.data();
sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]); sprintf(exeName, "%c%c%c%c%c%c%c%c%c%c%c",str[8],str[9],str[10],str[11],str[12],str[13],str[14],str[15],str[16],str[17],str[18]);
DevCon::Notice("exeName = %s", params &str[8]); DevCon::Notice("exeName = %s", params &str[8]);
@ -693,7 +700,7 @@ __forceinline void cdvdGetDiskType()
cdvd.Type = CDVDgetDiskType(); cdvd.Type = CDVDgetDiskType();
if (cdvd.Type == CDVD_TYPE_PS2CD) // && needReset == 1) if (cdvd.Type == CDVD_TYPE_PS2CD) // && needReset == 1)
{ {
char str[g_MaxPath]; wxString str;
if (GetPS2ElfName(str) == 1) if (GetPS2ElfName(str) == 1)
{ {
cdvd.Type = CDVD_TYPE_PSCD; cdvd.Type = CDVD_TYPE_PSCD;
@ -768,12 +775,18 @@ void cdvdReset()
cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM );
// any random valid date will do // any random valid date will do
cdvd.RTC.hour = 1; //cdvd.RTC.hour = 1;
cdvd.RTC.day = 25; //cdvd.RTC.day = 25;
cdvd.RTC.month = 5; //cdvd.RTC.month = 5;
cdvd.RTC.year = 7; //2007 //cdvd.RTC.year = 7; //2007
cdvdSetSystemTime( cdvd ); wxDateTime curtime( wxDateTime::GetTimeNow() );
cdvd.RTC.second = (u8)curtime.GetSecond();
cdvd.RTC.minute = (u8)curtime.GetMinute();
cdvd.RTC.hour = (u8)(curtime.GetHour()+1) % 24;
cdvd.RTC.day = (u8)curtime.GetDay();
cdvd.RTC.month = (u8)curtime.GetMonth();
cdvd.RTC.year = (u8)(curtime.GetYear() - 2000);
} }
struct Freeze_v10Compat struct Freeze_v10Compat
@ -805,7 +818,7 @@ void cdvdNewDiskCB()
{ {
cdvd.Type = CDVDgetDiskType(); cdvd.Type = CDVDgetDiskType();
if(cdvd.Type == CDVD_TYPE_PS2CD) { if(cdvd.Type == CDVD_TYPE_PS2CD) {
char str[g_MaxPath]; wxString str;
if(GetPS2ElfName(str) == 1) { if(GetPS2ElfName(str) == 1) {
cdvd.Type = CDVD_TYPE_PSCD; cdvd.Type = CDVD_TYPE_PSCD;
} // ENDIF- Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then. } // ENDIF- Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then.

View File

@ -141,7 +141,4 @@ void cdvdWrite17(u8 rt);
void cdvdWrite18(u8 rt); void cdvdWrite18(u8 rt);
void cdvdWrite3A(u8 rt); void cdvdWrite3A(u8 rt);
// Platform dependent system time assignment (see WinMisc / LnxMisc)
extern void cdvdSetSystemTime( cdvdStruct& setme );
#endif /* __CDVD_H__ */ #endif /* __CDVD_H__ */

View File

@ -308,8 +308,8 @@ namespace COP0 {
void MFC0() void MFC0()
{ {
// Note on _Rd_ Condition 9: CP0.Count should be updated even if _Rt_ is 0. // Note on _Rd_ Condition 9: CP0.Count should be updated even if _Rt_ is 0.
if( (_Rd_ != 9) && !_Rt_ ) return; if ((_Rd_ != 9) && !_Rt_ ) return;
if(_Rd_ != 9) { COP0_LOG("%s", disR5900Current.getCString() ); } if (_Rd_ != 9) { COP0_LOG("%s", disR5900Current.getCString() ); }
//if(bExecBIOS == FALSE && _Rd_ == 25) Console::WriteLn("MFC0 _Rd_ %x = %x", params _Rd_, cpuRegs.CP0.r[_Rd_]); //if(bExecBIOS == FALSE && _Rd_ == 25) Console::WriteLn("MFC0 _Rd_ %x = %x", params _Rd_, cpuRegs.CP0.r[_Rd_]);
switch (_Rd_) switch (_Rd_)
@ -412,30 +412,37 @@ int CPCOND0() {
//#define CPCOND0 1 //#define CPCOND0 1
#define BC0(cond) \ /*#define BC0(cond) \
if (CPCOND0() cond) { \ if (CPCOND0() cond) { \
intDoBranch(_BranchTarget_); \ intDoBranch(_BranchTarget_); \
} }*/
void BC0F() { void BC0F() {
BC0(== 0); if (CPCOND0() == 0) intDoBranch(_BranchTarget_);
} }
void BC0T() { void BC0T() {
BC0(== 1); if (CPCOND0() == 1) intDoBranch(_BranchTarget_);
} }
#define BC0L(cond) \ /*#define BC0L(cond) \
if (CPCOND0() cond) { \ if (CPCOND0() cond) { \
intDoBranch(_BranchTarget_); \ intDoBranch(_BranchTarget_); \
} else cpuRegs.pc+= 4; } else cpuRegs.pc+= 4;*/
void BC0FL() { void BC0FL() {
BC0L(== 0); if (CPCOND0() == 0)
intDoBranch(_BranchTarget_);
else
cpuRegs.pc+= 4;
} }
void BC0TL() { void BC0TL() {
BC0L(== 1); if (CPCOND0() == 1)
intDoBranch(_BranchTarget_);
else
cpuRegs.pc+= 4;
} }
void TLBR() { void TLBR() {
@ -482,8 +489,7 @@ void TLBWR() {
void TLBP() { void TLBP() {
int i; int i;
union { union {
struct { struct {
u32 VPN2:19; u32 VPN2:19;
@ -494,13 +500,13 @@ void TLBP() {
u32 u; u32 u;
} EntryHi32; } EntryHi32;
EntryHi32.u=cpuRegs.CP0.n.EntryHi; EntryHi32.u = cpuRegs.CP0.n.EntryHi;
cpuRegs.CP0.n.Index=0xFFFFFFFF; cpuRegs.CP0.n.Index=0xFFFFFFFF;
for(i=0;i<48;i++){ for(i=0;i<48;i++){
if(tlb[i].VPN2==((~tlb[i].Mask)&(EntryHi32.s.VPN2)) if (tlb[i].VPN2 == ((~tlb[i].Mask) & (EntryHi32.s.VPN2))
&&((tlb[i].G&1)||((tlb[i].ASID & 0xff) == EntryHi32.s.ASID))) { && ((tlb[i].G&1) || ((tlb[i].ASID & 0xff) == EntryHi32.s.ASID))) {
cpuRegs.CP0.n.Index=i; cpuRegs.CP0.n.Index = i;
break; break;
} }
} }

View File

@ -25,10 +25,6 @@
#include "VUops.h" #include "VUops.h"
#include "VUmicro.h" #include "VUmicro.h"
//namespace R5900 {
//namespace Interpreter {
//namespace OpcodeImpl{
using namespace R5900; using namespace R5900;
using namespace R5900::Interpreter; using namespace R5900::Interpreter;
@ -85,5 +81,3 @@ void BC2TL()
cpuRegs.pc+= 4; cpuRegs.pc+= 4;
} }
} }
//}}}

View File

@ -937,6 +937,34 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
psxDmaInterrupt(3); psxDmaInterrupt(3);
} }
#ifdef ENABLE_NEW_IOPDMA
s32 cdvdDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed)
{
// hacked up from the code above
if (cdr.Readed == 0)
{
//CDR_LOG("*** DMA 3 *** NOT READY");
wordsProcessed = 0;
return 10000;
}
memcpy_fast(data, cdr.pTransfer, wordsLeft);
//psxCpu->Clear(madr, cdsize/4);
cdr.pTransfer+=wordsLeft;
*wordsProcessed = wordsLeft;
Console::Status("New IOP DMA handled CDVD DMA: channel %d, data %p, remaining %08x, processed %08x.", params channel,data,wordsLeft, *wordsProcessed);
return 0;
}
void cdvdDmaInterrupt(s32 channel)
{
cdrInterrupt();
}
#endif
void cdrReset() { void cdrReset() {
memzero_obj(cdr); memzero_obj(cdr);
cdr.CurTrack=1; cdr.CurTrack=1;

View File

@ -29,6 +29,8 @@
#define PCSX2_VERSION "(beta)" #define PCSX2_VERSION "(beta)"
#include "System.h"
#include "Plugins.h" #include "Plugins.h"
#include "SaveState.h" #include "SaveState.h"
@ -40,7 +42,4 @@
#include "Elfheader.h" #include "Elfheader.h"
#include "Patch.h" #include "Patch.h"
#include "System.h"
#include "Pcsx2Config.h"
#endif /* __COMMON_H__ */ #endif /* __COMMON_H__ */

190
pcsx2/Config.h Normal file
View File

@ -0,0 +1,190 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
class IniInterface;
//////////////////////////////////////////////////////////////////////////////////////////
// Pcsx2 Application Configuration.
//
// [TODO] : Rename this once we get to the point where the old Pcsx2Config stuff isn't in
// the way anymore. :)
//
class AppConfig
{
public:
struct ConsoleLogOptions
{
bool Visible;
// if true, DisplayPos is ignored and the console is automatically docked to the main window.
bool AutoDock;
// Display position used if AutoDock is false (ignored otherwise)
wxPoint DisplayPosition;
wxSize DisplaySize;
void LoadSave( IniInterface& conf );
};
struct FolderOptions
{
wxDirName Plugins;
wxDirName Bios;
wxDirName Snapshots;
wxDirName Savestates;
wxDirName MemoryCards;
wxDirName Dumps;
};
struct FilenameOptions
{
wxFileName Bios;
wxFileName CDVD;
wxFileName GS;
wxFileName PAD1;
wxFileName PAD2;
wxFileName SPU2;
wxFileName USB;
wxFileName FW;
wxFileName DEV9;
};
// Options struct for each memory card.
struct McdOptions
{
wxFileName Filename; // user-configured location of this memory card
bool Enabled; // memory card enabled (if false, memcard will not show up in-game)
};
struct McdSysOptions
{
McdOptions Mcd[2];
bool EnableNTFS; // enables automatic ntfs compression of memory cards (Win32 only)
bool EnableEjection; // enables simulated ejection of memory cards when loading savestates
void LoadSave( IniInterface& conf );
};
struct CpuRecompilerOptions
{
struct
{
bool
Enabled:1, // universal toggle for the profiler.
RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
RecBlocks_VU1:1; // Enables per-block profiling for the VU1 recompiler [unimplemented]
} Profiler;
struct
{
bool
EnableEE:1,
EnableIOP:1,
EnableVU0:1,
EnableVU1:1;
} Recompiler;
void LoadSave( IniInterface& conf );
};
struct VideoOptions
{
bool MultithreadGS; // Uses the multithreaded GS interface.
bool closeOnEsc; // Closes the GS/Video port on escape (good for fullscreen activity)
bool UseFramelimiter;
int RegionMode; // 0=NTSC and 1=PAL
int CustomFps;
int CustomFrameSkip;
int CustomConsecutiveFrames;
int CustomConsecutiveSkip;
void LoadSave( IniInterface& conf );
};
struct GamefixOptions
{
bool
VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
FpuMulHack:1; // Fix for Tales of Destiny hangs.
void LoadSave();
};
struct SpeedhackOptions
{
int
EECycleRate:3, // EE cyclerate selector (1.0, 1.5, 2.0, 3.0)
IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
ExtWaitcycles:1, // enables extended waitcycles duration
IntcStat:1; // tells Pcsx2 to fast-forward through intc_stat waits.
void LoadSave( IniInterface& conf );
};
// Helper functions for returning full pathnames of various Folders and files
struct FullpathHelpers
{
FullpathHelpers( const AppConfig& conf ) : m_conf( conf ) {}
const AppConfig& m_conf;
wxString Bios() const;
wxString CDVD() const;
wxString GS() const;
wxString PAD1() const;
wxString PAD2() const;
wxString SPU2() const;
wxString DEV9() const;
wxString USB() const;
wxString FW() const;
wxString Mcd( uint mcdidx ) const;
};
public:
AppConfig() : Files( *this )
{
}
FullpathHelpers Files;
wxPoint MainGuiPosition;
bool CdvdVerboseReads; // enables cdvd read activity verbosely dumped to the console
CpuRecompilerOptions Cpu;
SpeedhackOptions Speedhacks;
GamefixOptions Gamefixes;
VideoOptions Video;
ConsoleLogOptions ConLogBox;
FolderOptions Folders;
FilenameOptions BaseFilenames;
McdSysOptions MemoryCards;
public:
void LoadSave( IniInterface& ini );
};
extern AppConfig g_Conf;

View File

@ -36,6 +36,7 @@ namespace Console
MutexLock m_writelock; MutexLock m_writelock;
std::string m_format_buffer; std::string m_format_buffer;
// ------------------------------------------------------------------------
void __fastcall SetTitle( const wxString& title ) void __fastcall SetTitle( const wxString& title )
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -43,6 +44,7 @@ namespace Console
FrameHandle->SetTitle( title ); FrameHandle->SetTitle( title );
} }
// ------------------------------------------------------------------------
void __fastcall SetColor( Colors color ) void __fastcall SetColor( Colors color )
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -57,6 +59,7 @@ namespace Console
FrameHandle->ClearColor(); FrameHandle->ClearColor();
} }
// ------------------------------------------------------------------------
bool Newline() bool Newline()
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -67,6 +70,7 @@ namespace Console
return false; return false;
} }
// ------------------------------------------------------------------------
bool __fastcall Write( const char* fmt ) bool __fastcall Write( const char* fmt )
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -91,8 +95,34 @@ namespace Console
return false; return false;
} }
// Writes an unformatted string of text to the console (fast!) // ------------------------------------------------------------------------
// A newline is automatically appended. bool __fastcall Write( const wxString& fmt )
{
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
if( FrameHandle != NULL )
FrameHandle->Write( fmt );
wxCharBuffer jones( fmt.ToAscii() );
fwrite( fmt, 1, strlen( jones.data() ), emuLog );
return false;
}
bool __fastcall Write( Colors color, const wxString& fmt )
{
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
if( FrameHandle != NULL )
{
FrameHandle->SetColor( color );
FrameHandle->Write( fmt );
FrameHandle->ClearColor();
}
wxCharBuffer jones( fmt.ToAscii() );
fwrite( fmt, 1, strlen( jones.data() ), emuLog );
return false;
}
// ------------------------------------------------------------------------
bool __fastcall WriteLn( const char* fmt ) bool __fastcall WriteLn( const char* fmt )
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -106,8 +136,6 @@ namespace Console
return false; return false;
} }
// Writes an unformatted string of text to the console (fast!)
// A newline is automatically appended.
bool __fastcall WriteLn( Colors color, const char* fmt ) bool __fastcall WriteLn( Colors color, const char* fmt )
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -123,6 +151,38 @@ namespace Console
return false; return false;
} }
// ------------------------------------------------------------------------
bool __fastcall WriteLn( const wxString& fmt )
{
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
if( FrameHandle != NULL )
{
FrameHandle->Write( fmt.c_str() );
FrameHandle->Newline();
}
wxCharBuffer jones( fmt.ToAscii() );
fputs( jones.data(), emuLog );
return false;
}
bool __fastcall WriteLn( Colors color, const wxString& fmt )
{
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
if( FrameHandle != NULL )
{
FrameHandle->SetColor( color );
FrameHandle->Write( fmt );
FrameHandle->Newline();
FrameHandle->ClearColor();
}
wxCharBuffer jones( fmt.ToAscii() );
fputs( jones.data(), emuLog );
return false;
}
// ------------------------------------------------------------------------
__forceinline void __fastcall _WriteLn( Colors color, const char* fmt, va_list args ) __forceinline void __fastcall _WriteLn( Colors color, const char* fmt, va_list args )
{ {
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame(); ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
@ -147,12 +207,13 @@ namespace Console
if( color == Color_Red || color == Color_Yellow ) if( color == Color_Red || color == Color_Yellow )
fputs( cstr, stderr ); // log notices and errors to stderr fputs( cstr, stderr ); // log notices and errors to stderr
wxASSERT_MSG( 0, cstr ); wxASSERT_MSG_A( 0, cstr );
} }
fputs( cstr, emuLog ); fputs( cstr, emuLog );
} }
// ------------------------------------------------------------------------
bool Write( const char* fmt, VARG_PARAM dummy, ... ) bool Write( const char* fmt, VARG_PARAM dummy, ... )
{ {
varg_assert(); varg_assert();
@ -184,6 +245,7 @@ namespace Console
return false; return false;
} }
// ------------------------------------------------------------------------
bool WriteLn( const char* fmt, VARG_PARAM dummy, ... ) bool WriteLn( const char* fmt, VARG_PARAM dummy, ... )
{ {
varg_assert(); varg_assert();
@ -198,7 +260,7 @@ namespace Console
return false; return false;
} }
// Writes a line of colored text to the console, with automatic newline appendage. // ------------------------------------------------------------------------
bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... ) bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... )
{ {
varg_assert(); varg_assert();
@ -210,8 +272,7 @@ namespace Console
return false; return false;
} }
// Displays a message in the console with red emphasis. // ------------------------------------------------------------------------
// Newline is automatically appended.
bool Error( const char* fmt, VARG_PARAM dummy, ... ) bool Error( const char* fmt, VARG_PARAM dummy, ... )
{ {
varg_assert(); varg_assert();
@ -223,8 +284,7 @@ namespace Console
return false; return false;
} }
// Displays a message in the console with yellow emphasis. // ------------------------------------------------------------------------
// Newline is automatically appended.
bool Notice( const char* fmt, VARG_PARAM dummy, ... ) bool Notice( const char* fmt, VARG_PARAM dummy, ... )
{ {
varg_assert(); varg_assert();
@ -236,8 +296,7 @@ namespace Console
return false; return false;
} }
// Displays a message in the console with green emphasis. // ------------------------------------------------------------------------
// Newline is automatically appended.
bool Status( const char* fmt, VARG_PARAM dummy, ... ) bool Status( const char* fmt, VARG_PARAM dummy, ... )
{ {
varg_assert(); varg_assert();
@ -249,57 +308,57 @@ namespace Console
return false; return false;
} }
// Displays a message in the console with red emphasis. // ------------------------------------------------------------------------
// Newline is automatically appended.
bool __fastcall Error( const char* fmt ) bool __fastcall Error( const char* fmt )
{ {
WriteLn( Color_Red, fmt ); WriteLn( Color_Red, fmt );
return false; return false;
} }
// Displays a message in the console with yellow emphasis.
// Newline is automatically appended.
bool __fastcall Notice( const char* fmt ) bool __fastcall Notice( const char* fmt )
{ {
WriteLn( Color_Yellow, fmt ); WriteLn( Color_Yellow, fmt );
return false; return false;
} }
// Displays a message in the console with green emphasis.
// Newline is automatically appended.
bool __fastcall Status( const char* fmt ) bool __fastcall Status( const char* fmt )
{ {
WriteLn( Color_Green, fmt ); WriteLn( Color_Green, fmt );
return false; return false;
} }
// ------------------------------------------------------------------------
bool __fastcall Error( const wxString& src )
{
WriteLn( Color_Red, src );
return false;
}
bool __fastcall Notice( const wxString& src )
{
WriteLn( Color_Yellow, src );
return false;
}
bool __fastcall Status( const wxString& src )
{
WriteLn( Color_Green, src );
return false;
}
} }
namespace Msgbox namespace Msgbox
{ {
bool Alert(const char* text) bool Alert( const wxString& text )
{ {
wxMessageBox( text, "Pcsx2 Message", wxOK, wxGetApp().GetTopWindow() ); wxMessageBox( text, wxT("Pcsx2 Message"), wxOK, wxGetApp().GetTopWindow() );
return false; return false;
} }
bool Alert(const char* fmt, VARG_PARAM dummy, ...) bool OkCancel( const wxString& text )
{ {
va_list list; int result = wxMessageBox( text, wxT("Pcsx2 Message"), wxOK | wxCANCEL, wxGetApp().GetTopWindow() );
va_start(list, dummy); return result == wxOK;
Alert( vfmt_string( fmt, list ).c_str() );
va_end(list);
return false;
}
bool OkCancel( const char* fmt, VARG_PARAM dummy, ... )
{
va_list list;
va_start(list, dummy);
int result = wxMessageBox( vfmt_string( fmt, list ), "Pcsx2 Message", wxOK | wxCANCEL, wxGetApp().GetTopWindow() );
va_end(list);
return result == wxOK;
} }
} }

View File

@ -164,7 +164,7 @@ struct vSyncTimingInfo
static vSyncTimingInfo vSyncInfo; static vSyncTimingInfo vSyncInfo;
static __forceinline void vSyncInfoCalc( vSyncTimingInfo* info, u32 framesPerSecond, u32 scansPerFrame ) static void vSyncInfoCalc( vSyncTimingInfo* info, u32 framesPerSecond, u32 scansPerFrame )
{ {
// Important: Cannot use floats or doubles here. The emulator changes rounding modes // Important: Cannot use floats or doubles here. The emulator changes rounding modes
// depending on user-set speedhack options, and it can break float/double code // depending on user-set speedhack options, and it can break float/double code
@ -270,8 +270,6 @@ u32 UpdateVSyncRate()
return (u32)m_iTicks; return (u32)m_iTicks;
} }
extern u32 vu0time;
void frameLimitReset() void frameLimitReset()
{ {
m_iStart = GetCPUTicks(); m_iStart = GetCPUTicks();
@ -282,13 +280,13 @@ void frameLimitReset()
// See the GS FrameSkip function for details on why this is here and not in the GS. // See the GS FrameSkip function for details on why this is here and not in the GS.
static __forceinline void frameLimit() static __forceinline void frameLimit()
{ {
if( CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_NORMAL ) return;
if( Config.CustomFps >= 999 ) return; // means the user would rather just have framelimiting turned off...
s64 sDeltaTime; s64 sDeltaTime;
u64 uExpectedEnd; u64 uExpectedEnd;
u64 iEnd; u64 iEnd;
if( CHECK_FRAMELIMIT == PCSX2_FRAMELIMIT_NORMAL ) return;
if( Config.CustomFps >= 999 ) return; // means the user would rather just have framelimiting turned off...
uExpectedEnd = m_iStart + m_iTicks; uExpectedEnd = m_iStart + m_iTicks;
iEnd = GetCPUTicks(); iEnd = GetCPUTicks();
@ -465,7 +463,7 @@ __forceinline bool rcntUpdate_vSync()
return false; return false;
} }
static __forceinline void __fastcall _cpuTestTarget( int i ) static __forceinline void _cpuTestTarget( int i )
{ {
if (counters[i].count < counters[i].target) return; if (counters[i].count < counters[i].target) return;
@ -538,7 +536,7 @@ __forceinline bool rcntUpdate()
return retval; return retval;
} }
static void _rcntSetGate( int index ) static __forceinline void _rcntSetGate( int index )
{ {
if (counters[index].mode.EnableGate) if (counters[index].mode.EnableGate)
{ {
@ -563,7 +561,7 @@ static void _rcntSetGate( int index )
} }
// mode - 0 means hblank source, 8 means vblank source. // mode - 0 means hblank source, 8 means vblank source.
void __fastcall rcntStartGate(bool isVblank, u32 sCycle) __forceinline void rcntStartGate(bool isVblank, u32 sCycle)
{ {
int i; int i;
@ -624,7 +622,7 @@ void __fastcall rcntStartGate(bool isVblank, u32 sCycle)
} }
// mode - 0 means hblank signal, 8 means vblank signal. // mode - 0 means hblank signal, 8 means vblank signal.
void __fastcall rcntEndGate(bool isVblank , u32 sCycle) __forceinline void rcntEndGate(bool isVblank , u32 sCycle)
{ {
int i; int i;
@ -665,7 +663,7 @@ void __fastcall rcntEndGate(bool isVblank , u32 sCycle)
// rcntUpdate, since we're being called from there anyway. // rcntUpdate, since we're being called from there anyway.
} }
void __fastcall rcntWmode(int index, u32 value) __forceinline void rcntWmode(int index, u32 value)
{ {
if(counters[index].mode.IsCounting) { if(counters[index].mode.IsCounting) {
if(counters[index].mode.ClockSource != 0x3) { if(counters[index].mode.ClockSource != 0x3) {
@ -696,7 +694,7 @@ void __fastcall rcntWmode(int index, u32 value)
_rcntSet( index ); _rcntSet( index );
} }
void __fastcall rcntWcount(int index, u32 value) __forceinline void rcntWcount(int index, u32 value)
{ {
EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x", index, value, counters[index].count, counters[index].target ); EECNT_LOG("EE Counter[%d] writeCount = %x, oldcount=%x, target=%x", index, value, counters[index].count, counters[index].target );
@ -722,7 +720,7 @@ void __fastcall rcntWcount(int index, u32 value)
_rcntSet( index ); _rcntSet( index );
} }
void __fastcall rcntWtarget(int index, u32 value) __forceinline void rcntWtarget(int index, u32 value)
{ {
EECNT_LOG("EE Counter[%d] writeTarget = %x", index, value); EECNT_LOG("EE Counter[%d] writeTarget = %x", index, value);
@ -738,13 +736,13 @@ void __fastcall rcntWtarget(int index, u32 value)
_rcntSet( index ); _rcntSet( index );
} }
void __fastcall rcntWhold(int index, u32 value) __forceinline void rcntWhold(int index, u32 value)
{ {
EECNT_LOG("EE Counter[%d] Hold Write = %x", index, value); EECNT_LOG("EE Counter[%d] Hold Write = %x", index, value);
counters[index].hold = value; counters[index].hold = value;
} }
u32 __fastcall rcntRcount(int index) __forceinline u32 rcntRcount(int index)
{ {
u32 ret; u32 ret;
@ -759,7 +757,7 @@ u32 __fastcall rcntRcount(int index)
return ret; return ret;
} }
u32 __fastcall rcntCycle(int index) __forceinline u32 rcntCycle(int index)
{ {
if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3)) if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3))
return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate); return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate);

View File

@ -139,14 +139,14 @@ extern bool rcntUpdate_vSync();
extern bool rcntUpdate(); extern bool rcntUpdate();
extern void rcntInit(); extern void rcntInit();
extern void __fastcall rcntStartGate(bool mode, u32 sCycle); extern void rcntStartGate(bool mode, u32 sCycle);
extern void __fastcall rcntEndGate(bool mode, u32 sCycle); extern void rcntEndGate(bool mode, u32 sCycle);
extern void __fastcall rcntWcount(int index, u32 value); extern void rcntWcount(int index, u32 value);
extern void __fastcall rcntWmode(int index, u32 value); extern void rcntWmode(int index, u32 value);
extern void __fastcall rcntWtarget(int index, u32 value); extern void rcntWtarget(int index, u32 value);
extern void __fastcall rcntWhold(int index, u32 value); extern void rcntWhold(int index, u32 value);
extern u32 __fastcall rcntRcount(int index); extern u32 rcntRcount(int index);
extern u32 __fastcall rcntCycle(int index); extern u32 rcntCycle(int index);
u32 UpdateVSyncRate(); u32 UpdateVSyncRate();
void frameLimitReset(); void frameLimitReset();

View File

@ -216,6 +216,8 @@ extern bool SrcLog_GPU( const char* fmt, ... );
#define MEMCARDS_LOG 0&& #define MEMCARDS_LOG 0&&
#endif #endif
//#define VIFUNPACKDEBUG //enable unpack debugging output
#ifdef VIFUNPACKDEBUG #ifdef VIFUNPACKDEBUG
#define VIFUNPACK_LOG VIF_LOG #define VIFUNPACK_LOG VIF_LOG
#else #else

View File

@ -606,7 +606,7 @@ void (*COP2SPECIAL2PrintTable[128])( string& output ) =
//**************************TABLES CALLS*********************** //**************************TABLES CALLS***********************
void disR5900Fasm(string& output, u32 code, u32 pc) void disR5900Fasm( string& output, u32 code, u32 pc )
{ {
string dbuf; string dbuf;
char obuf[48]; char obuf[48];

303
pcsx2/Dump.cpp Normal file
View File

@ -0,0 +1,303 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
////////////////////////////////////////////////////
#include "PrecompiledHeader.h"
#include "IopCommon.h"
#include "Counters.h"
#include "iCore.h"
#include "iR5900.h"
#include "IPU/IPU.h"
using namespace R5900;
// fixme: currently should not be uncommented.
//#define TEST_BROKEN_DUMP_ROUTINES
#ifdef TEST_BROKEN_DUMP_ROUTINES
//extern u32 psxdump;
//extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX
//extern int rdram_sdevid;
extern tIPU_BP g_BP;
#define VF_VAL(x) ((x==0x80000000)?0:(x))
#endif
// iR5900-32.cpp
extern EEINST* s_pInstCache;
extern u32 s_nEndBlock; // what pc the current block ends
void iDumpPsxRegisters(u32 startpc, u32 temp)
{
// [TODO] fixme : thie code is broken and has no labels. Needs a rewrite to be useful.
#ifdef TEST_BROKEN_DUMP_ROUTINES
int i;
const char* pstr = temp ? "t" : "";
// fixme: PSXM doesn't exist any more.
//__Log("%spsxreg: %x %x ra:%x k0: %x %x", pstr, startpc, psxRegs.cycle, psxRegs.GPR.n.ra, psxRegs.GPR.n.k0, *(int*)PSXM(0x13c128));
for(i = 0; i < 34; i+=2) __Log("%spsx%s: %x %x", pstr, disRNameGPR[i], psxRegs.GPR.r[i], psxRegs.GPR.r[i+1]);
__Log("%scycle: %x %x %x; counters %x %x", pstr, psxRegs.cycle, g_psxNextBranchCycle, EEsCycle,
psxNextsCounter, psxNextCounter);
__Log("psxdma%d c%x b%x m%x t%x", 2, HW_DMA2_CHCR, HW_DMA2_BCR, HW_DMA2_MADR, HW_DMA2_TADR);
__Log("psxdma%d c%x b%x m%x", 3, HW_DMA3_CHCR, HW_DMA3_BCR, HW_DMA3_MADR);
__Log("psxdma%d c%x b%x m%x t%x", 4, HW_DMA4_CHCR, HW_DMA4_BCR, HW_DMA4_MADR, HW_DMA4_TADR);
__Log("psxdma%d c%x b%x m%x", 6, HW_DMA6_CHCR, HW_DMA6_BCR, HW_DMA6_MADR);
__Log("psxdma%d c%x b%x m%x", 7, HW_DMA7_CHCR, HW_DMA7_BCR, HW_DMA7_MADR);
__Log("psxdma%d c%x b%x m%x", 8, HW_DMA8_CHCR, HW_DMA8_BCR, HW_DMA8_MADR);
__Log("psxdma%d c%x b%x m%x t%x", 9, HW_DMA9_CHCR, HW_DMA9_BCR, HW_DMA9_MADR, HW_DMA9_TADR);
__Log("psxdma%d c%x b%x m%x", 10, HW_DMA10_CHCR, HW_DMA10_BCR, HW_DMA10_MADR);
__Log("psxdma%d c%x b%x m%x", 11, HW_DMA11_CHCR, HW_DMA11_BCR, HW_DMA11_MADR);
__Log("psxdma%d c%x b%x m%x", 12, HW_DMA12_CHCR, HW_DMA12_BCR, HW_DMA12_MADR);
for(i = 0; i < 7; ++i)
__Log("%scounter%d: mode %x count %I64x rate %x scycle %x target %I64x", pstr, i, psxCounters[i].mode, psxCounters[i].count, psxCounters[i].rate, psxCounters[i].sCycleT, psxCounters[i].target);
#endif
}
void iDumpRegisters(u32 startpc, u32 temp)
{
// [TODO] fixme : this code is broken and has no labels. Needs a rewrite to be useful.
#ifdef TEST_BROKEN_DUMP_ROUTINES
int i;
const char* pstr;// = temp ? "t" : "";
const u32 dmacs[] = {0x8000, 0x9000, 0xa000, 0xb000, 0xb400, 0xc000, 0xc400, 0xc800, 0xd000, 0xd400 };
const char* psymb;
if (temp)
pstr = "t";
else
pstr = "";
psymb = disR5900GetSym(startpc);
if( psymb != NULL )
__Log("%sreg(%s): %x %x c:%x", pstr, psymb, startpc, cpuRegs.interrupt, cpuRegs.cycle);
else
__Log("%sreg: %x %x c:%x", pstr, startpc, cpuRegs.interrupt, cpuRegs.cycle);
for(i = 1; i < 32; ++i) __Log("%s: %x_%x_%x_%x", disRNameGPR[i], cpuRegs.GPR.r[i].UL[3], cpuRegs.GPR.r[i].UL[2], cpuRegs.GPR.r[i].UL[1], cpuRegs.GPR.r[i].UL[0]);
//for(i = 0; i < 32; i+=4) __Log("cp%d: %x_%x_%x_%x", i, cpuRegs.CP0.r[i], cpuRegs.CP0.r[i+1], cpuRegs.CP0.r[i+2], cpuRegs.CP0.r[i+3]);
//for(i = 0; i < 32; ++i) __Log("%sf%d: %f %x", pstr, i, fpuRegs.fpr[i].f, fpuRegs.fprc[i]);
//for(i = 1; i < 32; ++i) __Log("%svf%d: %f %f %f %f, vi: %x", pstr, i, VU0.VF[i].F[3], VU0.VF[i].F[2], VU0.VF[i].F[1], VU0.VF[i].F[0], VU0.VI[i].UL);
for(i = 0; i < 32; ++i) __Log("%sf%d: %x %x", pstr, i, fpuRegs.fpr[i].UL, fpuRegs.fprc[i]);
for(i = 1; i < 32; ++i) __Log("%svf%d: %x %x %x %x, vi: %x", pstr, i, VU0.VF[i].UL[3], VU0.VF[i].UL[2], VU0.VF[i].UL[1], VU0.VF[i].UL[0], VU0.VI[i].UL);
__Log("%svfACC: %x %x %x %x", pstr, VU0.ACC.UL[3], VU0.ACC.UL[2], VU0.ACC.UL[1], VU0.ACC.UL[0]);
__Log("%sLO: %x_%x_%x_%x, HI: %x_%x_%x_%x", pstr, cpuRegs.LO.UL[3], cpuRegs.LO.UL[2], cpuRegs.LO.UL[1], cpuRegs.LO.UL[0],
cpuRegs.HI.UL[3], cpuRegs.HI.UL[2], cpuRegs.HI.UL[1], cpuRegs.HI.UL[0]);
__Log("%sCycle: %x %x, Count: %x", pstr, cpuRegs.cycle, g_nextBranchCycle, cpuRegs.CP0.n.Count);
iDumpPsxRegisters(psxRegs.pc, temp);
__Log("f410,30,40: %x %x %x, %d %d", psHu32(0xf410), psHu32(0xf430), psHu32(0xf440), rdram_sdevid, rdram_devices);
__Log("cyc11: %x %x; vu0: %x, vu1: %x", cpuRegs.sCycle[1], cpuRegs.eCycle[1], VU0.cycle, VU1.cycle);
__Log("%scounters: %x %x; psx: %x %x", pstr, nextsCounter, nextCounter, psxNextsCounter, psxNextCounter);
// fixme: The members of the counters[i] struct are wrong here.
/*for(i = 0; i < 4; ++i) {
__Log("eetimer%d: count: %x mode: %x target: %x %x; %x %x; %x %x %x %x", i,
counters[i].count, counters[i].mode, counters[i].target, counters[i].hold, counters[i].rate,
counters[i].interrupt, counters[i].Cycle, counters[i].sCycle, counters[i].CycleT, counters[i].sCycleT);
}*/
__Log("VIF0_STAT = %x, VIF1_STAT = %x", psHu32(0x3800), psHu32(0x3C00));
__Log("ipu %x %x %x %x; bp: %x %x %x %x", psHu32(0x2000), psHu32(0x2010), psHu32(0x2020), psHu32(0x2030), g_BP.BP, g_BP.bufferhasnew, g_BP.FP, g_BP.IFC);
__Log("gif: %x %x %x", psHu32(0x3000), psHu32(0x3010), psHu32(0x3020));
for(i = 0; i < ArraySize(dmacs); ++i) {
DMACh* p = (DMACh*)(PS2MEM_HW+dmacs[i]);
__Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr);
}
__Log("dmac %x %x %x %x", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR));
__Log("intc %x %x", psHu32(INTC_STAT), psHu32(INTC_MASK));
__Log("sif: %x %x %x %x %x", psHu32(0xf200), psHu32(0xf220), psHu32(0xf230), psHu32(0xf240), psHu32(0xf260));
#endif
}
void iDumpVU0Registers()
{
// fixme: This code is outdated, broken, and lacks printed labels.
// Needs heavy mods to be useful.
#ifdef TEST_BROKEN_DUMP_ROUTINES
int i;
for(i = 1; i < 32; ++i) {
__Log("v%d: %x %x %x %x, vi: ", i, VF_VAL(VU0.VF[i].UL[3]), VF_VAL(VU0.VF[i].UL[2]),
VF_VAL(VU0.VF[i].UL[1]), VF_VAL(VU0.VF[i].UL[0]));
if( i == REG_Q || i == REG_P )
__Log("%f\n", VU0.VI[i].F);
else if( i == REG_MAC_FLAG )
__Log("%x\n", 0);//VU0.VI[i].UL&0xff);
else if( i == REG_STATUS_FLAG )
__Log("%x\n", 0);//VU0.VI[i].UL&0x03);
else if( i == REG_CLIP_FLAG )
__Log("0\n");
else
__Log("%x\n", VU0.VI[i].UL);
}
__Log("vfACC: %f %f %f %f\n", VU0.ACC.F[3], VU0.ACC.F[2], VU0.ACC.F[1], VU0.ACC.F[0]);
#endif
}
void iDumpVU1Registers()
{
// fixme: This code is outdated, broken, and lacks printed labels.
// Needs heavy mods to be useful.
#ifdef TEST_BROKEN_DUMP_ROUTINES
int i;
// static int icount = 0;
// __Log("%x\n", icount);
for(i = 1; i < 32; ++i) {
// __Log("v%d: w%f(%x) z%f(%x) y%f(%x) x%f(%x), vi: ", i, VU1.VF[i].F[3], VU1.VF[i].UL[3], VU1.VF[i].F[2], VU1.VF[i].UL[2],
// VU1.VF[i].F[1], VU1.VF[i].UL[1], VU1.VF[i].F[0], VU1.VF[i].UL[0]);
//__Log("v%d: %f %f %f %f, vi: ", i, VU1.VF[i].F[3], VU1.VF[i].F[2], VU1.VF[i].F[1], VU1.VF[i].F[0]);
__Log("v%d: %x %x %x %x, vi: ", i, VF_VAL(VU1.VF[i].UL[3]), VF_VAL(VU1.VF[i].UL[2]), VF_VAL(VU1.VF[i].UL[1]), VF_VAL(VU1.VF[i].UL[0]));
if( i == REG_Q || i == REG_P ) __Log("%f\n", VU1.VI[i].F);
//else __Log("%x\n", VU1.VI[i].UL);
else __Log("%x\n", (i==REG_STATUS_FLAG||i==REG_MAC_FLAG||i==REG_CLIP_FLAG)?0:VU1.VI[i].UL);
}
__Log("vfACC: %f %f %f %f\n", VU1.ACC.F[3], VU1.ACC.F[2], VU1.ACC.F[1], VU1.ACC.F[0]);
#endif
}
#ifdef PCSX2_DEVBUILD
// and not sure what these might have once been used for... (air)
//static const char *txt0 = "EAX = %x : ECX = %x : EDX = %x\n";
//static const char *txt0RC = "EAX = %x : EBX = %x : ECX = %x : EDX = %x : ESI = %x : EDI = %x\n";
//static const char *txt1 = "REG[%d] = %x_%x\n";
//static const char *txt2 = "M32 = %x\n";
#endif
////////////////////////////////////////////////////
#include "Utilities/AsciiFile.h"
// Originally from iR5900-32.cpp
void iDumpBlock( int startpc, u8 * ptr )
{
u8 used[34];
u8 fpuused[33];
int numused, fpunumused;
Console::Status( "dump1 %x:%x, %x", params startpc, pc, cpuRegs.cycle );
g_Conf.Folders.Dumps.Mkdir();
AsciiFile eff(
Path::Combine( g_Conf.Folders.Dumps, wxsFormat(wxT("R5900dump%.8X.txt"), startpc) ),
wxFile::write
);
if( disR5900GetSym(startpc) != NULL )
{
eff.Printf( disR5900GetSym( startpc ) );
eff.Printf( "\n" );
}
for ( uint i = startpc; i < s_nEndBlock; i += 4 )
{
string output;
disR5900Fasm( output, memRead32( i ), i );
eff.Printf( output.c_str() );
}
// write the instruction info
eff.Printf( "\n\nlive0 - %x, live1 - %x, live2 - %x, lastuse - %x\nmmx - %x, xmm - %x, used - %x\n",
EEINST_LIVE0, EEINST_LIVE1, EEINST_LIVE2, EEINST_LASTUSE, EEINST_MMX, EEINST_XMM, EEINST_USED
);
memzero_obj(used);
numused = 0;
for(uint i = 0; i < ArraySize(s_pInstCache->regs); ++i) {
if( s_pInstCache->regs[i] & EEINST_USED ) {
used[i] = 1;
numused++;
}
}
memzero_obj(fpuused);
fpunumused = 0;
for(uint i = 0; i < ArraySize(s_pInstCache->fpuregs); ++i) {
if( s_pInstCache->fpuregs[i] & EEINST_USED ) {
fpuused[i] = 1;
fpunumused++;
}
}
eff.Printf( " " );
for(uint i = 0; i < ArraySize(s_pInstCache->regs); ++i) {
if( used[i] ) eff.Printf( "%2d ", i );
}
eff.Printf( "\n" );
for(uint i = 0; i < ArraySize(s_pInstCache->fpuregs); ++i) {
if( fpuused[i] ) eff.Printf( "%2d ", i );
}
eff.Printf( "\n" );
eff.Printf( " " );
// TODO : Finish converting this over to wxWidgers wxFile stuff...
/*
int count;
EEINST* pcur;
for(uint i = 0; i < ArraySize(s_pInstCache->regs); ++i) {
if( used[i] ) fprintf(f, "%s ", disRNameGPR[i]);
}
for(uint i = 0; i < ArraySize(s_pInstCache->fpuregs); ++i) {
if( fpuused[i] ) fprintf(f, "%s ", i<32?"FR":"FA");
}
fprintf(f, "\n");
pcur = s_pInstCache+1;
for( uint i = 0; i < (s_nEndBlock-startpc)/4; ++i, ++pcur) {
fprintf(f, "%2d: %2.2x ", i+1, pcur->info);
count = 1;
for(uint j = 0; j < ArraySize(s_pInstCache->regs); j++) {
if( used[j] ) {
fprintf(f, "%2.2x%s", pcur->regs[j], ((count%8)&&count<numused)?"_":" ");
++count;
}
}
count = 1;
for(uint j = 0; j < ArraySize(s_pInstCache->fpuregs); j++) {
if( fpuused[j] ) {
fprintf(f, "%2.2x%s", pcur->fpuregs[j], ((count%8)&&count<fpunumused)?"_":" ");
++count;
}
}
fprintf(f, "\n");
}
fclose( f );*/
}

26
pcsx2/Dump.h Normal file
View File

@ -0,0 +1,26 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
extern void iDumpRegisters(u32 startpc, u32 temp);
extern void iDumpPsxRegisters(u32 startpc, u32 temp);
extern void iDumpVU0Registers();
extern void iDumpVU1Registers();
extern void iDumpBlock( int startpc, u8 * ptr );
extern void iIopDumpBlock( int startpc, u8 * ptr );

View File

@ -127,6 +127,12 @@ struct Elf32_Rel {
u32 r_info; u32 r_info;
}; };
#if 0
// fixme: ELF command line option system.
// It parses a command line and pastes it into PS2 memory, and then points the a0 register at it.
// A user-written ELF can then load the data and respond accordingly. Needs a rewrite using modern
// string parsing utils. :)
//2002-09-19 (Florin) //2002-09-19 (Florin)
char args[256]="ez.m2v"; //to be accessed by other files char args[256]="ez.m2v"; //to be accessed by other files
uptr args_ptr; //a big value; in fact, it is an address uptr args_ptr; //a big value; in fact, it is an address
@ -142,7 +148,7 @@ uptr args_ptr; //a big value; in fact, it is an address
//+08+4*argc the program name(first param) <-- //+08+4*argc the program name(first param) <--
//+08+4*argc+strlen(argv[0]+1) the rest of params; i.e. a copy of 'args' //+08+4*argc+strlen(argv[0]+1) the rest of params; i.e. a copy of 'args'
// see above 'char args[256];' // see above 'char args[256];'
static uint parseCommandLine( const char *filename ) static uint parseCommandLine( const wxString& filename )
{ {
if ( ( args_ptr != 0xFFFFFFFF ) && ( args_ptr > 264 ) ) if ( ( args_ptr != 0xFFFFFFFF ) && ( args_ptr > 264 ) )
{ // 4 + 4 + 256 { // 4 + 4 + 256
@ -209,11 +215,12 @@ static uint parseCommandLine( const char *filename )
return 0; return 0;
} }
#endif
//--------------- //---------------
struct ElfObject struct ElfObject
{ {
string filename; wxString filename;
SafeArray<u8> data; SafeArray<u8> data;
ELF_HEADER& header; ELF_HEADER& header;
ELF_PHR* proghead; ELF_PHR* proghead;
@ -223,7 +230,7 @@ struct ElfObject
// C++ does all the cleanup automagically for us. // C++ does all the cleanup automagically for us.
~ElfObject() { } ~ElfObject() { }
ElfObject( const string& srcfile, uint hdrsize ) : ElfObject( const wxString& srcfile, uint hdrsize ) :
filename( srcfile ) filename( srcfile )
, data( hdrsize, "ELF headers" ) , data( hdrsize, "ELF headers" )
, header( *(ELF_HEADER*)data.GetPtr() ) , header( *(ELF_HEADER*)data.GetPtr() )
@ -296,10 +303,11 @@ struct ElfObject
void readFile() void readFile()
{ {
int rsize = 0; int rsize = 0;
if ((strnicmp( filename.c_str(), "cdrom0:", strlen("cdromN:")) == 0) || const wxCharBuffer work( filename.ToAscii() );
(strnicmp( filename.c_str(), "cdrom1:", strlen("cdromN:")) == 0)) if ((strnicmp( work.data(), "cdrom0:", strlen("cdromN:")) == 0) ||
(strnicmp( work.data(), "cdrom1:", strlen("cdromN:")) == 0))
{ {
int fi = CDVDFS_open(filename.c_str() + strlen("cdromN:"), 1);//RDONLY int fi = CDVDFS_open(work.data() + strlen("cdromN:"), 1);//RDONLY
if (fi < 0) throw Exception::FileNotFound( filename ); if (fi < 0) throw Exception::FileNotFound( filename );
@ -311,7 +319,7 @@ struct ElfObject
{ {
FILE *f; FILE *f;
f = fopen( filename.c_str(), "rb" ); f = fopen( work.data(), "rb" );
if( f == NULL ) Exception::FileNotFound( filename ); if( f == NULL ) Exception::FileNotFound( filename );
fseek( f, 0, SEEK_SET ); fseek( f, 0, SEEK_SET );
@ -404,8 +412,9 @@ struct ElfObject
{ {
ELF_LOG( "Elf32 Section Header [%x] %s", i, &sections_names[ secthead[ i ].sh_name ] ); ELF_LOG( "Elf32 Section Header [%x] %s", i, &sections_names[ secthead[ i ].sh_name ] );
if ( secthead[i].sh_flags & 0x2 ) // used by parseCommandLine
args_ptr = min( args_ptr, secthead[ i ].sh_addr & 0x1ffffff ); //if ( secthead[i].sh_flags & 0x2 )
// args_ptr = min( args_ptr, secthead[ i ].sh_addr & 0x1ffffff );
#ifdef PCSX2_DEVBULD #ifdef PCSX2_DEVBULD
ELF_LOG("\n"); ELF_LOG("\n");
@ -462,21 +471,20 @@ struct ElfObject
void ElfApplyPatches() void ElfApplyPatches()
{ {
string filename; wxString filename( wxsFormat( wxT("%8.8x"), ElfCRC ) );
ssprintf( filename, "%8.8x", ElfCRC );
// if patches found the following status msg will be overwritten // if patches found the following status msg will be overwritten
Console::SetTitle( fmt_string( "Game running [CRC=%hs]", &filename ) ); Console::SetTitle( wxsFormat( _("Game running [CRC=%s]"), filename.c_str() ) );
if( !Config.Patch ) return; if( !Config.Patch ) return;
if(LoadPatch( filename ) != 0) if(LoadPatch( filename ) != 0)
{ {
Console::WriteLn("XML Loader returned an error. Trying to load a pnach..."); Console::WriteLn( "XML Loader returned an error. Trying to load a pnach..." );
inifile_read( filename.c_str() ); inifile_read( filename.ToAscii().data() );
} }
else else
Console::WriteLn("XML Loading success. Will not load from pnach..."); Console::WriteLn( "XML Loading success. Will not load from pnach..." );
applypatch( 0 ); applypatch( 0 );
} }
@ -491,20 +499,20 @@ u32 loadElfCRC( const char* filename )
return 0; return 0;
DevCon::Status( "loadElfFile: %d bytes", params toc.fileSize ); DevCon::Status( "loadElfFile: %d bytes", params toc.fileSize );
u32 crcval = ElfObject( filename, toc.fileSize ).GetCRC(); u32 crcval = ElfObject( wxString::FromAscii( filename ), toc.fileSize ).GetCRC();
Console::Status( "loadElfFile: %s; CRC = %8.8X", params filename, crcval ); Console::Status( "loadElfFile: %s; CRC = %8.8X", params filename, crcval );
return crcval; return crcval;
} }
int loadElfFile(const char *filename) int loadElfFile(const wxString& filename)
{ {
// Reset all recompilers prior to initiating a BIOS or new ELF. The cleaner the // Reset all recompilers prior to initiating a BIOS or new ELF. The cleaner the
// slate, the happier the recompiler! // slate, the happier the recompiler!
SysClearExecutionCache(); SysClearExecutionCache();
if( filename == NULL || filename[0] == 0 ) if( filename.IsEmpty() )
{ {
Console::Notice( "Running the PS2 BIOS..." ); Console::Notice( "Running the PS2 BIOS..." );
return -1; return -1;
@ -514,35 +522,42 @@ int loadElfFile(const char *filename)
cpuExecuteBios(); cpuExecuteBios();
int elfsize; int elfsize;
Console::Status( wxsFormat( L"loadElfFile: %s", filename.c_str() ) );
Console::Status("loadElfFile: %s", params filename); const wxCharBuffer buffer( filename.ToAscii() );
if (strnicmp( filename, "cdrom0:", strlen( "cdromN:" ) ) && const char* fnptr = buffer.data();
strnicmp( filename, "cdrom1:", strlen( "cdromN:" ) ) )
if( !filename.StartsWith( L"cdrom0:" ) && !filename.StartsWith( L"cdrom1:" ) )
{ {
// Loading from a file (or non-cd image) // Loading from a file (or non-cd image)
struct stat sbuf;
if ( stat( filename, &sbuf ) != 0 ) elfsize = Path::GetFileSize( filename );
return -1;
elfsize = sbuf.st_size;
} }
else else
{ {
// Loading from a CD rom or CD image. // Loading from a CD rom or CD image.
TocEntry toc; TocEntry toc;
CDVDFS_init( ); CDVDFS_init( );
if ( CDVD_findfile( filename + strlen( "cdromN:" ), &toc ) == -1 ) if ( CDVD_findfile( fnptr + strlen( "cdromN:" ), &toc ) == -1 )
return -1; return -1;
elfsize = toc.fileSize; elfsize = toc.fileSize;
} }
Console::Status( "loadElfFile: %d", params elfsize); Console::Status( wxsFormat(L"loadElfFile: %d", elfsize) );
if( elfsize == 0 ) return -1;
ElfObject elfobj( filename, elfsize ); ElfObject elfobj( filename, elfsize );
if( elfobj.proghead == NULL ) if( elfobj.proghead == NULL )
throw Exception::CpuStateShutdown( fmt_string( "%s > This ELF has no program headers; Pcsx2 can't run what doesn't exist...", filename ) ); {
throw Exception::CpuStateShutdown(
wxsFormat( wxT("Invalid ELF header encountered in file:\n\t%s"), elfobj.filename ),
wxsFormat(_("Invalid ELF header, file: %s"), elfobj.filename )
);
}
//2002-09-19 (Florin) //2002-09-19 (Florin)
args_ptr = 0xFFFFFFFF; //big value, searching for minimum //args_ptr = 0xFFFFFFFF; //big value, searching for minimum [used by parseCommandLine]
elfobj.loadProgramHeaders(); elfobj.loadProgramHeaders();
elfobj.loadSectionHeaders(); elfobj.loadSectionHeaders();
@ -552,17 +567,19 @@ int loadElfFile(const char *filename)
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000; cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
cpuRegs.GPR.n.gp.UL[0] = 0x81f80000; // might not be 100% ok cpuRegs.GPR.n.gp.UL[0] = 0x81f80000; // might not be 100% ok
cpuRegs.GPR.n.a0.UL[0] = parseCommandLine( filename ); //cpuRegs.GPR.n.a0.UL[0] = parseCommandLine( filename ); // see #ifdef'd out parseCommendLine for details.
for ( uint i = 0; i < 0x100000; i++ ) { for( uint i = 0; i < 0x100000; i++ )
if ( strcmp( "rom0:OSDSYS", (char*)PSM( i ) ) == 0 ) { {
strcpy( (char*)PSM( i ), filename ); if( memcmp( "rom0:OSDSYS", (char*)PSM( i ), 11 ) == 0 )
DevCon::Status( "addr %x \"%s\" -> \"%s\"", params i, "rom0:OSDSYS", filename ); {
strcpy( (char*)PSM( i ), fnptr );
DevCon::Status( "loadElfFile: addr %x \"%s\" -> \"%s\"", params i, "rom0:OSDSYS", fnptr );
} }
} }
ElfCRC = elfobj.GetCRC(); ElfCRC = elfobj.GetCRC();
Console::Status( "loadElfFile: %s; CRC = %8.8X", params filename, ElfCRC); Console::Status( wxsFormat( L"loadElfFile: %s; CRC = %8.8X", filename.c_str(), ElfCRC ) );
ElfApplyPatches(); ElfApplyPatches();
LoadGameSpecificSettings(); LoadGameSpecificSettings();

View File

@ -24,7 +24,7 @@ extern char args[256]; //to be filled by GUI
extern unsigned int args_ptr; extern unsigned int args_ptr;
//------------------- //-------------------
int loadElfFile(const char *filename); int loadElfFile(const wxString& filename);
u32 loadElfCRC(const char *filename); u32 loadElfCRC(const char *filename);
void LoadGameSpecificSettings(); void LoadGameSpecificSettings();
void ElfApplyPatches(); void ElfApplyPatches();

165
pcsx2/Exceptions.cpp Normal file
View File

@ -0,0 +1,165 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
wxLocale* g_EnglishLocale = NULL;
//g_EnglishLocale = new wxLocale( wxLANGUAGE_ENGLISH );
wxString GetEnglish( const char* msg )
{
if( g_EnglishLocale == NULL ) return wxString::FromAscii(msg);
return g_EnglishLocale->GetString( wxString::FromAscii(msg).c_str() );
}
wxString GetTranslation( const char* msg )
{
return wxGetTranslation( wxString::FromAscii(msg).c_str() );
}
//////////////////////////////////////////////////////////////////////////////////////////
//
namespace Exception
{
// ------------------------------------------------------------------------
BaseException::~BaseException() throw() {}
BaseException::BaseException( const wxString& msg_eng, const wxString& msg_xlt ) :
m_message_eng( msg_eng ),
m_message( msg_xlt ),
m_stacktrace( wxEmptyString ) // unsupported yet
{
// Major hack. After a couple of tries, I'm still not managing to get Linux to catch these exceptions, so that the user actually
// gets the messages. Since Console is unavailable at this level, I'm using a simple printf, which of course, means it doesn't get
// logged. But at least the user sees it.
//
// I'll rip this out once I get Linux to actually catch these exceptions. Say, in BeginExecution or StartGui, like I would expect.
// -- arcum42
#ifdef __LINUX__
printf(msg.c_str());
#endif
}
// given message is assumed to be a translation key, and will be stored in translated
// and untranslated forms.
BaseException::BaseException( const char* msg_eng ) :
m_message_eng( GetEnglish( msg_eng ) ),
m_message( GetTranslation( msg_eng ) ),
m_stacktrace( wxEmptyString ) // unsupported yet
{
}
wxString BaseException::LogMessage() const
{
return m_message_eng + wxT("\n\n") + m_stacktrace;
}
// ------------------------------------------------------------------------
wxString Stream::LogMessage() const
{
return wxsFormat(
wxT("Stream exception: %s\n\tObject name: %s"),
m_message_eng, StreamName.c_str()
) + m_stacktrace;
}
wxString Stream::DisplayMessage() const
{
return m_message + wxT("\n") + StreamName.c_str();
}
// ------------------------------------------------------------------------
wxString PluginFailure::LogMessage() const
{
return wxsFormat(
wxT("%s plugin has encountered an error.\n\n"),
plugin_name.c_str()
) + m_stacktrace;
}
wxString PluginFailure::DisplayMessage() const
{
return wxsFormat( m_message, plugin_name );
}
// ------------------------------------------------------------------------
wxString FreezePluginFailure::LogMessage() const
{
return wxsFormat(
wxT("%s plugin returned an error while %s the state.\n\n"),
plugin_name.c_str(),
freeze_action.c_str()
) + m_stacktrace;
}
wxString FreezePluginFailure::DisplayMessage() const
{
return m_message;
}
// ------------------------------------------------------------------------
wxString UnsupportedStateVersion::LogMessage() const
{
// Note: no stacktrace needed for this one...
return wxsFormat( wxT("Unknown or unsupported savestate version: 0x%x"), Version );
}
wxString UnsupportedStateVersion::DisplayMessage() const
{
// m_message contains a recoverable savestate error which is helpful to the user.
return wxsFormat(
m_message + wxT("\n\n") +
wxsFormat( _("Unknown savestate version: 0x%x"), Version )
);
}
// ------------------------------------------------------------------------
wxString StateCrcMismatch::LogMessage() const
{
// Note: no stacktrace needed for this one...
return wxsFormat(
wxT("Game/CDVD does not match the savestate CRC.\n")
wxT("\tCdvd CRC: 0x%X\n\tGame CRC: 0x%X\n"),
Crc_Savestate, Crc_Cdvd
);
}
wxString StateCrcMismatch::DisplayMessage() const
{
return wxsFormat(
m_message + wxT("\n\n") +
wxsFormat( _(
"Savestate game/crc mismatch. Cdvd CRC: 0x%X Game CRC: 0x%X\n"),
Crc_Savestate, Crc_Cdvd
)
);
}
// ------------------------------------------------------------------------
wxString IndexBoundsFault::LogMessage() const
{
return wxT("Index out of bounds on SafeArray: ") + ArrayName +
wxsFormat( wxT("(index=%d, size=%d)"), BadIndex, ArrayLength );
}
wxString IndexBoundsFault::DisplayMessage() const
{
return m_message;
}
}

View File

@ -16,12 +16,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef _PCSX2_EXCEPTIONS_H_ #pragma once
#define _PCSX2_EXCEPTIONS_H_
#include <stdexcept>
#include "StringUtils.h"
//////////////////////////////////////////////////////////////////////////////////////////
// This class provides an easy and clean method for ensuring objects are not copyable. // This class provides an easy and clean method for ensuring objects are not copyable.
class NoncopyableObject class NoncopyableObject
{ {
@ -39,12 +36,12 @@ private:
const NoncopyableObject& operator=( const NoncopyableObject& ); const NoncopyableObject& operator=( const NoncopyableObject& );
}; };
//////////////////////////////////////////////////////////////////////////////////////////
// Base class used to implement type-safe sealed classes. // Base class used to implement type-safe sealed classes.
// This class should never be used directly. Use the Sealed // This class should never be used directly. Use the Sealed macro instead, which ensures
// macro instead, which ensures all sealed classes derive from a unique BaseSealed // all sealed classes derive from a unique BaseSealed (preventing them from accidentally
// (preventing them from accidentally cirumventing sealing by inheriting from // circumventing sealing by inheriting from multiple sealed classes.
// multiple sealed classes. //
template < int T > template < int T >
class __BaseSealed class __BaseSealed
{ {
@ -54,52 +51,70 @@ protected:
} }
}; };
// Use this macro/class as a base to seal a class from being derrived from. // Use this macro/class as a base to seal a class from being derived from.
// This macro works by providing a unique base class with a protected constructor // This macro works by providing a unique base class with a protected constructor
// for every class that derives from it. // for every class that derives from it.
#define Sealed private virtual __BaseSealed<__COUNTER__> #define Sealed private virtual __BaseSealed<__COUNTER__>
extern wxLocale* g_EnglishLocale;
extern wxString GetEnglish( const char* msg );
extern wxString GetTranslation( const char* msg );
namespace Exception namespace Exception
{ {
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
// std::exception sucks, so I made a replacement. // std::exception sucks, and isn't entirely cross-platform reliable in its implementation,
// so I made a replacement.
//
// Note, this class is "abstract" which means you shouldn't use it directly like, ever. // Note, this class is "abstract" which means you shouldn't use it directly like, ever.
// Use Exception::RuntimeError or Exception::LogicError instead. // Use Exception::RuntimeError or Exception::LogicError instead for generic exceptions.
//
class BaseException class BaseException
{ {
protected: protected:
const wxString m_message; // a "detailed" message of what disasterous thing has occured! const wxString m_message_eng; // (untranslated) a "detailed" message of what disastrous thing has occurred!
const wxString m_message; // (translated) a "detailed" message of what disastrous thing has occurred!
const wxString m_stacktrace; // contains the stack trace string dump (unimplemented)
public: public:
virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode. virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode.
explicit BaseException( const wxString& msg="Unhandled exception." ) :
m_message( msg ) // copy construct
{ BaseException( const BaseException& src ) :
// Major hack. After a couple of tries, I'm still not managing to get Linux to catch these exceptions, so that the user actually m_message_eng( src.m_message_eng ),
// gets the messages. Since Console is unavailable at this level, I'm using a simple printf, which of course, means it doesn't get m_message( src.m_message ),
// logged. But at least the user sees it. m_stacktrace( src.m_stacktrace ) { }
//
// I'll rip this out once I get Linux to actually catch these exceptions. Say, in BeginExecution or StartGui, like I would expect. // Contruction using two pre-formatted pre-translated messages
// -- arcum42 BaseException( const wxString& msg_eng, const wxString& msg_xlt );
#ifdef __LINUX__
printf(msg.c_str());
#endif
}
const wxString& Message() const { return m_message; } // Construction using one translation key.
const char* cMessage() const { return m_message.c_str(); } explicit BaseException( const char* msg_eng );
// Returns a message suitable for diagnostic / logging purposes.
// This message is always in english, and includes a full stack trace.
virtual wxString LogMessage() const;
// Returns a message suitable for end-user display.
// This message is usually meant for display in a user popup or such.
virtual wxString DisplayMessage() const { return m_message; }
}; };
//////////////////////////////////////////////////////////////////////////////////////////
// This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc). // This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc).
// Translation Note: These exceptions are never translated, except to issue a general
// error message to the user (which is xspecified below).
//
class Ps2Generic : public BaseException class Ps2Generic : public BaseException
{ {
public: public:
virtual ~Ps2Generic() throw() {} virtual ~Ps2Generic() throw() {}
explicit Ps2Generic( const wxString& msg="The Ps2/MIPS state encountered a general exception." ) : explicit Ps2Generic( const char* msg="Ps2/MIPS cpu caused a general exception" ) :
Exception::BaseException( msg ) BaseException( msg ) { }
{ explicit Ps2Generic( const wxString& msg_eng, const wxString& msg_xlt=_("Ps2/MIPS cpu caused a general exception") ) :
} BaseException( msg_eng, msg_xlt ) { }
virtual u32 GetPc() const=0; virtual u32 GetPc() const=0;
virtual bool IsDelaySlot() const=0; virtual bool IsDelaySlot() const=0;
@ -111,18 +126,29 @@ namespace Exception
{ {
public: public:
virtual ~RuntimeError() throw() {} virtual ~RuntimeError() throw() {}
explicit RuntimeError( const wxString& msg="An unhandled runtime error has occurred, somewhere in the depths of Pcsx2's cluttered brain-matter." ) :
BaseException( msg ) RuntimeError( const RuntimeError& src ) : BaseException( src ) {}
{}
explicit RuntimeError( const char* msg="An unhandled runtime error has occurred, somewhere in the depths of Pcsx2's cluttered brain-matter." ) :
BaseException( msg ) { }
explicit RuntimeError( const wxString& msg_eng, const wxString& msg_xlt ) :
BaseException( msg_eng, msg_xlt ) { }
}; };
// ------------------------------------------------------------------------
class LogicError : public BaseException class LogicError : public BaseException
{ {
public: public:
virtual ~LogicError() throw() {} virtual ~LogicError() throw() {}
explicit LogicError( const wxString& msg="An unhandled logic error has occured." ) :
BaseException( msg ) LogicError( const LogicError& src ) : BaseException( src ) {}
{}
explicit LogicError( const char* msg="An unhandled logic error has occurred." ) :
BaseException( msg ) { }
explicit LogicError( const wxString& msg_eng, const wxString& msg_xlt ) :
BaseException( msg_eng, msg_xlt ) { }
}; };
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
@ -130,46 +156,75 @@ namespace Exception
class OutOfMemory : public RuntimeError class OutOfMemory : public RuntimeError
{ {
public: public:
explicit OutOfMemory( const wxString& msg="Out of memory!" ) :
RuntimeError( msg ) {}
virtual ~OutOfMemory() throw() {} virtual ~OutOfMemory() throw() {}
explicit OutOfMemory( const char* msg="Out of memory" ) :
RuntimeError( msg ) {}
explicit OutOfMemory( const wxString& msg_eng, const wxString& msg_xlt=_("Out of memory") ) :
RuntimeError( msg_eng, msg_xlt ) { }
}; };
// ------------------------------------------------------------------------
// This exception thrown any time an operation is attempted when an object // This exception thrown any time an operation is attempted when an object
// is in an uninitialized state. // is in an uninitialized state.
class InvalidOperation : public LogicError class InvalidOperation : public LogicError
{ {
public: public:
virtual ~InvalidOperation() throw() {} virtual ~InvalidOperation() throw() {}
explicit InvalidOperation( const wxString& msg="Attempted method call is invalid for the current object or program state." ) : explicit InvalidOperation( const char* msg="Attempted method call is invalid for the current object or program state." ) :
LogicError( msg ) {} LogicError( msg ) {}
explicit InvalidOperation( const wxString& msg_eng, const wxString& msg_xlt ) :
LogicError( msg_eng, msg_xlt ) { }
}; };
// ------------------------------------------------------------------------
// This exception thrown any time an operation is attempted when an object // This exception thrown any time an operation is attempted when an object
// is in an uninitialized state. // is in an uninitialized state.
class InvalidArgument : public LogicError class InvalidArgument : public LogicError
{ {
public: public:
virtual ~InvalidArgument() throw() {} virtual ~InvalidArgument() throw() {}
explicit InvalidArgument( const wxString& msg="Invalid argument passed to a function." ) : explicit InvalidArgument( const char* msg="Invalid argument passed to a function." ) :
LogicError( msg ) {} LogicError( msg )
{
// assertions make debugging easier sometimes. :)
wxASSERT( msg );
}
}; };
// ------------------------------------------------------------------------
// Keep those array indexers in bounds when using the SafeArray type, or you'll be // Keep those array indexers in bounds when using the SafeArray type, or you'll be
// seeing these. // seeing these.
class IndexBoundsFault : public LogicError class IndexBoundsFault : public LogicError
{ {
public:
const wxString ArrayName;
const int ArrayLength;
const int BadIndex;
public: public:
virtual ~IndexBoundsFault() throw() {} virtual ~IndexBoundsFault() throw() {}
explicit IndexBoundsFault( const wxString& msg="Array index is outsides the bounds of an array." ) : explicit IndexBoundsFault( const wxString& objname, int index, int arrsize ) :
LogicError( msg ) {} LogicError( "Index is outside the bounds of an array." ),
ArrayName( objname ),
ArrayLength( arrsize ),
BadIndex( index )
{
// assertions make debugging easier sometimes. :)
wxASSERT( wxT("Index is outside the bounds of an array") );
}
virtual wxString LogMessage() const;
virtual wxString DisplayMessage() const;
}; };
// ------------------------------------------------------------------------
class ParseError : public RuntimeError class ParseError : public RuntimeError
{ {
public: public:
virtual ~ParseError() throw() {} virtual ~ParseError() throw() {}
explicit ParseError( const wxString& msg="Parse error" ) : explicit ParseError( const char* msg="Parse error" ) :
RuntimeError( msg ) {} RuntimeError( msg ) {}
}; };
@ -178,11 +233,12 @@ namespace Exception
class HardwareDeficiency : public RuntimeError class HardwareDeficiency : public RuntimeError
{ {
public: public:
explicit HardwareDeficiency( const wxString& msg="Your machine's hardware is incapable of running Pcsx2. Sorry dood." ) : explicit HardwareDeficiency( const char* msg="Your machine's hardware is incapable of running Pcsx2. Sorry dood." ) :
RuntimeError( msg ) {} RuntimeError( msg ) {}
virtual ~HardwareDeficiency() throw() {} virtual ~HardwareDeficiency() throw() {}
}; };
// ------------------------------------------------------------------------
// This exception is thrown by the PS2 emulation (R5900, etc) when bad things happen // This exception is thrown by the PS2 emulation (R5900, etc) when bad things happen
// that force the emulation state to terminate. The GUI should handle them by returning // that force the emulation state to terminate. The GUI should handle them by returning
// the user to the GUI. // the user to the GUI.
@ -190,66 +246,72 @@ namespace Exception
{ {
public: public:
virtual ~CpuStateShutdown() throw() {} virtual ~CpuStateShutdown() throw() {}
explicit CpuStateShutdown( const wxString& msg="The PS2 emulated state was shut down unexpectedly." ) : explicit CpuStateShutdown( const char* msg="Unexpected emulation shutdown" ) :
RuntimeError( msg ) {} RuntimeError( msg ) {}
explicit CpuStateShutdown( const wxString& msg_eng, const wxString& msg_xlt=wxString() ) :
RuntimeError( msg_eng, msg_xlt.IsEmpty() ? _("Unexpected emulation shutdown") : msg_xlt ) { }
}; };
// ------------------------------------------------------------------------
class PluginFailure : public RuntimeError class PluginFailure : public RuntimeError
{ {
public: public:
wxString plugin_name; // name of the plugin wxString plugin_name; // name of the plugin
virtual ~PluginFailure() throw() {} virtual ~PluginFailure() throw() {}
explicit PluginFailure( const wxString& plugin, const wxString& msg = "A plugin encountered a critical error." ) :
explicit PluginFailure( const char* plugin, const char* msg="%s plugin encountered a critical error" ) :
RuntimeError( msg ) RuntimeError( msg )
, plugin_name( plugin ) {} , plugin_name( wxString::FromAscii(plugin) ) {}
virtual wxString LogMessage() const;
virtual wxString DisplayMessage() const;
}; };
// ------------------------------------------------------------------------
class ThreadCreationError : public RuntimeError class ThreadCreationError : public RuntimeError
{ {
public: public:
virtual ~ThreadCreationError() throw() {} virtual ~ThreadCreationError() throw() {}
explicit ThreadCreationError( const wxString& msg="Thread could not be created." ) : explicit ThreadCreationError( const char* msg="Thread could not be created." ) :
RuntimeError( msg ) {}
};
// This is a "special" exception that's primarily included for safe functioning in the
// Win32's ASCII API (ie, the non-Unicode one). Many of the old Win32 APIs don't support
// paths over 256 characters.
class PathTooLong : public RuntimeError
{
public:
virtual ~PathTooLong() throw() {}
explicit PathTooLong( const wxString& msg=
"A Pcsx2 pathname was too long for the system. Please move or reinstall Pcsx2 to\n"
"a location on your hard drive that has a shorter path." ) :
RuntimeError( msg ) {} RuntimeError( msg ) {}
}; };
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////
// STREAMING EXCEPTIONS // STREAMING EXCEPTIONS
// ------------------------------------------------------------------------
// Generic stream error. Contains the name of the stream and a message. // Generic stream error. Contains the name of the stream and a message.
// This exception is usually thrown via derrived classes, except in the (rare) case of a generic / unknown error. // This exception is usually thrown via derived classes, except in the (rare) case of a generic / unknown error.
class Stream : public RuntimeError class Stream : public RuntimeError
{ {
public: public:
wxString stream_name; // name of the stream (if applicable) wxString StreamName; // name of the stream (if applicable)
virtual ~Stream() throw() {} virtual ~Stream() throw() {}
// copy construct! // copy construct!
Stream( const Stream& src ) : Stream( const Stream& src ) :
RuntimeError( src.Message() ) RuntimeError( src ),
, stream_name( src.stream_name ) {} StreamName( src.StreamName ) {}
explicit Stream( explicit Stream(
const wxString& objname=wxString(), const wxString& objname=wxString(),
const wxString& msg="Invalid stream object" ) : const char* msg="General file operation error" // general error while accessing or operating on a file or stream
RuntimeError( msg + "\n\tFilename: " + objname ) ) :
, stream_name( objname ) {} RuntimeError( msg ),
StreamName( objname ) {}
explicit Stream( const wxString& objname, const wxString& msg_eng, const wxString& msg_xlt=_("General file operation error") ) :
RuntimeError( msg_eng, msg_xlt ),
StreamName( objname ) {}
virtual wxString LogMessage() const;
virtual wxString DisplayMessage() const;
}; };
// ------------------------------------------------------------------------
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of // A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to read the data after the // connection, or anything else that would indicate a failure to read the data after the
// stream was successfully opened. // stream was successfully opened.
@ -259,50 +321,63 @@ namespace Exception
virtual ~BadStream() throw() {} virtual ~BadStream() throw() {}
explicit BadStream( explicit BadStream(
const wxString& objname=wxString(), const wxString& objname=wxString(),
const wxString& msg="Stream data is corrupted or incomplete, or the stream connection closed unexpectedly" ) : const char* msg="File data is corrupted or incomplete, or the stream connection closed unexpectedly"
Stream( objname, msg ) {} ) :
Stream( objname, msg ) {}
}; };
// ------------------------------------------------------------------------
// A generic exception for odd-ball stream creation errors. // A generic exception for odd-ball stream creation errors.
class CreateStream : public Stream class CreateStream : public Stream
{ {
public: public:
virtual ~CreateStream() throw() {} virtual ~CreateStream() throw() {}
explicit CreateStream(
const char* objname,
const char* msg="File could not be created or opened" ) :
Stream( wxString::FromAscii( objname ), msg ) {}
explicit CreateStream( explicit CreateStream(
const wxString& objname=wxString(), const wxString& objname=wxString(),
const wxString& msg="Stream could not be created or opened" ) : const char* msg="File could not be created or opened" ) :
Stream( objname, msg ) {} Stream( objname, msg ) {}
}; };
// ------------------------------------------------------------------------
// Exception thrown when an attempt to open a non-existent file is made. // Exception thrown when an attempt to open a non-existent file is made.
// (this exception can also mean file permissions are invalid) // (this exception can also mean file permissions are invalid)
class FileNotFound : public CreateStream class FileNotFound : public CreateStream
{ {
public: public:
virtual ~FileNotFound() throw() {} virtual ~FileNotFound() throw() {}
explicit FileNotFound( explicit FileNotFound(
const wxString& objname=wxString(), const wxString& objname=wxString(),
const wxString& msg="File not found" ) : const char* msg="File not found" ) :
CreateStream( objname, msg ) {} CreateStream( objname, msg ) {}
}; };
// ------------------------------------------------------------------------
class AccessDenied : public CreateStream class AccessDenied : public CreateStream
{ {
public: public:
virtual ~AccessDenied() throw() {} virtual ~AccessDenied() throw() {}
explicit AccessDenied( explicit AccessDenied(
const wxString& objname=wxString(), const wxString& objname=wxString(),
const wxString& msg="Permission denied to file or stream" ) : const char* msg="Permission denied to file" ) :
CreateStream( objname, msg ) {} CreateStream( objname, msg ) {}
}; };
// ------------------------------------------------------------------------
// Generic End of Stream exception (sometimes an error, and sometimes just used as a // Generic End of Stream exception (sometimes an error, and sometimes just used as a
// shortcut for manual feof checks). // shortcut for manual feof checks).
class EndOfStream : public Stream class EndOfStream : public Stream
{ {
public: public:
virtual ~EndOfStream() throw() {} virtual ~EndOfStream() throw() {}
explicit EndOfStream( const wxString& objname=wxString(), const wxString& msg="End of stream was encountered" ) : explicit EndOfStream( const wxString& objname, const char* msg="End of file" ) :
Stream( objname, msg ) {} Stream( objname, msg ) {}
}; };
@ -316,10 +391,11 @@ namespace Exception
virtual ~BadSavedState() throw() {} virtual ~BadSavedState() throw() {}
explicit BadSavedState( explicit BadSavedState(
const wxString& objname=wxString(), const wxString& objname=wxString(),
const wxString& msg="Savestate data is corrupted or incomplete" ) : const char* msg="Savestate data is corrupted" ) : // or incomplete
BadStream( objname, msg ) {} BadStream( objname, msg ) {}
}; };
// ------------------------------------------------------------------------
// Exception thrown by SaveState class when a critical plugin or gzread // Exception thrown by SaveState class when a critical plugin or gzread
class FreezePluginFailure : public RuntimeError class FreezePluginFailure : public RuntimeError
{ {
@ -328,12 +404,18 @@ namespace Exception
wxString freeze_action; wxString freeze_action;
virtual ~FreezePluginFailure() throw() {} virtual ~FreezePluginFailure() throw() {}
explicit FreezePluginFailure( const wxString& plugin, const wxString& action ) : explicit FreezePluginFailure( const char* plugin, const char* action,
RuntimeError( plugin + " plugin returned an error while " + action + " the state." ) const wxString& msg_xlt=_("Plugin error occurred while loading/saving state") )
, plugin_name( plugin ) :
, freeze_action( action ){} RuntimeError( wxString(), msg_xlt ) // LogMessage / DisplayMessage build their own messages
, plugin_name( wxString::FromAscii(plugin) )
, freeze_action( wxString::FromAscii(action) ){}
virtual wxString LogMessage() const;
virtual wxString DisplayMessage() const;
}; };
// ------------------------------------------------------------------------
// The savestate code throws Recoverable errors when it fails prior to actually modifying // The savestate code throws Recoverable errors when it fails prior to actually modifying
// the current emulation state. Recoverable errors are always thrown from the SaveState // the current emulation state. Recoverable errors are always thrown from the SaveState
// object construction (and never from Freeze methods). // object construction (and never from Freeze methods).
@ -341,10 +423,11 @@ namespace Exception
{ {
public: public:
virtual ~StateLoadError_Recoverable() throw() {} virtual ~StateLoadError_Recoverable() throw() {}
explicit StateLoadError_Recoverable( const wxString& msg="Recoverable error while loading savestate (existing emulation state is still intact)." ) : explicit StateLoadError_Recoverable( const char* msg="Recoverable savestate load error" ) :
RuntimeError( msg ) {} RuntimeError( msg ) {}
}; };
// ------------------------------------------------------------------------
// A recoverable exception thrown when the savestate being loaded isn't supported. // A recoverable exception thrown when the savestate being loaded isn't supported.
class UnsupportedStateVersion : public StateLoadError_Recoverable class UnsupportedStateVersion : public StateLoadError_Recoverable
{ {
@ -354,13 +437,15 @@ namespace Exception
public: public:
virtual ~UnsupportedStateVersion() throw() {} virtual ~UnsupportedStateVersion() throw() {}
explicit UnsupportedStateVersion( int version ) : explicit UnsupportedStateVersion( int version ) :
StateLoadError_Recoverable( fmt_string( "Unknown or unsupported savestate version: 0x%x", version ) ) StateLoadError_Recoverable(),
Version( version )
{} {}
explicit UnsupportedStateVersion( __unused int version, const wxString& msg ) : virtual wxString LogMessage() const;
StateLoadError_Recoverable( msg ) {} virtual wxString DisplayMessage() const;
}; };
// ------------------------------------------------------------------------
// A recoverable exception thrown when the CRC of the savestate does not match the // A recoverable exception thrown when the CRC of the savestate does not match the
// CRC returned by the Cdvd driver. // CRC returned by the Cdvd driver.
// [feature not implemented yet] // [feature not implemented yet]
@ -373,20 +458,12 @@ namespace Exception
public: public:
virtual ~StateCrcMismatch() throw() {} virtual ~StateCrcMismatch() throw() {}
explicit StateCrcMismatch( u32 crc_save, u32 crc_cdvd ) explicit StateCrcMismatch( u32 crc_save, u32 crc_cdvd )
: StateLoadError_Recoverable( fmt_string( : StateLoadError_Recoverable()
"Game/CDVD does not match the savestate CRC.\n"
"\tCdvd CRC: 0x%X\n\tGame CRC: 0x%X\n", params crc_save, crc_cdvd
) )
, Crc_Savestate( crc_save ) , Crc_Savestate( crc_save )
, Crc_Cdvd( crc_cdvd ) , Crc_Cdvd( crc_cdvd )
{} {}
explicit StateCrcMismatch( u32 crc_save, u32 crc_cdvd, const wxString& msg ) virtual wxString LogMessage() const;
: StateLoadError_Recoverable( msg ) virtual wxString DisplayMessage() const;
, Crc_Savestate( crc_save )
, Crc_Cdvd( crc_cdvd )
{}
}; };
} }
#endif

View File

@ -24,16 +24,27 @@
#include "GS.h" #include "GS.h"
#include "iR5900.h" #include "iR5900.h"
#include "Counters.h" #include "Counters.h"
#include "VifDma.h" #include "VifDma.h"
using namespace Threading; using namespace Threading;
using namespace std; using namespace std;
using namespace R5900; using namespace R5900;
static bool m_gsOpened = false; static bool m_gsOpened = false;
u32 CSRw;
PCSX2_ALIGNED16( u8 g_RealGSMem[0x2000] );
extern int m_nCounters[];
// FrameSkipping Stuff
// Yuck, iSlowStart is needed by the MTGS, so can't make it static yet.
u64 m_iSlowStart=0;
static s64 m_iSlowTicks=0;
static bool m_justSkipped = false;
static bool m_StrictSkipping = false;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
// GS Playback // GS Playback
@ -98,21 +109,6 @@ __forceinline void GSVSYNC(void) {
} }
#endif #endif
u32 CSRw;
PCSX2_ALIGNED16( u8 g_RealGSMem[0x2000] );
#define PS2GS_BASE(mem) (g_RealGSMem+(mem&0x13ff))
extern int m_nCounters[];
// FrameSkipping Stuff
// Yuck, iSlowStart is needed by the MTGS, so can't make it static yet.
u64 m_iSlowStart=0;
static s64 m_iSlowTicks=0;
static bool m_justSkipped = false;
static bool m_StrictSkipping = false;
void _gs_ChangeTimings( u32 framerate, u32 iTicks ) void _gs_ChangeTimings( u32 framerate, u32 iTicks )
{ {
m_iSlowStart = GetCPUTicks(); m_iSlowStart = GetCPUTicks();
@ -839,8 +835,6 @@ void RunGSState( gzLoadingState& f )
list<GSStatePacket>::iterator it = packets.begin(); list<GSStatePacket>::iterator it = packets.begin();
g_SaveGSStream = 3; g_SaveGSStream = 3;
//int skipfirst = 1;
// first extract the data // first extract the data
while(1) { while(1) {
@ -877,4 +871,4 @@ void RunGSState( gzLoadingState& f )
#endif #endif
#undef GIFchain //#undef GIFchain

View File

@ -28,18 +28,17 @@
using std::min; using std::min;
#define gif ((DMACh*)&psH[0xA000]) #define gifsplit 64
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
enum gifstate_t enum gifstate_t
{ {
GIF_STATE_EMPTY = 0, GIF_STATE_READY = 0,
GIF_STATE_STALL, GIF_STATE_STALL = 1,
GIF_STATE_DONE GIF_STATE_DONE = 2,
GIF_STATE_EMPTY = 0x10
}; };
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished). // A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
static gifstate_t gifstate = GIF_STATE_EMPTY; static int gifstate = GIF_STATE_READY;
static u64 s_gstag = 0; // used for querying the last tag static u64 s_gstag = 0; // used for querying the last tag
@ -49,6 +48,7 @@ static int gspath3done = 0;
static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0; static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0;
static u32 gifqwc = 0; static u32 gifqwc = 0;
bool gifmfifoirq = FALSE;
__forceinline void gsInterrupt() { __forceinline void gsInterrupt() {
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle); GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
@ -57,8 +57,8 @@ __forceinline void gsInterrupt() {
//Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done); //Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done);
return; return;
} }
if(gif->qwc > 0 || gspath3done == 0) { if (gif->qwc > 0 || gspath3done == 0) {
if( !(psHu32(DMAC_CTRL) & 0x1) ) { if (!(psHu32(DMAC_CTRL) & 0x1)) {
Console::Notice("gs dma masked, re-scheduling..."); Console::Notice("gs dma masked, re-scheduling...");
// re-raise the int shortly in the future // re-raise the int shortly in the future
CPU_INT( 2, 64 ); CPU_INT( 2, 64 );
@ -73,7 +73,7 @@ __forceinline void gsInterrupt() {
/*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1)) /*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
CPU_INT( 2, 64 );*/ CPU_INT( 2, 64 );*/
#endif #endif
if(gspath3done == 0) return; if(gspath3done == 0 || gif->qwc > 0) return;
} }
gspath3done = 0; gspath3done = 0;
@ -85,6 +85,7 @@ __forceinline void gsInterrupt() {
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0 psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
GIF_LOG("GIF DMA end");
} }
@ -127,7 +128,7 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
int _GIFchain() { int _GIFchain() {
#ifdef GSPATH3FIX #ifdef GSPATH3FIX
u32 qwc = ((psHu32(GIF_MODE) & 0x4) && (vif1Regs->mskpath3)) ? min(8, (int)gif->qwc) : gif->qwc; u32 qwc = ((psHu32(GIF_MODE) & 0x4) && (vif1Regs->mskpath3)) ? min(8, (int)gif->qwc) : min( gifsplit, (int)gif->qwc );
#else #else
u32 qwc = gif->qwc; u32 qwc = gif->qwc;
#endif #endif
@ -151,7 +152,7 @@ int _GIFchain() {
return (qwc)*2; return (qwc)*2;
} }
__forceinline void GIFchain() static __forceinline void GIFchain()
{ {
FreezeRegs(1); FreezeRegs(1);
if (gif->qwc) gscycles+= _GIFchain(); /* guessing */ if (gif->qwc) gscycles+= _GIFchain(); /* guessing */
@ -163,7 +164,7 @@ static __forceinline void dmaGIFend()
if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
else else
CPU_INT(2, gif->qwc /** BIAS*/); CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/);
} }
// These could probably be consolidated into one function, // These could probably be consolidated into one function,
@ -174,7 +175,7 @@ static __forceinline void GIFdmaEnd()
if (psHu32(GIF_MODE) & 0x4) if (psHu32(GIF_MODE) & 0x4)
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/); CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
else else
CPU_INT(2, gif->qwc /** BIAS*/); CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/);
} }
void GIFdma() void GIFdma()
@ -189,7 +190,7 @@ void GIFdma()
return; return;
} }
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
#ifndef GSPATH3FIX #ifndef GSPATH3FIX
if ( !(psHu32(GIF_MODE) & 0x4) ) { if ( !(psHu32(GIF_MODE) & 0x4) ) {
@ -225,7 +226,7 @@ void GIFdma()
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
if (ptag == NULL) { //Is ptag empty? if (ptag == NULL) { //Is ptag empty?
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
return; return;
} }
gscycles += 2; gscycles += 2;
@ -243,14 +244,10 @@ void GIFdma()
} }
} }
} }
// When MTGS is enabled, Gifchain calls WRITERING_DMA, which calls GSRINGBUF_DONECOPY, which freezes
// the registers inside of the FreezeXMMRegs calls here and in the other two below..
// I'm not really sure that is intentional. --arcum42
GIFchain(); GIFchain();
// Theres a comment below that says not to unfreeze the xmm regs, so not sure about freezing and unfreezing in GIFchain.
if((gif->qwc == 0) && ((gspath3done == 1) || (gif->chcr & 0xc) == 0)){ if((gif->qwc == 0) && ((gspath3done == 1) || (gif->chcr & 0xc) == 0)){
//if(gif->qwc > 0) Console::WriteLn("Hurray!"); // We *know* it is 0!
gspath3done = 0; gspath3done = 0;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
GSCSRr &= ~0xC000; GSCSRr &= ~0xC000;
@ -272,17 +269,20 @@ void GIFdma()
if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0)) if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0))
gspath3done = 1; gspath3done = 1;
else else if(gif->qwc > 0)
{
GIFdmaEnd(); GIFdmaEnd();
return; return;
} }
else { }
if ((gif->chcr & 0xc) == 0x4 && gspath3done == 0)
{
// Chain Mode // Chain Mode
while ((gspath3done == 0) && (gif->qwc == 0)) { //Loop if the transfers aren't intermittent //while ((gspath3done == 0) && (gif->qwc == 0)) { //Loop if the transfers aren't intermittent
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
if (ptag == NULL) { //Is ptag empty? if (ptag == NULL) { //Is ptag empty?
psHu32(DMAC_STAT)|= 1<<15; //If yes, set BEIS (BUSERR) in DMAC_STAT register psHu32(DMAC_STAT)|= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
return; return;
} }
gscycles+=2; // Add 1 cycles from the QW read for the tag gscycles+=2; // Add 1 cycles from the QW read for the tag
@ -300,7 +300,7 @@ void GIFdma()
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) { // STD == GIF if ((psHu32(DMAC_CTRL) & 0xC0) == 0x80) { // STD == GIF
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall // there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if(!gspath3done && gif->madr + (gif->qwc * 16) > psHu32(DMAC_STADR) && id == 4) { if(!gspath3done && ((gif->madr + (gif->qwc * 16)) > psHu32(DMAC_STADR)) && (id == 4)) {
// stalled // stalled
Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR)); Console::WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", params (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
prevcycles = gscycles; prevcycles = gscycles;
@ -313,20 +313,20 @@ void GIFdma()
} }
GIFchain(); //Transfers the data set by the switch GIFchain(); //Transfers the data set by the switch
if ((gif->chcr & 0x80) && ptag[0] >> 31) { //Check TIE bit of CHCR and IRQ bit of tag if ((gif->chcr & 0x80) && (ptag[0] >> 31)) { //Check TIE bit of CHCR and IRQ bit of tag
GIF_LOG("dmaIrq Set"); GIF_LOG("dmaIrq Set");
gspath3done = 1; gspath3done = 1;
} }
} //}
} }
prevcycles = 0; prevcycles = 0;
if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) { if (!(vif1Regs->mskpath3 || (psHu32(GIF_MODE) & 0x1))) {
if (gspath3done == 0) if (gspath3done == 0 || gif->qwc > 0)
{ {
if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0) if (gif->qwc != 0)
{ {
CPU_INT(2, min( 8, (int)gif->qwc )/** BIAS*/); GIFdmaEnd();
} }
else else
{ {
@ -346,9 +346,9 @@ void GIFdma()
void dmaGIF() { void dmaGIF() {
//We used to addd wait time for the buffer to fill here, fixing some timing problems in path 3 masking //We used to addd wait time for the buffer to fill here, fixing some timing problems in path 3 masking
//It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball //It takes the time of 24 QW for the BUS to become ready - The Punisher, And1 Streetball
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO if ((psHu32(DMAC_CTRL) & 0xC) == 0xC ) { // GIF MFIFO
Console::WriteLn("GIF MFIFO"); //Console::WriteLn("GIF MFIFO");
gifMFIFOInterrupt(); gifMFIFOInterrupt();
return; return;
} }
@ -365,7 +365,8 @@ void dmaGIF() {
gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag gif->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15 gif->chcr = ( gif->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
dmaGIFend(); //gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7);
GIFdmaEnd();
gif->qwc = 0; gif->qwc = 0;
return; return;
} }
@ -414,8 +415,8 @@ static __forceinline int mfifoGIFrbTransfer() {
gifqwc -= mfifoqwc; gifqwc -= mfifoqwc;
gif->qwc -= mfifoqwc; gif->qwc -= mfifoqwc;
gif->madr+= mfifoqwc*16; gif->madr += mfifoqwc*16;
mfifocycles+= (mfifoqwc) * 2; /* guessing */ //mfifocycles += (mfifoqwc) * 2; /* guessing */
return 0; return 0;
} }
@ -438,14 +439,13 @@ static __forceinline int mfifoGIFchain() {
if (pMem == NULL) return -1; if (pMem == NULL) return -1;
WRITERING_DMA(pMem, mfifoqwc); WRITERING_DMA(pMem, mfifoqwc);
gif->madr+= mfifoqwc*16; gif->madr += mfifoqwc*16;
gif->qwc -= mfifoqwc; gif->qwc -= mfifoqwc;
mfifocycles+= (mfifoqwc) * 2; /* guessing */ mfifocycles += (mfifoqwc) * 2; /* guessing */
} }
return 0; return 0;
} }
bool gifmfifoirq = FALSE;
void mfifoGIFtransfer(int qwc) { void mfifoGIFtransfer(int qwc) {
u32 *ptag; u32 *ptag;
@ -457,14 +457,14 @@ void mfifoGIFtransfer(int qwc) {
if(qwc > 0 ) { if(qwc > 0 ) {
gifqwc += qwc; gifqwc += qwc;
if(!(gif->chcr & 0x100))return; if (gifstate != GIF_STATE_EMPTY) return;
if(gifstate == GIF_STATE_STALL) return; gifstate &= ~GIF_STATE_EMPTY;
} }
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr); SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
if(gif->qwc == 0){ if (gif->qwc == 0) {
if(gif->tadr == spr0->madr) { if (gif->tadr == spr0->madr) {
//if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc); //if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);
//hwDmacIrq(14); //hwDmacIrq(14);
@ -492,20 +492,20 @@ void mfifoGIFtransfer(int qwc) {
case 1: // CNT - Transfer QWC following the tag. case 1: // CNT - Transfer QWC following the tag.
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW after Tag
gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data gif->tadr = psHu32(DMAC_RBOR) + ((gif->madr + (gif->qwc << 4)) & psHu32(DMAC_RBSR)); //Set TADR to QW following the data
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
break; break;
case 2: // Next - Transfer QWC following tag. TADR = ADDR case 2: // Next - Transfer QWC following tag. TADR = ADDR
temp = gif->madr; //Temporarily Store ADDR temp = gif->madr; //Temporarily Store ADDR
gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag gif->madr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set MADR to QW following the tag
gif->tadr = temp; //Copy temporarily stored ADDR to Tag gif->tadr = temp; //Copy temporarily stored ADDR to Tag
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
break; break;
case 3: // Ref - Transfer QWC from ADDR field case 3: // Ref - Transfer QWC from ADDR field
case 4: // Refs - Transfer QWC from ADDR field (Stall Control) case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag gif->tadr = psHu32(DMAC_RBOR) + ((gif->tadr + 16) & psHu32(DMAC_RBSR)); //Set TADR to next tag
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
break; break;
case 7: // End - Transfer QWC following the tag case 7: // End - Transfer QWC following the tag
@ -521,12 +521,15 @@ void mfifoGIFtransfer(int qwc) {
gifmfifoirq = TRUE; gifmfifoirq = TRUE;
} }
} }
FreezeRegs(1); FreezeRegs(1);
if (mfifoGIFchain() == -1) { if (mfifoGIFchain() == -1) {
Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params
gif->qwc, gif->madr, gif->tadr); gif->qwc, gif->madr, gif->tadr);
gifstate = GIF_STATE_STALL; gifstate = GIF_STATE_STALL;
} }
FreezeRegs(0); FreezeRegs(0);
if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL; if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL;
@ -542,10 +545,16 @@ void gifMFIFOInterrupt()
cpuRegs.interrupt &= ~(1 << 11); cpuRegs.interrupt &= ~(1 << 11);
return ; return ;
} }
if((spr0->chcr & 0x100) && spr0->qwc == 0)
{
spr0->chcr &= ~0x100;
hwDmacIrq(8);
}
if(gifstate != GIF_STATE_STALL) { if(gifstate != GIF_STATE_STALL) {
if(gifqwc <= 0) { if(gifqwc <= 0) {
//Console::WriteLn("Empty"); //Console::WriteLn("Empty");
gifstate |= GIF_STATE_EMPTY;
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0 psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
hwDmacIrq(14); hwDmacIrq(14);
return; return;
@ -554,14 +563,14 @@ void gifMFIFOInterrupt()
return; return;
} }
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if(gifstate == GIF_STATE_EMPTY || gif->qwc > 0) { if(gifstate == GIF_STATE_READY || gif->qwc > 0) {
Console::Error("gifMFIFO Panic > Shouldn't go here!"); Console::Error("gifMFIFO Panic > Shouldn't go here!");
return; return;
} }
#endif #endif
//if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc); //if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc);
if (!gifmfifoirq) gifqwc = 0; if (!gifmfifoirq) gifqwc = 0;
gifstate = GIF_STATE_EMPTY; gifstate = GIF_STATE_READY;
gif->chcr &= ~0x100; gif->chcr &= ~0x100;
hwDmacIrq(DMAC_GIF); hwDmacIrq(DMAC_GIF);
GSCSRr &= ~0xC000; //Clear FIFO stuff GSCSRr &= ~0xC000; //Clear FIFO stuff

View File

@ -93,8 +93,8 @@ namespace HostGui
// For issuing notices to both the status bar and the console at the same time. // For issuing notices to both the status bar and the console at the same time.
// Single-line text only please! Multi-line msgs should be directed to the // Single-line text only please! Multi-line msgs should be directed to the
// console directly, thanks. // console directly, thanks.
extern void Notice( const std::string& text ); extern void Notice( const wxString& text );
// sets the contents of the pcsx2 window status bar. // sets the contents of the pcsx2 window status bar.
extern void SetStatusMsg( const std::string& text ); extern void SetStatusMsg( const wxString& text );
}; };

View File

@ -148,31 +148,31 @@ int hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
} }
int hwDmacSrcChainWithStack(DMACh *dma, int id) { bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
u32 temp;
switch (id) { switch (id) {
case 0: // Refe - Transfer Packet According to ADDR field case 0: // Refe - Transfer Packet According to ADDR field
return 1; //End Transfer return true; //End Transfer
case 1: // CNT - Transfer QWC following the tag. case 1: // CNT - Transfer QWC following the tag.
dma->madr = dma->tadr + 16; //Set MADR to QW after Tag dma->madr = dma->tadr + 16; //Set MADR to QW after Tag
dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data
return 0; return false;
case 2: // Next - Transfer QWC following tag. TADR = ADDR case 2: // Next - Transfer QWC following tag. TADR = ADDR
temp = dma->madr; //Temporarily Store ADDR {
u32 temp = dma->madr; //Temporarily Store ADDR
dma->madr = dma->tadr + 16; //Set MADR to QW following the tag dma->madr = dma->tadr + 16; //Set MADR to QW following the tag
dma->tadr = temp; //Copy temporarily stored ADDR to Tag dma->tadr = temp; //Copy temporarily stored ADDR to Tag
return 0; return false;
}
case 3: // Ref - Transfer QWC from ADDR field case 3: // Ref - Transfer QWC from ADDR field
case 4: // Refs - Transfer QWC from ADDR field (Stall Control) case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
dma->tadr += 16; //Set TADR to next tag dma->tadr += 16; //Set TADR to next tag
return 0; return false;
case 5: // Call - Transfer QWC following the tag, save succeeding tag case 5: // Call - Transfer QWC following the tag, save succeeding tag
temp = dma->madr; //Temporarily Store ADDR {
u32 temp = dma->madr; //Temporarily Store ADDR
dma->madr = dma->tadr + 16; //Set MADR to data following the tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag
@ -185,12 +185,12 @@ int hwDmacSrcChainWithStack(DMACh *dma, int id) {
dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1 dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1
}else { }else {
Console::Notice("Call Stack Overflow (report if it fixes/breaks anything)"); Console::Notice("Call Stack Overflow (report if it fixes/breaks anything)");
return 1; //Return done return true; //Return done
} }
dma->tadr = temp; //Set TADR to temporarily stored ADDR dma->tadr = temp; //Set TADR to temporarily stored ADDR
return 0; return false;
}
case 6: // Ret - Transfer QWC following the tag, load next tag case 6: // Ret - Transfer QWC following the tag, load next tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag
@ -209,668 +209,45 @@ int hwDmacSrcChainWithStack(DMACh *dma, int id) {
return 1; //End Transfer return 1; //End Transfer
} }
} }
return 0; return false;
case 7: // End - Transfer QWC following the tag case 7: // End - Transfer QWC following the tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag
//Dont Increment tadr, breaks Soul Calibur II and III //Dont Increment tadr, breaks Soul Calibur II and III
return 1; //End Transfer return true; //End Transfer
} }
return -1; return false;
} }
int hwDmacSrcChain(DMACh *dma, int id) { bool hwDmacSrcChain(DMACh *dma, int id) {
u32 temp; u32 temp;
switch (id) { switch (id) {
case 0: // Refe - Transfer Packet According to ADDR field case 0: // Refe - Transfer Packet According to ADDR field
return 1; //End Transfer return true; //End Transfer
case 1: // CNT - Transfer QWC following the tag. case 1: // CNT - Transfer QWC following the tag.
dma->madr = dma->tadr + 16; //Set MADR to QW after Tag dma->madr = dma->tadr + 16; //Set MADR to QW after Tag
dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data dma->tadr = dma->madr + (dma->qwc << 4); //Set TADR to QW following the data
return 0; return false;
case 2: // Next - Transfer QWC following tag. TADR = ADDR case 2: // Next - Transfer QWC following tag. TADR = ADDR
temp = dma->madr; //Temporarily Store ADDR temp = dma->madr; //Temporarily Store ADDR
dma->madr = dma->tadr + 16; //Set MADR to QW following the tag dma->madr = dma->tadr + 16; //Set MADR to QW following the tag
dma->tadr = temp; //Copy temporarily stored ADDR to Tag dma->tadr = temp; //Copy temporarily stored ADDR to Tag
return 0; return false;
case 3: // Ref - Transfer QWC from ADDR field case 3: // Ref - Transfer QWC from ADDR field
case 4: // Refs - Transfer QWC from ADDR field (Stall Control) case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
dma->tadr += 16; //Set TADR to next tag dma->tadr += 16; //Set TADR to next tag
return 0; return false;
case 7: // End - Transfer QWC following the tag case 7: // End - Transfer QWC following the tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag dma->madr = dma->tadr + 16; //Set MADR to data following the tag
//Dont Increment tadr, breaks Soul Calibur II and III //Dont Increment tadr, breaks Soul Calibur II and III
return 1; //End Transfer return true; //End Transfer
} }
return -1; return false;
} }
// Original hwRead/Write32 functions .. left in for now, for troubleshooting purposes.
#if 0
mem32_t __fastcall hwRead32(u32 mem)
{
// *Performance Warning* This function is called -A-LOT. Be weary when making changes. It
// could impact FPS significantly.
// Optimization Note:
// Shortcut for the INTC_STAT register, which is checked *very* frequently as part of the EE's
// vsynch timers. INTC_STAT has the disadvantage of being in the 0x1000f000 case, which has
// a lot of additional registers in it, and combined with it's call frequency is a bad thing.
if(mem == INTC_STAT)
{
// This one is checked alot, so leave it commented out unless you love 600 meg logfiles.
//HW_LOG("DMAC_STAT Read 32bit %x\n", psHu32(0xe010));
return psHu32(INTC_STAT);
}
const u16 masked_mem = mem & 0xffff;
// We optimize the hw register reads by breaking them into manageable 4k chunks (for a total of
// 16 cases spanning the 64k PS2 hw register memory map). It helps also that the EE is, for
// the most part, designed so that various classes of registers are sectioned off into these
// 4k segments.
// Notes: Breaks from the switch statement will return a standard hw memory read.
// Special case handling of reads should use "return" directly.
switch( masked_mem>>12 ) // switch out as according to the 4k page of the access.
{
// Counters Registers
// This code uses some optimized trickery to produce more compact output.
// See below for the "reference" block to get a better idea what this code does. :)
case 0x0: // counters 0 and 1
case 0x1: // counters 2 and 3
{
const uint cntidx = masked_mem >> 11; // neat trick to scale the counter HW address into 0-3 range.
switch( (masked_mem>>4) & 0xf )
{
case 0x0: return (u16)rcntRcount(cntidx);
case 0x1: return (u16)counters[cntidx].modeval;
case 0x2: return (u16)counters[cntidx].target;
case 0x3: return (u16)counters[cntidx].hold;
}
}
#if 0 // Counters Reference Block (original case setup)
case 0x10000000: return (u16)rcntRcount(0);
case 0x10000010: return (u16)counters[0].modeval;
case 0x10000020: return (u16)counters[0].target;
case 0x10000030: return (u16)counters[0].hold;
case 0x10000800: return (u16)rcntRcount(1);
case 0x10000810: return (u16)counters[1].modeval;
case 0x10000820: return (u16)counters[1].target;
case 0x10000830: return (u16)counters[1].hold;
case 0x10001000: return (u16)rcntRcount(2);
case 0x10001010: return (u16)counters[2].modeval;
case 0x10001020: return (u16)counters[2].target;
case 0x10001800: return (u16)rcntRcount(3);
case 0x10001810: return (u16)counters[3].modeval;
case 0x10001820: return (u16)counters[3].target;
#endif
break;
case 0x2: return ipuRead32( mem );
case 0xf:
switch( (masked_mem >> 4) & 0xff )
{
case 0x01:
HW_LOG("INTC_MASK Read32, value=0x%x", psHu32(INTC_MASK));
break;
case 0x13: // 0x1000f130
case 0x26: // 0x1000f260 SBUS?
case 0x41: // 0x1000f410
case 0x43: // MCH_RICM
return 0;
case 0x24: // 0x1000f240: SBUS
return psHu32(0xf240) | 0xF0000102;
case 0x44: // 0x1000f440: MCH_DRD
if( !((psHu32(0xf430) >> 6) & 0xF) )
{
switch ((psHu32(0xf430)>>16) & 0xFFF)
{
//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
case 0x21://INIT
if(rdram_sdevid < rdram_devices)
{
rdram_sdevid++;
return 0x1F;
}
return 0;
case 0x23://CNFGA
return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5
case 0x24://CNFGB
//0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0
return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0
case 0x40://DEVID
return psHu32(0xf430) & 0x1F; // =SDEV
}
}
return 0;
}
break;
///////////////////////////////////////////////////////
// Most of the following case handlers are for developer builds only (logging).
// It'll all optimize to ziltch in public release builds.
case 0x03:
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0a:
{
const char* regName = "Unknown";
switch( mem )
{
case D2_CHCR: regName = "DMA2_CHCR"; break;
case D2_MADR: regName = "DMA2_MADR"; break;
case D2_QWC: regName = "DMA2_QWC"; break;
case D2_TADR: regName = "DMA2_TADDR"; break;
case D2_ASR0: regName = "DMA2_ASR0"; break;
case D2_ASR1: regName = "DMA2_ASR1"; break;
case D2_SADR: regName = "DMA2_SADDR"; break;
}
HW_LOG( "Hardware Read32 at 0x%x (%s), value=0x%x", mem, regName, psHu32(mem) );
}
break;
case 0x0b:
if( mem == D4_CHCR )
HW_LOG("Hardware Read32 at 0x%x (IPU1:DMA4_CHCR), value=0x%x", mem, psHu32(mem));
break;
case 0x0c:
case 0x0d:
case 0x0e:
if( mem == DMAC_STAT )
HW_LOG("DMAC_STAT Read32, value=0x%x", psHu32(DMAC_STAT));
break;
jNO_DEFAULT;
}
// Optimization note: We masked 'mem' earlier, so it's safe to access PS2MEM_HW directly.
// (checked disasm, and MSVC 2008 fails to optimize it on its own)
//return psHu32(mem);
return *((u32*)&PS2MEM_HW[masked_mem]);
}
__forceinline void __fastcall hwWrite32(u32 mem, u32 value)
{
if ((mem>=0x10002000) && (mem<0x10003000)) { //IPU regs
ipuWrite32(mem,value);
return;
}
if ((mem>=0x10003800) && (mem<0x10003c00)) {
vif0Write32(mem, value);
return;
}
if ((mem>=0x10003c00) && (mem<0x10004000)) {
vif1Write32(mem, value);
return;
}
switch (mem) {
case 0x10000000: rcntWcount(0, value); break;
case 0x10000010: rcntWmode(0, value); break;
case 0x10000020: rcntWtarget(0, value); break;
case 0x10000030: rcntWhold(0, value); break;
case 0x10000800: rcntWcount(1, value); break;
case 0x10000810: rcntWmode(1, value); break;
case 0x10000820: rcntWtarget(1, value); break;
case 0x10000830: rcntWhold(1, value); break;
case 0x10001000: rcntWcount(2, value); break;
case 0x10001010: rcntWmode(2, value); break;
case 0x10001020: rcntWtarget(2, value); break;
case 0x10001800: rcntWcount(3, value); break;
case 0x10001810: rcntWmode(3, value); break;
case 0x10001820: rcntWtarget(3, value); break;
case GIF_CTRL:
//Console::WriteLn("GIF_CTRL write %x", params value);
psHu32(mem) = value & 0x8;
if (value & 0x1)
gsGIFReset();
else if( value & 8 )
psHu32(GIF_STAT) |= 8;
else
psHu32(GIF_STAT) &= ~8;
return;
case GIF_MODE:
// need to set GIF_MODE (hamster ball)
psHu32(GIF_MODE) = value;
if (value & 0x1)
psHu32(GIF_STAT)|= 0x1;
else
psHu32(GIF_STAT)&= ~0x1;
if (value & 0x4)
psHu32(GIF_STAT)|= 0x4;
else
psHu32(GIF_STAT)&= ~0x4;
break;
case GIF_STAT: // stat is readonly
Console::WriteLn("Gifstat write value = %x", params value);
return;
case 0x10008000: // dma0 - vif0
DMA_LOG("VIF0dma %lx", value);
DmaExec(dmaVIF0, mem, value);
break;
case 0x10009000: // dma1 - vif1 - chcr
DMA_LOG("VIF1dma CHCR %lx", value);
DmaExec(dmaVIF1, mem, value);
break;
#ifdef PCSX2_DEVBUILD
case 0x10009010: // dma1 - vif1 - madr
HW_LOG("VIF1dma Madr %lx", value);
psHu32(mem) = value;//dma1 madr
break;
case 0x10009020: // dma1 - vif1 - qwc
HW_LOG("VIF1dma QWC %lx", value);
psHu32(mem) = value;//dma1 qwc
break;
case 0x10009030: // dma1 - vif1 - tadr
HW_LOG("VIF1dma TADR %lx", value);
psHu32(mem) = value;//dma1 tadr
break;
case 0x10009040: // dma1 - vif1 - asr0
HW_LOG("VIF1dma ASR0 %lx", value);
psHu32(mem) = value;//dma1 asr0
break;
case 0x10009050: // dma1 - vif1 - asr1
HW_LOG("VIF1dma ASR1 %lx", value);
psHu32(mem) = value;//dma1 asr1
break;
case 0x10009080: // dma1 - vif1 - sadr
HW_LOG("VIF1dma SADR %lx", value);
psHu32(mem) = value;//dma1 sadr
break;
#endif
case 0x1000a000: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value);
DmaExec(dmaGIF, mem, value);
break;
#ifdef PCSX2_DEVBUILD
case 0x1000a010:
psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value);
break;
case 0x1000a020:
psHu32(mem) = value;//dma2 qwc
HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
break;
case 0x1000a030:
psHu32(mem) = value;//dma2 taddr
HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
break;
case 0x1000a040:
psHu32(mem) = value;//dma2 asr0
HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
break;
case 0x1000a050:
psHu32(mem) = value;//dma2 asr1
HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
break;
case 0x1000a080:
psHu32(mem) = value;//dma2 saddr
HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
break;
#endif
case 0x1000b000: // dma3 - fromIPU
DMA_LOG("IPU0dma %lx", value);
DmaExec(dmaIPU0, mem, value);
break;
#ifdef PCSX2_DEVBUILD
case 0x1000b010:
psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value);
break;
case 0x1000b020:
psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value);
break;
case 0x1000b030:
psHu32(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value);
break;
case 0x1000b080:
psHu32(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value);
break;
#endif
case 0x1000b400: // dma4 - toIPU
DMA_LOG("IPU1dma %lx", value);
DmaExec(dmaIPU1, mem, value);
break;
#ifdef PCSX2_DEVBUILD
case 0x1000b410:
psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value);
break;
case 0x1000b420:
psHu32(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value);
break;
case 0x1000b430:
psHu32(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value);
break;
case 0x1000b480:
psHu32(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value);
break;
#endif
case 0x1000c000: // dma5 - sif0
DMA_LOG("SIF0dma %lx", value);
DmaExec(dmaSIF0, mem, value);
break;
case 0x1000c400: // dma6 - sif1
DMA_LOG("SIF1dma %lx", value);
DmaExec(dmaSIF1, mem, value);
break;
#ifdef PCSX2_DEVBUILD
case 0x1000c420: // dma6 - sif1 - qwc
HW_LOG("SIF1dma QWC = %lx", value);
psHu32(mem) = value;
break;
case 0x1000c430: // dma6 - sif1 - tadr
HW_LOG("SIF1dma TADR = %lx", value);
psHu32(mem) = value;
break;
#endif
case 0x1000c800: // dma7 - sif2
DMA_LOG("SIF2dma %lx", value);
DmaExec(dmaSIF2, mem, value);
break;
case 0x1000d000: // dma8 - fromSPR
DMA_LOG("fromSPRdma %lx", value);
DmaExec(dmaSPR0, mem, value);
break;
case 0x1000d400: // dma9 - toSPR
DMA_LOG("toSPRdma %lx", value);
DmaExec(dmaSPR1, mem, value);
break;
case 0x1000e000: // DMAC_CTRL
HW_LOG("DMAC_CTRL Write 32bit %x", value);
psHu32(0xe000) = value;
break;
case 0x1000e010: // DMAC_STAT
HW_LOG("DMAC_STAT Write 32bit %x", value);
psHu16(0xe010)&= ~(value & 0xffff); // clear on 1
psHu16(0xe012) ^= (u16)(value >> 16);
cpuTestDMACInts();
break;
case 0x1000f000: // INTC_STAT
HW_LOG("INTC_STAT Write 32bit %x", value);
psHu32(0xf000)&=~value;
break;
case 0x1000f010: // INTC_MASK
HW_LOG("INTC_MASK Write 32bit %x", value);
psHu32(0xf010) ^= (u16)value;
cpuTestINTCInts();
break;
case 0x1000f430://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0
rdram_sdevid = 0; // if SIO repeater is cleared, reset sdevid
psHu32(mem) = value & ~0x80000000; //kill the busy bit
break;
case 0x1000f440://MCH_DRD:
psHu32(mem) = value;
break;
case 0x1000f590: // DMAC_ENABLEW
HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
psHu32(0xf590) = value;
psHu32(0xf520) = value;
return;
case 0x1000f200:
psHu32(mem) = value;
break;
case 0x1000f220:
psHu32(mem) |= value;
break;
case 0x1000f230:
psHu32(mem) &= ~value;
break;
case 0x1000f240:
if(!(value & 0x100))
psHu32(mem) &= ~0x100;
else
psHu32(mem) |= 0x100;
break;
case 0x1000f260:
psHu32(mem) = 0;
break;
case 0x1000f130:
case 0x1000f410:
HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val);
break;
default:
psHu32(mem) = value;
HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)", mem, value, cpuRegs.CP0.n.Status.val);
break;
}
}
#endif
/*
__forceinline void hwWrite64(u32 mem, u64 value)
{
u32 val32;
int i;
if ((mem>=0x10002000) && (mem<=0x10002030)) {
ipuWrite64(mem, value);
return;
}
if ((mem>=0x10003800) && (mem<0x10003c00)) {
vif0Write32(mem, value); return;
}
if ((mem>=0x10003c00) && (mem<0x10004000)) {
vif1Write32(mem, value); return;
}
switch (mem) {
case GIF_CTRL:
DevCon::Status("GIF_CTRL write 64", params value);
psHu32(mem) = value & 0x8;
if(value & 0x1) {
gsGIFReset();
//gsReset();
}
else {
if( value & 8 ) psHu32(GIF_STAT) |= 8;
else psHu32(GIF_STAT) &= ~8;
}
return;
case GIF_MODE:
#ifdef GSPATH3FIX
Console::Status("GIFMODE64 %x", params value);
#endif
psHu64(GIF_MODE) = value;
if (value & 0x1) psHu32(GIF_STAT)|= 0x1;
else psHu32(GIF_STAT)&= ~0x1;
if (value & 0x4) psHu32(GIF_STAT)|= 0x4;
else psHu32(GIF_STAT)&= ~0x4;
break;
case GIF_STAT: // stat is readonly
return;
case 0x1000a000: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite64: GSdma %lx", cpuRegs.cycle, value);
DmaExec(dmaGIF, mem, value);
break;
case 0x1000e000: // DMAC_CTRL
HW_LOG("DMAC_CTRL Write 64bit %x", value);
psHu64(mem) = value;
break;
case 0x1000e010: // DMAC_STAT
HW_LOG("DMAC_STAT Write 64bit %x", value);
val32 = (u32)value;
psHu16(0xe010)&= ~(val32 & 0xffff); // clear on 1
val32 = val32 >> 16;
for (i=0; i<16; i++) { // reverse on 1
if (val32 & (1<<i)) {
if (psHu16(0xe012) & (1<<i))
psHu16(0xe012)&= ~(1<<i);
else
psHu16(0xe012)|= 1<<i;
}
}
cpuTestDMACInts();
break;
case 0x1000f590: // DMAC_ENABLEW
psHu32(0xf590) = value;
psHu32(0xf520) = value;
break;
case 0x1000f000: // INTC_STAT
HW_LOG("INTC_STAT Write 64bit %x", value);
psHu32(INTC_STAT)&=~value;
cpuTestINTCInts();
break;
case 0x1000f010: // INTC_MASK
HW_LOG("INTC_MASK Write 32bit %x", value);
for (i=0; i<16; i++) { // reverse on 1
const int s = (1<<i);
if (value & s) {
if (psHu32(INTC_MASK) & s)
psHu32(INTC_MASK)&= ~s;
else
psHu32(INTC_MASK)|= s;
}
}
cpuTestINTCInts();
break;
case 0x1000f130:
case 0x1000f410:
case 0x1000f430:
break;
default:
psHu64(mem) = value;
HW_LOG("Unknown Hardware write 64 at %x with value %x (status=%x)",mem,value, cpuRegs.CP0.n.Status.val);
break;
}
}
__forceinline void hwWrite128(u32 mem, const u64 *value)
{
if (mem >= 0x10004000 && mem < 0x10008000) {
WriteFIFO(mem, value); return;
}
switch (mem) {
case 0x1000f590: // DMAC_ENABLEW
psHu32(0xf590) = *(u32*)value;
psHu32(0xf520) = *(u32*)value;
break;
case 0x1000f130:
case 0x1000f410:
case 0x1000f430:
break;
default:
psHu64(mem ) = value[0];
psHu64(mem+8) = value[1];
HW_LOG("Unknown Hardware write 128 at %x with value %x_%x (status=%x)", mem, value[1], value[0], cpuRegs.CP0.n.Status.val);
break;
}
}
*/

View File

@ -21,25 +21,16 @@
extern u8 *psH; // hw mem extern u8 *psH; // hw mem
#define psHs8(mem) (*(s8 *)&PS2MEM_HW[(mem) & 0xffff])
#define psHs16(mem) (*(s16*)&PS2MEM_HW[(mem) & 0xffff])
#define psHs32(mem) (*(s32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHs64(mem) (*(s64*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu8(mem) (*(u8 *)&PS2MEM_HW[(mem) & 0xffff])
#define psHu16(mem) (*(u16*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu32(mem) (*(u32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu64(mem) (*(u64*)&PS2MEM_HW[(mem) & 0xffff])
extern void CPU_INT( u32 n, s32 ecycle ); extern void CPU_INT( u32 n, s32 ecycle );
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Hardware FIFOs (128 bit access only!) // Hardware FIFOs (128 bit access only!)
// //
// VIF0 -- 0x10004000 -- psH[0x4000] // VIF0 -- 0x10004000 -- PS2MEM_HW[0x4000]
// VIF1 -- 0x10005000 -- psH[0x5000] // VIF1 -- 0x10005000 -- PS2MEM_HW[0x5000]
// GIF -- 0x10006000 -- psH[0x6000] // GIF -- 0x10006000 -- PS2MEM_HW[0x6000]
// IPUout -- 0x10007000 -- psH[0x7000] // IPUout -- 0x10007000 -- PS2MEM_HW[0x7000]
// IPUin -- 0x10007010 -- psH[0x7010] // IPUin -- 0x10007010 -- PS2MEM_HW[0x7010]
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out); void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out);
void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out); void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out);
@ -73,177 +64,183 @@ struct DMACh {
}; };
// HW defines // HW defines
enum HWaddress
{
RCNT0_COUNT = 0x10000000,
RCNT0_MODE = 0x10000010,
RCNT0_TARGET = 0x10000020,
RCNT0_HOLD = 0x10000030,
#define RCNT0_COUNT 0x10000000 RCNT1_COUNT = 0x10000800,
#define RCNT0_MODE 0x10000010 RCNT1_MODE = 0x10000810,
#define RCNT0_TARGET 0x10000020 RCNT1_TARGET = 0x10000820,
#define RCNT0_HOLD 0x10000030 RCNT1_HOLD = 0x10000830,
#define RCNT1_COUNT 0x10000800 RCNT2_COUNT = 0x10001000,
#define RCNT1_MODE 0x10000810 RCNT2_MODE = 0x10001010,
#define RCNT1_TARGET 0x10000820 RCNT2_TARGET = 0x10001020,
#define RCNT1_HOLD 0x10000830
#define RCNT2_COUNT 0x10001000 RCNT3_COUNT = 0x10001800,
#define RCNT2_MODE 0x10001010 RCNT3_MODE = 0x10001810,
#define RCNT2_TARGET 0x10001020 RCNT3_TARGET = 0x10001820,
#define RCNT3_COUNT 0x10001800 IPU_CMD = 0x10002000,
#define RCNT3_MODE 0x10001810 IPU_CTRL = 0x10002010,
#define RCNT3_TARGET 0x10001820 IPU_BP = 0x10002020,
IPU_TOP = 0x10002030,
#define IPU_CMD 0x10002000 GIF_CTRL = 0x10003000,
#define IPU_CTRL 0x10002010 GIF_MODE = 0x10003010,
#define IPU_BP 0x10002020 GIF_STAT = 0x10003020,
#define IPU_TOP 0x10002030 GIF_TAG0 = 0x10003040,
GIF_TAG1 = 0x10003050,
GIF_TAG2 = 0x10003060,
GIF_TAG3 = 0x10003070,
GIF_CNT = 0x10003080,
GIF_P3CNT = 0x10003090,
GIF_P3TAG = 0x100030A0,
GIF_FIFO = 0x10006000,
#define GIF_CTRL 0x10003000 IPUout_FIFO = 0x10007000,
#define GIF_MODE 0x10003010 IPUin_FIFO = 0x10007010,
#define GIF_STAT 0x10003020
#define GIF_TAG0 0x10003040
#define GIF_TAG1 0x10003050
#define GIF_TAG2 0x10003060
#define GIF_TAG3 0x10003070
#define GIF_CNT 0x10003080
#define GIF_P3CNT 0x10003090
#define GIF_P3TAG 0x100030A0
#define GIF_FIFO 0x10006000
#define IPUout_FIFO 0x10007000
#define IPUin_FIFO 0x10007010
//VIF0 //VIF0
#define D0_CHCR 0x10008000 D0_CHCR = 0x10008000,
#define D0_MADR 0x10008010 D0_MADR = 0x10008010,
#define D0_QWC 0x10008020 D0_QWC = 0x10008020,
//VIF1 //VIF1
#define D1_CHCR 0x10009000 D1_CHCR = 0x10009000,
#define D1_MADR 0x10009010 D1_MADR = 0x10009010,
#define D1_QWC 0x10009020 D1_QWC = 0x10009020,
#define D1_TADR 0x10009030 D1_TADR = 0x10009030,
#define D1_ASR0 0x10009040 D1_ASR0 = 0x10009040,
#define D1_ASR1 0x10009050 D1_ASR1 = 0x10009050,
#define D1_SADR 0x10009080 D1_SADR = 0x10009080,
//GS //GS
#define D2_CHCR 0x1000A000 D2_CHCR = 0x1000A000,
#define D2_MADR 0x1000A010 D2_MADR = 0x1000A010,
#define D2_QWC 0x1000A020 D2_QWC = 0x1000A020,
#define D2_TADR 0x1000A030 D2_TADR = 0x1000A030,
#define D2_ASR0 0x1000A040 D2_ASR0 = 0x1000A040,
#define D2_ASR1 0x1000A050 D2_ASR1 = 0x1000A050,
#define D2_SADR 0x1000A080 D2_SADR = 0x1000A080,
//fromIPU //fromIPU
#define D3_CHCR 0x1000B000 D3_CHCR = 0x1000B000,
#define D3_MADR 0x1000B010 D3_MADR = 0x1000B010,
#define D3_QWC 0x1000B020 D3_QWC = 0x1000B020,
#define D3_TADR 0x1000B030 D3_TADR = 0x1000B030,
#define D3_SADR 0x1000B080 D3_SADR = 0x1000B080,
//toIPU //toIPU
#define D4_CHCR 0x1000B400 D4_CHCR = 0x1000B400,
#define D4_MADR 0x1000B410 D4_MADR = 0x1000B410,
#define D4_QWC 0x1000B420 D4_QWC = 0x1000B420,
#define D4_TADR 0x1000B430 D4_TADR = 0x1000B430,
#define D4_SADR 0x1000B480 D4_SADR = 0x1000B480,
//SIF0 //SIF0
#define D5_CHCR 0x1000C000 D5_CHCR = 0x1000C000,
#define D5_MADR 0x1000C010 D5_MADR = 0x1000C010,
#define D5_QWC 0x1000C020 D5_QWC = 0x1000C020,
//SIF1 //SIF1
#define D6_CHCR 0x1000C400 D6_CHCR = 0x1000C400,
#define D6_MADR 0x1000C410 D6_MADR = 0x1000C410,
#define D6_QWC 0x1000C420 D6_QWC = 0x1000C420,
//SIF2 //SIF2
#define D7_CHCR 0x1000C800 D7_CHCR = 0x1000C800,
#define D7_MADR 0x1000C810 D7_MADR = 0x1000C810,
#define D7_QWC 0x1000C820 D7_QWC = 0x1000C820,
//fromSPR //fromSPR
#define D8_CHCR 0x1000D000 D8_CHCR = 0x1000D000,
#define D8_MADR 0x1000D010 D8_MADR = 0x1000D010,
#define D8_QWC 0x1000D020 D8_QWC = 0x1000D020,
#define D8_SADR 0x1000D080 D8_SADR = 0x1000D080,
DMAC_CTRL = 0x1000E000,
DMAC_STAT = 0x1000E010,
DMAC_PCR = 0x1000E020,
DMAC_SQWC = 0x1000E030,
DMAC_RBSR = 0x1000E040,
DMAC_RBOR = 0x1000E050,
DMAC_STADR = 0x1000E060,
#define DMAC_CTRL 0x1000E000 INTC_STAT = 0x1000F000,
#define DMAC_STAT 0x1000E010 INTC_MASK = 0x1000F010,
#define DMAC_PCR 0x1000E020
#define DMAC_SQWC 0x1000E030
#define DMAC_RBSR 0x1000E040
#define DMAC_RBOR 0x1000E050
#define DMAC_STADR 0x1000E060
#define INTC_STAT 0x1000F000 SBUS_F220 = 0x1000F220,
#define INTC_MASK 0x1000F010 SBUS_SMFLG = 0x1000F230,
SBUS_F240 = 0x1000F240,
#define SBUS_F220 0x1000F220 DMAC_ENABLER = 0x1000F520,
#define SBUS_SMFLG 0x1000F230 DMAC_ENABLEW = 0x1000F590,
#define SBUS_F240 0x1000F240
#define DMAC_ENABLER 0x1000F520 GS_PMODE = 0x12000000,
#define DMAC_ENABLEW 0x1000F590 GS_SMODE1 = 0x12000010,
GS_SMODE2 = 0x12000020,
GS_SRFSH = 0x12000030,
GS_SYNCH1 = 0x12000040,
GS_SYNCH2 = 0x12000050,
GS_SYNCV = 0x12000060,
GS_DISPFB1 = 0x12000070,
GS_DISPLAY1 = 0x12000080,
GS_DISPFB2 = 0x12000090,
GS_DISPLAY2 = 0x120000A0,
GS_EXTBUF = 0x120000B0,
GS_EXTDATA = 0x120000C0,
GS_EXTWRITE = 0x120000D0,
GS_BGCOLOR = 0x120000E0,
GS_CSR = 0x12001000,
GS_IMR = 0x12001010,
GS_BUSDIR = 0x12001040,
GS_SIGLBLID = 0x12001080
};
#define SBFLG_IOPALIVE 0x10000 #define SBFLG_IOPALIVE 0x10000
#define SBFLG_IOPSYNC 0x40000 #define SBFLG_IOPSYNC 0x40000
#define GS_PMODE 0x12000000
#define GS_SMODE1 0x12000010
#define GS_SMODE2 0x12000020
#define GS_SRFSH 0x12000030
#define GS_SYNCH1 0x12000040
#define GS_SYNCH2 0x12000050
#define GS_SYNCV 0x12000060
#define GS_DISPFB1 0x12000070
#define GS_DISPLAY1 0x12000080
#define GS_DISPFB2 0x12000090
#define GS_DISPLAY2 0x120000A0
#define GS_EXTBUF 0x120000B0
#define GS_EXTDATA 0x120000C0
#define GS_EXTWRITE 0x120000D0
#define GS_BGCOLOR 0x120000E0
#define GS_CSR 0x12001000
#define GS_IMR 0x12001010
#define GS_BUSDIR 0x12001040
#define GS_SIGLBLID 0x12001080
#define INTC_GS 0
#define INTC_SBUS 1
#define INTC_VBLANK_S 2
#define INTC_VBLANK_E 3
#define INTC_VIF0 4
#define INTC_VIF1 5
#define INTC_VU0 6
#define INTC_VU1 7
#define INTC_IPU 8
#define INTC_TIM0 9
#define INTC_TIM1 10
#define INTC_TIM2 11
#define INTC_TIM3 12
enum INTCIrqs
{
INTC_GS = 0,
INTC_SBUS,
INTC_VBLANK_S,
INTC_VBLANK_E,
INTC_VIF0,
INTC_VIF1,
INTC_VU0,
INTC_VU1,
INTC_IPU,
INTC_TIM0,
INTC_TIM1,
INTC_TIM2,
INTC_TIM3,
};
#define DMAC_STAT_SIS (1<<13) // stall condition #define DMAC_STAT_SIS (1<<13) // stall condition
#define DMAC_STAT_MEIS (1<<14) // mfifo empty #define DMAC_STAT_MEIS (1<<14) // mfifo empty
#define DMAC_STAT_BEIS (1<<15) // bus error #define DMAC_STAT_BEIS (1<<15) // bus error
#define DMAC_STAT_SIM (1<<29) // stall mask #define DMAC_STAT_SIM (1<<29) // stall mask
#define DMAC_STAT_MEIM (1<<30) // mfifo mask #define DMAC_STAT_MEIM (1<<30) // mfifo mask
#define DMAC_VIF0 0 enum DMACIrqs
#define DMAC_VIF1 1 {
#define DMAC_GIF 2 DMAC_VIF0 = 0,
#define DMAC_FROM_IPU 3 DMAC_VIF1,
#define DMAC_TO_IPU 4 DMAC_GIF,
#define DMAC_SIF0 5 DMAC_FROM_IPU,
#define DMAC_SIF1 6 DMAC_TO_IPU,
#define DMAC_SIF2 7 DMAC_SIF0,
#define DMAC_FROM_SPR 8 DMAC_SIF1,
#define DMAC_TO_SPR 9 DMAC_SIF2,
#define DMAC_ERROR 15 DMAC_FROM_SPR,
DMAC_TO_SPR,
DMAC_ERROR = 15,
};
#define VIF0_STAT_VPS_W (1) #define VIF0_STAT_VPS_W (1)
#define VIF0_STAT_VPS_D (2) #define VIF0_STAT_VPS_D (2)
@ -275,35 +272,39 @@ struct DMACh {
#define VIF1_STAT_ER1 (1<<13) #define VIF1_STAT_ER1 (1<<13)
#define VIF1_STAT_FDR (1<<23) #define VIF1_STAT_FDR (1<<23)
#define VIF_STAT_VPS_W (1)
#define VIF_STAT_VPS_D (2)
#define VIF_STAT_VPS_T (3)
#define VIF_STAT_VPS (3)
#define VIF_STAT_VEW (1<<2)
#define VIF_STAT_VGW (1<<3)
#define VIF_STAT_MRK (1<<6)
#define VIF_STAT_DBF (1<<7)
#define VIF_STAT_VSS (1<<8)
#define VIF_STAT_VFS (1<<9)
#define VIF_STAT_VIS (1<<10)
#define VIF_STAT_INT (1<<11)
#define VIF_STAT_ER0 (1<<12)
#define VIF_STAT_ER1 (1<<13)
#define VIF_STAT_FDR (1<<23)
//DMA interrupts & masks //DMA interrupts & masks
#define BEISintr (0x8000) enum DMAInter
#define VIF0intr (0x10001) {
#define VIF1intr (0x20002) BEISintr = 0x8000,
#define GIFintr (0x40004) VIF0intr = 0x10001,
#define IPU0intr (0x80008) VIF1intr = 0x20002,
#define IPU1intr (0x100010) GIFintr = 0x40004,
#define SIF0intr (0x200020) IPU0intr = 0x80008,
#define SIF1intr (0x400040) IPU1intr = 0x100010,
#define SIF2intr (0x800080) SIF0intr = 0x200020,
#define SPR0intr (0x1000100) SIF1intr =0x400040,
#define SPR1intr (0x2000200) SIF2intr = 0x800080,
#define SISintr (0x20002000) SPR0intr = 0x1000100,
#define MEISintr (0x40004000) SPR1intr = 0x2000200,
SISintr = 0x20002000,
#define DMAend(dma, num) { \ MEISintr = 0x40004000
dma->chcr &= ~0x100; \ };
psHu32(DMAC_STAT)|= 1<<num; \
return; \
}
#define DMAerror(dma, num) { \
psHu32(DMAC_STAT)|= 1<<15; /* BUS error */ \
DMAend(dma, num); \
}
#define _dmaGetAddr(dma, ptr, addr, num) \
ptr = (u32*)dmaGetAddr(addr); \
if (ptr == NULL) DMAerror(dma, num);
#ifdef PCSX2_VIRTUAL_MEM #ifdef PCSX2_VIRTUAL_MEM
@ -348,20 +349,35 @@ static __forceinline void *dmaGetAddr(u32 addr) {
u8 *ptr; u8 *ptr;
// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); } // if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
if (addr & 0x80000000) { // teh sux why the f00k 0xE0000000 // teh sux why the f00k 0xE0000000
return (void*)&psS[addr & 0x3ff0]; if (addr & 0x80000000) return (void*)&psS[addr & 0x3ff0];
}
ptr = (u8*)vtlb_GetPhyPtr(addr&0x1FFFFFF0); ptr = (u8*)vtlb_GetPhyPtr(addr&0x1FFFFFF0);
if (ptr == NULL) { if (ptr == NULL) {
Console::Error("*PCSX2*: DMA error: %8.8x", params addr); Console::Error( "*PCSX2*: DMA error: %8.8x", params addr);
return NULL; return NULL;
} }
return ptr; return ptr;
} }
#endif #endif
static __forceinline u32 *_dmaGetAddr(DMACh *dma, u32 addr, u32 num)
{
u32 *ptr = (u32*)dmaGetAddr(addr);
if (ptr == NULL)
{
// DMA Error
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; /* BUS error */
// DMA End
psHu32(DMAC_STAT) |= 1<<num;
dma->chcr &= ~0x100;
}
return ptr;
}
void hwInit(); void hwInit();
void hwReset(); void hwReset();
@ -422,8 +438,8 @@ void hwDmacIrq(int n);
int hwMFIFORead(u32 addr, u8 *data, u32 size); int hwMFIFORead(u32 addr, u8 *data, u32 size);
int hwMFIFOWrite(u32 addr, u8 *data, u32 size); int hwMFIFOWrite(u32 addr, u8 *data, u32 size);
int hwDmacSrcChainWithStack(DMACh *dma, int id); bool hwDmacSrcChainWithStack(DMACh *dma, int id);
int hwDmacSrcChain(DMACh *dma, int id); bool hwDmacSrcChain(DMACh *dma, int id);
int hwConstRead8 (u32 x86reg, u32 mem, u32 sign); int hwConstRead8 (u32 x86reg, u32 mem, u32 sign);
int hwConstRead16(u32 x86reg, u32 mem, u32 sign); int hwConstRead16(u32 x86reg, u32 mem, u32 sign);

View File

@ -61,34 +61,35 @@ __forceinline u8 hwRead8(u32 mem)
switch (mem) switch (mem)
{ {
case 0x10000000: ret = (u8)rcntRcount(0); break; // Note: the values without defines = the defines + 1.
case 0x10000010: ret = (u8)counters[0].modeval; break; case RCNT0_COUNT: ret = (u8)rcntRcount(0); break;
case 0x10000020: ret = (u8)counters[0].target; break; case RCNT0_MODE: ret = (u8)counters[0].modeval; break;
case 0x10000030: ret = (u8)counters[0].hold; break; case RCNT0_TARGET: ret = (u8)counters[0].target; break;
case RCNT0_HOLD: ret = (u8)counters[0].hold; break;
case 0x10000001: ret = (u8)(rcntRcount(0)>>8); break; case 0x10000001: ret = (u8)(rcntRcount(0)>>8); break;
case 0x10000011: ret = (u8)(counters[0].modeval>>8); break; case 0x10000011: ret = (u8)(counters[0].modeval>>8); break;
case 0x10000021: ret = (u8)(counters[0].target>>8); break; case 0x10000021: ret = (u8)(counters[0].target>>8); break;
case 0x10000031: ret = (u8)(counters[0].hold>>8); break; case 0x10000031: ret = (u8)(counters[0].hold>>8); break;
case 0x10000800: ret = (u8)rcntRcount(1); break; case RCNT1_COUNT: ret = (u8)rcntRcount(1); break;
case 0x10000810: ret = (u8)counters[1].modeval; break; case RCNT1_MODE: ret = (u8)counters[1].modeval; break;
case 0x10000820: ret = (u8)counters[1].target; break; case RCNT1_TARGET: ret = (u8)counters[1].target; break;
case 0x10000830: ret = (u8)counters[1].hold; break; case RCNT1_HOLD: ret = (u8)counters[1].hold; break;
case 0x10000801: ret = (u8)(rcntRcount(1)>>8); break; case 0x10000801: ret = (u8)(rcntRcount(1)>>8); break;
case 0x10000811: ret = (u8)(counters[1].modeval>>8); break; case 0x10000811: ret = (u8)(counters[1].modeval>>8); break;
case 0x10000821: ret = (u8)(counters[1].target>>8); break; case 0x10000821: ret = (u8)(counters[1].target>>8); break;
case 0x10000831: ret = (u8)(counters[1].hold>>8); break; case 0x10000831: ret = (u8)(counters[1].hold>>8); break;
case 0x10001000: ret = (u8)rcntRcount(2); break; case RCNT2_COUNT: ret = (u8)rcntRcount(2); break;
case 0x10001010: ret = (u8)counters[2].modeval; break; case RCNT2_MODE: ret = (u8)counters[2].modeval; break;
case 0x10001020: ret = (u8)counters[2].target; break; case RCNT2_TARGET: ret = (u8)counters[2].target; break;
case 0x10001001: ret = (u8)(rcntRcount(2)>>8); break; case 0x10001001: ret = (u8)(rcntRcount(2)>>8); break;
case 0x10001011: ret = (u8)(counters[2].modeval>>8); break; case 0x10001011: ret = (u8)(counters[2].modeval>>8); break;
case 0x10001021: ret = (u8)(counters[2].target>>8); break; case 0x10001021: ret = (u8)(counters[2].target>>8); break;
case 0x10001800: ret = (u8)rcntRcount(3); break; case RCNT3_COUNT: ret = (u8)rcntRcount(3); break;
case 0x10001810: ret = (u8)counters[3].modeval; break; case RCNT3_MODE: ret = (u8)counters[3].modeval; break;
case 0x10001820: ret = (u8)counters[3].target; break; case RCNT3_TARGET: ret = (u8)counters[3].target; break;
case 0x10001801: ret = (u8)(rcntRcount(3)>>8); break; case 0x10001801: ret = (u8)(rcntRcount(3)>>8); break;
case 0x10001811: ret = (u8)(counters[3].modeval>>8); break; case 0x10001811: ret = (u8)(counters[3].modeval>>8); break;
case 0x10001821: ret = (u8)(counters[3].target>>8); break; case 0x10001821: ret = (u8)(counters[3].target>>8); break;
@ -97,7 +98,7 @@ __forceinline u8 hwRead8(u32 mem)
if ((mem & 0xffffff0f) == 0x1000f200) if ((mem & 0xffffff0f) == 0x1000f200)
{ {
if(mem == 0x1000f260) ret = 0; if(mem == 0x1000f260) ret = 0;
else if(mem == 0x1000F240) { else if(mem == SBUS_F240) {
ret = psHu32(mem); ret = psHu32(mem);
//psHu32(mem) &= ~0x4000; //psHu32(mem) &= ~0x4000;
} }
@ -120,34 +121,34 @@ __forceinline u16 hwRead16(u32 mem)
{ {
u16 ret; u16 ret;
if( mem >= 0x10002000 && mem < 0x10008000 ) if( mem >= IPU_CMD && mem < D0_CHCR )
Console::Notice("Unexpected hwRead16 from 0x%x", params mem); Console::Notice("Unexpected hwRead16 from 0x%x", params mem);
switch (mem) switch (mem)
{ {
case 0x10000000: ret = (u16)rcntRcount(0); break; case RCNT0_COUNT: ret = (u16)rcntRcount(0); break;
case 0x10000010: ret = (u16)counters[0].modeval; break; case RCNT0_MODE: ret = (u16)counters[0].modeval; break;
case 0x10000020: ret = (u16)counters[0].target; break; case RCNT0_TARGET: ret = (u16)counters[0].target; break;
case 0x10000030: ret = (u16)counters[0].hold; break; case RCNT0_HOLD: ret = (u16)counters[0].hold; break;
case 0x10000800: ret = (u16)rcntRcount(1); break; case RCNT1_COUNT: ret = (u16)rcntRcount(1); break;
case 0x10000810: ret = (u16)counters[1].modeval; break; case RCNT1_MODE: ret = (u16)counters[1].modeval; break;
case 0x10000820: ret = (u16)counters[1].target; break; case RCNT1_TARGET: ret = (u16)counters[1].target; break;
case 0x10000830: ret = (u16)counters[1].hold; break; case RCNT1_HOLD: ret = (u16)counters[1].hold; break;
case 0x10001000: ret = (u16)rcntRcount(2); break; case RCNT2_COUNT: ret = (u16)rcntRcount(2); break;
case 0x10001010: ret = (u16)counters[2].modeval; break; case RCNT2_MODE: ret = (u16)counters[2].modeval; break;
case 0x10001020: ret = (u16)counters[2].target; break; case RCNT2_TARGET: ret = (u16)counters[2].target; break;
case 0x10001800: ret = (u16)rcntRcount(3); break; case RCNT3_COUNT: ret = (u16)rcntRcount(3); break;
case 0x10001810: ret = (u16)counters[3].modeval; break; case RCNT3_MODE: ret = (u16)counters[3].modeval; break;
case 0x10001820: ret = (u16)counters[3].target; break; case RCNT3_TARGET: ret = (u16)counters[3].target; break;
default: default:
if ((mem & 0xffffff0f) == 0x1000f200) if ((mem & 0xffffff0f) == 0x1000f200)
{ {
if(mem == 0x1000f260) ret = 0; if(mem == 0x1000f260) ret = 0;
else if(mem == 0x1000F240) { else if(mem == SBUS_F240) {
ret = psHu16(mem) | 0x0102; ret = psHu16(mem) | 0x0102;
psHu32(mem) &= ~0x4000; psHu32(mem) &= ~0x4000;
} }

View File

@ -40,11 +40,22 @@ using namespace R5900;
// dark cloud2 uses 8 bit DMAs register writes // dark cloud2 uses 8 bit DMAs register writes
static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value ) static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value )
{ {
u32 qwcRegister = (mem | 0x20) & ~0x1; //Need to remove the lower bit else we end up clearing TADR
//Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
if((value & 0x1) && (psHu8(mem) & 0x1) == 0x1 && (psHu32(DMAC_CTRL) & 0x1) == 1) { if((value & 0x1) && (psHu8(mem) & 0x1) == 0x1 && (psHu32(DMAC_CTRL) & 0x1) == 1) {
DMA_LOG( "DMAExec8 Attempt to run DMA while one is already active mem = %x", mem ); DMA_LOG( "DMAExec8 Attempt to run DMA while one is already active mem = %x", mem );
return;
} }
// Upper 16bits of QWC should not be written since QWC is 16bits in size.
if ((psHu32(qwcRegister) >> 16) != 0)
{
DMA_LOG("DMA QWC (%x) upper 16bits set to %x\n",
qwcRegister,
psHu32(qwcRegister) >> 16);
psHu32(qwcRegister) = 0;
}
psHu8(mem) = (u8)value; psHu8(mem) = (u8)value;
if ((psHu8(mem) & 0x1) && (psHu32(DMAC_CTRL) & 0x1)) if ((psHu8(mem) & 0x1) && (psHu32(DMAC_CTRL) & 0x1))
{ {
@ -55,11 +66,22 @@ static __forceinline void DmaExec8( void (*func)(), u32 mem, u8 value )
static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value ) static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
{ {
u32 qwcRegister = mem | 0x20;
//Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) { if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) {
DMA_LOG( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem); DMA_LOG( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem);
return;
} }
// Upper 16bits of QWC should not be written since QWC is 16bits in size.
if ((psHu32(qwcRegister) >> 16) != 0)
{
DMA_LOG("DMA QWC (%x) upper 16bits set to %x\n",
qwcRegister,
psHu32(qwcRegister) >> 16);
psHu32(qwcRegister) = 0;
}
psHu16(mem) = (u16)value; psHu16(mem) = (u16)value;
if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1)) if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1))
{ {
@ -70,11 +92,22 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
static void DmaExec( void (*func)(), u32 mem, u32 value ) static void DmaExec( void (*func)(), u32 mem, u32 value )
{ {
u32 qwcRegister = mem | 0x20;
//Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC //Its invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) { if((value & 0x100) && (psHu32(mem) & 0x100) == 0x100 && (psHu32(DMAC_CTRL) & 0x1) == 1) {
DMA_LOG( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem ); DMA_LOG( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem );
return;
} }
// Upper 16bits of QWC should not be written since QWC is 16bits in size.
if ((psHu32(qwcRegister) >> 16) != 0)
{
DMA_LOG("DMA QWC (%x) upper 16bits set to %x\n",
qwcRegister,
psHu32(qwcRegister) >> 16);
psHu32(qwcRegister) = 0;
}
/* Keep the old tag if in chain mode and hw doesnt set it*/ /* Keep the old tag if in chain mode and hw doesnt set it*/
if( (value & 0xc) == 0x4 && (value & 0xffff0000) == 0) if( (value & 0xc) == 0x4 && (value & 0xffff0000) == 0)
psHu32(mem) = (psHu32(mem) & 0xFFFF0000) | (u16)value; psHu32(mem) = (psHu32(mem) & 0xFFFF0000) | (u16)value;
@ -112,27 +145,27 @@ void hwWrite8(u32 mem, u8 value) {
DevCon::Notice( "hwWrite8 to 0x%x = 0x%x", params mem, value ); DevCon::Notice( "hwWrite8 to 0x%x = 0x%x", params mem, value );
switch (mem) { switch (mem) {
case 0x10000000: rcntWcount(0, value); break; case RCNT0_COUNT: rcntWcount(0, value); break;
case 0x10000010: rcntWmode(0, (counters[0].modeval & 0xff00) | value); break; case RCNT0_MODE: rcntWmode(0, (counters[0].modeval & 0xff00) | value); break;
case 0x10000011: rcntWmode(0, (counters[0].modeval & 0xff) | value << 8); break; case 0x10000011: rcntWmode(0, (counters[0].modeval & 0xff) | value << 8); break;
case 0x10000020: rcntWtarget(0, value); break; case RCNT0_TARGET: rcntWtarget(0, value); break;
case 0x10000030: rcntWhold(0, value); break; case RCNT0_HOLD: rcntWhold(0, value); break;
case 0x10000800: rcntWcount(1, value); break; case RCNT1_COUNT: rcntWcount(1, value); break;
case 0x10000810: rcntWmode(1, (counters[1].modeval & 0xff00) | value); break; case RCNT1_MODE: rcntWmode(1, (counters[1].modeval & 0xff00) | value); break;
case 0x10000811: rcntWmode(1, (counters[1].modeval & 0xff) | value << 8); break; case 0x10000811: rcntWmode(1, (counters[1].modeval & 0xff) | value << 8); break;
case 0x10000820: rcntWtarget(1, value); break; case RCNT1_TARGET: rcntWtarget(1, value); break;
case 0x10000830: rcntWhold(1, value); break; case RCNT1_HOLD: rcntWhold(1, value); break;
case 0x10001000: rcntWcount(2, value); break; case RCNT2_COUNT: rcntWcount(2, value); break;
case 0x10001010: rcntWmode(2, (counters[2].modeval & 0xff00) | value); break; case RCNT2_MODE: rcntWmode(2, (counters[2].modeval & 0xff00) | value); break;
case 0x10001011: rcntWmode(2, (counters[2].modeval & 0xff) | value << 8); break; case 0x10001011: rcntWmode(2, (counters[2].modeval & 0xff) | value << 8); break;
case 0x10001020: rcntWtarget(2, value); break; case RCNT2_TARGET: rcntWtarget(2, value); break;
case 0x10001800: rcntWcount(3, value); break; case RCNT3_COUNT: rcntWcount(3, value); break;
case 0x10001810: rcntWmode(3, (counters[3].modeval & 0xff00) | value); break; case RCNT3_MODE: rcntWmode(3, (counters[3].modeval & 0xff00) | value); break;
case 0x10001811: rcntWmode(3, (counters[3].modeval & 0xff) | value << 8); break; case 0x10001811: rcntWmode(3, (counters[3].modeval & 0xff) | value << 8); break;
case 0x10001820: rcntWtarget(3, value); break; case RCNT3_TARGET: rcntWtarget(3, value); break;
case 0x1000f180: case 0x1000f180:
if (value == '\n') { if (value == '\n') {
@ -166,7 +199,7 @@ void hwWrite8(u32 mem, u8 value) {
DevCon::Notice("8 bit VIF1 DMA Start while DMAC Disabled\n"); DevCon::Notice("8 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2; QueuedDMA |= 0x2;
} }
if(value & 0x1) vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO if(value & 0x1) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
DmaExec8(dmaVIF1, mem, value); DmaExec8(dmaVIF1, mem, value);
break; break;
@ -288,25 +321,25 @@ __forceinline void hwWrite16(u32 mem, u16 value)
switch(mem) switch(mem)
{ {
case 0x10000000: rcntWcount(0, value); break; case RCNT0_COUNT: rcntWcount(0, value); break;
case 0x10000010: rcntWmode(0, value); break; case RCNT0_MODE: rcntWmode(0, value); break;
case 0x10000020: rcntWtarget(0, value); break; case RCNT0_TARGET: rcntWtarget(0, value); break;
case 0x10000030: rcntWhold(0, value); break; case RCNT0_HOLD: rcntWhold(0, value); break;
case 0x10000800: rcntWcount(1, value); break; case RCNT1_COUNT: rcntWcount(1, value); break;
case 0x10000810: rcntWmode(1, value); break; case RCNT1_MODE: rcntWmode(1, value); break;
case 0x10000820: rcntWtarget(1, value); break; case RCNT1_TARGET: rcntWtarget(1, value); break;
case 0x10000830: rcntWhold(1, value); break; case RCNT1_HOLD: rcntWhold(1, value); break;
case 0x10001000: rcntWcount(2, value); break; case RCNT2_COUNT: rcntWcount(2, value); break;
case 0x10001010: rcntWmode(2, value); break; case RCNT2_MODE: rcntWmode(2, value); break;
case 0x10001020: rcntWtarget(2, value); break; case RCNT2_TARGET: rcntWtarget(2, value); break;
case 0x10001800: rcntWcount(3, value); break; case RCNT3_COUNT: rcntWcount(3, value); break;
case 0x10001810: rcntWmode(3, value); break; case RCNT3_MODE: rcntWmode(3, value); break;
case 0x10001820: rcntWtarget(3, value); break; case RCNT3_TARGET: rcntWtarget(3, value); break;
case 0x10008000: // dma0 - vif0 case D0_CHCR: // dma0 - vif0
DMA_LOG("VIF0dma %lx", value); DMA_LOG("VIF0dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -316,46 +349,46 @@ __forceinline void hwWrite16(u32 mem, u16 value)
DmaExec16(dmaVIF0, mem, value); DmaExec16(dmaVIF0, mem, value);
break; break;
case 0x10009000: // dma1 - vif1 - chcr case D1_CHCR: // dma1 - vif1 - chcr
DMA_LOG("VIF1dma CHCR %lx", value); DMA_LOG("VIF1dma CHCR %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
DevCon::Notice("16 bit VIF1 DMA Start while DMAC Disabled\n"); DevCon::Notice("16 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2; QueuedDMA |= 0x2;
} }
if(value & 0x100) vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO if(value & 0x100) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
DmaExec16(dmaVIF1, mem, value); DmaExec16(dmaVIF1, mem, value);
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x10009010: // dma1 - vif1 - madr case D1_MADR: // dma1 - vif1 - madr
HW_LOG("VIF1dma Madr %lx", value); HW_LOG("VIF1dma Madr %lx", value);
psHu16(mem) = value;//dma1 madr psHu16(mem) = value;//dma1 madr
break; break;
case 0x10009020: // dma1 - vif1 - qwc case D1_QWC: // dma1 - vif1 - qwc
HW_LOG("VIF1dma QWC %lx", value); HW_LOG("VIF1dma QWC %lx", value);
psHu16(mem) = value;//dma1 qwc psHu16(mem) = value;//dma1 qwc
break; break;
case 0x10009030: // dma1 - vif1 - tadr case D1_TADR: // dma1 - vif1 - tadr
HW_LOG("VIF1dma TADR %lx", value); HW_LOG("VIF1dma TADR %lx", value);
psHu16(mem) = value;//dma1 tadr psHu16(mem) = value;//dma1 tadr
break; break;
case 0x10009040: // dma1 - vif1 - asr0 case D1_ASR0: // dma1 - vif1 - asr0
HW_LOG("VIF1dma ASR0 %lx", value); HW_LOG("VIF1dma ASR0 %lx", value);
psHu16(mem) = value;//dma1 asr0 psHu16(mem) = value;//dma1 asr0
break; break;
case 0x10009050: // dma1 - vif1 - asr1 case D1_ASR1: // dma1 - vif1 - asr1
HW_LOG("VIF1dma ASR1 %lx", value); HW_LOG("VIF1dma ASR1 %lx", value);
psHu16(mem) = value;//dma1 asr1 psHu16(mem) = value;//dma1 asr1
break; break;
case 0x10009080: // dma1 - vif1 - sadr case D1_SADR: // dma1 - vif1 - sadr
HW_LOG("VIF1dma SADR %lx", value); HW_LOG("VIF1dma SADR %lx", value);
psHu16(mem) = value;//dma1 sadr psHu16(mem) = value;//dma1 sadr
break; break;
#endif #endif
// --------------------------------------------------- // ---------------------------------------------------
case 0x1000a000: // dma2 - gif case D2_CHCR: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value); DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -366,33 +399,33 @@ __forceinline void hwWrite16(u32 mem, u16 value)
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000a010: case D2_MADR:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a020: case D2_QWC:
psHu16(mem) = value;//dma2 qwc psHu16(mem) = value;//dma2 qwc
HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value); HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a030: case D2_TADR:
psHu16(mem) = value;//dma2 taddr psHu16(mem) = value;//dma2 taddr
HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a040: case D2_ASR0:
psHu16(mem) = value;//dma2 asr0 psHu16(mem) = value;//dma2 asr0
HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value); HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a050: case D2_ASR1:
psHu16(mem) = value;//dma2 asr1 psHu16(mem) = value;//dma2 asr1
HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value); HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
break; break;
case 0x1000a080: case D2_SADR:
psHu16(mem) = value;//dma2 saddr psHu16(mem) = value;//dma2 saddr
HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
case 0x1000b000: // dma3 - fromIPU case D3_CHCR: // dma3 - fromIPU
DMA_LOG("IPU0dma %lx", value); DMA_LOG("IPU0dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -403,25 +436,25 @@ __forceinline void hwWrite16(u32 mem, u16 value)
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000b010: case D3_MADR:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b020: case D3_QWC:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b030: case D3_TADR:
psHu16(mem) = value;//dma2 tadr psHu16(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b080: case D3_SADR:
psHu16(mem) = value;//dma2 saddr psHu16(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
case 0x1000b400: // dma4 - toIPU case D4_CHCR: // dma4 - toIPU
DMA_LOG("IPU1dma %lx", value); DMA_LOG("IPU1dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -432,24 +465,24 @@ __forceinline void hwWrite16(u32 mem, u16 value)
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000b410: case D4_MADR:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b420: case D4_QWC:
psHu16(mem) = value;//dma2 madr psHu16(mem) = value;//dma2 madr
HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b430: case D4_TADR:
psHu16(mem) = value;//dma2 tadr psHu16(mem) = value;//dma2 tadr
HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value);
break; break;
case 0x1000b480: case D4_SADR:
psHu16(mem) = value;//dma2 saddr psHu16(mem) = value;//dma2 saddr
HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value); HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value);
break; break;
#endif #endif
case 0x1000c000: // dma5 - sif0 case D5_CHCR: // dma5 - sif0
DMA_LOG("SIF0dma %lx", value); DMA_LOG("SIF0dma %lx", value);
// if (value == 0) psxSu32(0x30) = 0x40000; // if (value == 0) psxSu32(0x30) = 0x40000;
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
@ -463,7 +496,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
case 0x1000c002: case 0x1000c002:
//? //?
break; break;
case 0x1000c400: // dma6 - sif1 case D6_CHCR: // dma6 - sif1
DMA_LOG("SIF1dma %lx", value); DMA_LOG("SIF1dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -474,7 +507,8 @@ __forceinline void hwWrite16(u32 mem, u16 value)
break; break;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1000c420: // dma6 - sif1 - qwc // No D6_MADR, and a TADR address that's not in the defines?
case D6_QWC: // dma6 - sif1 - qwc
HW_LOG("SIF1dma QWC = %lx", value); HW_LOG("SIF1dma QWC = %lx", value);
psHu16(mem) = value; psHu16(mem) = value;
break; break;
@ -485,7 +519,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
break; break;
#endif #endif
case 0x1000c800: // dma7 - sif2 case D7_CHCR: // dma7 - sif2
DMA_LOG("SIF2dma %lx", value); DMA_LOG("SIF2dma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -497,7 +531,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
case 0x1000c802: case 0x1000c802:
//? //?
break; break;
case 0x1000d000: // dma8 - fromSPR case D8_CHCR: // dma8 - fromSPR
DMA_LOG("fromSPRdma %lx", value); DMA_LOG("fromSPRdma %lx", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -532,13 +566,13 @@ __forceinline void hwWrite16(u32 mem, u16 value)
psHu16(mem) = value; psHu16(mem) = value;
break; break;
case 0x1000f220: case SBUS_F220:
psHu16(mem) |= value; psHu16(mem) |= value;
break; break;
case 0x1000f230: case SBUS_SMFLG:
psHu16(mem) &= ~value; psHu16(mem) &= ~value;
break; break;
case 0x1000f240: case SBUS_F240:
if(!(value & 0x100)) if(!(value & 0x100))
psHu16(mem) &= ~0x100; psHu16(mem) &= ~0x100;
else else
@ -762,13 +796,13 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
case HELPSWITCH(0x1000f200): case HELPSWITCH(0x1000f200):
psHu32(mem) = value; psHu32(mem) = value;
break; break;
case HELPSWITCH(0x1000f220): case HELPSWITCH(SBUS_F220):
psHu32(mem) |= value; psHu32(mem) |= value;
break; break;
case HELPSWITCH(0x1000f230): case HELPSWITCH(SBUS_SMFLG):
psHu32(mem) &= ~value; psHu32(mem) &= ~value;
break; break;
case HELPSWITCH(0x1000f240): case HELPSWITCH(SBUS_F240):
if(!(value & 0x100)) if(!(value & 0x100))
psHu32(mem) &= ~0x100; psHu32(mem) &= ~0x100;
else else
@ -782,7 +816,7 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
psHu32(mem) = value; psHu32(mem) = value;
break; break;
case HELPSWITCH(0x1000f590): // DMAC_ENABLEW case HELPSWITCH(DMAC_ENABLEW): // DMAC_ENABLEW
HW_LOG("DMAC_ENABLEW Write 32bit %lx", value); HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
psHu32(0xf590) = value; psHu32(0xf590) = value;
psHu32(0xf520) = value; psHu32(0xf520) = value;
@ -826,7 +860,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
} }
if(value & 0x100) if(value & 0x100)
{ {
vif1.done = 0; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
} }
DmaExec(dmaVIF1, mem, value); DmaExec(dmaVIF1, mem, value);
return; return;
@ -850,14 +884,14 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
return; return;
case D2_MADR: regName = "GIFdma MADR"; break; case D2_MADR: regName = "GIFdma MADR"; break;
case D2_QWC: regName = "GIFdma QWC"; break; case D2_QWC: regName = "GIFdma QWC"; break;
case D2_TADR: regName = "GIFdma TADDR"; break; case D2_TADR: regName = "GIFdma TADDR"; break;
case D2_ASR0: regName = "GIFdma ASR0"; break; case D2_ASR0: regName = "GIFdma ASR0"; break;
case D2_ASR1: regName = "GIFdma ASR1"; break; case D2_ASR1: regName = "GIFdma ASR1"; break;
case D2_SADR: regName = "GIFdma SADDR"; break; case D2_SADR: regName = "GIFdma SADDR"; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c000: // dma5 - sif0 case D5_CHCR: // dma5 - sif0
DMA_LOG("SIF0dma EXECUTE, value=0x%x", value); DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
//if (value == 0) psxSu32(0x30) = 0x40000; //if (value == 0) psxSu32(0x30) = 0x40000;
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
@ -868,7 +902,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
DmaExec(dmaSIF0, mem, value); DmaExec(dmaSIF0, mem, value);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c400: // dma6 - sif1 case D6_CHCR: // dma6 - sif1
DMA_LOG("SIF1dma EXECUTE, value=0x%x", value); DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -878,11 +912,12 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
DmaExec(dmaSIF1, mem, value); DmaExec(dmaSIF1, mem, value);
return; return;
case 0x1000c420: regName = "SIF1dma QWC"; break; // Again, no MADR, and an undefined TADR.
case D6_QWC: regName = "SIF1dma QWC"; break;
case 0x1000c430: regName = "SIF1dma TADR"; break; case 0x1000c430: regName = "SIF1dma TADR"; break;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000c800: // dma7 - sif2 case D7_CHCR: // dma7 - sif2
DMA_LOG("SIF2dma EXECUTE, value=0x%x", value); DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -892,7 +927,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
DmaExec(dmaSIF2, mem, value); DmaExec(dmaSIF2, mem, value);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
case 0x1000d000: // dma8 - fromSPR case D8_CHCR: // dma8 - fromSPR
DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value); DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1)) if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
{ {
@ -1015,7 +1050,7 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
switch (mem) switch (mem)
{ {
case 0x1000a000: // dma2 - gif case D2_CHCR: // dma2 - gif
DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value); DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value);
DmaExec(dmaGIF, mem, value); DmaExec(dmaGIF, mem, value);
break; break;
@ -1037,7 +1072,7 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
case 0x1000f430: case 0x1000f430:
break; break;
case 0x1000f590: // DMAC_ENABLEW case DMAC_ENABLEW: // DMAC_ENABLEW
psHu32(0xf590) = value; psHu32(0xf590) = value;
psHu32(0xf520) = value; psHu32(0xf520) = value;
break; break;
@ -1070,7 +1105,7 @@ void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval)
cpuTestINTCInts(); cpuTestINTCInts();
break; break;
case 0x1000f590: // DMAC_ENABLEW case DMAC_ENABLEW: // DMAC_ENABLEW
psHu32(0xf590) = srcval[0]; psHu32(0xf590) = srcval[0];
psHu32(0xf520) = srcval[0]; psHu32(0xf520) = srcval[0];
break; break;

View File

@ -48,11 +48,6 @@ using namespace std; // for min / max
# define IPU_FORCEINLINE __forceinline # define IPU_FORCEINLINE __forceinline
#endif #endif
//IPUregisters g_ipuRegsReal;
#define ipu0dma ((DMACh *)&PS2MEM_HW[0xb000])
#define ipu1dma ((DMACh *)&PS2MEM_HW[0xb400])
#define IPU_DMA_GIFSTALL 1 #define IPU_DMA_GIFSTALL 1
#define IPU_DMA_TIE0 2 #define IPU_DMA_TIE0 2
#define IPU_DMA_TIE1 4 #define IPU_DMA_TIE1 4
@ -369,7 +364,7 @@ __forceinline void ipuWrite64(u32 mem, u64 value)
switch (mem) switch (mem)
{ {
case 0x10: case 0x00:
IPU_LOG("Ipu write64: IPU_CMD=0x%08X", value); IPU_LOG("Ipu write64: IPU_CMD=0x%08X", value);
IPUCMD_WRITE((u32)value); IPUCMD_WRITE((u32)value);
break; break;
@ -1372,9 +1367,11 @@ int FIFOto_write(u32* pMem, int size)
g_nDMATransfer |= IPU_DMA_ACTV1; \ g_nDMATransfer |= IPU_DMA_ACTV1; \
return totalqwc; \ return totalqwc; \
} \ } \
} \ } \
} }
extern void gsInterrupt();
int IPU1dma() int IPU1dma()
{ {
u32 *ptag, *pMem; u32 *ptag, *pMem;
@ -1388,6 +1385,13 @@ int IPU1dma()
assert(!(g_nDMATransfer & IPU_DMA_TIE1)); assert(!(g_nDMATransfer & IPU_DMA_TIE1));
//We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos
while(gif->chcr & 0x100)
{
GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr, gif->tadr, gif->madr, gif->qwc);
gsInterrupt();
}
// in kh, qwc == 0 when dma_actv1 is set // in kh, qwc == 0 when dma_actv1 is set
if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0) if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0)
{ {
@ -1404,8 +1408,6 @@ int IPU1dma()
return totalqwc; return totalqwc;
} }
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
if ((ipu1dma->chcr&0xc) == 0) if ((ipu1dma->chcr&0xc) == 0)
{ {
IPU_INT_TO(totalqwc*BIAS); IPU_INT_TO(totalqwc*BIAS);
@ -1449,6 +1451,8 @@ int IPU1dma()
return totalqwc; return totalqwc;
} }
} }
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
} }
if ((ipu1dma->chcr & 0xc) == 0 && ipu1dma->qwc == 0) // Normal Mode if ((ipu1dma->chcr & 0xc) == 0 && ipu1dma->qwc == 0) // Normal Mode

View File

@ -112,7 +112,8 @@ void __fastcall intDoBranch(u32 target)
} }
} }
void intSetBranch() { void intSetBranch()
{
branch2 = /*cpuRegs.branch =*/ 1; branch2 = /*cpuRegs.branch =*/ 1;
} }
@ -133,90 +134,223 @@ namespace OpcodeImpl {
* Format: OP target * * Format: OP target *
*********************************************************/ *********************************************************/
void J() { void J()
{
doBranch(_JumpTarget_); doBranch(_JumpTarget_);
} }
void JAL() { void JAL()
_SetLink(31); doBranch(_JumpTarget_); {
_SetLink(31);
doBranch(_JumpTarget_);
} }
/********************************************************* /*********************************************************
* Register branch logic * * Register branch logic *
* Format: OP rs, rt, offset * * Format: OP rs, rt, offset *
*********************************************************/ *********************************************************/
#define RepBranchi32(op) \
if (cpuRegs.GPR.r[_Rs_].SD[0] op cpuRegs.GPR.r[_Rt_].SD[0]) doBranch(_BranchTarget_); \
else intEventTest();
void BEQ() // Branch if Rs == Rt
{
if (cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0])
doBranch(_BranchTarget_);
else
intEventTest();
}
void BEQ() { RepBranchi32(==) } // Branch if Rs == Rt void BNE() // Branch if Rs != Rt
void BNE() { RepBranchi32(!=) } // Branch if Rs != Rt {
if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0])
doBranch(_BranchTarget_);
else
intEventTest();
}
/********************************************************* /*********************************************************
* Register branch logic * * Register branch logic *
* Format: OP rs, offset * * Format: OP rs, offset *
*********************************************************/ *********************************************************/
#define RepZBranchi32(op) \
if(cpuRegs.GPR.r[_Rs_].SD[0] op 0) { \
doBranch(_BranchTarget_); \
}
#define RepZBranchLinki32(op) \ void BGEZ() // Branch if Rs >= 0
{
if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
{
doBranch(_BranchTarget_);
}
}
void BGEZAL() // Branch if Rs >= 0 and link
{
_SetLink(31);
if (cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
{
doBranch(_BranchTarget_);
}
}
void BGTZ() // Branch if Rs > 0
{
if (cpuRegs.GPR.r[_Rs_].SD[0] > 0)
{
doBranch(_BranchTarget_);
}
}
void BLEZ() // Branch if Rs <= 0
{
if (cpuRegs.GPR.r[_Rs_].SD[0] <= 0)
{
doBranch(_BranchTarget_);
}
}
void BLTZ() // Branch if Rs < 0
{
if (cpuRegs.GPR.r[_Rs_].SD[0] < 0)
{
doBranch(_BranchTarget_);
}
}
void BLTZAL() // Branch if Rs < 0 and link
{
_SetLink(31); \ _SetLink(31); \
if(cpuRegs.GPR.r[_Rs_].SD[0] op 0) { \ if (cpuRegs.GPR.r[_Rs_].SD[0] < 0)
doBranch(_BranchTarget_); \ {
doBranch(_BranchTarget_);
} }
}
void BGEZ() { RepZBranchi32(>=) } // Branch if Rs >= 0
void BGEZAL() { RepZBranchLinki32(>=) } // Branch if Rs >= 0 and link
void BGTZ() { RepZBranchi32(>) } // Branch if Rs > 0
void BLEZ() { RepZBranchi32(<=) } // Branch if Rs <= 0
void BLTZ() { RepZBranchi32(<) } // Branch if Rs < 0
void BLTZAL() { RepZBranchLinki32(<) } // Branch if Rs < 0 and link
/********************************************************* /*********************************************************
* Register branch logic Likely * * Register branch logic Likely *
* Format: OP rs, offset * * Format: OP rs, offset *
*********************************************************/ *********************************************************/
#define RepZBranchi32Likely(op) \
if(cpuRegs.GPR.r[_Rs_].SD[0] op 0) { \
doBranch(_BranchTarget_); \
} else { cpuRegs.pc +=4; intEventTest(); }
#define RepZBranchLinki32Likely(op) \
_SetLink(31); \
if(cpuRegs.GPR.r[_Rs_].SD[0] op 0) { \
doBranch(_BranchTarget_); \
} else { cpuRegs.pc +=4; intEventTest(); }
#define RepBranchi32Likely(op) \
if(cpuRegs.GPR.r[_Rs_].SD[0] op cpuRegs.GPR.r[_Rt_].SD[0]) { \
doBranch(_BranchTarget_); \
} else { cpuRegs.pc +=4; intEventTest(); }
void BEQL() { RepBranchi32Likely(==) } // Branch if Rs == Rt void BEQL() // Branch if Rs == Rt
void BNEL() { RepBranchi32Likely(!=) } // Branch if Rs != Rt {
void BLEZL() { RepZBranchi32Likely(<=) } // Branch if Rs <= 0 if(cpuRegs.GPR.r[_Rs_].SD[0] == cpuRegs.GPR.r[_Rt_].SD[0])
void BGTZL() { RepZBranchi32Likely(>) } // Branch if Rs > 0 {
void BLTZL() { RepZBranchi32Likely(<) } // Branch if Rs < 0 doBranch(_BranchTarget_);
void BGEZL() { RepZBranchi32Likely(>=) } // Branch if Rs >= 0 }
void BLTZALL() { RepZBranchLinki32Likely(<) } // Branch if Rs < 0 and link else
void BGEZALL() { RepZBranchLinki32Likely(>=) } // Branch if Rs >= 0 and link {
cpuRegs.pc +=4;
intEventTest();
}
}
void BNEL() // Branch if Rs != Rt
{
if(cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0])
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
void BLEZL() // Branch if Rs <= 0
{
if(cpuRegs.GPR.r[_Rs_].SD[0] <= 0)
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
void BGTZL() // Branch if Rs > 0
{
if(cpuRegs.GPR.r[_Rs_].SD[0] > 0)
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
void BLTZL() // Branch if Rs < 0
{
if(cpuRegs.GPR.r[_Rs_].SD[0] < 0)
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
void BGEZL() // Branch if Rs >= 0
{
if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
void BLTZALL() // Branch if Rs < 0 and link
{
_SetLink(31);
if(cpuRegs.GPR.r[_Rs_].SD[0] < 0)
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
void BGEZALL() // Branch if Rs >= 0 and link
{
_SetLink(31);
if(cpuRegs.GPR.r[_Rs_].SD[0] >= 0)
{
doBranch(_BranchTarget_);
}
else
{
cpuRegs.pc +=4;
intEventTest();
}
}
/********************************************************* /*********************************************************
* Register jump * * Register jump *
* Format: OP rs, rd * * Format: OP rs, rd *
*********************************************************/ *********************************************************/
void JR() { void JR()
{
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]); doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
} }
void JALR() { void JALR()
{
u32 temp = cpuRegs.GPR.r[_Rs_].UL[0]; u32 temp = cpuRegs.GPR.r[_Rs_].UL[0];
if (_Rd_) { _SetLink(_Rd_); }
if (_Rd_) _SetLink(_Rd_);
doBranch(temp); doBranch(temp);
} }
@ -235,7 +369,7 @@ void intReset()
branch2 = 0; branch2 = 0;
} }
bool intEventTest() bool intEventTest()
{ {
// Perform counters, ints, and IOP updates: // Perform counters, ints, and IOP updates:
return _cpuBranchTest_Shared(); return _cpuBranchTest_Shared();

View File

@ -29,10 +29,10 @@
#include "Sio.h" #include "Sio.h"
#include "Sif.h" #include "Sif.h"
#include "IopDma.h"
#include "IopMem.h" #include "IopMem.h"
#include "IopHw.h" #include "IopHw.h"
#include "IopBios.h" #include "IopBios.h"
#include "IopDma.h"
#include "IopCounters.h" #include "IopCounters.h"
#include "IopSio2.h" #include "IopSio2.h"

View File

@ -38,8 +38,7 @@
#define PSXPIXEL ((int)(PSXCLK / 13500000)) #define PSXPIXEL ((int)(PSXCLK / 13500000))
#define PSXSOUNDCLK ((int)(48000)) #define PSXSOUNDCLK ((int)(48000))
psxCounter psxCounters[NUM_COUNTERS];
psxCounter psxCounters[8];
s32 psxNextCounter; s32 psxNextCounter;
u32 psxNextsCounter; u32 psxNextsCounter;
u8 psxhblankgate = 0; u8 psxhblankgate = 0;
@ -141,6 +140,12 @@ void psxRcntInit() {
psxCounters[7].mode = 0x8; psxCounters[7].mode = 0x8;
} }
#ifdef ENABLE_NEW_IOPDMA
psxCounters[8].rate = 2000;
psxCounters[8].CycleT = psxCounters[7].rate;
psxCounters[8].mode = 0x8;
#endif
for (i=0; i<8; i++) for (i=0; i<8; i++)
psxCounters[i].sCycleT = psxRegs.cycle; psxCounters[i].sCycleT = psxRegs.cycle;
@ -453,6 +458,24 @@ void psxRcntUpdate()
if (c < psxNextCounter) psxNextCounter = c; if (c < psxNextCounter) psxNextCounter = c;
} }
#ifdef ENABLE_NEW_IOPDMA
// New Iop DMA handler WIP
{
const s32 difference = psxRegs.cycle - psxCounters[8].sCycleT;
s32 c = psxCounters[8].CycleT;
if(difference >= psxCounters[8].CycleT)
{
psxCounters[8].sCycleT = psxRegs.cycle;
psxCounters[8].CycleT = psxCounters[8].rate;
IopDmaUpdate(difference);
}
else c -= difference;
if (c < psxNextCounter) psxNextCounter = c;
}
#endif
for (i=0; i<6; i++) _rcntSet( i ); for (i=0; i<6; i++) _rcntSet( i );
} }

View File

@ -27,7 +27,13 @@ struct psxCounter {
s32 CycleT; s32 CycleT;
}; };
extern psxCounter psxCounters[8]; #ifdef ENABLE_NEW_IOPDMA
# define NUM_COUNTERS 9
#else
# define NUM_COUNTERS 8
#endif
extern psxCounter psxCounters[NUM_COUNTERS];
extern s32 psxNextCounter; extern s32 psxNextCounter;
extern u32 psxNextsCounter; extern u32 psxNextsCounter;

View File

@ -28,6 +28,7 @@ using namespace R3000A;
// Should be a bool, and will be next time I break savestate. --arcum42 // Should be a bool, and will be next time I break savestate. --arcum42
int iopsifbusy[2] = { 0, 0 }; int iopsifbusy[2] = { 0, 0 };
extern int eesifbusy[2];
static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _SPU2writeDMA4Mem spu2WriteFunc, _SPU2readDMA4Mem spu2ReadFunc) static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _SPU2writeDMA4Mem spu2WriteFunc, _SPU2readDMA4Mem spu2ReadFunc)
{ {
@ -74,6 +75,14 @@ static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _
} }
} }
void psxDma2(u32 madr, u32 bcr, u32 chcr) // GPU
{
HW_DMA2_CHCR &= ~0x01000000;
psxDmaInterrupt(2);
}
/* psxDma3 is in CdRom.cpp */
void psxDma4(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 0 void psxDma4(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 0
{ {
psxDmaGeneric(madr, bcr, chcr, 0, SPU2writeDMA4Mem, SPU2readDMA4Mem); psxDmaGeneric(madr, bcr, chcr, 0, SPU2writeDMA4Mem, SPU2readDMA4Mem);
@ -87,12 +96,6 @@ int psxDma4Interrupt()
return 1; return 1;
} }
void psxDma2(u32 madr, u32 bcr, u32 chcr) // GPU
{
HW_DMA2_CHCR &= ~0x01000000;
psxDmaInterrupt(2);
}
void psxDma6(u32 madr, u32 bcr, u32 chcr) void psxDma6(u32 madr, u32 bcr, u32 chcr)
{ {
u32 *mem = (u32 *)iopPhysMem(madr); u32 *mem = (u32 *)iopPhysMem(madr);
@ -130,7 +133,32 @@ int psxDma7Interrupt()
return 1; return 1;
} }
extern int eesifbusy[2];
void psxDma8(u32 madr, u32 bcr, u32 chcr)
{
const int size = (bcr >> 16) * (bcr & 0xFFFF) * 8;
switch (chcr & 0x01000201)
{
case 0x01000201: //cpu to dev9 transfer
PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx", chcr, madr, bcr);
DEV9writeDMA8Mem((u32*)iopPhysMem(madr), size);
break;
case 0x01000200: //dev9 to cpu transfer
PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx", chcr, madr, bcr);
DEV9readDMA8Mem((u32*)iopPhysMem(madr), size);
break;
default:
PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx", chcr, madr, bcr);
break;
}
HW_DMA8_CHCR &= ~0x01000000;
psxDmaInterrupt2(1);
}
void psxDma9(u32 madr, u32 bcr, u32 chcr) void psxDma9(u32 madr, u32 bcr, u32 chcr)
{ {
SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR); SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx", chcr, madr, bcr, HW_DMA9_TADR);
@ -164,32 +192,9 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr)
} }
} }
void psxDma8(u32 madr, u32 bcr, u32 chcr) /* psxDma11 & psxDma 12 are in IopSio2,cpp, along with the appropriate interrupt functions. */
{
const int size = (bcr >> 16) * (bcr & 0xFFFF) * 8; void dev9Interrupt()
switch (chcr & 0x01000201)
{
case 0x01000201: //cpu to dev9 transfer
PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx", chcr, madr, bcr);
DEV9writeDMA8Mem((u32*)iopPhysMem(madr), size);
break;
case 0x01000200: //dev9 to cpu transfer
PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx", chcr, madr, bcr);
DEV9readDMA8Mem((u32*)iopPhysMem(madr), size);
break;
default:
PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx", chcr, madr, bcr);
break;
}
HW_DMA8_CHCR &= ~0x01000000;
psxDmaInterrupt2(1);
}
void dev9Interrupt()
{ {
if ((dev9Handler != NULL) && (dev9Handler() != 1)) return; if ((dev9Handler != NULL) && (dev9Handler() != 1)) return;
@ -202,7 +207,7 @@ void dev9Irq(int cycles)
PSX_INT(IopEvt_DEV9, cycles); PSX_INT(IopEvt_DEV9, cycles);
} }
void usbInterrupt() void usbInterrupt()
{ {
if (usbHandler != NULL && (usbHandler() != 1)) return; if (usbHandler != NULL && (usbHandler() != 1)) return;
@ -253,35 +258,96 @@ void iopIntcIrq(uint irqType)
// //
// fixme: Is this in progress? // fixme: Is this in progress?
#if FALSE #ifdef ENABLE_NEW_IOPDMA
typedef s32(* DmaHandler)(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed); s32 spu2DmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
typedef void (* DmaIHandler)(s32 channel);
s32 errDmaWrite(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
s32 errDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
struct DmaHandlerInfo
{ {
DmaHandler Read; // FIXME: change the plugin interfaces so that they are aware of this new dma handler
DmaHandler Write;
DmaIHandler Interrupt;
};
struct DmaStatusInfo /*
u32 bytes = 1024;
if(bytesLeft<1024)
bytes=bytesLeft;
*/
u32 bytes=bytesLeft;
// Update the spu2 to the current cycle before initiating the DMA
if (SPU2async)
{
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
//Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = bytes * 3;
psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
psxNextsCounter = psxRegs.cycle;
if (psxCounters[6].CycleT < psxNextCounter)
psxNextCounter = psxCounters[6].CycleT;
}
if(channel==7)
SPU2readDMA7Mem((u16 *)data, bytes/2);
else
SPU2readDMA4Mem((u16 *)data, bytes/2);
*bytesProcessed = bytes;
return 0;
}
s32 spu2DmaWrite(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{ {
u32 Control; // FIXME: change the plugin interfaces so that they are aware of this new dma handler
u32 Width; // bytes/word, for timing purposes
u32 MemAddr;
u32 ByteCount;
u32 Target;
};
// FIXME: Dummy constants, to be "filled in" with proper values later
#define DMA_CTRL_ACTIVE 0x80000000
#define DMA_CTRL_DIRECTION 0x00000001
#define DMA_CHANNEL_MAX 16 /* ? */ /*
u32 bytes = 1024;
if(bytesLeft<1024)
bytes=bytesLeft;
*/
u32 bytes=bytesLeft;
// Update the spu2 to the current cycle before initiating the DMA
if (SPU2async)
{
SPU2async(psxRegs.cycle - psxCounters[6].sCycleT);
//Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT);
psxCounters[6].sCycleT = psxRegs.cycle;
psxCounters[6].CycleT = bytes * 3;
psxNextCounter -= (psxRegs.cycle - psxNextsCounter);
psxNextsCounter = psxRegs.cycle;
if (psxCounters[6].CycleT < psxNextCounter)
psxNextCounter = psxCounters[6].CycleT;
}
if(channel==7)
SPU2writeDMA7Mem((u16 *)data, bytes/2);
else
SPU2writeDMA4Mem((u16 *)data, bytes/2);
*bytesProcessed = bytes;
return 0;
}
void spu2DmaInterrupt(s32 channel)
{
if(channel==7)
SPU2interruptDMA7();
else
SPU2interruptDMA4();
}
//typedef s32(* DmaHandler)(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
//typedef void (* DmaIHandler)(s32 channel);
s32 errDmaWrite(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
s32 errDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; // I dont' knwo how many there are, 10? DmaStatusInfo IopChannels[DMA_CHANNEL_MAX]; // I dont' knwo how many there are, 10?
@ -295,9 +361,9 @@ DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] =
{0}, //5 {0}, //5
{0}, //6: OT? {0}, //6: OT?
{spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //7: Spu Core1 {spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //7: Spu Core1
{dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9 {0},//{dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9
{sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0 {0},//{sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0
{sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1 {0},//{sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1
{0}, // Sio2 {0}, // Sio2
{0}, // Sio2 {0}, // Sio2
}; };
@ -319,26 +385,37 @@ const char* IopDmaNames[DMA_CHANNEL_MAX] =
"Sio2", "Sio2",
"?", "?", "?" "?", "?", "?"
}; };
};
// Prototypes. To be implemented later (or in other parts of the emulator) // Prototypes. To be implemented later (or in other parts of the emulator)
void SetDmaUpdateTarget(u32 delay); void SetDmaUpdateTarget(u32 delay)
void RaiseDmaIrq(u32 channel); {
psxCounters[8].CycleT = delay;
}
void RaiseDmaIrq(u32 channel)
{
if(channel<7)
psxDmaInterrupt(channel);
else
psxDmaInterrupt2(channel-7);
}
// WARNING: CALLER ****[MUST]**** CALL IopDmaUpdate RIGHT AFTER THIS! // WARNING: CALLER ****[MUST]**** CALL IopDmaUpdate RIGHT AFTER THIS!
void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr) void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr)
{ {
// I dont' really understand this, but it's used above. Is this BYTES OR WHAT? // I dont' really understand this, but it's used above. Is this BYTES OR WHAT?
int size = (bcr >> 16) * (bcr & 0xFFFF); int size = 4* (bcr >> 16) * (bcr & 0xFFFF);
IopChannels[channel].Control = chcr | DMA_CTRL_ACTIVE; IopChannels[channel].Control = chcr | DMA_CTRL_ACTIVE;
IopChannels[channel].MemAddr = madr; IopChannels[channel].MemAddr = madr;
IopChannels[channel].ByteCount = size; IopChannels[channel].ByteCount = size;
SetDmaUpdateTarget(0);
} }
void IopDmaUpdate(u32 elapsed) void IopDmaUpdate(u32 elapsed)
{ {
u32 MinDelay = 0xFFFFFFFF; s32 MinDelay = 0x7FFFFFFF;
for (int i = 0;i < DMA_CHANNEL_MAX;i++) for (int i = 0;i < DMA_CHANNEL_MAX;i++)
{ {
@ -358,12 +435,17 @@ void IopDmaUpdate(u32 elapsed)
else else
{ {
// TODO: Make sure it's the right order // TODO: Make sure it's the right order
DmaHandler handler = (ch->Control & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Read : IopDmaHandlers[i].Write; DmaHandler handler = (ch->Control & DMA_CTRL_DIRECTION) ? IopDmaHandlers[i].Write : IopDmaHandlers[i].Read;
u32 BCount = 0; u32 BCount = 0;
s32 Target = (handler) ? handler(i, (u32*)PSXM(ch->MemAddr), ch->ByteCount, &BCount) : 0; s32 Target = (handler) ? handler(i, (u32*)iopPhysMem(ch->MemAddr), ch->ByteCount, &BCount) : 0;
ch->Target = 100; if(BCount>0)
{
psxCpu->Clear(ch->MemAddr, BCount/4);
}
int TTarget = 100;
if (Target < 0) if (Target < 0)
{ {
// TODO: ... What to do if the plugin errors? :P // TODO: ... What to do if the plugin errors? :P
@ -373,29 +455,38 @@ void IopDmaUpdate(u32 elapsed)
ch->MemAddr += BCount; ch->MemAddr += BCount;
ch->ByteCount -= BCount; ch->ByteCount -= BCount;
ch->Target = BCount / ch->Width; TTarget = BCount; // / ch->Width;
} }
if (Target != 0) ch->Target = Target; if (Target != 0) TTarget = Target;
if (ch->Target<MinDelay) MinDelay = TTarget;
ch->Target += TTarget;
} }
} }
} }
} }
if(MinDelay<0x7FFFFFFF)
SetDmaUpdateTarget(MinDelay);
else
SetDmaUpdateTarget(10000);
} }
s32 errDmaRead(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed) s32 errDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{ {
Console::Error("ERROR: Tried to read using DMA %d (%s). Ignoring.", 0, channel, IopDmaNames[channel]); Console::Error("ERROR: Tried to read using DMA %d (%s). Ignoring.", params 0, channel, IopDmaNames[channel]);
*wordsProcessed = wordsLeft; *bytesProcessed = bytesLeft;
return 0; return 0;
} }
s32 errDmaWrite(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed) s32 errDmaWrite(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
{ {
Console::Error("ERROR: Tried to write using DMA %d (%s). Ignoring.", 0, channel, IopDmaNames[channel]); Console::Error("ERROR: Tried to write using DMA %d (%s). Ignoring.", params 0, channel, IopDmaNames[channel]);
*wordsProcessed = wordsLeft; *bytesProcessed = bytesLeft;
return 0; return 0;
} }

View File

@ -21,6 +21,46 @@
#include "PS2Edefs.h" #include "PS2Edefs.h"
//#define ENABLE_NEW_IOPDMA
#ifdef ENABLE_NEW_IOPDMA
typedef s32(* DmaHandler)(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
typedef void (* DmaIHandler)(s32 channel);
struct DmaHandlerInfo
{
DmaHandler Read;
DmaHandler Write;
DmaIHandler Interrupt;
};
struct DmaStatusInfo
{
u32 Control;
u32 Width; // bytes/word, for timing purposes
u32 MemAddr;
u32 ByteCount;
s32 Target;
};
// FIXME: Dummy constants, to be "filled in" with proper values later
#define DMA_CTRL_ACTIVE 0x01000000
#define DMA_CTRL_DIRECTION 0x00000001
#define DMA_CHANNEL_MAX 16 /* ? */
// WARNING: CALLER ****[MUST]**** CALL IopDmaUpdate RIGHT AFTER THIS!
void IopDmaStart(int channel, u32 chcr, u32 madr, u32 bcr);
void IopDmaUpdate(u32 elapsed);
// external dma handlers
extern s32 cdvdDmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed);
extern void cdvdDmaInterrupt(s32 channel);
//#else
#endif
void psxDma2(u32 madr, u32 bcr, u32 chcr); void psxDma2(u32 madr, u32 bcr, u32 chcr);
void psxDma3(u32 madr, u32 bcr, u32 chcr); void psxDma3(u32 madr, u32 bcr, u32 chcr);
void psxDma4(u32 madr, u32 bcr, u32 chcr); void psxDma4(u32 madr, u32 bcr, u32 chcr);

View File

@ -41,7 +41,7 @@ void psxHwReset() {
u8 psxHwRead8(u32 add) { u8 psxHwRead8(u32 add) {
u8 hard; u8 hard;
if (add >= 0x1f801600 && add < 0x1f801700) { if (add >= HW_USB_START && add < HW_USB_END) {
return USBread8(add); return USBread8(add);
} }
@ -53,24 +53,24 @@ u8 psxHwRead8(u32 add) {
return DEV9read8(add); return DEV9read8(add);
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
case 0x1f801100: case IOP_T0_COUNT:
case 0x1f801104: case IOP_T0_MODE:
case 0x1f801108: case IOP_T0_TARGET:
case 0x1f801110: case IOP_T1_COUNT:
case 0x1f801114: case IOP_T1_MODE:
case 0x1f801118: case IOP_T1_TARGET:
case 0x1f801120: case IOP_T2_COUNT:
case 0x1f801124: case IOP_T2_MODE:
case 0x1f801128: case IOP_T2_TARGET:
case 0x1f801480: case IOP_T3_COUNT:
case 0x1f801484: case IOP_T3_MODE:
case 0x1f801488: case IOP_T3_TARGET:
case 0x1f801490: case IOP_T4_COUNT:
case 0x1f801494: case IOP_T4_MODE:
case 0x1f801498: case IOP_T4_TARGET:
case 0x1f8014a0: case IOP_T5_COUNT:
case 0x1f8014a4: case IOP_T5_MODE:
case 0x1f8014a8: case IOP_T5_TARGET:
DevCon::Notice( "IOP Counter Read8 from addr0x%x = 0x%x", params add, psxHu8(add) ); DevCon::Notice( "IOP Counter Read8 from addr0x%x = 0x%x", params add, psxHu8(add) );
return psxHu8(add); return psxHu8(add);
#endif #endif
@ -102,7 +102,7 @@ u8 psxHwRead8(u32 add) {
u16 psxHwRead16(u32 add) { u16 psxHwRead16(u32 add) {
u16 hard; u16 hard;
if (add >= 0x1f801600 && add < 0x1f801700) { if (add >= HW_USB_START && add < HW_USB_END) {
return USBread16(add); return USBread16(add);
} }
@ -136,50 +136,50 @@ u16 psxHwRead16(u32 add) {
return hard; return hard;
//Serial port stuff not support now ;P //Serial port stuff not support now ;P
// case 0x1f801050: hard = serial_read16(); break; // case 0x1f801050: hard = serial_read16(); break;
// case 0x1f801054: hard = serial_status_read(); break; // case 0x1f801054: hard = serial_status_read(); break;
// case 0x1f80105a: hard = serial_control_read(); break; // case 0x1f80105a: hard = serial_control_read(); break;
// case 0x1f80105e: hard = serial_baud_read(); break; // case 0x1f80105e: hard = serial_baud_read(); break;
case 0x1f801100: case IOP_T0_COUNT:
hard = (u16)psxRcntRcount16(0); hard = (u16)psxRcntRcount16(0);
PSXCNT_LOG("T0 count read16: %x", hard); PSXCNT_LOG("T0 count read16: %x", hard);
return hard; return hard;
case 0x1f801104: case IOP_T0_MODE:
hard = psxCounters[0].mode; hard = psxCounters[0].mode;
psxCounters[0].mode &= ~0x1800; psxCounters[0].mode &= ~0x1800;
psxCounters[0].mode |= 0x400; psxCounters[0].mode |= 0x400;
PSXCNT_LOG("T0 mode read16: %x", hard); PSXCNT_LOG("T0 mode read16: %x", hard);
return hard; return hard;
case 0x1f801108: case IOP_T0_TARGET:
hard = psxCounters[0].target; hard = psxCounters[0].target;
PSXCNT_LOG("T0 target read16: %x", hard); PSXCNT_LOG("T0 target read16: %x", hard);
return hard; return hard;
case 0x1f801110: case IOP_T1_COUNT:
hard = (u16)psxRcntRcount16(1); hard = (u16)psxRcntRcount16(1);
PSXCNT_LOG("T1 count read16: %x", hard); PSXCNT_LOG("T1 count read16: %x", hard);
return hard; return hard;
case 0x1f801114: case IOP_T1_MODE:
hard = psxCounters[1].mode; hard = psxCounters[1].mode;
psxCounters[1].mode &= ~0x1800; psxCounters[1].mode &= ~0x1800;
psxCounters[1].mode |= 0x400; psxCounters[1].mode |= 0x400;
PSXCNT_LOG("T1 mode read16: %x", hard); PSXCNT_LOG("T1 mode read16: %x", hard);
return hard; return hard;
case 0x1f801118: case IOP_T1_TARGET:
hard = psxCounters[1].target; hard = psxCounters[1].target;
PSXCNT_LOG("T1 target read16: %x", hard); PSXCNT_LOG("T1 target read16: %x", hard);
return hard; return hard;
case 0x1f801120: case IOP_T2_COUNT:
hard = (u16)psxRcntRcount16(2); hard = (u16)psxRcntRcount16(2);
PSXCNT_LOG("T2 count read16: %x", hard); PSXCNT_LOG("T2 count read16: %x", hard);
return hard; return hard;
case 0x1f801124: case IOP_T2_MODE:
hard = psxCounters[2].mode; hard = psxCounters[2].mode;
psxCounters[2].mode &= ~0x1800; psxCounters[2].mode &= ~0x1800;
psxCounters[2].mode |= 0x400; psxCounters[2].mode |= 0x400;
PSXCNT_LOG("T2 mode read16: %x", hard); PSXCNT_LOG("T2 mode read16: %x", hard);
return hard; return hard;
case 0x1f801128: case IOP_T2_TARGET:
hard = psxCounters[2].target; hard = psxCounters[2].target;
PSXCNT_LOG("T2 target read16: %x", hard); PSXCNT_LOG("T2 target read16: %x", hard);
return hard; return hard;
@ -187,45 +187,45 @@ u16 psxHwRead16(u32 add) {
case 0x1f80146e: // DEV9_R_REV case 0x1f80146e: // DEV9_R_REV
return DEV9read16(add); return DEV9read16(add);
case 0x1f801480: case IOP_T3_COUNT:
hard = (u16)psxRcntRcount32(3); hard = (u16)psxRcntRcount32(3);
PSXCNT_LOG("T3 count read16: %lx", hard); PSXCNT_LOG("T3 count read16: %lx", hard);
return hard; return hard;
case 0x1f801484: case IOP_T3_MODE:
hard = psxCounters[3].mode; hard = psxCounters[3].mode;
psxCounters[3].mode &= ~0x1800; psxCounters[3].mode &= ~0x1800;
psxCounters[3].mode |= 0x400; psxCounters[3].mode |= 0x400;
PSXCNT_LOG("T3 mode read16: %lx", hard); PSXCNT_LOG("T3 mode read16: %lx", hard);
return hard; return hard;
case 0x1f801488: case IOP_T3_TARGET:
hard = psxCounters[3].target; hard = psxCounters[3].target;
PSXCNT_LOG("T3 target read16: %lx", hard); PSXCNT_LOG("T3 target read16: %lx", hard);
return hard; return hard;
case 0x1f801490: case IOP_T4_COUNT:
hard = (u16)psxRcntRcount32(4); hard = (u16)psxRcntRcount32(4);
PSXCNT_LOG("T4 count read16: %lx", hard); PSXCNT_LOG("T4 count read16: %lx", hard);
return hard; return hard;
case 0x1f801494: case IOP_T4_MODE:
hard = psxCounters[4].mode; hard = psxCounters[4].mode;
psxCounters[4].mode &= ~0x1800; psxCounters[4].mode &= ~0x1800;
psxCounters[4].mode |= 0x400; psxCounters[4].mode |= 0x400;
PSXCNT_LOG("T4 mode read16: %lx", hard); PSXCNT_LOG("T4 mode read16: %lx", hard);
return hard; return hard;
case 0x1f801498: case IOP_T4_TARGET:
hard = psxCounters[4].target; hard = psxCounters[4].target;
PSXCNT_LOG("T4 target read16: %lx", hard); PSXCNT_LOG("T4 target read16: %lx", hard);
return hard; return hard;
case 0x1f8014a0: case IOP_T5_COUNT:
hard = (u16)psxRcntRcount32(5); hard = (u16)psxRcntRcount32(5);
PSXCNT_LOG("T5 count read16: %lx", hard); PSXCNT_LOG("T5 count read16: %lx", hard);
return hard; return hard;
case 0x1f8014a4: case IOP_T5_MODE:
hard = psxCounters[5].mode; hard = psxCounters[5].mode;
psxCounters[5].mode &= ~0x1800; psxCounters[5].mode &= ~0x1800;
psxCounters[5].mode |= 0x400; psxCounters[5].mode |= 0x400;
PSXCNT_LOG("T5 mode read16: %lx", hard); PSXCNT_LOG("T5 mode read16: %lx", hard);
return hard; return hard;
case 0x1f8014a8: case IOP_T5_TARGET:
hard = psxCounters[5].target; hard = psxCounters[5].target;
PSXCNT_LOG("T5 target read16: %lx", hard); PSXCNT_LOG("T5 target read16: %lx", hard);
return hard; return hard;
@ -238,11 +238,11 @@ u16 psxHwRead16(u32 add) {
hard = psxHu16(0x1506); hard = psxHu16(0x1506);
PSXHW_LOG("DMA7 BCR_count 16bit read %lx", hard); PSXHW_LOG("DMA7 BCR_count 16bit read %lx", hard);
return hard; return hard;
//case 0x1f802030: hard = //int_2000???? // case 0x1f802030: hard = //int_2000????
//case 0x1f802040: hard =//dip switches...?? // case 0x1f802040: hard =//dip switches...??
default: default:
if (add>=0x1f801c00 && add<0x1f801e00) { if (add>=HW_SPU2_START && add<HW_SPU2_END) {
hard = SPU2read(add); hard = SPU2read(add);
} else { } else {
hard = psxHu16(add); hard = psxHu16(add);
@ -259,10 +259,10 @@ u16 psxHwRead16(u32 add) {
u32 psxHwRead32(u32 add) { u32 psxHwRead32(u32 add) {
u32 hard; u32 hard;
if (add >= 0x1f801600 && add < 0x1f801700) { if (add >= HW_USB_START && add < HW_USB_END) {
return USBread32(add); return USBread32(add);
} }
if (add >= 0x1f808400 && add <= 0x1f808550) {//the size is a complete guess.. if (add >= HW_FW_START && add <= HW_FW_END) {//the size is a complete guess..
return FWread32(add); return FWread32(add);
} }
@ -275,7 +275,7 @@ u32 psxHwRead32(u32 add) {
PAD_LOG("sio read32 ;ret = %lx", hard); PAD_LOG("sio read32 ;ret = %lx", hard);
return hard; return hard;
// case 0x1f801050: hard = serial_read32(); break;//serial port // case 0x1f801050: hard = serial_read32(); break;//serial port
case 0x1f801060: case 0x1f801060:
PSXHW_LOG("RAM size read %lx", psxHu32(0x1060)); PSXHW_LOG("RAM size read %lx", psxHu32(0x1060));
return psxHu32(0x1060); return psxHu32(0x1060);
@ -289,18 +289,17 @@ u32 psxHwRead32(u32 add) {
psxHu32(0x1078) = 0; psxHu32(0x1078) = 0;
return hard; return hard;
/* case 0x1f801810: // case 0x1f801810:
// hard = GPU_readData(); // hard = GPU_readData();
PSXHW_LOG("GPU DATA 32bit read %lx", hard); // PSXHW_LOG("GPU DATA 32bit read %lx", hard);
return hard;*/ // return hard;
/* case 0x1f801814: // case 0x1f801814:
hard = GPU_readStatus(); // hard = GPU_readStatus();
PSXHW_LOG("GPU STATUS 32bit read %lx", hard); // PSXHW_LOG("GPU STATUS 32bit read %lx", hard);
return hard; // return hard;
*/ //
/* case 0x1f801820: hard = mdecRead0(); break; // case 0x1f801820: hard = mdecRead0(); break;
case 0x1f801824: hard = mdecRead1(); break; // case 0x1f801824: hard = mdecRead1(); break;
*/
case 0x1f8010a0: case 0x1f8010a0:
PSXHW_LOG("DMA2 MADR 32bit read %lx", psxHu32(0x10a0)); PSXHW_LOG("DMA2 MADR 32bit read %lx", psxHu32(0x10a0));
@ -352,7 +351,7 @@ u32 psxHwRead32(u32 add) {
PSXHW_LOG("DMA ICR 32bit read %lx", HW_DMA_ICR); PSXHW_LOG("DMA ICR 32bit read %lx", HW_DMA_ICR);
return HW_DMA_ICR; return HW_DMA_ICR;
//SSBus registers //SSBus registers
case 0x1f801000: case 0x1f801000:
hard = psxHu32(0x1000); hard = psxHu32(0x1000);
PSXHW_LOG("SSBUS <spd_addr> 32bit read %lx", hard); PSXHW_LOG("SSBUS <spd_addr> 32bit read %lx", hard);
@ -432,79 +431,78 @@ u32 psxHwRead32(u32 add) {
case 0x1f8010c8: case 0x1f8010c8:
PSXHW_LOG("DMA4 CHCR 32bit read %lx", HW_DMA4_CHCR); PSXHW_LOG("DMA4 CHCR 32bit read %lx", HW_DMA4_CHCR);
return HW_DMA4_CHCR; // DMA4 chcr (SPU DMA) return HW_DMA4_CHCR; // DMA4 chcr (SPU DMA)
// time for rootcounters :) // time for rootcounters :)
case 0x1f801100: case IOP_T0_COUNT:
hard = (u16)psxRcntRcount16(0); hard = (u16)psxRcntRcount16(0);
PSXCNT_LOG("T0 count read32: %lx", hard); PSXCNT_LOG("T0 count read32: %lx", hard);
return hard; return hard;
case 0x1f801104: case IOP_T0_MODE:
hard = (u16)psxCounters[0].mode; hard = (u16)psxCounters[0].mode;
PSXCNT_LOG("T0 mode read32: %lx", hard); PSXCNT_LOG("T0 mode read32: %lx", hard);
return hard; return hard;
case 0x1f801108: case IOP_T0_TARGET:
hard = psxCounters[0].target; hard = psxCounters[0].target;
PSXCNT_LOG("T0 target read32: %lx", hard); PSXCNT_LOG("T0 target read32: %lx", hard);
return hard; return hard;
case 0x1f801110: case IOP_T1_COUNT:
hard = (u16)psxRcntRcount16(1); hard = (u16)psxRcntRcount16(1);
PSXCNT_LOG("T1 count read32: %lx", hard); PSXCNT_LOG("T1 count read32: %lx", hard);
return hard; return hard;
case 0x1f801114: case IOP_T1_MODE:
hard = (u16)psxCounters[1].mode; hard = (u16)psxCounters[1].mode;
PSXCNT_LOG("T1 mode read32: %lx", hard); PSXCNT_LOG("T1 mode read32: %lx", hard);
return hard; return hard;
case 0x1f801118: case IOP_T1_TARGET:
hard = psxCounters[1].target; hard = psxCounters[1].target;
PSXCNT_LOG("T1 target read32: %lx", hard); PSXCNT_LOG("T1 target read32: %lx", hard);
return hard; return hard;
case 0x1f801120: case IOP_T2_COUNT:
hard = (u16)psxRcntRcount16(2); hard = (u16)psxRcntRcount16(2);
PSXCNT_LOG("T2 count read32: %lx", hard); PSXCNT_LOG("T2 count read32: %lx", hard);
return hard; return hard;
case 0x1f801124: case IOP_T2_MODE:
hard = (u16)psxCounters[2].mode; hard = (u16)psxCounters[2].mode;
PSXCNT_LOG("T2 mode read32: %lx", hard); PSXCNT_LOG("T2 mode read32: %lx", hard);
return hard; return hard;
case 0x1f801128: case IOP_T2_TARGET:
hard = psxCounters[2].target; hard = psxCounters[2].target;
PSXCNT_LOG("T2 target read32: %lx", hard); PSXCNT_LOG("T2 target read32: %lx", hard);
return hard; return hard;
case IOP_T3_COUNT:
case 0x1f801480:
hard = (u32)psxRcntRcount32(3); hard = (u32)psxRcntRcount32(3);
PSXCNT_LOG("T3 count read32: %lx", hard); PSXCNT_LOG("T3 count read32: %lx", hard);
return hard; return hard;
case 0x1f801484: case IOP_T3_MODE:
hard = (u16)psxCounters[3].mode; hard = (u16)psxCounters[3].mode;
PSXCNT_LOG("T3 mode read32: %lx", hard); PSXCNT_LOG("T3 mode read32: %lx", hard);
return hard; return hard;
case 0x1f801488: case IOP_T3_TARGET:
hard = psxCounters[3].target; hard = psxCounters[3].target;
PSXCNT_LOG("T3 target read32: %lx", hard); PSXCNT_LOG("T3 target read32: %lx", hard);
return hard; return hard;
case 0x1f801490: case IOP_T4_COUNT:
hard = (u32)psxRcntRcount32(4); hard = (u32)psxRcntRcount32(4);
PSXCNT_LOG("T4 count read32: %lx", hard); PSXCNT_LOG("T4 count read32: %lx", hard);
return hard; return hard;
case 0x1f801494: case IOP_T4_MODE:
hard = (u16)psxCounters[4].mode; hard = (u16)psxCounters[4].mode;
PSXCNT_LOG("T4 mode read32: %lx", hard); PSXCNT_LOG("T4 mode read32: %lx", hard);
return hard; return hard;
case 0x1f801498: case IOP_T4_TARGET:
hard = psxCounters[4].target; hard = psxCounters[4].target;
PSXCNT_LOG("T4 target read32: %lx", hard); PSXCNT_LOG("T4 target read32: %lx", hard);
return hard; return hard;
case 0x1f8014a0: case IOP_T5_COUNT:
hard = (u32)psxRcntRcount32(5); hard = (u32)psxRcntRcount32(5);
PSXCNT_LOG("T5 count read32: %lx", hard); PSXCNT_LOG("T5 count read32: %lx", hard);
return hard; return hard;
case 0x1f8014a4: case IOP_T5_MODE:
hard = (u16)psxCounters[5].mode; hard = (u16)psxCounters[5].mode;
PSXCNT_LOG("T5 mode read32: %lx", hard); PSXCNT_LOG("T5 mode read32: %lx", hard);
return hard; return hard;
case 0x1f8014a8: case IOP_T5_TARGET:
hard = psxCounters[5].target; hard = psxCounters[5].target;
PSXCNT_LOG("T5 target read32: %lx", hard); PSXCNT_LOG("T5 target read32: %lx", hard);
return hard; return hard;
@ -619,18 +617,11 @@ u32 psxHwRead32(u32 add) {
return hard; return hard;
} }
int g_pbufi; // A buffer that stores messages until it gets a /n or the number of chars (g_pbufi) is more then 1023.
s8 g_pbuf[1024]; s8 g_pbuf[1024];
int g_pbufi;
#define DmaExec(n) { \
if (HW_DMA##n##_CHCR & 0x01000000 && \
HW_DMA_PCR & (8 << (n * 4))) { \
psxDma##n(HW_DMA##n##_MADR, HW_DMA##n##_BCR, HW_DMA##n##_CHCR); \
} \
}
void psxHwWrite8(u32 add, u8 value) { void psxHwWrite8(u32 add, u8 value) {
if (add >= 0x1f801600 && add < 0x1f801700) { if (add >= HW_USB_START && add < HW_USB_END) {
USBwrite8(add, value); return; USBwrite8(add, value); return;
} }
if((add & 0xf) == 0xa) if((add & 0xf) == 0xa)
@ -638,28 +629,28 @@ void psxHwWrite8(u32 add, u8 value) {
switch (add) { switch (add) {
case 0x1f801040: case 0x1f801040:
sioWrite8(value); sioWrite8(value);
break; break;
// case 0x1f801050: serial_write8(value); break;//serial port // case 0x1f801050: serial_write8(value); break;//serial port
case 0x1f801100: case IOP_T0_COUNT:
case 0x1f801104: case IOP_T0_MODE:
case 0x1f801108: case IOP_T0_TARGET:
case 0x1f801110: case IOP_T1_COUNT:
case 0x1f801114: case IOP_T1_MODE:
case 0x1f801118: case IOP_T1_TARGET:
case 0x1f801120: case IOP_T2_COUNT:
case 0x1f801124: case IOP_T2_MODE:
case 0x1f801128: case IOP_T2_TARGET:
case 0x1f801480: case IOP_T3_COUNT:
case 0x1f801484: case IOP_T3_MODE:
case 0x1f801488: case IOP_T3_TARGET:
case 0x1f801490: case IOP_T4_COUNT:
case 0x1f801494: case IOP_T4_MODE:
case 0x1f801498: case IOP_T4_TARGET:
case 0x1f8014a0: case IOP_T5_COUNT:
case 0x1f8014a4: case IOP_T5_MODE:
case 0x1f8014a8: case IOP_T5_TARGET:
DevCon::Notice( "IOP Counter Write8 to addr 0x%x = 0x%x", params add, value ); DevCon::Notice( "IOP Counter Write8 to addr 0x%x = 0x%x", params add, value );
psxHu8(add) = value; psxHu8(add) = value;
return; return;
@ -676,17 +667,19 @@ void psxHwWrite8(u32 add, u8 value) {
case 0x1f80380c: case 0x1f80380c:
if (value == '\r') break; if (value == '\r') break;
if (value == '\n' || g_pbufi >= 1023) { if (value == '\n' || g_pbufi >= 1023) { // A line break, or the buffer is about to overflow.
g_pbuf[g_pbufi++] = 0; g_pbufi = 0; g_pbuf[g_pbufi++] = 0;
g_pbufi = 0;
DevCon::WriteLn( Color_Cyan, g_pbuf ); DevCon::WriteLn( Color_Cyan, g_pbuf );
} }
else g_pbuf[g_pbufi++] = value; else g_pbuf[g_pbufi++] = value;
psxHu8(add) = value; psxHu8(add) = value;
return; return;
case 0x1F808260: case 0x1F808260:
PSXHW_LOG("SIO2 write8 DATAIN <- %08X", value); PSXHW_LOG("SIO2 write8 DATAIN <- %08X", value);
sio2_serialIn(value);return;//serial data feed/fifo sio2_serialIn(value);
return;//serial data feed/fifo
default: default:
psxHu8(add) = value; psxHu8(add) = value;
@ -698,7 +691,7 @@ void psxHwWrite8(u32 add, u8 value) {
} }
void psxHwWrite16(u32 add, u16 value) { void psxHwWrite16(u32 add, u16 value) {
if (add >= 0x1f801600 && add < 0x1f801700) { if (add >= HW_USB_START && add < HW_USB_END) {
USBwrite16(add, value); return; USBwrite16(add, value); return;
} }
@ -727,10 +720,10 @@ void psxHwWrite16(u32 add, u16 value) {
return; return;
//serial port ;P //serial port ;P
// case 0x1f801050: serial_write16(value); break; // case 0x1f801050: serial_write16(value); break;
// case 0x1f80105a: serial_control_write(value);break; // case 0x1f80105a: serial_control_write(value);break;
// case 0x1f80105e: serial_baud_write(value); break; // case 0x1f80105e: serial_baud_write(value); break;
// case 0x1f801054: serial_status_write(value); break; // case 0x1f801054: serial_status_write(value); break;
case 0x1f801070: case 0x1f801070:
PSXHW_LOG("IREG 16bit write %x", value); PSXHW_LOG("IREG 16bit write %x", value);
@ -760,33 +753,33 @@ void psxHwWrite16(u32 add, u16 value) {
PSXHW_LOG("DMA4 BCR_count 16bit write %lx", value); PSXHW_LOG("DMA4 BCR_count 16bit write %lx", value);
psxHu16(0x10c6) = value; return; // DMA4 bcr_count psxHu16(0x10c6) = value; return; // DMA4 bcr_count
case 0x1f801100: case IOP_T0_COUNT:
PSXCNT_LOG("COUNTER 0 COUNT 16bit write %x", value); PSXCNT_LOG("COUNTER 0 COUNT 16bit write %x", value);
psxRcntWcount16(0, value); return; psxRcntWcount16(0, value); return;
case 0x1f801104: case IOP_T0_MODE:
PSXCNT_LOG("COUNTER 0 MODE 16bit write %x", value); PSXCNT_LOG("COUNTER 0 MODE 16bit write %x", value);
psxRcnt0Wmode(value); return; psxRcnt0Wmode(value); return;
case 0x1f801108: case IOP_T0_TARGET:
PSXCNT_LOG("COUNTER 0 TARGET 16bit write %x", value); PSXCNT_LOG("COUNTER 0 TARGET 16bit write %x", value);
psxRcntWtarget16(0, value); return; psxRcntWtarget16(0, value); return;
case 0x1f801110: case IOP_T1_COUNT:
PSXCNT_LOG("COUNTER 1 COUNT 16bit write %x", value); PSXCNT_LOG("COUNTER 1 COUNT 16bit write %x", value);
psxRcntWcount16(1, value); return; psxRcntWcount16(1, value); return;
case 0x1f801114: case IOP_T1_MODE:
PSXCNT_LOG("COUNTER 1 MODE 16bit write %x", value); PSXCNT_LOG("COUNTER 1 MODE 16bit write %x", value);
psxRcnt1Wmode(value); return; psxRcnt1Wmode(value); return;
case 0x1f801118: case IOP_T1_TARGET:
PSXCNT_LOG("COUNTER 1 TARGET 16bit write %x", value); PSXCNT_LOG("COUNTER 1 TARGET 16bit write %x", value);
psxRcntWtarget16(1, value); return; psxRcntWtarget16(1, value); return;
case 0x1f801120: case IOP_T2_COUNT:
PSXCNT_LOG("COUNTER 2 COUNT 16bit write %x", value); PSXCNT_LOG("COUNTER 2 COUNT 16bit write %x", value);
psxRcntWcount16(2, value); return; psxRcntWcount16(2, value); return;
case 0x1f801124: case IOP_T2_MODE:
PSXCNT_LOG("COUNTER 2 MODE 16bit write %x", value); PSXCNT_LOG("COUNTER 2 MODE 16bit write %x", value);
psxRcnt2Wmode(value); return; psxRcnt2Wmode(value); return;
case 0x1f801128: case IOP_T2_TARGET:
PSXCNT_LOG("COUNTER 2 TARGET 16bit write %x", value); PSXCNT_LOG("COUNTER 2 TARGET 16bit write %x", value);
psxRcntWtarget16(2, value); return; psxRcntWtarget16(2, value); return;
@ -795,33 +788,33 @@ void psxHwWrite16(u32 add, u16 value) {
psxHu16(0x1450) = value/* & (~0x8)*/; psxHu16(0x1450) = value/* & (~0x8)*/;
return; return;
case 0x1f801480: case IOP_T3_COUNT:
PSXCNT_LOG("COUNTER 3 COUNT 16bit write %lx", value); PSXCNT_LOG("COUNTER 3 COUNT 16bit write %lx", value);
psxRcntWcount32(3, value); return; psxRcntWcount32(3, value); return;
case 0x1f801484: case IOP_T3_MODE:
PSXCNT_LOG("COUNTER 3 MODE 16bit write %lx", value); PSXCNT_LOG("COUNTER 3 MODE 16bit write %lx", value);
psxRcnt3Wmode(value); return; psxRcnt3Wmode(value); return;
case 0x1f801488: case IOP_T3_TARGET:
PSXCNT_LOG("COUNTER 3 TARGET 16bit write %lx", value); PSXCNT_LOG("COUNTER 3 TARGET 16bit write %lx", value);
psxRcntWtarget32(3, value); return; psxRcntWtarget32(3, value); return;
case 0x1f801490: case IOP_T4_COUNT:
PSXCNT_LOG("COUNTER 4 COUNT 16bit write %lx", value); PSXCNT_LOG("COUNTER 4 COUNT 16bit write %lx", value);
psxRcntWcount32(4, value); return; psxRcntWcount32(4, value); return;
case 0x1f801494: case IOP_T4_MODE:
PSXCNT_LOG("COUNTER 4 MODE 16bit write %lx", value); PSXCNT_LOG("COUNTER 4 MODE 16bit write %lx", value);
psxRcnt4Wmode(value); return; psxRcnt4Wmode(value); return;
case 0x1f801498: case IOP_T4_TARGET:
PSXCNT_LOG("COUNTER 4 TARGET 16bit write %lx", value); PSXCNT_LOG("COUNTER 4 TARGET 16bit write %lx", value);
psxRcntWtarget32(4, value); return; psxRcntWtarget32(4, value); return;
case 0x1f8014a0: case IOP_T5_COUNT:
PSXCNT_LOG("COUNTER 5 COUNT 16bit write %lx", value); PSXCNT_LOG("COUNTER 5 COUNT 16bit write %lx", value);
psxRcntWcount32(5, value); return; psxRcntWcount32(5, value); return;
case 0x1f8014a4: case IOP_T5_MODE:
PSXCNT_LOG("COUNTER 5 MODE 16bit write %lx", value); PSXCNT_LOG("COUNTER 5 MODE 16bit write %lx", value);
psxRcnt5Wmode(value); return; psxRcnt5Wmode(value); return;
case 0x1f8014a8: case IOP_T5_TARGET:
PSXCNT_LOG("COUNTER 5 TARGET 16bit write %lx", value); PSXCNT_LOG("COUNTER 5 TARGET 16bit write %lx", value);
psxRcntWtarget32(5, value); return; psxRcntWtarget32(5, value); return;
@ -834,7 +827,7 @@ void psxHwWrite16(u32 add, u16 value) {
PSXHW_LOG("DMA7 BCR_count 16bit write %lx", value); PSXHW_LOG("DMA7 BCR_count 16bit write %lx", value);
return; return;
default: default:
if (add>=0x1f801c00 && add<0x1f801e00) { if (add>=HW_SPU2_START && add<HW_SPU2_END) {
SPU2write(add, value); SPU2write(add, value);
return; return;
} }
@ -847,18 +840,11 @@ void psxHwWrite16(u32 add, u16 value) {
PSXHW_LOG("*Known 16bit write at address %lx value %x", add, value); PSXHW_LOG("*Known 16bit write at address %lx value %x", add, value);
} }
#define DmaExec2(n) { \
if (HW_DMA##n##_CHCR & 0x01000000 && \
HW_DMA_PCR2 & (8 << ((n-7) * 4))) { \
psxDma##n(HW_DMA##n##_MADR, HW_DMA##n##_BCR, HW_DMA##n##_CHCR); \
} \
}
void psxHwWrite32(u32 add, u32 value) { void psxHwWrite32(u32 add, u32 value) {
if (add >= 0x1f801600 && add < 0x1f801700) { if (add >= HW_USB_START && add < HW_USB_END) {
USBwrite32(add, value); return; USBwrite32(add, value); return;
} }
if (add >= 0x1f808400 && add <= 0x1f808550) { if (add >= HW_FW_START && add <= HW_FW_END) {
FWwrite32(add, value); return; FWwrite32(add, value); return;
} }
switch (add) { switch (add) {
@ -1034,7 +1020,7 @@ void psxHwWrite32(u32 add, u32 value) {
case 0x1f8010c8: case 0x1f8010c8:
PSXHW_LOG("DMA4 CHCR 32bit write %lx", value); PSXHW_LOG("DMA4 CHCR 32bit write %lx", value);
HW_DMA4_CHCR = value; // DMA4 chcr (SPU DMA) HW_DMA4_CHCR = value; // DMA4 chcr (SPU DMA)
DmaExec(4); DmaExecNew(4);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -1067,7 +1053,7 @@ void psxHwWrite32(u32 add, u32 value) {
case 0x1f801508: case 0x1f801508:
PSXHW_LOG("DMA7 CHCR 32bit write %lx", value); PSXHW_LOG("DMA7 CHCR 32bit write %lx", value);
HW_DMA7_CHCR = value; // DMA7 chcr (SPU2) HW_DMA7_CHCR = value; // DMA7 chcr (SPU2)
DmaExec2(7); DmaExecNew2(7);
return; return;
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -1179,63 +1165,63 @@ void psxHwWrite32(u32 add, u32 value) {
case 0x1f801824: case 0x1f801824:
mdecWrite1(value); break; mdecWrite1(value); break;
*/ */
case 0x1f801100: case IOP_T0_COUNT:
PSXCNT_LOG("COUNTER 0 COUNT 32bit write %lx", value); PSXCNT_LOG("COUNTER 0 COUNT 32bit write %lx", value);
psxRcntWcount16(0, value ); return; psxRcntWcount16(0, value ); return;
case 0x1f801104: case IOP_T0_MODE:
PSXCNT_LOG("COUNTER 0 MODE 32bit write %lx", value); PSXCNT_LOG("COUNTER 0 MODE 32bit write %lx", value);
psxRcnt0Wmode(value); return; psxRcnt0Wmode(value); return;
case 0x1f801108: case IOP_T0_TARGET:
PSXCNT_LOG("COUNTER 0 TARGET 32bit write %lx", value); PSXCNT_LOG("COUNTER 0 TARGET 32bit write %lx", value);
psxRcntWtarget16(0, value ); return; psxRcntWtarget16(0, value ); return;
case 0x1f801110: case IOP_T1_COUNT:
PSXCNT_LOG("COUNTER 1 COUNT 32bit write %lx", value); PSXCNT_LOG("COUNTER 1 COUNT 32bit write %lx", value);
psxRcntWcount16(1, value ); return; psxRcntWcount16(1, value ); return;
case 0x1f801114: case IOP_T1_MODE:
PSXCNT_LOG("COUNTER 1 MODE 32bit write %lx", value); PSXCNT_LOG("COUNTER 1 MODE 32bit write %lx", value);
psxRcnt1Wmode(value); return; psxRcnt1Wmode(value); return;
case 0x1f801118: case IOP_T1_TARGET:
PSXCNT_LOG("COUNTER 1 TARGET 32bit write %lx", value); PSXCNT_LOG("COUNTER 1 TARGET 32bit write %lx", value);
psxRcntWtarget16(1, value ); return; psxRcntWtarget16(1, value ); return;
case 0x1f801120: case IOP_T2_COUNT:
PSXCNT_LOG("COUNTER 2 COUNT 32bit write %lx", value); PSXCNT_LOG("COUNTER 2 COUNT 32bit write %lx", value);
psxRcntWcount16(2, value ); return; psxRcntWcount16(2, value ); return;
case 0x1f801124: case IOP_T2_MODE:
PSXCNT_LOG("COUNTER 2 MODE 32bit write %lx", value); PSXCNT_LOG("COUNTER 2 MODE 32bit write %lx", value);
psxRcnt2Wmode(value); return; psxRcnt2Wmode(value); return;
case 0x1f801128: case IOP_T2_TARGET:
PSXCNT_LOG("COUNTER 2 TARGET 32bit write %lx", value); PSXCNT_LOG("COUNTER 2 TARGET 32bit write %lx", value);
psxRcntWtarget16(2, value); return; psxRcntWtarget16(2, value); return;
case 0x1f801480: case IOP_T3_COUNT:
PSXCNT_LOG("COUNTER 3 COUNT 32bit write %lx", value); PSXCNT_LOG("COUNTER 3 COUNT 32bit write %lx", value);
psxRcntWcount32(3, value); return; psxRcntWcount32(3, value); return;
case 0x1f801484: case IOP_T3_MODE:
PSXCNT_LOG("COUNTER 3 MODE 32bit write %lx", value); PSXCNT_LOG("COUNTER 3 MODE 32bit write %lx", value);
psxRcnt3Wmode(value); return; psxRcnt3Wmode(value); return;
case 0x1f801488: case IOP_T3_TARGET:
PSXCNT_LOG("COUNTER 3 TARGET 32bit write %lx", value); PSXCNT_LOG("COUNTER 3 TARGET 32bit write %lx", value);
psxRcntWtarget32(3, value); return; psxRcntWtarget32(3, value); return;
case 0x1f801490: case IOP_T4_COUNT:
PSXCNT_LOG("COUNTER 4 COUNT 32bit write %lx", value); PSXCNT_LOG("COUNTER 4 COUNT 32bit write %lx", value);
psxRcntWcount32(4, value); return; psxRcntWcount32(4, value); return;
case 0x1f801494: case IOP_T4_MODE:
PSXCNT_LOG("COUNTER 4 MODE 32bit write %lx", value); PSXCNT_LOG("COUNTER 4 MODE 32bit write %lx", value);
psxRcnt4Wmode(value); return; psxRcnt4Wmode(value); return;
case 0x1f801498: case IOP_T4_TARGET:
PSXCNT_LOG("COUNTER 4 TARGET 32bit write %lx", value); PSXCNT_LOG("COUNTER 4 TARGET 32bit write %lx", value);
psxRcntWtarget32(4, value); return; psxRcntWtarget32(4, value); return;
case 0x1f8014a0: case IOP_T5_COUNT:
PSXCNT_LOG("COUNTER 5 COUNT 32bit write %lx", value); PSXCNT_LOG("COUNTER 5 COUNT 32bit write %lx", value);
psxRcntWcount32(5, value); return; psxRcntWcount32(5, value); return;
case 0x1f8014a4: case IOP_T5_MODE:
PSXCNT_LOG("COUNTER 5 MODE 32bit write %lx", value); PSXCNT_LOG("COUNTER 5 MODE 32bit write %lx", value);
psxRcnt5Wmode(value); return; psxRcnt5Wmode(value); return;
case 0x1f8014a8: case IOP_T5_TARGET:
PSXCNT_LOG("COUNTER 5 TARGET 32bit write %lx", value); PSXCNT_LOG("COUNTER 5 TARGET 32bit write %lx", value);
psxRcntWtarget32(5, value); return; psxRcntWtarget32(5, value); return;

View File

@ -22,6 +22,72 @@
#include "R3000A.h" #include "R3000A.h"
#include "IopMem.h" #include "IopMem.h"
#define HW_USB_START 0x1f801600
#define HW_USB_END 0x1f801700
#define HW_FW_START 0x1f808400
#define HW_FW_END 0x1f808550
#define HW_SPU2_START 0x1f801c00
#define HW_SPU2_END 0x1f801e00
/* Registers for the IOP Counters */
enum IOPCountRegs
{
IOP_T0_COUNT = 0x1f801100,
IOP_T1_COUNT = 0x1f801110,
IOP_T2_COUNT = 0x1f801120,
IOP_T3_COUNT = 0x1f801480,
IOP_T4_COUNT = 0x1f801490,
IOP_T5_COUNT = 0x1f8014a0,
IOP_T0_MODE = 0x1f801104,
IOP_T1_MODE = 0x1f801114,
IOP_T2_MODE = 0x1f801124,
IOP_T3_MODE = 0x1f801484,
IOP_T4_MODE = 0x1f801494,
IOP_T5_MODE = 0x1f8014a4,
IOP_T0_TARGET= 0x1f801108,
IOP_T1_TARGET = 0x1f801118,
IOP_T2_TARGET = 0x1f801128,
IOP_T3_TARGET = 0x1f801488,
IOP_T4_TARGET = 0x1f801498,
IOP_T5_TARGET = 0x1f8014a8
};
// fixme: I'm sure there's a better way to do this. --arcum42
#define DmaExec(n) { \
if (HW_DMA##n##_CHCR & 0x01000000 && \
HW_DMA_PCR & (8 << (n * 4))) { \
psxDma##n(HW_DMA##n##_MADR, HW_DMA##n##_BCR, HW_DMA##n##_CHCR); \
} \
}
#define DmaExec2(n) { \
if (HW_DMA##n##_CHCR & 0x01000000 && \
HW_DMA_PCR2 & (8 << ((n-7) * 4))) { \
psxDma##n(HW_DMA##n##_MADR, HW_DMA##n##_BCR, HW_DMA##n##_CHCR); \
} \
}
#ifdef ENABLE_NEW_IOPDMA
#define DmaExecNew(n) { \
if (HW_DMA##n##_CHCR & 0x01000000 && \
HW_DMA_PCR & (8 << (n * 4))) { \
IopDmaStart(n, HW_DMA##n##_CHCR, HW_DMA##n##_MADR, HW_DMA##n##_BCR); \
} \
}
#define DmaExecNew2(n) { \
if (HW_DMA##n##_CHCR & 0x01000000 && \
HW_DMA_PCR2 & (8 << ((n-7) * 4))) { \
IopDmaStart(n, HW_DMA##n##_CHCR, HW_DMA##n##_MADR, HW_DMA##n##_BCR); \
} \
}
#else
#define DmaExecNew(n) DmaExec(n)
#define DmaExecNew2(n) DmaExec2(n)
#endif
#define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA #define HW_DMA0_MADR (psxHu32(0x1080)) // MDEC in DMA
#define HW_DMA0_BCR (psxHu32(0x1084)) #define HW_DMA0_BCR (psxHu32(0x1084))
#define HW_DMA0_CHCR (psxHu32(0x1088)) #define HW_DMA0_CHCR (psxHu32(0x1088))

View File

@ -53,59 +53,65 @@ void on_Game_Fix_OK(GtkButton *button, gpointer user_data)
gtk_main_quit(); gtk_main_quit();
} }
void on_vu_slider_changed(GtkRange *range, gpointer user_data)
{
int i;
i = gtk_range_get_value(range);
gtk_label_set_text(GTK_LABEL(lookup_widget(SpeedHacksDlg,"vu_cycle_stealing_label")),vu_stealing_labels[i]);
}
void on_ee_slider_changed(GtkRange *range, gpointer user_data)
{
int i;
i = gtk_range_get_value(range);
gtk_label_set_text(GTK_LABEL(lookup_widget(SpeedHacksDlg,"ee_cycle_label")),ee_cycle_labels[i]);
}
void on_Speed_Hacks(GtkMenuItem *menuitem, gpointer user_data) void on_Speed_Hacks(GtkMenuItem *menuitem, gpointer user_data)
{ {
SpeedHacksDlg = create_SpeedHacksDlg(); SpeedHacksDlg = create_SpeedHacksDlg();
GtkRange *vuScale = GTK_RANGE(lookup_widget(SpeedHacksDlg, "VUCycleHackScale"));
GtkRange *eeScale = GTK_RANGE(lookup_widget(SpeedHacksDlg, "EECycleHackScale"));
set_checked(SpeedHacksDlg, "check_iop_cycle_rate", Config.Hacks.IOPCycleDouble);
set_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack", Config.Hacks.WaitCycleExt);
set_checked(SpeedHacksDlg, "check_intc_sync_hack", Config.Hacks.INTCSTATSlow);
set_checked(SpeedHacksDlg, "check_idle_loop_fastforward", Config.Hacks.IdleLoopFF);
switch (CHECK_EE_CYCLERATE) gtk_range_set_value(vuScale, Config.Hacks.VUCycleSteal);
{ on_vu_slider_changed(vuScale, NULL);
case 0: gtk_range_set_value(eeScale, Config.Hacks.EECycleRate);
set_checked(SpeedHacksDlg, "check_default_cycle_rate", true); on_ee_slider_changed(eeScale, NULL);
break;
case 1:
set_checked(SpeedHacksDlg, "check_1_5_cycle_rate", true);
break;
case 2:
set_checked(SpeedHacksDlg, "check_2_cycle_rate", true);
break;
case 3:
set_checked(SpeedHacksDlg, "check_3_cycle_rate", true);
break;
default:
set_checked(SpeedHacksDlg, "check_default_cycle_rate", true);
break;
}
set_checked(SpeedHacksDlg, "check_iop_cycle_rate", CHECK_IOP_CYCLERATE);
set_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack", CHECK_WAITCYCLE_HACK);
set_checked(SpeedHacksDlg, "check_intc_sync_hack", CHECK_INTC_STAT_HACK);
set_checked(SpeedHacksDlg, "check_ESC_hack", CHECK_ESCAPE_HACK);
gtk_widget_show_all(SpeedHacksDlg); gtk_widget_show_all(SpeedHacksDlg);
gtk_widget_set_sensitive(MainWindow, FALSE); gtk_widget_set_sensitive(MainWindow, FALSE);
gtk_main(); gtk_main();
} }
void on_Speed_Hack_OK(GtkButton *button, gpointer user_data) void on_Speed_Hack_OK(GtkButton *button, gpointer user_data)
{ {
Config.Hacks = 0; PcsxConfig::Hacks_t newhacks;
newhacks.EECycleRate = 0;
if is_checked(SpeedHacksDlg, "check_default_cycle_rate")
Config.Hacks = 0; newhacks.IOPCycleDouble = is_checked(SpeedHacksDlg, "check_iop_cycle_rate");
else if is_checked(SpeedHacksDlg, "check_1_5_cycle_rate") newhacks.WaitCycleExt = is_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack");
Config.Hacks = 1; newhacks.INTCSTATSlow = is_checked(SpeedHacksDlg, "check_intc_sync_hack");
else if is_checked(SpeedHacksDlg, "check_2_cycle_rate") newhacks.IdleLoopFF = is_checked(SpeedHacksDlg, "check_idle_loop_fastforward");
Config.Hacks = 2;
else if is_checked(SpeedHacksDlg, "check_3_cycle_rate") newhacks.VUCycleSteal = gtk_range_get_value(GTK_RANGE(lookup_widget(SpeedHacksDlg, "VUCycleHackScale")));
Config.Hacks = 3; newhacks.EECycleRate = gtk_range_get_value(GTK_RANGE(lookup_widget(SpeedHacksDlg, "EECycleHackScale")));
Config.Hacks |= is_checked(SpeedHacksDlg, "check_iop_cycle_rate") << 3; if (memcmp(&newhacks, &Config.Hacks, sizeof(newhacks)))
Config.Hacks |= is_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack") << 4; {
Config.Hacks |= is_checked(SpeedHacksDlg, "check_intc_sync_hack") << 5; SysRestorableReset();
Config.Hacks |= is_checked(SpeedHacksDlg, "check_ESC_hack") << 10; Config.Hacks = newhacks;
SaveConfig();
SaveConfig(); }
gtk_widget_destroy(SpeedHacksDlg); gtk_widget_destroy(SpeedHacksDlg);
gtk_widget_set_sensitive(MainWindow, TRUE); gtk_widget_set_sensitive(MainWindow, TRUE);
gtk_main_quit(); gtk_main_quit();

View File

@ -101,6 +101,21 @@ char iop_log_names[9][32] =
"GPU Log" "GPU Log"
}; };
char vu_stealing_labels[5][256] =
{
"0: No speedup.",
"1: Slight speedup, should work with most games.",
"2: Moderate speedup, should work with most games with minor problems.",
"3: Large speedup, may break many games and make others skip frames.",
"4: Very large speedup, will break games in interesting ways."
};
char ee_cycle_labels[3][256] =
{
"Default Cycle Rate: Most compatible option - recommended for everyone with high-end machines.",
"x1.5 Cycle Rate: Moderate speedup, and works well with most games.",
"x2 Cycle Rate: Big speedup! Works well with many games."
};
//Tri-Ace - IDC_GAMEFIX2 //Tri-Ace - IDC_GAMEFIX2
#define FLAG_VU_ADD_SUB 0x1 #define FLAG_VU_ADD_SUB 0x1
// Persona3/4 - IDC_GAMEFIX4 // Persona3/4 - IDC_GAMEFIX4

View File

@ -39,18 +39,3 @@ u64 GetCPUTicks()
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
return ((u64)t.tv_sec*GetTickFrequency())+t.tv_usec; return ((u64)t.tv_sec*GetTickFrequency())+t.tv_usec;
} }
void cdvdSetSystemTime( cdvdStruct& cdvd )
{
time_t traw;
struct tm* ptlocal;
time(&traw);
ptlocal = localtime(&traw);
cdvd.RTC.second = ptlocal->tm_sec;
cdvd.RTC.minute = ptlocal->tm_min;
cdvd.RTC.hour = ptlocal->tm_hour;
cdvd.RTC.day = ptlocal->tm_mday;
cdvd.RTC.month = ptlocal->tm_mon;
cdvd.RTC.year = ptlocal->tm_year;
}

View File

@ -100,7 +100,19 @@ int LoadConfig()
GetValuel("varLog", varLog); GetValuel("varLog", varLog);
#endif #endif
GetValuel("Options", Config.Options); GetValuel("Options", Config.Options);
GetValuel("Hacks", Config.Hacks);
GetValuel("EECycleRate", Config.Hacks.EECycleRate);
if (Config.Hacks.EECycleRate > 2)
Config.Hacks.EECycleRate = 2;
GetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
GetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt);
GetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
GetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal);
GetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF);
GetValuel("ESCExits", Config.Hacks.ESCExits);
if (Config.Hacks.VUCycleSteal < 0 || Config.Hacks.VUCycleSteal > 4)
Config.Hacks.VUCycleSteal = 0;
GetValuel("Fixes", Config.GameFixes); GetValuel("Fixes", Config.GameFixes);
GetValuel("CustomFps", Config.CustomFps); GetValuel("CustomFps", Config.CustomFps);
@ -162,7 +174,14 @@ void SaveConfig()
SetValuel("Options", Config.Options); SetValuel("Options", Config.Options);
SetValuel("Hacks", Config.Hacks); SetValuel("EECycleRate", Config.Hacks.EECycleRate);
SetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
SetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt);
SetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
SetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal);
SetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF);
SetValuel("ESCExits", Config.Hacks.ESCExits);
SetValuel("Fixes", Config.GameFixes); SetValuel("Fixes", Config.GameFixes);
SetValuel("Patch", Config.Patch); SetValuel("Patch", Config.Patch);

View File

@ -13,6 +13,14 @@ void
On_Dialog_Cancelled (GtkButton *button, On_Dialog_Cancelled (GtkButton *button,
gpointer user_data); gpointer user_data);
void
on_ee_slider_changed (GtkRange *range,
gpointer user_data);
void
on_vu_slider_changed (GtkRange *range,
gpointer user_data);
void void
on_Speed_Hack_OK (GtkButton *button, on_Speed_Hack_OK (GtkButton *button,
gpointer user_data); gpointer user_data);

View File

@ -615,21 +615,21 @@ create_SpeedHacksDlg (void)
GtkWidget *vbox59; GtkWidget *vbox59;
GtkWidget *label88; GtkWidget *label88;
GtkWidget *hbox39; GtkWidget *hbox39;
GtkWidget *vbox72;
GtkWidget *frame37; GtkWidget *frame37;
GtkWidget *alignment32; GtkWidget *alignment32;
GtkWidget *vbox61; GtkWidget *vbox61;
GtkWidget *check_default_cycle_rate; GtkWidget *EECycleHackScale;
GSList *check_default_cycle_rate_group = NULL; GtkWidget *ee_cycle_label;
GtkWidget *label98; GtkWidget *hseparator2;
GtkWidget *check_1_5_cycle_rate;
GtkWidget *label93;
GtkWidget *check_2_cycle_rate;
GtkWidget *label94;
GtkWidget *check_3_cycle_rate;
GtkWidget *label95;
GtkWidget *hseparator1;
GtkWidget *label91; GtkWidget *label91;
GtkWidget *label105; GtkWidget *label105;
GtkWidget *frame39;
GtkWidget *alignment34;
GtkWidget *vbox73;
GtkWidget *VUCycleHackScale;
GtkWidget *vu_cycle_stealing_label;
GtkWidget *label111;
GtkWidget *vbox60; GtkWidget *vbox60;
GtkWidget *check_iop_cycle_rate; GtkWidget *check_iop_cycle_rate;
GtkWidget *label96; GtkWidget *label96;
@ -637,10 +637,10 @@ create_SpeedHacksDlg (void)
GtkWidget *label97; GtkWidget *label97;
GtkWidget *check_intc_sync_hack; GtkWidget *check_intc_sync_hack;
GtkWidget *label101; GtkWidget *label101;
GtkWidget *frame36; GtkWidget *vbox71;
GtkWidget *alignment31; GtkWidget *check_idle_loop_fastforward;
GtkWidget *check_ESC_hack; GtkWidget *label110;
GtkWidget *label89; GtkWidget *hseparator1;
GtkWidget *dialog_action_area3; GtkWidget *dialog_action_area3;
GtkWidget *button99; GtkWidget *button99;
GtkWidget *button98; GtkWidget *button98;
@ -669,10 +669,15 @@ create_SpeedHacksDlg (void)
gtk_widget_show (hbox39); gtk_widget_show (hbox39);
gtk_box_pack_start (GTK_BOX (vbox59), hbox39, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox59), hbox39, TRUE, TRUE, 0);
vbox72 = gtk_vbox_new (FALSE, 0);
gtk_widget_set_name (vbox72, "vbox72");
gtk_widget_show (vbox72);
gtk_box_pack_start (GTK_BOX (hbox39), vbox72, TRUE, TRUE, 0);
frame37 = gtk_frame_new (NULL); frame37 = gtk_frame_new (NULL);
gtk_widget_set_name (frame37, "frame37"); gtk_widget_set_name (frame37, "frame37");
gtk_widget_show (frame37); gtk_widget_show (frame37);
gtk_box_pack_start (GTK_BOX (hbox39), frame37, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox72), frame37, TRUE, TRUE, 0);
alignment32 = gtk_alignment_new (0.5, 0.5, 1, 1); alignment32 = gtk_alignment_new (0.5, 0.5, 1, 1);
gtk_widget_set_name (alignment32, "alignment32"); gtk_widget_set_name (alignment32, "alignment32");
@ -685,68 +690,25 @@ create_SpeedHacksDlg (void)
gtk_widget_show (vbox61); gtk_widget_show (vbox61);
gtk_container_add (GTK_CONTAINER (alignment32), vbox61); gtk_container_add (GTK_CONTAINER (alignment32), vbox61);
check_default_cycle_rate = gtk_radio_button_new_with_mnemonic (NULL, _("Default Cycle Rate")); EECycleHackScale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 2, 1, 0, 0)));
gtk_widget_set_name (check_default_cycle_rate, "check_default_cycle_rate"); gtk_widget_set_name (EECycleHackScale, "EECycleHackScale");
gtk_widget_show (check_default_cycle_rate); gtk_widget_show (EECycleHackScale);
gtk_box_pack_start (GTK_BOX (vbox61), check_default_cycle_rate, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox61), EECycleHackScale, FALSE, FALSE, 0);
gtk_radio_button_set_group (GTK_RADIO_BUTTON (check_default_cycle_rate), check_default_cycle_rate_group); gtk_scale_set_draw_value (GTK_SCALE (EECycleHackScale), FALSE);
check_default_cycle_rate_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (check_default_cycle_rate)); gtk_scale_set_digits (GTK_SCALE (EECycleHackScale), 0);
label98 = gtk_label_new (_("Most compatible option - recommended for everyone with high-end machines.")); ee_cycle_label = gtk_label_new (_("Most compatible option - recommended for everyone with high-end machines."));
gtk_widget_set_name (label98, "label98"); gtk_widget_set_name (ee_cycle_label, "ee_cycle_label");
gtk_widget_show (label98); gtk_widget_show (ee_cycle_label);
gtk_box_pack_start (GTK_BOX (vbox61), label98, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox61), ee_cycle_label, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label98), TRUE); gtk_label_set_line_wrap (GTK_LABEL (ee_cycle_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (label98), 0.29, 0.5);
check_1_5_cycle_rate = gtk_radio_button_new_with_mnemonic (NULL, _("Use x1.5 Cycle Rate")); hseparator2 = gtk_hseparator_new ();
gtk_widget_set_name (check_1_5_cycle_rate, "check_1_5_cycle_rate"); gtk_widget_set_name (hseparator2, "hseparator2");
gtk_widget_show (check_1_5_cycle_rate); gtk_widget_show (hseparator2);
gtk_box_pack_start (GTK_BOX (vbox61), check_1_5_cycle_rate, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox61), hseparator2, FALSE, FALSE, 0);
gtk_radio_button_set_group (GTK_RADIO_BUTTON (check_1_5_cycle_rate), check_default_cycle_rate_group);
check_default_cycle_rate_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (check_1_5_cycle_rate));
label93 = gtk_label_new (_("Moderate speedup, and works well with most games.")); label91 = gtk_label_new (_("Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies."));
gtk_widget_set_name (label93, "label93");
gtk_widget_show (label93);
gtk_box_pack_start (GTK_BOX (vbox61), label93, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label93), TRUE);
gtk_misc_set_alignment (GTK_MISC (label93), 0.29, 0.5);
check_2_cycle_rate = gtk_radio_button_new_with_mnemonic (NULL, _("Use x2 Cycle Rate"));
gtk_widget_set_name (check_2_cycle_rate, "check_2_cycle_rate");
gtk_widget_show (check_2_cycle_rate);
gtk_box_pack_start (GTK_BOX (vbox61), check_2_cycle_rate, FALSE, FALSE, 0);
gtk_radio_button_set_group (GTK_RADIO_BUTTON (check_2_cycle_rate), check_default_cycle_rate_group);
check_default_cycle_rate_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (check_2_cycle_rate));
label94 = gtk_label_new (_("Big speedup! Works well with many games."));
gtk_widget_set_name (label94, "label94");
gtk_widget_show (label94);
gtk_box_pack_start (GTK_BOX (vbox61), label94, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label94), TRUE);
gtk_misc_set_alignment (GTK_MISC (label94), 0.36, 0.5);
check_3_cycle_rate = gtk_radio_button_new_with_mnemonic (NULL, _("Use x3 Cycle Rate"));
gtk_widget_set_name (check_3_cycle_rate, "check_3_cycle_rate");
gtk_widget_show (check_3_cycle_rate);
gtk_box_pack_start (GTK_BOX (vbox61), check_3_cycle_rate, FALSE, FALSE, 0);
gtk_radio_button_set_group (GTK_RADIO_BUTTON (check_3_cycle_rate), check_default_cycle_rate_group);
check_default_cycle_rate_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (check_3_cycle_rate));
label95 = gtk_label_new (_("Big speedup, but causes flickering or missing geometry on many games."));
gtk_widget_set_name (label95, "label95");
gtk_widget_show (label95);
gtk_box_pack_start (GTK_BOX (vbox61), label95, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label95), TRUE);
gtk_misc_set_alignment (GTK_MISC (label95), 0.24, 0.5);
hseparator1 = gtk_hseparator_new ();
gtk_widget_set_name (hseparator1, "hseparator1");
gtk_widget_show (hseparator1);
gtk_box_pack_start (GTK_BOX (vbox61), hseparator1, FALSE, FALSE, 0);
label91 = gtk_label_new (_("Important: X2 & X3 sync hacks *will* cause choppy/skippy audio on many FMV movies.\nKnown to work well with a couple games, namely Shadow of the Colossus (but breaks most other games)."));
gtk_widget_set_name (label91, "label91"); gtk_widget_set_name (label91, "label91");
gtk_widget_show (label91); gtk_widget_show (label91);
gtk_box_pack_start (GTK_BOX (vbox61), label91, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox61), label91, FALSE, FALSE, 0);
@ -758,6 +720,41 @@ create_SpeedHacksDlg (void)
gtk_frame_set_label_widget (GTK_FRAME (frame37), label105); gtk_frame_set_label_widget (GTK_FRAME (frame37), label105);
gtk_label_set_use_markup (GTK_LABEL (label105), TRUE); gtk_label_set_use_markup (GTK_LABEL (label105), TRUE);
frame39 = gtk_frame_new (NULL);
gtk_widget_set_name (frame39, "frame39");
gtk_widget_show (frame39);
gtk_box_pack_start (GTK_BOX (vbox72), frame39, TRUE, TRUE, 0);
alignment34 = gtk_alignment_new (0.5, 0.5, 1, 1);
gtk_widget_set_name (alignment34, "alignment34");
gtk_widget_show (alignment34);
gtk_container_add (GTK_CONTAINER (frame39), alignment34);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment34), 0, 0, 12, 0);
vbox73 = gtk_vbox_new (FALSE, 0);
gtk_widget_set_name (vbox73, "vbox73");
gtk_widget_show (vbox73);
gtk_container_add (GTK_CONTAINER (alignment34), vbox73);
VUCycleHackScale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 4, 1, 0, 0)));
gtk_widget_set_name (VUCycleHackScale, "VUCycleHackScale");
gtk_widget_show (VUCycleHackScale);
gtk_box_pack_start (GTK_BOX (vbox73), VUCycleHackScale, TRUE, TRUE, 0);
gtk_scale_set_draw_value (GTK_SCALE (VUCycleHackScale), FALSE);
gtk_scale_set_digits (GTK_SCALE (VUCycleHackScale), 0);
vu_cycle_stealing_label = gtk_label_new (_("2: Moderate speedup, should work with most games with minor problems."));
gtk_widget_set_name (vu_cycle_stealing_label, "vu_cycle_stealing_label");
gtk_widget_show (vu_cycle_stealing_label);
gtk_box_pack_start (GTK_BOX (vbox73), vu_cycle_stealing_label, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (vu_cycle_stealing_label), TRUE);
label111 = gtk_label_new (_("<b>VU Cycle Stealing (Speedup for 3d geometry)</b>"));
gtk_widget_set_name (label111, "label111");
gtk_widget_show (label111);
gtk_frame_set_label_widget (GTK_FRAME (frame39), label111);
gtk_label_set_use_markup (GTK_LABEL (label111), TRUE);
vbox60 = gtk_vbox_new (FALSE, 0); vbox60 = gtk_vbox_new (FALSE, 0);
gtk_widget_set_name (vbox60, "vbox60"); gtk_widget_set_name (vbox60, "vbox60");
gtk_widget_show (vbox60); gtk_widget_show (vbox60);
@ -785,7 +782,7 @@ create_SpeedHacksDlg (void)
gtk_box_pack_start (GTK_BOX (vbox60), label97, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox60), label97, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label97), TRUE); gtk_label_set_line_wrap (GTK_LABEL (label97), TRUE);
check_intc_sync_hack = gtk_check_button_new_with_mnemonic (_("INTC Sync Hack (experimental)")); check_intc_sync_hack = gtk_check_button_new_with_mnemonic (_("INTC Sync Hack"));
gtk_widget_set_name (check_intc_sync_hack, "check_intc_sync_hack"); gtk_widget_set_name (check_intc_sync_hack, "check_intc_sync_hack");
gtk_widget_show (check_intc_sync_hack); gtk_widget_show (check_intc_sync_hack);
gtk_box_pack_start (GTK_BOX (vbox60), check_intc_sync_hack, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox60), check_intc_sync_hack, FALSE, FALSE, 0);
@ -796,27 +793,26 @@ create_SpeedHacksDlg (void)
gtk_box_pack_start (GTK_BOX (vbox60), label101, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox60), label101, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label101), TRUE); gtk_label_set_line_wrap (GTK_LABEL (label101), TRUE);
frame36 = gtk_frame_new (NULL); vbox71 = gtk_vbox_new (FALSE, 0);
gtk_widget_set_name (frame36, "frame36"); gtk_widget_set_name (vbox71, "vbox71");
gtk_widget_show (frame36); gtk_widget_show (vbox71);
gtk_box_pack_start (GTK_BOX (vbox59), frame36, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (vbox60), vbox71, TRUE, TRUE, 0);
alignment31 = gtk_alignment_new (0.5, 0.5, 1, 1); check_idle_loop_fastforward = gtk_check_button_new_with_mnemonic (_("Idle Loop Fast-Forward (experimental)"));
gtk_widget_set_name (alignment31, "alignment31"); gtk_widget_set_name (check_idle_loop_fastforward, "check_idle_loop_fastforward");
gtk_widget_show (alignment31); gtk_widget_show (check_idle_loop_fastforward);
gtk_container_add (GTK_CONTAINER (frame36), alignment31); gtk_box_pack_start (GTK_BOX (vbox71), check_idle_loop_fastforward, FALSE, FALSE, 0);
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment31), 0, 0, 12, 0);
check_ESC_hack = gtk_check_button_new_with_mnemonic (_("Escape Hack - Use Esc key to fully exit PCSX2.")); label110 = gtk_label_new (_("Speedup for a few games, including FFX with no known side effects. More later."));
gtk_widget_set_name (check_ESC_hack, "check_ESC_hack"); gtk_widget_set_name (label110, "label110");
gtk_widget_show (check_ESC_hack); gtk_widget_show (label110);
gtk_container_add (GTK_CONTAINER (alignment31), check_ESC_hack); gtk_box_pack_start (GTK_BOX (vbox71), label110, FALSE, FALSE, 0);
gtk_label_set_line_wrap (GTK_LABEL (label110), TRUE);
label89 = gtk_label_new (_("<b>Miscellaneous</b>")); hseparator1 = gtk_hseparator_new ();
gtk_widget_set_name (label89, "label89"); gtk_widget_set_name (hseparator1, "hseparator1");
gtk_widget_show (label89); gtk_widget_show (hseparator1);
gtk_frame_set_label_widget (GTK_FRAME (frame36), label89); gtk_box_pack_start (GTK_BOX (vbox60), hseparator1, FALSE, FALSE, 0);
gtk_label_set_use_markup (GTK_LABEL (label89), TRUE);
dialog_action_area3 = GTK_DIALOG (SpeedHacksDlg)->action_area; dialog_action_area3 = GTK_DIALOG (SpeedHacksDlg)->action_area;
gtk_widget_set_name (dialog_action_area3, "dialog_action_area3"); gtk_widget_set_name (dialog_action_area3, "dialog_action_area3");
@ -835,6 +831,12 @@ create_SpeedHacksDlg (void)
gtk_dialog_add_action_widget (GTK_DIALOG (SpeedHacksDlg), button98, GTK_RESPONSE_CANCEL); gtk_dialog_add_action_widget (GTK_DIALOG (SpeedHacksDlg), button98, GTK_RESPONSE_CANCEL);
GTK_WIDGET_SET_FLAGS (button98, GTK_CAN_DEFAULT); GTK_WIDGET_SET_FLAGS (button98, GTK_CAN_DEFAULT);
g_signal_connect ((gpointer) EECycleHackScale, "value_changed",
G_CALLBACK (on_ee_slider_changed),
NULL);
g_signal_connect ((gpointer) VUCycleHackScale, "value_changed",
G_CALLBACK (on_vu_slider_changed),
NULL);
g_signal_connect ((gpointer) button99, "clicked", g_signal_connect ((gpointer) button99, "clicked",
G_CALLBACK (on_Speed_Hack_OK), G_CALLBACK (on_Speed_Hack_OK),
NULL); NULL);
@ -848,20 +850,21 @@ create_SpeedHacksDlg (void)
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox59, "vbox59"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox59, "vbox59");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label88, "label88"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label88, "label88");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hbox39, "hbox39"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hbox39, "hbox39");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox72, "vbox72");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame37, "frame37"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame37, "frame37");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment32, "alignment32"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment32, "alignment32");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox61, "vbox61"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox61, "vbox61");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_default_cycle_rate, "check_default_cycle_rate"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, EECycleHackScale, "EECycleHackScale");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label98, "label98"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, ee_cycle_label, "ee_cycle_label");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_1_5_cycle_rate, "check_1_5_cycle_rate"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hseparator2, "hseparator2");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label93, "label93");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_2_cycle_rate, "check_2_cycle_rate");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label94, "label94");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_3_cycle_rate, "check_3_cycle_rate");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label95, "label95");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hseparator1, "hseparator1");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label91, "label91"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label91, "label91");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label105, "label105"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label105, "label105");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame39, "frame39");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment34, "alignment34");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox73, "vbox73");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, VUCycleHackScale, "VUCycleHackScale");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vu_cycle_stealing_label, "vu_cycle_stealing_label");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label111, "label111");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox60, "vbox60"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox60, "vbox60");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_iop_cycle_rate, "check_iop_cycle_rate"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_iop_cycle_rate, "check_iop_cycle_rate");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label96, "label96"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label96, "label96");
@ -869,10 +872,10 @@ create_SpeedHacksDlg (void)
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label97, "label97"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label97, "label97");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_intc_sync_hack, "check_intc_sync_hack"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_intc_sync_hack, "check_intc_sync_hack");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label101, "label101"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label101, "label101");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame36, "frame36"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox71, "vbox71");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment31, "alignment31"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_idle_loop_fastforward, "check_idle_loop_fastforward");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_ESC_hack, "check_ESC_hack"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label110, "label110");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label89, "label89"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hseparator1, "hseparator1");
GLADE_HOOKUP_OBJECT_NO_REF (SpeedHacksDlg, dialog_action_area3, "dialog_action_area3"); GLADE_HOOKUP_OBJECT_NO_REF (SpeedHacksDlg, dialog_action_area3, "dialog_action_area3");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button99, "button99"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button99, "button99");
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button98, "button98"); GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button98, "button98");

View File

@ -1275,270 +1275,250 @@ If you have problems, Disable all of these and try again.</property>
<property name="spacing">0</property> <property name="spacing">0</property>
<child> <child>
<widget class="GtkFrame" id="frame37"> <widget class="GtkVBox" id="vbox72">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label_xalign">0</property> <property name="homogeneous">False</property>
<property name="label_yalign">0.5</property> <property name="spacing">0</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child> <child>
<widget class="GtkAlignment" id="alignment32"> <widget class="GtkFrame" id="frame37">
<property name="visible">True</property> <property name="visible">True</property>
<property name="xalign">0.5</property> <property name="label_xalign">0</property>
<property name="yalign">0.5</property> <property name="label_yalign">0.5</property>
<property name="xscale">1</property> <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child> <child>
<widget class="GtkVBox" id="vbox61"> <widget class="GtkAlignment" id="alignment32">
<property name="visible">True</property> <property name="visible">True</property>
<property name="homogeneous">False</property> <property name="xalign">0.5</property>
<property name="spacing">2</property> <property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child> <child>
<widget class="GtkRadioButton" id="check_default_cycle_rate"> <widget class="GtkVBox" id="vbox61">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="homogeneous">False</property>
<property name="label" translatable="yes">Default Cycle Rate</property> <property name="spacing">2</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="label98"> <widget class="GtkHScale" id="EECycleHackScale">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">Most compatible option - recommended for everyone with high-end machines.</property> <property name="can_focus">True</property>
<property name="use_underline">False</property> <property name="draw_value">False</property>
<property name="use_markup">False</property> <property name="value_pos">GTK_POS_TOP</property>
<property name="justify">GTK_JUSTIFY_LEFT</property> <property name="digits">0</property>
<property name="wrap">True</property> <property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
<property name="selectable">False</property> <property name="inverted">False</property>
<property name="xalign">0.289999991655</property> <property name="adjustment">0 0 2 1 0 0</property>
<property name="yalign">0.5</property> <signal name="value_changed" handler="on_ee_slider_changed" last_modification_time="Wed, 22 Apr 2009 03:03:42 GMT"/>
<property name="xpad">0</property> </widget>
<property name="ypad">0</property> <packing>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="padding">0</property>
<property name="width_chars">-1</property> <property name="expand">False</property>
<property name="single_line_mode">False</property> <property name="fill">False</property>
<property name="angle">0</property> </packing>
</widget> </child>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child> <child>
<widget class="GtkRadioButton" id="check_1_5_cycle_rate"> <widget class="GtkLabel" id="ee_cycle_label">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="label" translatable="yes">Most compatible option - recommended for everyone with high-end machines.</property>
<property name="label" translatable="yes">Use x1.5 Cycle Rate</property> <property name="use_underline">False</property>
<property name="use_underline">True</property> <property name="use_markup">False</property>
<property name="relief">GTK_RELIEF_NORMAL</property> <property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="focus_on_click">True</property> <property name="wrap">True</property>
<property name="active">False</property> <property name="selectable">False</property>
<property name="inconsistent">False</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="yalign">0.5</property>
<property name="group">check_default_cycle_rate</property> <property name="xpad">0</property>
</widget> <property name="ypad">0</property>
<packing> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="padding">0</property> <property name="width_chars">-1</property>
<property name="expand">False</property> <property name="single_line_mode">False</property>
<property name="fill">False</property> <property name="angle">0</property>
</packing> </widget>
</child> <packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child> <child>
<widget class="GtkLabel" id="label93"> <widget class="GtkHSeparator" id="hseparator2">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">Moderate speedup, and works well with most games.</property> </widget>
<property name="use_underline">False</property> <packing>
<property name="use_markup">False</property> <property name="padding">0</property>
<property name="justify">GTK_JUSTIFY_LEFT</property> <property name="expand">False</property>
<property name="wrap">True</property> <property name="fill">False</property>
<property name="selectable">False</property> </packing>
<property name="xalign">0.289999991655</property> </child>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child> <child>
<widget class="GtkRadioButton" id="check_2_cycle_rate"> <widget class="GtkLabel" id="label91">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="label" translatable="yes">Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies.</property>
<property name="label" translatable="yes">Use x2 Cycle Rate</property> <property name="use_underline">False</property>
<property name="use_underline">True</property> <property name="use_markup">False</property>
<property name="relief">GTK_RELIEF_NORMAL</property> <property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="focus_on_click">True</property> <property name="wrap">True</property>
<property name="active">False</property> <property name="selectable">False</property>
<property name="inconsistent">False</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="yalign">0.5</property>
<property name="group">check_default_cycle_rate</property> <property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget> </widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label94">
<property name="visible">True</property>
<property name="label" translatable="yes">Big speedup! Works well with many games.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.360000014305</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkRadioButton" id="check_3_cycle_rate">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Use x3 Cycle Rate</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
<property name="group">check_default_cycle_rate</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label95">
<property name="visible">True</property>
<property name="label" translatable="yes">Big speedup, but causes flickering or missing geometry on many games.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.239999994636</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator1">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label91">
<property name="visible">True</property>
<property name="label" translatable="yes">Important: X2 &amp; X3 sync hacks *will* cause choppy/skippy audio on many FMV movies.
Known to work well with a couple games, namely Shadow of the Colossus (but breaks most other games).</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child> </child>
</widget> </widget>
</child> </child>
<child>
<widget class="GtkLabel" id="label105">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;EmotionEngine (EE) Sync Hacks&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget> </widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child> </child>
<child> <child>
<widget class="GtkLabel" id="label105"> <widget class="GtkFrame" id="frame39">
<property name="visible">True</property> <property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;EmotionEngine (EE) Sync Hacks&lt;/b&gt;</property> <property name="label_xalign">0</property>
<property name="use_underline">False</property> <property name="label_yalign">0.5</property>
<property name="use_markup">True</property> <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property> <child>
<property name="selectable">False</property> <widget class="GtkAlignment" id="alignment34">
<property name="xalign">0.5</property> <property name="visible">True</property>
<property name="yalign">0.5</property> <property name="xalign">0.5</property>
<property name="xpad">0</property> <property name="yalign">0.5</property>
<property name="ypad">0</property> <property name="xscale">1</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="yscale">1</property>
<property name="width_chars">-1</property> <property name="top_padding">0</property>
<property name="single_line_mode">False</property> <property name="bottom_padding">0</property>
<property name="angle">0</property> <property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkVBox" id="vbox73">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkHScale" id="VUCycleHackScale">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="draw_value">False</property>
<property name="value_pos">GTK_POS_TOP</property>
<property name="digits">0</property>
<property name="update_policy">GTK_UPDATE_CONTINUOUS</property>
<property name="inverted">False</property>
<property name="adjustment">0 0 4 1 0 0</property>
<signal name="value_changed" handler="on_vu_slider_changed" last_modification_time="Wed, 22 Apr 2009 02:51:47 GMT"/>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="vu_cycle_stealing_label">
<property name="visible">True</property>
<property name="label" translatable="yes">2: Moderate speedup, should work with most games with minor problems.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label111">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;VU Cycle Stealing (Speedup for 3d geometry)&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="type">label_item</property> <property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing> </packing>
</child> </child>
</widget> </widget>
@ -1649,7 +1629,7 @@ Known to work well with a couple games, namely Shadow of the Colossus (but break
<widget class="GtkCheckButton" id="check_intc_sync_hack"> <widget class="GtkCheckButton" id="check_intc_sync_hack">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="label" translatable="yes">INTC Sync Hack (experimental)</property> <property name="label" translatable="yes">INTC Sync Hack</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property> <property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property> <property name="focus_on_click">True</property>
@ -1688,6 +1668,74 @@ Known to work well with a couple games, namely Shadow of the Colossus (but break
<property name="fill">False</property> <property name="fill">False</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkVBox" id="vbox71">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
<child>
<widget class="GtkCheckButton" id="check_idle_loop_fastforward">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Idle Loop Fast-Forward (experimental)</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label110">
<property name="visible">True</property>
<property name="label" translatable="yes">Speedup for a few games, including FFX with no known side effects. More later.</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkHSeparator" id="hseparator1">
<property name="visible">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>
@ -1702,71 +1750,6 @@ Known to work well with a couple games, namely Shadow of the Colossus (but break
<property name="fill">True</property> <property name="fill">True</property>
</packing> </packing>
</child> </child>
<child>
<widget class="GtkFrame" id="frame36">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<widget class="GtkAlignment" id="alignment31">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
<property name="left_padding">12</property>
<property name="right_padding">0</property>
<child>
<widget class="GtkCheckButton" id="check_ESC_hack">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Escape Hack - Use Esc key to fully exit PCSX2.</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkLabel" id="label89">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Miscellaneous&lt;/b&gt;</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget> </widget>
<packing> <packing>
<property name="padding">0</property> <property name="padding">0</property>

View File

@ -177,11 +177,15 @@ void PLZCW() {
_PLZCW (1); _PLZCW (1);
} }
#define PMFHL_CLAMP(dst, src) \ __forceinline void PMFHL_CLAMP(u16 dst, u16 src)
if ((int)src > (int)0x00007fff) dst = 0x7fff; \ {
else \ if ((int)src > (int)0x00007fff)
if ((int)src < (int)0xffff8000) dst = 0x8000; \ dst = 0x7fff;
else dst = (u16)src; else if ((int)src < (int)0xffff8000)
dst = 0x8000;
else
dst = (u16)src;
}
void PMFHL() { void PMFHL() {
if (!_Rd_) return; if (!_Rd_) return;

View File

@ -224,7 +224,7 @@ void mtgsThreadObject::Start()
m_post_InitDone.Wait(); m_post_InitDone.Wait();
if( m_returncode != 0 ) // means the thread failed to init the GS plugin if( m_returncode != 0 ) // means the thread failed to init the GS plugin
throw Exception::PluginFailure( "GS", "The GS plugin failed to open/initialize." ); throw Exception::PluginFailure( "GS", wxLt("%s plugin initialization failed.") ); // plugin returned an error after having been asked very nicely to initialize itself." );
} }
mtgsThreadObject::~mtgsThreadObject() mtgsThreadObject::~mtgsThreadObject()

View File

@ -11,7 +11,7 @@ R3000AInterpreter.cpp R3000AOpcodeTables.cpp R5900.cpp R5900OpcodeImpl.cpp R5900
SPR.cpp SaveState.cpp Sif.cpp Sio.cpp SourceLog.cpp Stats.cpp System.cpp ThreadTools.cpp \ SPR.cpp SaveState.cpp Sif.cpp Sio.cpp SourceLog.cpp Stats.cpp System.cpp ThreadTools.cpp \
VU0.cpp VU0micro.cpp VU0microInterp.cpp VU1micro.cpp VU1microInterp.cpp VUflags.cpp VUmicroMem.cpp VUops.cpp \ VU0.cpp VU0micro.cpp VU0microInterp.cpp VU1micro.cpp VU1microInterp.cpp VUflags.cpp VUmicroMem.cpp VUops.cpp \
Vif.cpp VifDma.cpp vssprintf.cpp vtlb.cpp xmlpatchloader.cpp AlignedMalloc.cpp \ Vif.cpp VifDma.cpp vssprintf.cpp vtlb.cpp xmlpatchloader.cpp AlignedMalloc.cpp \
RecoverySystem.cpp Saveslots.cpp RecoverySystem.cpp Saveslots.cpp Dump.cpp
@ -20,7 +20,8 @@ CDVD.h CDVDiso.h CDVDisodrv.h CDVDlib.h COP0.h Cache.h CdRom.h Common.h Counters
Elfheader.h Exceptions.h GS.h Hw.h IopBios.h IopBios2.h IopCounters.h IopDma.h IopHw.h IopMem.h IopSio2.h Memcpyfast.h \ Elfheader.h Exceptions.h GS.h Hw.h IopBios.h IopBios2.h IopCounters.h IopDma.h IopHw.h IopMem.h IopSio2.h Memcpyfast.h \
Memory.h MemoryCard.h Misc.h Patch.h Paths.h Plugins.h PrecompiledHeader.h IopCommon.h R3000A.h R5900.h R5900OpcodeTables.h \ Memory.h MemoryCard.h Misc.h Patch.h Paths.h Plugins.h PrecompiledHeader.h IopCommon.h R3000A.h R5900.h R5900OpcodeTables.h \
SPR.h SamplProf.h SaveState.h Sif.h Sifcmd.h Sio.h SafeArray.h Stats.h StringUtils.h System.h Threading.h \ SPR.h SamplProf.h SaveState.h Sif.h Sifcmd.h Sio.h SafeArray.h Stats.h StringUtils.h System.h Threading.h \
VU.h VUflags.h VUmicro.h VUops.h Vif.h VifDma.h cheatscpp.h vtlb.h NakedAsm.h R5900Exceptions.h HostGui.h Pcsx2Config.h VU.h VUflags.h VUmicro.h VUops.h Vif.h VifDma.h cheatscpp.h vtlb.h NakedAsm.h R5900Exceptions.h HostGui.h Pcsx2Config.h \
Dump.h
SUBDIRS = x86 . DebugTools IPU RDebug tinyxml NewGUI SUBDIRS = x86 . DebugTools IPU RDebug tinyxml NewGUI
#Linux #Linux

View File

@ -42,6 +42,7 @@ BIOS
#pragma warning(disable:4799) // No EMMS at end of function #pragma warning(disable:4799) // No EMMS at end of function
#include <vector> #include <vector>
#include <wx/file.h>
#include "IopCommon.h" #include "IopCommon.h"
#include "iR5900.h" #include "iR5900.h"
@ -85,26 +86,26 @@ u16 ba0R16(u32 mem)
// Attempts to load a BIOS rom file, by trying multiple combinations of base filename // Attempts to load a BIOS rom file, by trying multiple combinations of base filename
// and extension. The bios specified in Config.Bios is used as the base. // and extension. The bios specified in Config.Bios is used as the base.
void loadBiosRom( const char *ext, u8 *dest, long maxSize ) void loadBiosRom( const wxChar *ext, u8 *dest, long maxSize )
{ {
string Bios1; wxString Bios1;
long filesize; long filesize;
string Bios( Path::Combine( Config.BiosDir, Config.Bios ) );
// Try first a basic extension concatenation (normally results in something like name.bin.rom1) // Try first a basic extension concatenation (normally results in something like name.bin.rom1)
ssprintf(Bios1, "%hs.%s", &Bios, ext); const wxString Bios( g_Conf.Files.Bios() );
if( (filesize=Path::getFileSize( Bios1 ) ) <= 0 ) Bios1.Printf( wxS("%s.%s"), Bios.c_str(), ext);
if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
{ {
// Try the name properly extensioned next (name.rom1) // Try the name properly extensioned next (name.rom1)
Bios1 = Path::ReplaceExtension( Bios, ext ); Bios1 = Path::ReplaceExtension( Bios, ext );
if( (filesize=Path::getFileSize( Bios1 ) ) <= 0 ) if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
{ {
// Try for the old-style method (rom1.bin) // Try for the old-style method (rom1.bin)
Bios1 = Path::Combine( Config.BiosDir, ext ) + ".bin"; Bios1 = Path::Combine( g_Conf.Folders.Bios, (wxString)ext ) + wxT(".bin");
if( (filesize=Path::getFileSize( Bios1 ) ) <= 0 ) if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
{ {
Console::Notice( "Bios Warning > %s not found.", params ext ); Console::Notice( "Load Bios Warning: %s not found (this is not an error!)", params wxString(ext).ToAscii().data() );
return; return;
} }
} }
@ -112,9 +113,8 @@ void loadBiosRom( const char *ext, u8 *dest, long maxSize )
// if we made it this far, we have a successful file found: // if we made it this far, we have a successful file found:
FILE *fp = fopen(Bios1.c_str(), "rb"); wxFile fp( Bios1 );
fread(dest, 1, min( maxSize, filesize ), fp); fp.Read( dest, min( maxSize, filesize ) );
fclose(fp);
} }
static u32 psMPWC[(Ps2MemSize::Base/32)>>12]; static u32 psMPWC[(Ps2MemSize::Base/32)>>12];
@ -517,8 +517,8 @@ void __fastcall vuMicroRead128(u32 addr,mem128_t* data)
data[1]=*(u64*)&vu->Micro[addr+8]; data[1]=*(u64*)&vu->Micro[addr+8];
} }
// [TODO] : Profile this code and see how often the VUs get written, and how // Profiled VU writes: Happen very infrequently, with exception of BIOS initialization (at most twice per
// often it changes the values being written (invoking a cpuClear). // frame in-game, and usually none at all after BIOS), so cpu clears aren't much of a big deal.
template<int vunum, bool dynrec> template<int vunum, bool dynrec>
void __fastcall vuMicroWrite8(u32 addr,mem8_t data) void __fastcall vuMicroWrite8(u32 addr,mem8_t data)
@ -738,8 +738,8 @@ void memReset()
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic _ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic
); );
vtlbMemR32FP* page0F32( CHECK_INTC_STAT_HACK ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F ); vtlbMemR32FP* page0F32( Config.Hacks.INTCSTATSlow ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
vtlbMemR64FP* page0F64( CHECK_INTC_STAT_HACK ? hwRead64_generic_INTC_HACK : hwRead64_generic ); vtlbMemR64FP* page0F64( Config.Hacks.INTCSTATSlow ? hwRead64_generic_INTC_HACK : hwRead64_generic );
hw_by_page[0xf] = vtlb_RegisterHandler( hw_by_page[0xf] = vtlb_RegisterHandler(
_ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic, _ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic,
@ -780,29 +780,28 @@ void memReset()
vtlb_VMap(0x00000000,0x00000000,0x20000000); vtlb_VMap(0x00000000,0x00000000,0x20000000);
vtlb_VMapUnmap(0x20000000,0x60000000); vtlb_VMapUnmap(0x20000000,0x60000000);
FILE *fp; wxString Bios( g_Conf.Files.Bios() );
string Bios( Path::Combine( Config.BiosDir, Config.Bios ) );
long filesize; long filesize = Path::GetFileSize( Bios );
if( ( filesize = Path::getFileSize( Bios ) ) <= 0 ) if( filesize <= 0 )
{ {
//Console::Error("Unable to load bios: '%s', PCSX2 can't run without that", params Bios); wxFile fp( Bios.c_str() );
throw Exception::FileNotFound( Bios, fp.Read( PS2MEM_ROM, min( (long)Ps2MemSize::Rom, filesize ) );
"The specified Bios file was not found. A bios is required for Pcsx2 to run.\n\nFile not found" ); }
else
{
// Translated: Bios file not found or not specified ... A bios is required for Pcsx2 to run!
throw Exception::FileNotFound( Bios, wxLt("Bios not found") );
} }
fp = fopen(Bios.c_str(), "rb");
fread(PS2MEM_ROM, 1, min( (long)Ps2MemSize::Rom, filesize ), fp);
fclose(fp);
BiosVersion = GetBiosVersion(); BiosVersion = GetBiosVersion();
Console::Status("Bios Version %d.%d", params BiosVersion >> 8, BiosVersion & 0xff); Console::Status("Bios Version %d.%d", params BiosVersion >> 8, BiosVersion & 0xff);
//injectIRX("host.irx"); //not fully tested; still buggy //injectIRX("host.irx"); //not fully tested; still buggy
loadBiosRom("rom1", PS2MEM_ROM1, Ps2MemSize::Rom1); loadBiosRom( wxT("rom1"), PS2MEM_ROM1, Ps2MemSize::Rom1 );
loadBiosRom("rom2", PS2MEM_ROM2, Ps2MemSize::Rom2); loadBiosRom( wxT("rom2"), PS2MEM_ROM2, Ps2MemSize::Rom2 );
loadBiosRom("erom", PS2MEM_EROM, Ps2MemSize::ERom); loadBiosRom( wxT("erom"), PS2MEM_EROM, Ps2MemSize::ERom );
} }
int mmap_GetRamPageInfo(void* ptr) int mmap_GetRamPageInfo(void* ptr)
@ -820,6 +819,7 @@ void mmap_MarkCountedRamPage(void* ptr,u32 vaddr)
u32 offset=((u8*)ptr-psM); u32 offset=((u8*)ptr-psM);
offset>>=12; offset>>=12;
psMPWC[(offset/32)] &= ~(1<<(offset&31));
for (u32 i=0;i<psMPWVA[offset].size();i++) for (u32 i=0;i<psMPWVA[offset].size();i++)
{ {

View File

@ -23,6 +23,7 @@
#endif #endif
//#define ENABLECACHE //#define ENABLECACHE
#include "vtlb.h"
namespace Ps2MemSize namespace Ps2MemSize
{ {
@ -57,9 +58,40 @@ extern u8 *psS; //0.015 mb, scratch pad
extern u8 g_RealGSMem[Ps2MemSize::GSregs]; extern u8 g_RealGSMem[Ps2MemSize::GSregs];
#define PS2MEM_GS g_RealGSMem #define PS2MEM_GS g_RealGSMem
#define PS2GS_BASE(mem) (g_RealGSMem+(mem&0x13ff))
// Various useful locations
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400])
#define gif ((DMACh*)&PS2MEM_HW[0xA000])
#define vif0ch ((DMACh*)&PS2MEM_HW[0x8000])
#define vif1ch ((DMACh*)&PS2MEM_HW[0x9000])
#define sif0dma ((DMACh*)&PS2MEM_HW[0xc000])
#define sif1dma ((DMACh*)&PS2MEM_HW[0xc400])
#define sif2dma ((DMACh*)&PS2MEM_HW[0xc800])
#define ipu0dma ((DMACh *)&PS2MEM_HW[0xb000])
#define ipu1dma ((DMACh *)&PS2MEM_HW[0xb400])
// From Gif.h
#define GSCSRr *((u64*)(g_RealGSMem+0x1000))
#define GSIMR *((u32*)(g_RealGSMem+0x1010))
#define GSSIGLBLID ((GSRegSIGBLID*)(g_RealGSMem+0x1080))
#define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D #define PSM(mem) (vtlb_GetPhyPtr((mem)&0x1fffffff)) //pcsx2 is a competition.The one with most hacks wins :D
#define psHs8(mem) (*(s8 *)&PS2MEM_HW[(mem) & 0xffff])
#define psHs16(mem) (*(s16*)&PS2MEM_HW[(mem) & 0xffff])
#define psHs32(mem) (*(s32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHs64(mem) (*(s64*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu8(mem) (*(u8 *)&PS2MEM_HW[(mem) & 0xffff])
#define psHu16(mem) (*(u16*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu32(mem) (*(u32*)&PS2MEM_HW[(mem) & 0xffff])
#define psHu64(mem) (*(u64*)&PS2MEM_HW[(mem) & 0xffff])
#define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff]) #define psMs8(mem) (*(s8 *)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMs16(mem) (*(s16*)&PS2MEM_BASE[(mem) & 0x1ffffff]) #define psMs16(mem) (*(s16*)&PS2MEM_BASE[(mem) & 0x1ffffff])
#define psMs32(mem) (*(s32*)&PS2MEM_BASE[(mem) & 0x1ffffff]) #define psMs32(mem) (*(s32*)&PS2MEM_BASE[(mem) & 0x1ffffff])
@ -114,15 +146,6 @@ extern u8 g_RealGSMem[Ps2MemSize::GSregs];
#define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff]) #define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff]) #define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
//#define PSMs8(mem) (*(s8 *)PSM(mem))
//#define PSMs16(mem) (*(s16*)PSM(mem))
//#define PSMs32(mem) (*(s32*)PSM(mem))
//#define PSMs64(mem) (*(s64*)PSM(mem))
//#define PSMu8(mem) (*(u8 *)PSM(mem))
//#define PSMu16(mem) (*(u16*)PSM(mem))
//#define PSMu32(mem) (*(u32*)PSM(mem))
//#define PSMu64(mem) (*(u64*)PSM(mem))
extern void memAlloc(); extern void memAlloc();
extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error. extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error.
extern void memShutdown(); extern void memShutdown();
@ -134,8 +157,6 @@ extern void memClearPageAddr(u32 vaddr);
extern void memMapVUmicro(); extern void memMapVUmicro();
#include "vtlb.h"
extern int mmap_GetRamPageInfo(void* ptr); extern int mmap_GetRamPageInfo(void* ptr);
extern void mmap_MarkCountedRamPage(void* ptr,u32 vaddr); extern void mmap_MarkCountedRamPage(void* ptr,u32 vaddr);
extern void mmap_ResetBlockTracking(); extern void mmap_ResetBlockTracking();

View File

@ -20,13 +20,14 @@
#include "System.h" #include "System.h"
#include "MemoryCard.h" #include "MemoryCard.h"
#include "Paths.h"
#include <wx/file.h>
#ifdef WIN32 #ifdef WIN32
extern void NTFS_CompressFile( const char* file, bool compressMode ); extern void NTFS_CompressFile( const wxString& file, bool compressMode );
#endif #endif
FILE* MemoryCard::cardfile[2] = { NULL, NULL }; wxFile MemoryCard::cardfile[2];
// Ensures memory card files are created/initialized. // Ensures memory card files are created/initialized.
@ -34,8 +35,8 @@ void MemoryCard::Init()
{ {
for( int i=0; i<2; i++ ) for( int i=0; i<2; i++ )
{ {
if( Config.Mcd[i].Enabled && cardfile[i] == NULL ) if( Config.Mcd[i].Enabled && !cardfile[i].IsOpened() )
cardfile[i] = Load(i); Load( i );
} }
} }
@ -48,88 +49,79 @@ void MemoryCard::Shutdown()
void MemoryCard::Unload( uint mcd ) void MemoryCard::Unload( uint mcd )
{ {
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
cardfile[mcd].Close();
if(cardfile[mcd] == NULL) return;
fclose( cardfile[mcd] );
cardfile[mcd] = NULL;
} }
bool MemoryCard::IsPresent( uint mcd ) bool MemoryCard::IsPresent( uint mcd )
{ {
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
return cardfile[mcd] != NULL; return cardfile[mcd].IsOpened();
} }
FILE *MemoryCard::Load( uint mcd ) void MemoryCard::Load( uint mcd )
{ {
FILE *f;
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
string str( Config.Mcd[mcd].Filename ); wxFileName fname( g_Conf.Files.Mcd( mcd ) );
wxString str( fname.GetFullPath() );
if( str.empty() ) if( !fname.FileExists() )
str = Path::Combine( MEMCARDS_DIR, fmt_string( "Mcd00%d.ps2", mcd ) ); Create( str );
if( !Path::Exists(str) )
Create( str.c_str() );
#ifdef WIN32 #ifdef WIN32
NTFS_CompressFile( str.c_str(), Config.McdEnableNTFS ); NTFS_CompressFile( str, Config.McdEnableNTFS );
#endif #endif
f = fopen( str.c_str(), "r+b" ); cardfile[mcd].Open( str.c_str(), wxFile::write );
if (f == NULL) if( !cardfile[mcd].IsOpened() )
{ {
Msgbox::Alert("Failed loading MemoryCard from file: %hs", params &str); // Translation note: detailed description should mention that the memory card will be disabled
return NULL; // for the duration of this session.
Msgbox::Alert( wxsFormat( _("Could not load MemoryCard from file: %s"), str.c_str() ) );
} }
return f;
} }
void MemoryCard::Seek( FILE *f, u32 adr ) void MemoryCard::Seek( wxFile& f, u32 adr )
{ {
u32 size; u32 size = f.Length();
fseek(f, 0, SEEK_END); size = ftell(f);
if (size == MCD_SIZE + 64) if (size == MCD_SIZE + 64)
fseek(f, adr + 64, SEEK_SET); f.Seek( adr + 64 );
else if (size == MCD_SIZE + 3904) else if (size == MCD_SIZE + 3904)
fseek(f, adr + 3904, SEEK_SET); f.Seek( adr + 3904 );
else else
fseek(f, adr, SEEK_SET); f.Seek( adr );
} }
void MemoryCard::Read( uint mcd, u8 *data, u32 adr, int size ) void MemoryCard::Read( uint mcd, u8 *data, u32 adr, int size )
{ {
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
FILE* const mcfp = cardfile[mcd]; wxFile& mcfp( cardfile[mcd] );
if( mcfp == NULL ) if( !mcfp.IsOpened() )
{ {
Console::Error( "MemoryCard > Ignoring attempted read from disabled card." ); DevCon::Error( "MemoryCard > Ignoring attempted read from disabled card." );
memset(data, 0, size); memset(data, 0, size);
return; return;
} }
Seek(mcfp, adr); Seek(mcfp, adr);
fread(data, 1, size, mcfp); mcfp.Read( data, size );
} }
void MemoryCard::Save( uint mcd, const u8 *data, u32 adr, int size ) void MemoryCard::Save( uint mcd, const u8 *data, u32 adr, int size )
{ {
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
FILE* const mcfp = cardfile[mcd]; wxFile& mcfp( cardfile[mcd] );
if( mcfp == NULL ) if( !mcfp.IsOpened() )
{ {
Console::Error( "MemoryCard > Ignoring attempted save/write to disabled card." ); DevCon::Error( "MemoryCard > Ignoring attempted save/write to disabled card." );
return; return;
} }
Seek(mcfp, adr); Seek(mcfp, adr);
u8 *currentdata = (u8 *)malloc(size); u8 *currentdata = (u8 *)malloc(size);
fread(currentdata, 1, size, mcfp); mcfp.Read( currentdata, size);
for (int i=0; i<size; i++) for (int i=0; i<size; i++)
{ {
@ -139,7 +131,7 @@ void MemoryCard::Save( uint mcd, const u8 *data, u32 adr, int size )
} }
Seek(mcfp, adr); Seek(mcfp, adr);
fwrite(currentdata, 1, size, mcfp); mcfp.Write( currentdata, size );
free(currentdata); free(currentdata);
} }
@ -150,46 +142,51 @@ void MemoryCard::Erase( uint mcd, u32 adr )
memset8_obj<0xff>(data); // clears to -1's memset8_obj<0xff>(data); // clears to -1's
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
FILE* const mcfp = cardfile[mcd]; wxFile& mcfp( cardfile[mcd] );
if( mcfp == NULL ) if( !mcfp.IsOpened() )
{ {
DevCon::Notice( "MemoryCard > Ignoring seek for disabled card." ); DevCon::Error( "MemoryCard > Ignoring seek for disabled card." );
return; return;
} }
Seek(mcfp, adr); Seek(mcfp, adr);
fwrite(data, 1, 528*16, mcfp); mcfp.Write( data, 528*16 );
} }
void MemoryCard::Create( const char *mcdFile ) void MemoryCard::Create( const wxString& mcdFile )
{ {
//int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0}; //int enc[16] = {0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0x77,0x7f,0x7f,0,0,0,0};
FILE* fp = fopen( mcdFile, "wb" ); wxFile fp( mcdFile, wxFile::write );
if( fp == NULL ) return; if( !fp.IsOpened() ) return;
u8 effeffs[528];
memset8_obj<0xff>( effeffs );
for( uint i=0; i<16384; i++ ) for( uint i=0; i<16384; i++ )
{ {
for( uint j=0; j<528; j++ ) fputc( 0xFF,fp ); for( uint j=0; j<528; j++ )
// for(j=0; j<16; j++) fputc(enc[j],fp); fp.Write( effeffs, sizeof(effeffs) );
//for(j=0; j<16; j++) fputc(enc[j],fp);
} }
fclose( fp );
} }
u64 MemoryCard::GetCRC( uint mcd ) u64 MemoryCard::GetCRC( uint mcd )
{ {
jASSUME( mcd < 2 ); jASSUME( mcd < 2 );
FILE* const mcfp = cardfile[mcd]; wxFile& mcfp( cardfile[mcd] );
if( mcfp == NULL ) return 0; if( !mcfp.IsOpened() ) return 0;
Seek( mcfp, 0 ); Seek( mcfp, 0 );
u64 retval = 0; u64 retval = 0;
for( uint i=MC2_SIZE/sizeof(u64); i; --i ) for( uint i=MC2_SIZE/sizeof(u64); i; --i )
{ {
u64 temp; fread( &temp, sizeof(temp), 1, mcfp ); u64 temp; mcfp.Read( &temp, sizeof(temp) );
retval ^= temp; retval ^= temp;
} }

View File

@ -25,11 +25,12 @@ static const int MC2_SIZE = 1024 * 528 * 16;
class MemoryCard class MemoryCard
{ {
protected: protected:
static FILE* cardfile[2]; static wxFile cardfile[2];
static FILE* Load( uint mcdId ); public:
static void Seek( FILE* mcdfp, u32 adr ); static void Load( uint mcdId );
static void Create( const char *mcd ); static void Seek( wxFile& mcdfp, u32 adr );
static void Create( const wxString& mcd );
public: public:
static void Init(); static void Init();

View File

@ -25,6 +25,7 @@
#endif #endif
#include <ctype.h> #include <ctype.h>
#include <wx/file.h>
#include "IopCommon.h" #include "IopCommon.h"
#include "HostGui.h" #include "HostGui.h"
@ -40,14 +41,13 @@
#include "COP0.h" #include "COP0.h"
#include "Cache.h" #include "Cache.h"
#include "Paths.h" #include "Dump.h"
using namespace std; using namespace std;
using namespace R5900; using namespace R5900;
PcsxConfig Config; PcsxConfig Config;
u32 BiosVersion; u32 BiosVersion;
char CdromId[12];
static int g_Pcsx2Recording = 0; // true 1 if recording video and sound static int g_Pcsx2Recording = 0; // true 1 if recording video and sound
bool renderswitch = 0; bool renderswitch = 0;
@ -64,7 +64,8 @@ extern wxString strgametitle;
#pragma pack(1) #pragma pack(1)
#endif #endif
struct romdir{ struct romdir
{
char fileName[10]; char fileName[10];
u16 extInfoSize; u16 extInfoSize;
u32 fileSize; u32 fileSize;
@ -115,43 +116,46 @@ u32 GetBiosVersion() {
} }
//2002-09-22 (Florin) //2002-09-22 (Florin)
int IsBIOS(const char *filename, char *description) bool IsBIOS(const wxString& filename, wxString& description)
{ {
char ROMVER[14+1]; uint fileOffset=0;
FILE *fp; romdir rd;
unsigned int fileOffset=0, found=FALSE;
struct romdir rd;
wxString Bios( Path::Combine( Config.BiosDir, filename ) ); wxFileName Bios( g_Conf.Folders.Bios + filename );
wxFile fp( Bios.GetFullPath().c_str() );
int biosFileSize = Path::getFileSize( Bios ); if( !fp.IsOpened() ) return FALSE;
if( biosFileSize <= 0) return FALSE;
fp = fopen(Bios.c_str(), "rb"); int biosFileSize = fp.Length();
if (fp == NULL) return FALSE; if( biosFileSize <= 0) return FALSE;
while ((ftell(fp)<512*1024) && (fread(&rd, DIRENTRY_SIZE, 1, fp)==1)) while( (fp.Tell() < 512*1024) && (fp.Read( &rd, DIRENTRY_SIZE ) == DIRENTRY_SIZE) )
{
if (strcmp(rd.fileName, "RESET") == 0) if (strcmp(rd.fileName, "RESET") == 0)
break; /* found romdir */ break; // found romdir
}
if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0)) { if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0)) {
fclose(fp);
return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img
} }
bool found = false;
while(strlen(rd.fileName) > 0) while(strlen(rd.fileName) > 0)
{ {
if (strcmp(rd.fileName, "ROMVER") == 0) // found romver if (strcmp(rd.fileName, "ROMVER") == 0) // found romver
{ {
uint filepos = ftell(fp); char aROMVER[14+1]; // ascii version loaded from disk.
fseek(fp, fileOffset, SEEK_SET);
if (fread(&ROMVER, 14, 1, fp) == 0) break;
fseek(fp, filepos, SEEK_SET);//go back
const char zonefail[2] = { ROMVER[4], '\0' }; // the default "zone" (unknown code) uint filepos = fp.Tell();
fp.Seek( fileOffset );
if( fp.Read( &aROMVER, 14 ) == 0 ) break;
fp.Seek( filepos ); //go back
const char zonefail[2] = { aROMVER[4], '\0' }; // the default "zone" (unknown code)
const char* zone = zonefail; const char* zone = zonefail;
switch(ROMVER[4]) switch(aROMVER[4])
{ {
case 'T': zone = "T10K "; break; case 'T': zone = "T10K "; break;
case 'X': zone = "Test "; break; case 'X': zone = "Test "; break;
@ -163,15 +167,17 @@ int IsBIOS(const char *filename, char *description)
case 'C': zone = "China "; break; case 'C': zone = "China "; break;
} }
sprintf(description, "%s v%c%c.%c%c(%c%c/%c%c/%c%c%c%c) %s", zone, const wxString romver( wxString::FromAscii(aROMVER) );
ROMVER[0], ROMVER[1], // ver major
ROMVER[2], ROMVER[3], // ver minor description.Printf( wxT("%s v%c%c.%c%c(%c%c/%c%c/%c%c%c%c) %s"), wxString::FromAscii(zone).ToAscii().data(),
ROMVER[12], ROMVER[13], // day romver[0], romver[1], // ver major
ROMVER[10], ROMVER[11], // month romver[2], romver[3], // ver minor
ROMVER[6], ROMVER[7], ROMVER[8], ROMVER[9], // year! romver[12], romver[13], // day
(ROMVER[5]=='C') ? "Console" : (ROMVER[5]=='D') ? "Devel" : "" romver[10], romver[11], // month
romver[6], romver[7], romver[8], romver[9], // year!
(aROMVER[5]=='C') ? wxT("Console") : (aROMVER[5]=='D') ? wxT("Devel") : wxT("")
); );
found = TRUE; found = true;
} }
if ((rd.fileSize % 0x10)==0) if ((rd.fileSize % 0x10)==0)
@ -179,29 +185,26 @@ int IsBIOS(const char *filename, char *description)
else else
fileOffset += (rd.fileSize + 0x10) & 0xfffffff0; fileOffset += (rd.fileSize + 0x10) & 0xfffffff0;
if (fread(&rd, DIRENTRY_SIZE, 1, fp)==0) break; if (fp.Read( &rd, DIRENTRY_SIZE ) != DIRENTRY_SIZE) break;
} }
fileOffset-=((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize; fileOffset-=((rd.fileSize + 0x10) & 0xfffffff0) - rd.fileSize;
fclose(fp);
if (found) if (found)
{ {
char percent[6];
if ( biosFileSize < (int)fileOffset) if ( biosFileSize < (int)fileOffset)
{ {
sprintf(percent, " %d%%", biosFileSize*100/(int)fileOffset); description << ((biosFileSize*100)/(int)fileOffset) << wxT("%");
strcat(description, percent);//we force users to have correct bioses, // we force users to have correct bioses,
//not that lame scph10000 of 513KB ;-) // not that lame scph10000 of 513KB ;-)
} }
return TRUE; return true;
} }
return FALSE; //fail quietly return false; //fail quietly
} }
int GetPS2ElfName(char *name){ int GetPS2ElfName( wxString& name )
{
int f; int f;
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
char *pos; char *pos;
@ -231,18 +234,17 @@ int GetPS2ElfName(char *name){
return 1; return 1;
} }
pos+=strlen("BOOT2"); pos+=strlen("BOOT2");
while (pos && *pos && pos<=&buffer[255] while (pos && *pos && pos<&buffer[g_MaxPath]
&& (*pos<'A' || (*pos>'Z' && *pos<'a') || *pos>'z')) && (*pos<'A' || (*pos>'Z' && *pos<'a') || *pos>'z'))
pos++; pos++;
if (!pos || *pos==0) if (!pos || *pos==0)
return 0; return 0;
sscanf(pos, "%s", name); // the filename is everything up to the first CR/LF/tab.. ?
// Or up to any whitespace? (I'm opting for first CRLF/tab, although the old code
// apparently stopped on spaces too) --air
name = wxStringTokenizer( wxString::FromAscii( pos ) ).GetNextToken();
if (strncmp("cdrom0:\\", name, 8) == 0) {
strncpy(CdromId, name+8, 11); CdromId[11] = 0;
}
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
FILE *fp; FILE *fp;
int i; int i;
@ -281,7 +283,7 @@ void SaveGSState(const wxString& file)
if( g_SaveGSStream ) return; if( g_SaveGSStream ) return;
Console::WriteLn( "Saving GS State..." ); Console::WriteLn( "Saving GS State..." );
Console::WriteLn( "\t%hs", params file.c_str() ); Console::WriteLn( "\t%s", params file.mb_str() );
g_fGSSave = new gzSavingState( file ); g_fGSSave = new gzSavingState( file );
@ -305,9 +307,9 @@ void LoadGSState(const wxString& file)
catch( Exception::FileNotFound& ) catch( Exception::FileNotFound& )
{ {
// file not found? try prefixing with sstates folder: // file not found? try prefixing with sstates folder:
if( !Path::isRooted( file ) ) if( !Path::IsRooted( file ) )
{ {
f = new gzLoadingState( Path::Combine( SSTATES_DIR, file ).c_str() ); f = new gzLoadingState( Path::Combine( g_Conf.Folders.Savestates, file ) );
// If this load attempt fails, then let the exception bubble up to // If this load attempt fails, then let the exception bubble up to
// the caller to deal with... // the caller to deal with...
@ -350,9 +352,7 @@ char* mystrlwr( char* string )
static wxString GetGSStateFilename() static wxString GetGSStateFilename()
{ {
wxString gsText; return Path::Combine( g_Conf.Folders.Savestates, wxsFormat( wxT("/%8.8X.%d.gs"), ElfCRC, StatesC ) );
gsText.Printf( "/%8.8X.%d.gs", ElfCRC, StatesC );
return Path::Combine( SSTATES_DIR, gsText );
} }
void CycleFrameLimit(int dir) void CycleFrameLimit(int dir)
@ -430,10 +430,11 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
// 99% of the time this is a file permission error and the // 99% of the time this is a file permission error and the
// cpu state is intact so just display a passive msg to console. // cpu state is intact so just display a passive msg to console without
// raising an exception.
Console::Error( "Error > Could not save state to slot %d", params StatesC ); Console::Error( "Error! Could not save state to slot %d", params StatesC );
Console::Error( ex.cMessage() ); Console::Error( ex.LogMessage() );
} }
break; break;
@ -446,7 +447,7 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
Console::Notice( " > Selected savestate slot %d", params StatesC); Console::Notice( " > Selected savestate slot %d", params StatesC);
if( GSchangeSaveState != NULL ) if( GSchangeSaveState != NULL )
GSchangeSaveState(StatesC, SaveState::GetFilename(StatesC).c_str()); GSchangeSaveState(StatesC, SaveState::GetFilename(StatesC).mb_str());
break; break;
case 3: case 3:
@ -471,16 +472,15 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
// This is the bad one. Chances are the cpu has been reset, so emulation has // This is the bad one. Chances are the cpu has been reset, so emulation has
// to be aborted. Sorry user! We'll give you some info for your trouble: // to be aborted. Sorry user! We'll give you some info for your trouble:
Console::Error( "An error occured while trying to load saveslot %d", params StatesC );
Console::Error( ex.cMessage() );
Msgbox::Alert(
"Pcsx2 encountered an error while trying to load the savestate\n"
"and emulation had to be aborted." );
ClosePlugins( true ); ClosePlugins( true );
throw Exception::CpuStateShutdown( throw Exception::CpuStateShutdown(
"Saveslot load failed; PS2 emulated state had to be shut down." ); // let the GUI handle the error "gracefully" // english log message:
wxsFormat( wxT("Error! Could not load from saveslot %d\n"), StatesC ) + ex.LogMessage(),
// translated message:
wxsFormat( _("Error loading saveslot %d. Emulator reset."), StatesC )
);
} }
break; break;
@ -490,7 +490,7 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
// note: VK_F5-VK_F7 are reserved for GS // note: VK_F5-VK_F7 are reserved for GS
case 8: case 8:
GSmakeSnapshot( SNAPSHOTS_DIR "/" ); GSmakeSnapshot( g_Conf.Folders.Snapshots.ToAscii().data() );
break; break;
case 9: //gsdx "on the fly" renderer switching case 9: //gsdx "on the fly" renderer switching
@ -539,16 +539,16 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
// only take the first two words // only take the first two words
wxString gsText; wxString gsText;
wxStringTokenizer parts( strgametitle, " " ); wxStringTokenizer parts( strgametitle, L" " );
wxString name( parts.GetNextToken() ); // first part wxString name( parts.GetNextToken() ); // first part
wxString part2( parts.GetNextToken() ); wxString part2( parts.GetNextToken() );
if( !!part2 )
name += "_" + part2;
gsText.Printf( "%s.%d.gs", name.c_str(), StatesC ); if( !!part2 )
Text = Path::Combine( SSTATES_DIR, gsText ); name += wxT("_") + part2;
gsText.Printf( wxT("%s.%d.gs"), name.c_str(), StatesC );
Text = Path::Combine( g_Conf.Folders.Savestates, gsText );
} }
else else
{ {

View File

@ -34,7 +34,7 @@ extern uptr pDsp; //Used in GS, MTGS, Plugins, Misc
u32 GetBiosVersion(); // Used in Misc, Memory u32 GetBiosVersion(); // Used in Misc, Memory
extern u32 BiosVersion; // Used in Memory, Misc, CDVD extern u32 BiosVersion; // Used in Memory, Misc, CDVD
int GetPS2ElfName(char*); // Used in Misc, System, Linux, CDVD int GetPS2ElfName( wxString& dest ); // Used in Misc, System, Linux, CDVD
// Not sure what header these should go in. Probably not this one. // Not sure what header these should go in. Probably not this one.
void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR); void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR);
@ -65,7 +65,7 @@ extern u64 GetTickFrequency();
// Used in Misc,and Windows/Linux files. // Used in Misc,and Windows/Linux files.
extern void ProcessFKeys(int fkey, struct KeyModifiers *keymod); // processes fkey related commands value 1-12 extern void ProcessFKeys(int fkey, struct KeyModifiers *keymod); // processes fkey related commands value 1-12
extern int IsBIOS(const char *filename, char *description); extern bool IsBIOS(const wxString& filename, wxString& description);
//extern const char *LabelAuthors; //extern const char *LabelAuthors;
//extern const char *LabelGreets; //extern const char *LabelGreets;

View File

@ -63,4 +63,5 @@ void DispatcherReg();
} }
#endif #endif
#endif #endif

View File

@ -24,190 +24,7 @@
#include "System.h" #include "System.h"
class MainEmuFrame; class MainEmuFrame;
class IniInterface;
class IniInterface // abstract base class!
{
protected:
wxConfigBase& m_Config;
public:
virtual ~IniInterface();
explicit IniInterface();
explicit IniInterface( wxConfigBase& config );
void SetPath( const wxString& path );
void Flush();
virtual void Entry( const wxString& var, wxString& value, const wxString& defvalue=wxString() )=0;
virtual void Entry( const wxString& var, int& value, const int defvalue=0 )=0;
virtual void Entry( const wxString& var, uint& value, const uint defvalue=0 )=0;
virtual void Entry( const wxString& var, bool& value, const bool defvalue=0 )=0;
virtual void Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue=wxDefaultPosition )=0;
virtual void Entry( const wxString& var, wxSize& value, const wxSize& defvalue=wxDefaultSize )=0;
virtual void Entry( const wxString& var, wxRect& value, const wxRect& defvalue=wxDefaultRect )=0;
virtual void EnumEntry( const wxString& var, int& value, const char* const* enumArray, const int defvalue=0 )=0;
};
class IniLoader : public IniInterface
{
public:
virtual ~IniLoader();
explicit IniLoader();
explicit IniLoader( wxConfigBase& config );
void Entry( const wxString& var, wxString& value, const wxString& defvalue=wxString() );
void Entry( const wxString& var, int& value, const int defvalue=0 );
void Entry( const wxString& var, uint& value, const uint defvalue=0 );
void Entry( const wxString& var, bool& value, const bool defvalue=false );
void Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue=wxDefaultPosition );
void Entry( const wxString& var, wxSize& value, const wxSize& defvalue=wxDefaultSize );
void Entry( const wxString& var, wxRect& value, const wxRect& defvalue=wxDefaultRect );
void EnumEntry( const wxString& var, int& value, const char* const* enumArray, const int defvalue=0 );
};
class IniSaver : public IniInterface
{
public:
virtual ~IniSaver();
explicit IniSaver();
explicit IniSaver( wxConfigBase& config );
void Entry( const wxString& var, wxString& value, const wxString& defvalue=wxString() );
void Entry( const wxString& var, int& value, const int defvalue=0 );
void Entry( const wxString& var, uint& value, const uint defvalue=0 );
void Entry( const wxString& var, bool& value, const bool defvalue=false );
void Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue=wxDefaultPosition );
void Entry( const wxString& var, wxSize& value, const wxSize& defvalue=wxDefaultSize );
void Entry( const wxString& var, wxRect& value, const wxRect& defvalue=wxDefaultRect );
void EnumEntry( const wxString& var, int& value, const char* const* enumArray, const int defvalue=0 );
};
//////////////////////////////////////////////////////////////////////////////////////////
//
class AppConfig
{
public:
struct ConsoleLogOptions
{
bool Visible;
// if true, DisplayPos is ignored and the console is automatically docked to the main window.
bool AutoDock;
// Display position used if AutoDock is false (ignored otherwise)
wxPoint DisplayPosition;
wxSize DisplaySize;
void LoadSave( IniInterface& conf );
};
struct FolderOptions
{
wxString Plugins;
wxString Bios;
wxString Snapshots;
wxString Savestates;
wxString MemoryCards;
};
// Options struct for each memory card.
struct McdOptions
{
wxString Filename; // user-configured location of this memory card
bool Enabled; // memory card enabled (if false, memcard will not show up in-game)
};
struct McdSysOptions
{
McdOptions Mcd[2];
bool EnableNTFS; // enables automatic ntfs compression of memory cards (Win32 only)
bool EnableEjection; // enables simulated ejection of memory cards when loading savestates
void LoadSave( IniInterface& conf );
};
struct CpuRecompilerOptions
{
struct
{
bool
Enabled:1, // universal toggle for the profiler.
RecBlocks_EE:1, // Enables per-block profiling for the EE recompiler [unimplemented]
RecBlocks_IOP:1, // Enables per-block profiling for the IOP recompiler [unimplemented]
RecBlocks_VU1:1; // Enables per-block profiling for the VU1 recompiler [unimplemented]
} Profiler;
struct
{
bool
EnableEE:1,
EnableIOP:1,
EnableVU0:1,
EnableVU1:1;
} Recompiler;
void LoadSave( IniInterface& conf );
};
struct VideoOptions
{
bool MultithreadGS; // Uses the multithreaded GS interface.
bool closeOnEsc; // Closes the GS/Video port on escape (good for fullscreen activity)
bool UseFramelimiter;
int RegionMode; // 0=NTSC and 1=PAL
int CustomFps;
int CustomFrameSkip;
int CustomConsecutiveFrames;
int CustomConsecutiveSkip;
void LoadSave( IniInterface& conf );
};
struct GamefixOptions
{
bool
VuAddSubHack:1, // Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
VuClipFlagHack:1, // Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
FpuCompareHack:1, // Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
FpuMulHack:1; // Fix for Tales of Destiny hangs.
void LoadSave();
};
struct SpeedhackOptions
{
int
EECycleRate:3, // EE cyclerate selector (1.0, 1.5, 2.0, 3.0)
IopCycleRate_X2:1, // enables the x2 multiplier of the IOP cyclerate
ExtWaitcycles:1, // enables extended waitcycles duration
IntcStat:1; // tells Pcsx2 to fast-forward through intc_stat waits.
void LoadSave( IniInterface& conf );
};
public:
wxPoint MainGuiPosition;
bool CdvdVerboseReads; // enables cdvd read activity verbosely dumped to the console
CpuRecompilerOptions Cpu;
SpeedhackOptions Speedhacks;
GamefixOptions Gamefixes;
VideoOptions Video;
ConsoleLogOptions ConLogBox;
FolderOptions Folders;
public:
void LoadSave( IniInterface& ini );
};
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
@ -229,6 +46,7 @@ public:
virtual void OnClear(wxCommandEvent& event); virtual void OnClear(wxCommandEvent& event);
virtual void Write( const wxChar* text ); virtual void Write( const wxChar* text );
virtual void Write( const char* text );
void Newline(); void Newline();
void SetColor( Console::Colors color ); void SetColor( Console::Colors color );
@ -264,8 +82,12 @@ protected:
public: public:
Pcsx2App(); Pcsx2App();
wxFrame* GetMainWindow() const;
bool OnInit(); bool OnInit();
int OnExit(); int OnExit();
void OnInitCmdLine( wxCmdLineParser& parser );
bool OnCmdLineParsed( wxCmdLineParser& parser );
const wxBitmap& GetLogoBitmap() const; const wxBitmap& GetLogoBitmap() const;
MainEmuFrame& GetMainFrame() const MainEmuFrame& GetMainFrame() const
@ -281,5 +103,3 @@ public:
}; };
DECLARE_APP(Pcsx2App) DECLARE_APP(Pcsx2App)
extern AppConfig g_Conf;

View File

@ -18,147 +18,130 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "App.h" #include "App.h"
#include "IniInterface.h"
IniInterface::IniInterface( wxConfigBase& config ) : #include <wx/stdpaths.h>
m_Config( config )
{
}
IniInterface::IniInterface() :
m_Config( *wxConfigBase::Get() )
{
}
IniInterface::~IniInterface()
{
Flush();
}
void IniInterface::SetPath( const wxString& path )
{
m_Config.SetPath( path );
}
void IniInterface::Flush()
{
m_Config.Flush();
}
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// PathDefs Namespace -- contains default values for various pcsx2 path names and locations.
// //
// Note: The members of this namespace are intended for default value initialization only.
IniLoader::IniLoader( wxConfigBase& config ) : IniInterface( config ) // Most of the time you should use the path folder assignments in Conf() instead, since those
// are user-configurable.
//
namespace PathDefs
{ {
} const wxDirName Snapshots( wxT("snaps") );
const wxDirName Savestates( wxT("sstates") );
IniLoader::IniLoader() : IniInterface() {} const wxDirName MemoryCards( wxT("memcards") );
IniLoader::~IniLoader() {} const wxDirName Configs( wxT("inis") );
const wxDirName Plugins( wxT("plugins") );
void IniLoader::Entry( const wxString& var, wxString& value, const wxString& defvalue ) // Fetches the path location for user-consumable documents -- stuff users are likely to want to
{ // share with other programs: screenshots, memory cards, and savestates.
m_Config.Read( var, &value, defvalue ); wxDirName GetDocuments()
}
void IniLoader::Entry( const wxString& var, int& value, const int defvalue )
{
m_Config.Read( var, &value, defvalue );
}
void IniLoader::Entry( const wxString& var, uint& value, const uint defvalue )
{
m_Config.Read( var, (int*)&value, (int)defvalue );
}
void IniLoader::Entry( const wxString& var, bool& value, const bool defvalue )
{
wxString dest;
m_Config.Read( var, &dest, defvalue ? "enabled" : "disabled" );
value = (dest == "enabled") || (dest == "1");
}
void IniLoader::Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue )
{
TryParse( value, m_Config.Read( var, ToString( defvalue ) ), defvalue );
}
void IniLoader::Entry( const wxString& var, wxSize& value, const wxSize& defvalue )
{
TryParse( value, m_Config.Read( var, ToString( defvalue ) ), defvalue );
}
void IniLoader::Entry( const wxString& var, wxRect& value, const wxRect& defvalue )
{
TryParse( value, m_Config.Read( var, ToString( defvalue ) ), defvalue );
}
void IniLoader::EnumEntry( const wxString& var, int& value, const char* const* enumArray, const int defvalue )
{
wxString retval;
m_Config.Read( var, &retval, enumArray[defvalue] );
int i=0;
while( enumArray[i] != NULL && ( retval != enumArray[i] ) ) i++;
if( enumArray[i] == NULL )
{ {
Console::Notice( "Loadini Warning > Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.", return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
params retval.c_str(), var.c_str(), enumArray[defvalue] );
value = defvalue;
} }
else
value = i;
}
////////////////////////////////////////////////////////////////////////////////////////// wxDirName GetSnapshots()
// {
return (wxDirName)GetDocuments() + Snapshots;
}
wxDirName GetBios()
{
return (wxDirName)wxT("bios");
}
wxDirName GetSavestates()
{
return (wxDirName)GetDocuments() + Savestates;
}
wxDirName GetMemoryCards()
{
return (wxDirName)GetDocuments() + MemoryCards;
}
wxDirName GetConfigs()
{
return (wxDirName)GetDocuments()+ Configs;
}
IniSaver::IniSaver( wxConfigBase& config ) : IniInterface( config ) wxDirName GetPlugins()
{
return (wxDirName)Plugins;
}
};
namespace FilenameDefs
{ {
} wxFileName GetConfig()
{
// TODO : ini extension on Win32 is normal. Linux ini filename default might differ
// from this? like pcsx2_conf or something ... ?
IniSaver::IniSaver() : IniInterface() {} return wxGetApp().GetAppName() + wxT(".ini");
IniSaver::~IniSaver() {} }
wxFileName Memcard[2] =
{
wxT("Mcd001.ps2"),
wxT("Mcd002.ps2")
};
};
void IniSaver::Entry( const wxString& var, wxString& value, const wxString& defvalue ) // ------------------------------------------------------------------------
wxFileName wxDirName::Combine( const wxFileName& right ) const
{ {
m_Config.Write( var, value ); wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation." );
if( right.IsAbsolute() )
return right;
// Append any directory parts from right, and then set the filename.
// Except we can't do that because our m_members are private (argh!) and there is no API
// for getting each component of the path. So instead let's use Normalize:
wxFileName result( right );
result.Normalize( wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS, GetPath() );
return result;
} }
void IniSaver::Entry( const wxString& var, int& value, const int defvalue ) wxDirName wxDirName::Combine( const wxDirName& right ) const
{ {
m_Config.Write( var, value ); wxASSERT_MSG( IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation." );
wxDirName result( right );
result.Normalize( wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS, GetPath() );
return result;
} }
void IniSaver::Entry( const wxString& var, uint& value, const uint defvalue ) void wxDirName::Rmdir()
{ {
m_Config.Write( var, (int)value ); if( !Exists() ) return;
wxFileName::Rmdir();
// TODO : Throw exception if operation failed? Do we care?
} }
void IniSaver::Entry( const wxString& var, bool& value, const bool defvalue ) bool wxDirName::Mkdir()
{ {
m_Config.Write( var, value ? "enabled" : "disabled" ); if( Exists() ) return true;
return wxFileName::Mkdir();
} }
void IniSaver::Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue ) // ------------------------------------------------------------------------
{ wxString AppConfig::FullpathHelpers::Bios() const { return Path::Combine( m_conf.Folders.Bios, m_conf.BaseFilenames.Bios ); }
m_Config.Write( var, ToString( value ) ); wxString AppConfig::FullpathHelpers::CDVD() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.CDVD ); }
} wxString AppConfig::FullpathHelpers::GS() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.GS ); }
wxString AppConfig::FullpathHelpers::PAD1() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.PAD1 ); }
wxString AppConfig::FullpathHelpers::PAD2() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.PAD2 ); }
wxString AppConfig::FullpathHelpers::SPU2() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.SPU2 ); }
wxString AppConfig::FullpathHelpers::DEV9() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.DEV9 ); }
wxString AppConfig::FullpathHelpers::USB() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.USB ); }
wxString AppConfig::FullpathHelpers::FW() const { return Path::Combine( m_conf.Folders.Plugins, m_conf.BaseFilenames.FW ); }
void IniSaver::Entry( const wxString& var, wxSize& value, const wxSize& defvalue ) wxString AppConfig::FullpathHelpers::Mcd( uint mcdidx ) const { return Path::Combine( m_conf.Folders.MemoryCards, m_conf.MemoryCards.Mcd[mcdidx].Filename ); }
{
m_Config.Write( var, ToString( value ) );
}
void IniSaver::Entry( const wxString& var, wxRect& value, const wxRect& defvalue )
{
m_Config.Write( var, ToString( value ) );
}
void IniSaver::EnumEntry( const wxString& var, int& value, const char* const* enumArray, const int defvalue )
{
m_Config.Write( var, enumArray[value] );
}
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //

View File

@ -59,7 +59,7 @@ static bool OpenLogFile(wxFile& file, wxString& filename, wxWindow *parent)
return false; return false;
default: default:
wxFAIL_MSG( "invalid message box return value" ); wxFAIL_MSG( L"invalid message box return value" );
} }
return ( bAppend ) ? return ( bAppend ) ?
@ -211,3 +211,14 @@ void ConsoleLogFrame::Write( const wxChar* text )
m_TextCtrl.AppendText( text ); m_TextCtrl.AppendText( text );
} }
void ConsoleLogFrame::Write( const char* text )
{
// remove selection (WriteText is in fact ReplaceSelection)
#ifdef __WXMSW__
wxTextPos nLen = m_TextCtrl.GetLastPosition();
m_TextCtrl.SetSelection(nLen, nLen);
#endif
m_TextCtrl.AppendText( wxString::FromAscii(text) );
}

View File

@ -52,7 +52,7 @@ AboutBoxDialog::AboutBoxDialog( wxWindow* parent, int id ):
m_bitmap_ps2system( this, wxID_ANY, wxBitmap( EmbeddedImage<png_ps2_silver>().GetImage() ), m_bitmap_ps2system( this, wxID_ANY, wxBitmap( EmbeddedImage<png_ps2_silver>().GetImage() ),
wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN ) wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN )
{ {
static const wxString LabelAuthors = _( static const wxString LabelAuthors = wxString::FromAscii(
"PCSX2, a PS2 emulator\n\n" "PCSX2, a PS2 emulator\n\n"
"Active Devs: Arcum42, Refraction," "Active Devs: Arcum42, Refraction,"
"drk||raziel, cottonvibes, gigaherz," "drk||raziel, cottonvibes, gigaherz,"
@ -69,7 +69,7 @@ AboutBoxDialog::AboutBoxDialog( wxWindow* parent, int id ):
"Webmasters: CKemu, Falcon4ever" "Webmasters: CKemu, Falcon4ever"
); );
static const wxString LabelGreets = _( static const wxString LabelGreets = wxString::FromAscii(
"Contributors: Hiryu and Sjeep for libcvd (the iso parsing and\n" "Contributors: Hiryu and Sjeep for libcvd (the iso parsing and\n"
"filesystem driver code), nneeve, pseudonym\n" "filesystem driver code), nneeve, pseudonym\n"
"\n" "\n"

52
pcsx2/NewGUI/HostGui.cpp Normal file
View File

@ -0,0 +1,52 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "App.h"
// This API is likely obsolete for the most part, so I've just included a few dummies
// to keep things compiling until I can get to the point of tying up loose ends.
namespace HostGui
{
// Sets the status bar message without mirroring the output to the console.
void SetStatusMsg( const wxString& text )
{
wxGetApp().GetMainWindow()->SetStatusText( text );
}
void Notice( const wxString& text )
{
// mirror output to the console!
Console::Status( text.c_str() );
SetStatusMsg( text );
}
void ResetMenuSlots()
{
// Probably obsolete if we do a savestate dialog.
}
void BeginExecution()
{
}
void __fastcall KeyEvent( keyEvent* ev )
{
}
}

View File

@ -0,0 +1,165 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "System.h"
#include "IniInterface.h"
//////////////////////////////////////////////////////////////////////////////////////////
//
IniInterface::IniInterface( wxConfigBase& config ) :
m_Config( config )
{
}
IniInterface::IniInterface() :
m_Config( *wxConfigBase::Get() )
{
}
IniInterface::~IniInterface()
{
Flush();
}
void IniInterface::SetPath( const wxString& path )
{
m_Config.SetPath( path );
}
void IniInterface::Flush()
{
m_Config.Flush();
}
//////////////////////////////////////////////////////////////////////////////////////////
//
IniLoader::IniLoader( wxConfigBase& config ) : IniInterface( config )
{
}
IniLoader::IniLoader() : IniInterface() {}
IniLoader::~IniLoader() {}
void IniLoader::Entry( const wxString& var, wxString& value, const wxString& defvalue )
{
m_Config.Read( var, &value, defvalue );
}
void IniLoader::Entry( const wxString& var, int& value, const int defvalue )
{
m_Config.Read( var, &value, defvalue );
}
void IniLoader::Entry( const wxString& var, uint& value, const uint defvalue )
{
m_Config.Read( var, (int*)&value, (int)defvalue );
}
void IniLoader::Entry( const wxString& var, bool& value, const bool defvalue )
{
wxString dest;
m_Config.Read( var, &dest, defvalue ? L"enabled" : L"disabled" );
value = (dest == L"enabled") || (dest == L"1");
}
void IniLoader::Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue )
{
TryParse( value, m_Config.Read( var, ToString( defvalue ) ), defvalue );
}
void IniLoader::Entry( const wxString& var, wxSize& value, const wxSize& defvalue )
{
TryParse( value, m_Config.Read( var, ToString( defvalue ) ), defvalue );
}
void IniLoader::Entry( const wxString& var, wxRect& value, const wxRect& defvalue )
{
TryParse( value, m_Config.Read( var, ToString( defvalue ) ), defvalue );
}
void IniLoader::EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, const int defvalue )
{
wxString retval;
m_Config.Read( var, &retval, enumArray[defvalue] );
int i=0;
while( enumArray[i] != NULL && ( retval != enumArray[i] ) ) i++;
if( enumArray[i] == NULL )
{
Console::Notice( wxsFormat( L"Loadini Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.",
params retval.c_str(), var.c_str(), enumArray[defvalue]
) );
value = defvalue;
}
else
value = i;
}
//////////////////////////////////////////////////////////////////////////////////////////
//
IniSaver::IniSaver( wxConfigBase& config ) : IniInterface( config )
{
}
IniSaver::IniSaver() : IniInterface() {}
IniSaver::~IniSaver() {}
void IniSaver::Entry( const wxString& var, wxString& value, const wxString& defvalue )
{
m_Config.Write( var, value );
}
void IniSaver::Entry( const wxString& var, int& value, const int defvalue )
{
m_Config.Write( var, value );
}
void IniSaver::Entry( const wxString& var, uint& value, const uint defvalue )
{
m_Config.Write( var, (int)value );
}
void IniSaver::Entry( const wxString& var, bool& value, const bool defvalue )
{
m_Config.Write( var, value ? L"enabled" : L"disabled" );
}
void IniSaver::Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue )
{
m_Config.Write( var, ToString( value ) );
}
void IniSaver::Entry( const wxString& var, wxSize& value, const wxSize& defvalue )
{
m_Config.Write( var, ToString( value ) );
}
void IniSaver::Entry( const wxString& var, wxRect& value, const wxRect& defvalue )
{
m_Config.Write( var, ToString( value ) );
}
void IniSaver::EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, const int defvalue )
{
m_Config.Write( var, enumArray[value] );
}

109
pcsx2/NewGUI/IniInterface.h Normal file
View File

@ -0,0 +1,109 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
#include <wx/config.h>
//////////////////////////////////////////////////////////////////////////////////////////
// IniInterface class (abstract base class)
//
// This is used as an interchangable interface for both loading and saving options from an
// ini/configuration file. The LoadSave code takes an IniInterface, and the interface
// implementation defines whether the options are read or written.
//
// See also: IniLoader, IniSaver
//
class IniInterface
{
protected:
wxConfigBase& m_Config;
public:
virtual ~IniInterface();
explicit IniInterface();
explicit IniInterface( wxConfigBase& config );
void SetPath( const wxString& path );
void Flush();
virtual void Entry( const wxString& var, wxString& value, const wxString& defvalue=wxString() )=0;
virtual void Entry( const wxString& var, int& value, const int defvalue=0 )=0;
virtual void Entry( const wxString& var, uint& value, const uint defvalue=0 )=0;
virtual void Entry( const wxString& var, bool& value, const bool defvalue=0 )=0;
virtual void Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue=wxDefaultPosition )=0;
virtual void Entry( const wxString& var, wxSize& value, const wxSize& defvalue=wxDefaultSize )=0;
virtual void Entry( const wxString& var, wxRect& value, const wxRect& defvalue=wxDefaultRect )=0;
virtual void EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, const int defvalue=0 )=0;
};
//////////////////////////////////////////////////////////////////////////////////////////
// IniLoader class
//
// Implementation of the IniInterface base class, which maps ini actions to loading from
// an ini source file.
//
// See also: IniInterface
//
class IniLoader : public IniInterface
{
public:
virtual ~IniLoader();
explicit IniLoader();
explicit IniLoader( wxConfigBase& config );
void Entry( const wxString& var, wxString& value, const wxString& defvalue=wxString() );
void Entry( const wxString& var, int& value, const int defvalue=0 );
void Entry( const wxString& var, uint& value, const uint defvalue=0 );
void Entry( const wxString& var, bool& value, const bool defvalue=false );
void Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue=wxDefaultPosition );
void Entry( const wxString& var, wxSize& value, const wxSize& defvalue=wxDefaultSize );
void Entry( const wxString& var, wxRect& value, const wxRect& defvalue=wxDefaultRect );
void EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, const int defvalue=0 );
};
//////////////////////////////////////////////////////////////////////////////////////////
// IniSaver class
//
// Implementation of the IniInterface base class, which maps ini actions to saving to
// an ini dest file.
//
// See also: IniInterface
//
class IniSaver : public IniInterface
{
public:
virtual ~IniSaver();
explicit IniSaver();
explicit IniSaver( wxConfigBase& config );
void Entry( const wxString& var, wxString& value, const wxString& defvalue=wxString() );
void Entry( const wxString& var, int& value, const int defvalue=0 );
void Entry( const wxString& var, uint& value, const uint defvalue=0 );
void Entry( const wxString& var, bool& value, const bool defvalue=false );
void Entry( const wxString& var, wxPoint& value, const wxPoint& defvalue=wxDefaultPosition );
void Entry( const wxString& var, wxSize& value, const wxSize& defvalue=wxDefaultSize );
void Entry( const wxString& var, wxRect& value, const wxRect& defvalue=wxDefaultRect );
void EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, const int defvalue=0 );
};

View File

@ -140,7 +140,7 @@ void MainEmuFrame::OnLogBoxHidden()
MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style): MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long style):
wxFrame(parent, id, title, pos, size, wxCAPTION|wxCLOSE_BOX|wxSYSTEM_MENU|wxBORDER_THEME), wxFrame(parent, id, title, pos, size, wxCAPTION|wxCLOSE_BOX|wxSYSTEM_MENU|wxBORDER_THEME),
m_logbox( this, "Pcsx2 Log" ), m_logbox( this, L"Pcsx2 Log" ),
m_statusbar( *CreateStatusBar(2, 0) ), m_statusbar( *CreateStatusBar(2, 0) ),
m_background( this, wxID_ANY, wxGetApp().GetLogoBitmap() ), m_background( this, wxID_ANY, wxGetApp().GetLogoBitmap() ),
@ -161,7 +161,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, int id, const wxString& title, cons
m_LoadStatesSubmenu( *MakeStatesSubMenu( Menu_State_Load01 ) ), m_LoadStatesSubmenu( *MakeStatesSubMenu( Menu_State_Load01 ) ),
m_SaveStatesSubmenu( *MakeStatesSubMenu( Menu_State_Save01 ) ), m_SaveStatesSubmenu( *MakeStatesSubMenu( Menu_State_Save01 ) ),
m_MenuItem_Console( *new wxMenuItem( &m_menuMisc, Menu_Console, _T("Show Console"), wxEmptyString, wxITEM_CHECK ) ) m_MenuItem_Console( *new wxMenuItem( &m_menuMisc, Menu_Console, L"Show Console", wxEmptyString, wxITEM_CHECK ) )
{ {
wxGetApp().SetConsoleFrame( m_logbox ); wxGetApp().SetConsoleFrame( m_logbox );

View File

@ -17,12 +17,13 @@
*/ */
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "IniInterface.h"
#include "MainFrame.h" #include "MainFrame.h"
#include "Resources/EmbeddedImage.h" #include "Resources/EmbeddedImage.h"
#include "Resources/BackgroundLogo.h" #include "Resources/BackgroundLogo.h"
#include <wx/stdpaths.h> #include <wx/cmdline.h>
IMPLEMENT_APP(Pcsx2App) IMPLEMENT_APP(Pcsx2App)
@ -30,81 +31,14 @@ AppConfig g_Conf;
const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord ); const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord );
//////////////////////////////////////////////////////////////////////////////////////////
// PathDefs Namespace -- contains default values for various pcsx2 path names and locations.
//
// Note: The members of this namespace are intended for default value initialization only.
// Most of the time you should use the path folder assignments in Conf() instead, since those
// are user-configurable.
//
namespace PathDefs
{
const wxString Snapshots( "snaps" );
const wxString Savestates( "sstates" );
const wxString MemoryCards( "memcards" );
const wxString Configs( "inis" );
const wxString Plugins( "plugins" );
// Fetches the path location for user-consumable documents -- stuff users are likely to want to
// share with other programs: screenshots, memory cards, and savestates.
wxString GetDocuments()
{
return Path::Combine( wxStandardPaths::Get().GetDocumentsDir(), wxGetApp().GetAppName() );
}
wxString GetSnapshots()
{
return Path::Combine( GetDocuments(), Snapshots );
}
wxString GetBios()
{
return "bios";
}
wxString GetSavestates()
{
return Path::Combine( GetDocuments(), Savestates );
}
wxString GetMemoryCards()
{
return Path::Combine( GetDocuments(), MemoryCards );
}
wxString GetConfigs()
{
return Path::Combine( GetDocuments(), Configs );
}
wxString GetPlugins()
{
return Plugins;
}
wxString GetWorking()
{
return wxGetCwd();
}
};
namespace FilenameDefs
{
wxString GetConfig()
{
// TODO : ini extension on Win32 is normal. Linux ini filename default might differ
// from this? like pcsx2_conf or something ... ?
return wxGetApp().GetAppName() + ".ini";
}
};
Pcsx2App::Pcsx2App() : Pcsx2App::Pcsx2App() :
m_ConsoleFrame( NULL ) m_ConsoleFrame( NULL )
{ {
SetAppName( "Pcsx2" ); SetAppName( L"Pcsx2" );
} }
wxFrame* Pcsx2App::GetMainWindow() const { return m_MainFrame; }
wxFileConfig* OpenConfig( const wxString& filename ) wxFileConfig* OpenConfig( const wxString& filename )
{ {
return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH ); return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
@ -114,21 +48,65 @@ wxFileConfig* OpenConfig( const wxString& filename )
// returns false if not (in which case the calling code should fall back on using OpenConfigUserLocal()) // returns false if not (in which case the calling code should fall back on using OpenConfigUserLocal())
bool Pcsx2App::TryOpenConfigCwd() bool Pcsx2App::TryOpenConfigCwd()
{ {
wxString inipath_cwd( Path::Combine( wxGetCwd(), PathDefs::Configs ) ); wxDirName inipath_cwd( (wxDirName)wxGetCwd() + PathDefs::Configs );
if( !Path::isDirectory( inipath_cwd ) ) return false; if( !inipath_cwd.IsReadable() ) return false;
wxString inifile_cwd( Path::Combine( inipath_cwd, FilenameDefs::GetConfig() ) ); wxString inifile_cwd( Path::Combine( inipath_cwd, FilenameDefs::GetConfig() ) );
if( !Path::isFile( inifile_cwd ) ) return false; if( !Path::IsFile( inifile_cwd ) ) return false;
if( Path::getFileSize( inifile_cwd ) <= 1 ) return false; if( Path::GetFileSize( inifile_cwd ) <= 1 ) return false;
wxConfigBase::Set( OpenConfig( inifile_cwd ) ); wxConfigBase::Set( OpenConfig( inifile_cwd ) );
return true; return true;
} }
void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser )
{
parser.SetLogo( _(
" >> Pcsx2 -- A Playstation2 Emulator for the PC\n"
) );
parser.AddParam( _( "CDVD/ELF" ), wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL );
parser.AddSwitch( wxT("h"), wxT("help"), _("displays this list of command line options"), wxCMD_LINE_OPTION_HELP );
parser.AddSwitch( wxT("nogui"), wxT("nogui"), _("disables display of the gui and enables the Escape Hack.") );
parser.AddOption( wxT("bootmode"), wxEmptyString, _("0 - quick (default), 1 - bios, 2 - load elf"), wxCMD_LINE_VAL_NUMBER );
parser.AddOption( wxEmptyString, wxT("cfg"), _("configuration file override"), wxCMD_LINE_VAL_STRING );
parser.AddOption( wxEmptyString,wxT("cdvd"), _("uses filename as the CDVD plugin for this session only.") );
parser.AddOption( wxEmptyString,wxT("gs"), _("uses filename as the GS plugin for this session only.") );
parser.AddOption( wxEmptyString,wxT("spu"), _("uses filename as the SPU2 plugin for this session only.") );
parser.AddOption( wxEmptyString,wxT("pad"), _("uses filename as *both* PAD plugins for this session only.") );
parser.AddOption( wxEmptyString,wxT("pad1"), _("uses filename as the PAD1 plugin for this session only.") );
parser.AddOption( wxEmptyString,wxT("pad2"), _("uses filename as the PAD2 plugin for this session only.") );
parser.AddOption( wxEmptyString,wxT("dev9"), _("uses filename as the DEV9 plugin for this session only.") );
parser.AddOption( wxEmptyString,wxT("usb"), _("uses filename as the USB plugin for this session only.") );
parser.SetSwitchChars( wxT("-") );
}
bool Pcsx2App::OnCmdLineParsed(wxCmdLineParser& parser)
{
if( parser.GetParamCount() >= 1 )
{
// [TODO] : Unnamed parameter is taken as an "autorun" option for a cdvd/iso.
parser.GetParam( 0 );
}
// Suppress wxWidgets automatic options parsing since none of them pertain to Pcsx2 needs.
//wxApp::OnCmdLineParsed( parser );
bool yay = parser.Found( wxT("nogui") );
return true;
}
bool Pcsx2App::OnInit() bool Pcsx2App::OnInit()
{ {
wxInitAllImageHandlers(); wxInitAllImageHandlers();
wxApp::OnInit();
// Ini Startup: The ini file could be in one of two locations, depending on how Pcsx2 has // Ini Startup: The ini file could be in one of two locations, depending on how Pcsx2 has
// been installed or configured. The first place we look is in our program's working // been installed or configured. The first place we look is in our program's working
// directory. If the ini there exist, and is *not* empty, then we'll use it. Otherwise // directory. If the ini there exist, and is *not* empty, then we'll use it. Otherwise
@ -136,8 +114,8 @@ bool Pcsx2App::OnInit()
if( !TryOpenConfigCwd() ) if( !TryOpenConfigCwd() )
{ {
Path::CreateDirectory( PathDefs::GetDocuments() ); PathDefs::GetDocuments().Mkdir();
Path::CreateDirectory( PathDefs::GetConfigs() ); PathDefs::GetConfigs().Mkdir();
// Allow wx to use our config, and enforces auto-cleanup as well // Allow wx to use our config, and enforces auto-cleanup as well
wxConfigBase::Set( OpenConfig( Path::Combine( PathDefs::GetConfigs(), FilenameDefs::GetConfig() ) ) ); wxConfigBase::Set( OpenConfig( Path::Combine( PathDefs::GetConfigs(), FilenameDefs::GetConfig() ) ) );

View File

@ -24,7 +24,6 @@
#define _PC_ // disables MIPS opcode macros. #define _PC_ // disables MIPS opcode macros.
#include "IopCommon.h" #include "IopCommon.h"
#include "Paths.h"
#include "Patch.h" #include "Patch.h"
#include "VU.h" #include "VU.h"
@ -462,20 +461,25 @@ void patchFunc_comment( char * text1, char * text2 )
void patchFunc_gametitle( char * text1, char * text2 ) void patchFunc_gametitle( char * text1, char * text2 )
{ {
Console::WriteLn( "gametitle: %s", params text2 ); Console::WriteLn( "gametitle: %s", params text2 );
strgametitle = text2; strgametitle.FromAscii( text2 );
Console::SetTitle(strgametitle); Console::SetTitle( strgametitle );
} }
void patchFunc_patch( char * cmd, char * param ) void patchFunc_patch( char * cmd, char * param )
{ {
char * pText; char* pText;
if ( patchnumber >= MAX_PATCH ) if ( patchnumber >= MAX_PATCH )
{ {
// TODO : Use wxLogError for this, once we have full unicode compliance on cmd/params vars.
//wxLogError( wxT("Patch ERROR: Maximum number of patches reached: %s=%s"), cmd, param );
Console::Error( "Patch ERROR: Maximum number of patches reached: %s=%s", params cmd, param ); Console::Error( "Patch ERROR: Maximum number of patches reached: %s=%s", params cmd, param );
return; return;
} }
//SafeList<wxString> pieces;
//SplitString( pieces, param, "," );
pText = strtok( param, "," ); pText = strtok( param, "," );
pText = param; pText = param;
@ -536,7 +540,10 @@ void inifile_command( char * cmd )
code = PatchTableExecute( command, parameter, commands ); code = PatchTableExecute( command, parameter, commands );
} }
void inifile_trim( char * buffer ) #define USE_CRAZY_BASHIT_INSANE_TRIM
#ifdef USE_CRAZY_BASHIT_INSANE_TRIM
void inifile_trim( char* buffer )
{ {
char * pInit = buffer; char * pInit = buffer;
char * pEnd = NULL; char * pEnd = NULL;
@ -574,6 +581,33 @@ void inifile_trim( char * buffer )
buffer[ pEnd - pInit + 1 ] = '\0'; buffer[ pEnd - pInit + 1 ] = '\0';
} }
#else
// New version of trim (untested), which I coded but can't use yet because the
// rest of Patch needs to be more wxString-involved first.
void inifile_trim( wxString& buffer )
{
buffer.Trim( false ); // trims left side.
if( buffer.Length() <= 1 ) // this I'm not sure about... - air
{
buffer.Clear();
return;
}
if( buffer.Left( 2 ) == "//" )
{
buffer.Clear();
return;
}
buffer.Trim(true); // trims right side.
}
#endif
void inisection_process( FILE * f1 ) void inisection_process( FILE * f1 )
{ {
char buffer[ 1024 ]; char buffer[ 1024 ];
@ -621,7 +655,7 @@ void inifile_read( const char * name )
if( !f1 ) if( !f1 )
{ {
Console::WriteLn("No patch found.Resuming execution without a patch (this is NOT an error)." ); Console::WriteLn("No patch found. Resuming execution without a patch (this is NOT an error)." );
return; return;
} }

View File

@ -115,8 +115,8 @@ extern int g_ZeroGSOptions;
extern u32 g_sseMXCSR; extern u32 g_sseMXCSR;
extern u32 g_sseVUMXCSR; extern u32 g_sseVUMXCSR;
void SetRoundMode(u32 ee, u32 vu); extern void SetRoundMode(u32 ee, u32 vu);
int LoadPatch(const std::string& patchfile); extern int LoadPatch(const wxString& patchfile);
#endif /* __PATCH_H__ */ #endif /* __PATCH_H__ */

View File

@ -36,65 +36,79 @@ namespace Path
#ifdef WIN32 #ifdef WIN32
// Path Separator used when creating new paths. // Path Separator used when creating new paths.
static const char Separator( '\\' ); static const wxChar Separator( wxT('\\') );
// Path separators used when breaking existing paths into parts and pieces. // Path separators used when breaking existing paths into parts and pieces.
static const wxString Delimiters( "\\/" ); static const wxString Delimiters( wxT("\\/") );
static const wxChar SeparatorExt( wxT('.') );
#else #else
static const char Separator = '/'; static const char Separator = '/';
static const char Delimiters( '/' ); static const char Delimiters( '/' );
#endif #endif
static bool IsPathSeparator( wxChar src )
{
#ifdef WIN32
return (src == Separator) || (src == wxT('/'));
#else
return src == Separator;
#endif
}
bool Exists( const wxString& path ) bool Exists( const wxString& path )
{ {
struct stat sbuf; wxStructStat sbuf;
return stat( path.c_str(), &sbuf ) == 0; return wxStat( path.c_str(), &sbuf ) == 0;
} }
// This function returns false if the path does not exist, or if the path exists and // This function returns false if the path does not exist, or if the path exists and
// is a file. // is a file.
bool isDirectory( const wxString& path ) bool IsDirectory( const wxString& path )
{ {
struct stat sbuf; wxStructStat sbuf;
if( stat( path.c_str(), &sbuf ) == -1 ) return false; if( wxStat( path.c_str(), &sbuf ) == -1 ) return false;
return !!(sbuf.st_mode & _S_IFDIR); return !!(sbuf.st_mode & _S_IFDIR);
} }
// This function returns false if the path does not exist, or if the path exists and // This function returns false if the path does not exist, or if the path exists and
// is a directory. // is a directory.
bool isFile( const wxString& path ) bool IsFile( const wxString& path )
{ {
struct stat sbuf; wxStructStat sbuf;
if( stat( path.c_str(), &sbuf ) == -1 ) return false; if( wxStat( path.c_str(), &sbuf ) == -1 ) return false;
return !!(sbuf.st_mode & _S_IFREG); return !!(sbuf.st_mode & _S_IFREG);
} }
// Returns the length of the file. // Returns the length of the file.
// returns -1 if the file is not found. // returns -1 if the file is not found.
int getFileSize( const wxString& path ) int GetFileSize( const wxString& path )
{ {
struct stat sbuf; wxStructStat sbuf;
if( stat( path.c_str(), &sbuf ) == -1 ) return -1; if( wxStat( path.c_str(), &sbuf ) == -1 ) return -1;
return sbuf.st_size; return sbuf.st_size;
} }
bool isRooted( const wxString& path ) bool IsRooted( const wxString& path )
{ {
// if the first character is a backslash or period, or the second character // if the first character is a backslash or period, or the second character
// a colon, it's a safe bet we're rooted. // a colon, it's a safe bet we're rooted.
if( path[0] == 0 ) return FALSE; if( path[0] == 0 ) return false;
#ifdef WIN32 #ifdef WIN32
return (path[0] == '/') || (path[0] == '\\') || (path[1] == ':'); return IsPathSeparator(path[0]) || ( (path[1] == ':') && IsPathSeparator(path[2]) );
#else #else
return (path[0] == Separator); return IsPathSeparator(path[0]);
#endif #endif
} }
// ------------------------------------------------------------------------
// Concatenates two pathnames together, inserting delimiters (backslash on win32) // Concatenates two pathnames together, inserting delimiters (backslash on win32)
// as needed! Assumes the 'dest' is allocated to at least g_MaxPath length. // as needed! Assumes the 'dest' is allocated to at least g_MaxPath length.
wxString Combine( const wxString& srcPath, const wxString& srcFile ) wxString Combine( const wxString& srcPath, const wxString& srcFile )
{ {
int pathlen, guesslen; #if 0
int pathlen;
if( srcFile.empty() ) if( srcFile.empty() )
{ {
@ -102,7 +116,7 @@ wxString Combine( const wxString& srcPath, const wxString& srcFile )
return srcPath; return srcPath;
} }
if( isRooted( srcFile ) || srcPath.empty() ) if( IsRooted( srcFile ) || srcPath.empty() )
{ {
// No source path? Or source filename is rooted? // No source path? Or source filename is rooted?
// Return the filename unmodified. // Return the filename unmodified.
@ -114,7 +128,7 @@ wxString Combine( const wxString& srcPath, const wxString& srcFile )
// This might be a problem on Linux builds or maybe it doesn't matter? // This might be a problem on Linux builds or maybe it doesn't matter?
pathlen = srcPath.length(); pathlen = srcPath.length();
while( pathlen > 0 && ((srcPath[pathlen-1] == '\\') || (srcPath[pathlen-1] == '/')) ) while( pathlen > 0 && IsPathSeparator(srcPath[pathlen-1]) )
--pathlen; --pathlen;
// Concatenate strings: // Concatenate strings:
@ -129,14 +143,31 @@ wxString Combine( const wxString& srcPath, const wxString& srcFile )
dest += Separator; dest += Separator;
dest += srcFile; dest += srcFile;
return dest; return dest;
#else
// Use wx's Path system for concatenation because it's pretty smart.
return (wxDirName( srcPath ) + srcFile).GetFullPath();
#endif
}
wxString Combine( const wxDirName& srcPath, const wxFileName& srcFile )
{
return (srcPath + srcFile).GetFullPath();
}
wxString Combine( const wxString& srcPath, const wxDirName& srcFile )
{
return ((wxDirName)srcPath + srcFile).ToString();
} }
// Replaces the extension of the file with the one given. // Replaces the extension of the file with the one given.
// This function works for path names as well as file names.
wxString ReplaceExtension( const wxString& src, const wxString& ext ) wxString ReplaceExtension( const wxString& src, const wxString& ext )
{ {
wxString dest; wxString dest;
int pos = src.find_last_of( '.' ); int pos = src.find_last_of( SeparatorExt );
if( pos == wxString::npos || pos == 0 ) if( pos == wxString::npos || pos == 0 )
dest = src; dest = src;
else else
@ -151,97 +182,32 @@ wxString ReplaceExtension( const wxString& src, const wxString& ext )
return dest; return dest;
} }
// finds the starting character position of a filename for the given source path.
static int _findFilenamePosition( const wxString& src)
{
// note: the source path could have multiple trailing slashes. We want to ignore those.
unsigned int startpos = src.find_last_not_of( Delimiters );
if(startpos == wxString::npos )
return 0;
int pos;
if( startpos < src.length() )
{
wxString trimmed( src.begin(), src.begin()+startpos );
pos = trimmed.find_last_of( Delimiters );
}
else
{
pos = src.find_last_of( Delimiters );
}
if( pos == wxString::npos )
return 0;
return pos;
}
wxString ReplaceFilename( const wxString& src, const wxString& newfilename ) wxString ReplaceFilename( const wxString& src, const wxString& newfilename )
{ {
wxString dest; // Implementation note: use wxWidgets to do this job.
int pos = _findFilenamePosition( src );
if( pos == 0 ) wxFileName jojo( src );
dest = src; jojo.SetFullName( newfilename );
else return jojo.GetFullPath();
dest.assign( src.begin(), src.begin()+pos );
if( !newfilename.empty() )
{
dest += Separator;
dest += newfilename;
}
return dest;
} }
wxString GetFilename( const wxString& src ) wxString GetFilename( const wxString& src )
{ {
int pos = _findFilenamePosition( src ); return wxFileName(src).GetFullName();
return wxString( src.begin()+pos, src.end() );
} }
wxString GetFilenameWithoutExt( const wxString& src ) wxString GetFilenameWithoutExt( const wxString& src )
{ {
wxString fname( GetFilename( src ) ); return wxFileName(src).GetName();
int pos = fname.find_last_of( '.' );
if( pos == wxString::npos || pos == 0 )
return fname;
else
return wxString( fname.begin(), fname.begin()+pos );
} }
wxString GetDirectory( const wxString& src ) wxString GetDirectory( const wxString& src )
{ {
int pos = _findFilenamePosition( src ); return wxFileName(src).GetPath();
if( pos == 0 )
return wxString();
else
return wxString( src.begin(), src.begin()+pos );
} }
// This function mimics the old ANSI C splitpath function. It's more or less superceeded
// by one of the many other Path utility functions, but someone might find it useful.
void Split( const wxString& src, wxString& destpath, wxString& destfile )
{
int pos = _findFilenamePosition( src );
if( pos == 0 ) // returns the base/root directory of the given path.
{
destpath.clear();
destfile = src;
}
else
{
destpath.assign( src.begin(), src.begin()+pos );
destfile.assign( src.begin()+pos, src.end() );
}
}
// Assigns the base/root directory of the given path into dest.
// Example /this/that/something.txt -> dest == "/" // Example /this/that/something.txt -> dest == "/"
wxString GetRootDirectory( const wxString& src ) wxString GetRootDirectory( const wxString& src )
{ {
@ -254,11 +220,12 @@ wxString GetRootDirectory( const wxString& src )
void CreateDirectory( const wxString& src ) void CreateDirectory( const wxString& src )
{ {
#ifdef _WIN32 wxFileName::Mkdir( src );
_mkdir( src.c_str() ); }
#else
mkdir( src.c_str(), 0755); void RemoveDirectory( const wxString& src )
#endif {
wxFileName::Rmdir( src );
} }
} }

View File

@ -7,6 +7,11 @@
extern char MAIN_DIR[g_MaxPath]; extern char MAIN_DIR[g_MaxPath];
#endif #endif
//////////////////////////////////////////////////////////////////////////////////////////
// Obsolete Values in wxWidgets Branch!
// The following set of macros has been superceeded by the PathDefs and FilenameDefs namespaces,
// and furethermore by a set of user-configurable paths in g_Conf.
//
#define DEFAULT_INIS_DIR "inis" #define DEFAULT_INIS_DIR "inis"
#define DEFAULT_BIOS_DIR "bios" #define DEFAULT_BIOS_DIR "bios"
#define DEFAULT_PLUGINS_DIR "plugins" #define DEFAULT_PLUGINS_DIR "plugins"
@ -25,25 +30,170 @@ extern char MAIN_DIR[g_MaxPath];
// Windows.h namespace pollution! // Windows.h namespace pollution!
#undef CreateDirectory #undef CreateDirectory
//////////////////////////////////////////////////////////////////////////////////////////
//
class wxDirName : protected wxFileName
{
public:
explicit wxDirName( const wxFileName& src )
{
wxASSERT_MSG( src.IsDir(), L"Warning: Creating a directory from what looks to be a filename..." );
Assign( src.GetPath() );
}
wxDirName() : wxFileName() {}
wxDirName( const wxDirName& src ) : wxFileName( src ) { }
explicit wxDirName( const char* src ) { Assign( wxString::FromAscii(src) ); }
explicit wxDirName( const wxString& src ) { Assign( src ); }
// ------------------------------------------------------------------------
void Assign( const wxString& volume, const wxString& path )
{
wxFileName::Assign( volume, path, wxEmptyString );
}
void Assign( const wxString& path )
{
wxFileName::Assign( path, wxEmptyString );
}
void Assign( const wxDirName& path )
{
wxFileName::Assign( path );
}
void Clear() { wxFileName::Clear(); }
wxCharBuffer ToAscii() const { return GetPath().ToAscii(); }
wxString ToString() const { return GetPath(); }
// ------------------------------------------------------------------------
bool IsWritable() const { return IsDirWritable(); }
bool IsReadable() const { return IsDirReadable(); }
bool Exists() const { return DirExists(); }
bool IsOk() const { return wxFileName::IsOk(); }
bool SameAs( const wxDirName& filepath ) const
{
return wxFileName::SameAs( filepath );
}
// Returns the number of sub folders in this directory path
size_t GetCount() const { return GetDirCount(); }
// ------------------------------------------------------------------------
wxFileName Combine( const wxFileName& right ) const;
wxDirName Combine( const wxDirName& right ) const;
// removes the lastmost directory from the path
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
// ------------------------------------------------------------------------
bool Normalize( int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString )
{
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
return wxFileName::Normalize( flags, cwd );
}
bool MakeRelativeTo( const wxString& pathBase = wxEmptyString )
{
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
return wxFileName::MakeRelativeTo( pathBase );
}
bool MakeAbsolute( const wxString& cwd = wxEmptyString )
{
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
return wxFileName::MakeAbsolute( cwd );
}
// ------------------------------------------------------------------------
void AssignCwd( const wxString& volume = wxEmptyString ) { wxFileName::AssignCwd( volume ); }
bool SetCwd() { wxFileName::SetCwd(); }
// wxWidgets is missing the const qualifier for this one! Shame!
void Rmdir();
bool Mkdir();
// ------------------------------------------------------------------------
wxDirName& operator=(const wxDirName& dirname) { Assign( dirname ); return *this; }
wxDirName& operator=(const wxString& dirname) { Assign( dirname ); return *this; }
wxDirName& operator=(const char* dirname) { Assign( wxString::FromAscii(dirname) ); return *this; }
wxFileName operator+( const wxFileName& right ) const { return Combine( right ); }
wxDirName operator+( const wxDirName& right ) const { return Combine( right ); }
bool operator==(const wxDirName& filename) const { return SameAs(filename); }
bool operator!=(const wxDirName& filename) const { return !SameAs(filename); }
bool operator==(const wxFileName& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxFileName& filename) const { return !SameAs(wxDirName(filename)); }
// compare with a filename string interpreted as a native file name
bool operator==(const wxString& filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxString& filename) const { return !SameAs(wxDirName(filename)); }
};
// remove windows.h namespace pollution:
#undef GetFileSize
#undef CreateDirectory
//////////////////////////////////////////////////////////////////////////////////////////
// Path Namespace
// Cross-platform utilities for manipulation of paths and filenames.
//
namespace Path namespace Path
{ {
extern bool isRooted( const wxString& path ); extern bool IsRooted( const wxString& path );
extern bool isDirectory( const wxString& path ); extern bool IsDirectory( const wxString& path );
extern bool isFile( const wxString& path ); extern bool IsFile( const wxString& path );
extern bool Exists( const wxString& path ); extern bool Exists( const wxString& path );
extern int getFileSize( const wxString& path ); extern int GetFileSize( const wxString& path );
extern wxString Combine( const wxString& srcPath, const wxString& srcFile ); extern wxString Combine( const wxString& srcPath, const wxString& srcFile );
extern wxString Combine( const wxDirName& srcPath, const wxFileName& srcFile );
extern wxString Combine( const wxString& srcPath, const wxDirName& srcFile );
extern wxString ReplaceExtension( const wxString& src, const wxString& ext ); extern wxString ReplaceExtension( const wxString& src, const wxString& ext );
extern wxString ReplaceFilename( const wxString& src, const wxString& newfilename ); extern wxString ReplaceFilename( const wxString& src, const wxString& newfilename );
extern wxString GetFilename( const wxString& src ); extern wxString GetFilename( const wxString& src );
extern wxString GetDirectory( const wxString& src ); extern wxString GetDirectory( const wxString& src );
extern wxString GetFilenameWithoutExt( const string& src ); extern wxString GetFilenameWithoutExt( const string& src );
extern wxString GetRootDirectory( const wxString& src ); extern wxString GetRootDirectory( const wxString& src );
extern void Split( const wxString& src, wxString& destpath, wxString& destfile );
extern void CreateDirectory( const wxString& src ); extern void CreateDirectory( const wxString& src );
extern void RemoveDirectory( const wxString& src );
} }
//////////////////////////////////////////////////////////////////////////////////////////
// PathDefs Namespace -- contains default values for various pcsx2 path names and locations.
//
// Note: The members of this namespace are intended for default value initialization only.
// Most of the time you should use the path folder assignments in g_Conf instead, since those
// are user-configurable.
//
namespace PathDefs
{
extern const wxDirName Snapshots;
extern const wxDirName Savestates;
extern const wxDirName MemoryCards;
extern const wxDirName Configs;
extern const wxDirName Plugins;
extern wxDirName GetDocuments();
extern wxDirName GetSnapshots();
extern wxDirName GetBios();
extern wxDirName GetSavestates();
extern wxDirName GetMemoryCards();
extern wxDirName GetConfigs();
extern wxDirName GetPlugins();
}
namespace FilenameDefs
{
extern wxFileName GetConfig();
extern wxFileName Memcard[2];
};
#endif #endif

View File

@ -216,6 +216,9 @@ _FWabout FWabout;
DEV9handler dev9Handler; DEV9handler dev9Handler;
USBhandler usbHandler; USBhandler usbHandler;
uptr pDsp;
#ifdef _not_wxWidgets_Land_
#define Sfy(x) #x #define Sfy(x) #x
#define Strfy(x) Sfy(x) #define Strfy(x) Sfy(x)
@ -695,7 +698,6 @@ void ShutdownPlugins()
initp = false; initp = false;
} }
uptr pDsp;
extern void spu2DMA4Irq(); extern void spu2DMA4Irq();
extern void spu2DMA7Irq(); extern void spu2DMA7Irq();
extern void spu2Irq(); extern void spu2Irq();
@ -922,3 +924,25 @@ void PluginsResetGS()
int ret = GSinit(); int ret = GSinit();
if (ret != 0) { Msgbox::Alert("GSinit error: %d", params ret); } if (ret != 0) { Msgbox::Alert("GSinit error: %d", params ret); }
} }
#else
int OpenPlugins(const char* pTitleFilename)
{
return 0;
}
void ClosePlugins( bool closegs )
{
}
void ShutdownPlugins()
{
}
void CloseGS()
{
}
#endif

View File

@ -36,12 +36,16 @@
#include <wx/string.h> #include <wx/string.h>
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff #include <wx/gdicmn.h> // for wxPoint/wxRect stuff
#include <wx/intl.h>
#include <wx/log.h>
#include <wx/filename.h>
extern const wxRect wxDefaultRect; // wxWidgets lacks one of its own. extern const wxRect wxDefaultRect; // wxWidgets lacks one of its own.
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Include the STL junk that's actually handy. // Include the STL junk that's actually handy.
#include <stdexcept>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <string> #include <string>
@ -67,10 +71,19 @@ using std::max;
typedef int BOOL; typedef int BOOL;
# undef TRUE #undef TRUE
# undef FALSE #undef FALSE
# define TRUE 1 #define TRUE 1
# define FALSE 0 #define FALSE 0
// This should prove useful....
#define wxsFormat wxString::Format
// macro provided for tagging translation strings, without actually running them through the
// translator (which the _() does automatically, and sometimes we don't want that)
#define wxLt(a) a
#define wxASSERT_MSG_A( cond, msg ) wxASSERT_MSG( cond, wxString::FromAscii(msg).c_str() );
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Begin Pcsx2 Includes: Add items here that are local to Pcsx2 but stay relatively // Begin Pcsx2 Includes: Add items here that are local to Pcsx2 but stay relatively
@ -79,6 +92,8 @@ typedef int BOOL;
#include "zlib/zlib.h" #include "zlib/zlib.h"
#include "PS2Etypes.h" #include "PS2Etypes.h"
#include "Paths.h"
#include "Config.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "Exceptions.h" #include "Exceptions.h"
#include "MemcpyFast.h" #include "MemcpyFast.h"
@ -141,24 +156,33 @@ static __forceinline u32 timeGetTime()
# define __releaseinline __forceinline # define __releaseinline __forceinline
#endif #endif
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
// Emitter Instance Identifiers. If you add a new emitter, do it here also. // Dev / Debug conditionals --
// Note: Currently most of the instances map back to 0, since existing dynarec code all // Consts for using if() statements instead of uglier #ifdef macros.
// shares iCore and must therefore all share the same emitter instance. // Abbreviated macros for dev/debug only consoles and msgboxes.
// (note: these don't really belong here per-se, but it's an easy spot to use for now)
enum
{
EmitterId_R5900 = 0,
EmitterId_R3000a = EmitterId_R5900,
EmitterId_VU0micro = EmitterId_R5900,
EmitterId_VU1micro = EmitterId_R5900,
// Cotton's new microVU, which is iCore-free
EmitterId_microVU0,
EmitterId_microVU1,
// Air's eventual IopRec, which will also be iCore-free #ifdef PCSX2_DEVBUILD
EmitterId_R3000air,
# define DevCon Console
EmitterId_Count // must always be last! # define DevMsg MsgBox
}; static const bool IsDevBuild = true;
#else
# define DevCon 0&&Console
# define DevMsg
static const bool IsDevBuild = false;
#endif
#ifdef _DEBUG
# define DbgCon Console
static const bool IsDebugBuild = true;
#else
# define DbgCon 0&&Console
static const bool IsDebugBuild = false;
#endif

View File

@ -224,7 +224,7 @@ static __forceinline void _psxTestInterrupts()
} }
} }
void psxBranchTest() __releaseinline void psxBranchTest()
{ {
if( psxTestCycle( psxNextsCounter, psxNextCounter ) ) if( psxTestCycle( psxNextsCounter, psxNextCounter ) )
{ {

View File

@ -126,14 +126,14 @@ extern s32 psxCycleEE; // tracks IOP's current sych status with the EE
#ifndef _PC_ #ifndef _PC_
#define _i32(x) (s32)x #define _i32(x) (s32)x //R3000A
#define _u32(x) (u32)x #define _u32(x) (u32)x //R3000A
#define _i16(x) (s16)x #define _i16(x) (s16)x // Not used
#define _u16(x) (u16)x #define _u16(x) (u16)x // Not used
#define _i8(x) (s8)x #define _i8(x) (s8)x // Not used
#define _u8(x) (u8)x #define _u8(x) (u8)x //R3000A - once
/**** R3000A Instruction Macros ****/ /**** R3000A Instruction Macros ****/
#define _PC_ psxRegs.pc // The next PC to be executed #define _PC_ psxRegs.pc // The next PC to be executed
@ -200,7 +200,7 @@ extern R3000Acpu psxRec;
void psxReset(); void psxReset();
void psxShutdown(); void psxShutdown();
void psxException(u32 code, u32 step); void psxException(u32 code, u32 step);
void psxBranchTest(); extern void psxBranchTest();
void psxExecuteBios(); void psxExecuteBios();
void psxMemReset(); void psxMemReset();

View File

@ -35,8 +35,6 @@
#include "SPR.h" #include "SPR.h"
#include "Sif.h" #include "Sif.h"
#include "Paths.h"
#include "R5900Exceptions.h" #include "R5900Exceptions.h"
using namespace R5900; // for R5900 disasm tools using namespace R5900; // for R5900 disasm tools
@ -82,11 +80,11 @@ void cpuReset()
g_nextBranchCycle = cpuRegs.cycle + 4; g_nextBranchCycle = cpuRegs.cycle + 4;
EEsCycle = 0; EEsCycle = 0;
EEoCycle = cpuRegs.cycle; EEoCycle = cpuRegs.cycle;
eeWaitCycles = CHECK_WAITCYCLE_HACK ? 3072 : 768; eeWaitCycles = Config.Hacks.WaitCycleExt ? 3072 : 768;
// Cyclerate hacks effectively speed up the rate of event tests, so we can safely boost // Cyclerate hacks effectively speed up the rate of event tests, so we can safely boost
// the WaitCycles value here for x2 and x3 modes: // the WaitCycles value here for x2 and x3 modes:
if( CHECK_EE_CYCLERATE > 1 ) if( Config.Hacks.EECycleRate > 1 )
eeWaitCycles += 1024; eeWaitCycles += 1024;
hwReset(); hwReset();
@ -106,7 +104,7 @@ void cpuShutdown()
disR5900FreeSyms(); disR5900FreeSyms();
} }
__releaseinline void __fastcall cpuException(u32 code, u32 bd) __releaseinline void cpuException(u32 code, u32 bd)
{ {
cpuRegs.branch = 0; // Tells the interpreter that an exception occurred during a branch. cpuRegs.branch = 0; // Tells the interpreter that an exception occurred during a branch.
bool errLevel2, checkStatus; bool errLevel2, checkStatus;
@ -244,7 +242,7 @@ void cpuTestMissingHwInts() {
} }
// sets a branch test to occur some time from an arbitrary starting point. // sets a branch test to occur some time from an arbitrary starting point.
__forceinline int __fastcall cpuSetNextBranch( u32 startCycle, s32 delta ) __forceinline void cpuSetNextBranch( u32 startCycle, s32 delta )
{ {
// typecast the conditional to signed so that things don't blow up // typecast the conditional to signed so that things don't blow up
// if startCycle is greater than our next branch cycle. // if startCycle is greater than our next branch cycle.
@ -252,20 +250,18 @@ __forceinline int __fastcall cpuSetNextBranch( u32 startCycle, s32 delta )
if( (int)(g_nextBranchCycle - startCycle) > delta ) if( (int)(g_nextBranchCycle - startCycle) > delta )
{ {
g_nextBranchCycle = startCycle + delta; g_nextBranchCycle = startCycle + delta;
return 1;
} }
return 0;
} }
// sets a branch to occur some time from the current cycle // sets a branch to occur some time from the current cycle
__forceinline int __fastcall cpuSetNextBranchDelta( s32 delta ) __forceinline void cpuSetNextBranchDelta( s32 delta )
{ {
return cpuSetNextBranch( cpuRegs.cycle, delta ); cpuSetNextBranch( cpuRegs.cycle, delta );
} }
// tests the cpu cycle agaisnt the given start and delta values. // tests the cpu cycle agaisnt the given start and delta values.
// Returns true if the delta time has passed. // Returns true if the delta time has passed.
__forceinline int __fastcall cpuTestCycle( u32 startCycle, s32 delta ) __forceinline int cpuTestCycle( u32 startCycle, s32 delta )
{ {
// typecast the conditional to signed so that things don't explode // typecast the conditional to signed so that things don't explode
// if the startCycle is ahead of our current cpu cycle. // if the startCycle is ahead of our current cpu cycle.
@ -279,7 +275,7 @@ __forceinline void cpuSetBranch()
g_nextBranchCycle = cpuRegs.cycle; g_nextBranchCycle = cpuRegs.cycle;
} }
void cpuClearInt( uint i ) __forceinline void cpuClearInt( uint i )
{ {
jASSUME( i < 32 ); jASSUME( i < 32 );
cpuRegs.interrupt &= ~(1 << i); cpuRegs.interrupt &= ~(1 << i);

View File

@ -121,16 +121,16 @@ union CP0regs {
}; };
struct cpuRegisters { struct cpuRegisters {
GPRregs GPR; // GPR regs GPRregs GPR; // GPR regs
// NOTE: don't change order since recompiler uses it // NOTE: don't change order since recompiler uses it
GPR_reg HI; GPR_reg HI;
GPR_reg LO; // hi & log 128bit wide GPR_reg LO; // hi & log 128bit wide
CP0regs CP0; // is COP0 32bit? CP0regs CP0; // is COP0 32bit?
u32 sa; // shift amount (32bit), needs to be 16 byte aligned u32 sa; // shift amount (32bit), needs to be 16 byte aligned
u32 IsDelaySlot; // set true when the current instruction is a delay slot. u32 IsDelaySlot; // set true when the current instruction is a delay slot.
u32 pc; // Program counter, when changing offset in struct, check iR5900-X.S to make sure offset is correct u32 pc; // Program counter, when changing offset in struct, check iR5900-X.S to make sure offset is correct
u32 code; // current instruction u32 code; // current instruction
PERFregs PERF; PERFregs PERF;
u32 eCycle[32]; u32 eCycle[32];
u32 sCycle[32]; // for internal counters u32 sCycle[32]; // for internal counters
u32 cycle; // calculate cpucycles.. u32 cycle; // calculate cpucycles..
@ -180,7 +180,7 @@ struct tlbs
#ifndef _PC_ #ifndef _PC_
#define _i64(x) (s64)x /*#define _i64(x) (s64)x
#define _u64(x) (u64)x #define _u64(x) (u64)x
#define _i32(x) (s32)x #define _i32(x) (s32)x
@ -190,12 +190,12 @@ struct tlbs
#define _u16(x) (u16)x #define _u16(x) (u16)x
#define _i8(x) (s8)x #define _i8(x) (s8)x
#define _u8(x) (u8)x #define _u8(x) (u8)x*/
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// R5900 Instruction Macros // R5900 Instruction Macros
#define _PC_ cpuRegs.pc // The next PC to be executed #define _PC_ cpuRegs.pc // The next PC to be executed - only used in this header and R3000A.h
#define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register #define _Funct_ ((cpuRegs.code ) & 0x3F) // The funct part of the instruction register
#define _Rd_ ((cpuRegs.code >> 11) & 0x1F) // The rd part of the instruction register #define _Rd_ ((cpuRegs.code >> 11) & 0x1F) // The rd part of the instruction register
@ -257,14 +257,14 @@ extern void cpuInit();
extern void cpuReset(); // can throw Exception::FileNotFound. extern void cpuReset(); // can throw Exception::FileNotFound.
extern void cpuShutdown(); extern void cpuShutdown();
extern void cpuExecuteBios(); extern void cpuExecuteBios();
extern void __fastcall cpuException(u32 code, u32 bd); extern void cpuException(u32 code, u32 bd);
extern void cpuTlbMissR(u32 addr, u32 bd); extern void cpuTlbMissR(u32 addr, u32 bd);
extern void cpuTlbMissW(u32 addr, u32 bd); extern void cpuTlbMissW(u32 addr, u32 bd);
extern void cpuTestHwInts(); extern void cpuTestHwInts();
extern int __fastcall cpuSetNextBranch( u32 startCycle, s32 delta ); extern void cpuSetNextBranch( u32 startCycle, s32 delta );
extern int __fastcall cpuSetNextBranchDelta( s32 delta ); extern void cpuSetNextBranchDelta( s32 delta );
extern int __fastcall cpuTestCycle( u32 startCycle, s32 delta ); extern int cpuTestCycle( u32 startCycle, s32 delta );
extern void cpuSetBranch(); extern void cpuSetBranch();
extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900: extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:

View File

@ -23,10 +23,13 @@ namespace R5900Exception
{ {
using Exception::Ps2Generic; using Exception::Ps2Generic;
////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Abstract base class for R5900 exceptions; contains the cpuRegs instance at the // Abstract base class for R5900 exceptions; contains the cpuRegs instance at the
// time the exception is raised. // time the exception is raised.
// //
// Translation note: EE Emulation exceptions are untranslated only. There's really no
// point in providing translations for this hardcore mess. :)
//
class BaseExcept : public Ps2Generic class BaseExcept : public Ps2Generic
{ {
public: public:
@ -35,8 +38,8 @@ namespace R5900Exception
public: public:
virtual ~BaseExcept() throw()=0; virtual ~BaseExcept() throw()=0;
explicit BaseExcept( const std::string& msg ) : explicit BaseExcept( const wxString& msg ) :
Exception::Ps2Generic( "(EE) " + msg ), Exception::Ps2Generic( wxT("(EE) ") + msg ),
cpuState( cpuRegs ) cpuState( cpuRegs )
{ {
} }
@ -57,7 +60,7 @@ namespace R5900Exception
virtual ~AddressError() throw() {} virtual ~AddressError() throw() {}
explicit AddressError( u32 ps2addr, bool onWrite ) : explicit AddressError( u32 ps2addr, bool onWrite ) :
BaseExcept( fmt_string( "Address error, addr=0x%x [%s]", ps2addr, onWrite ? "store" : "load" ) ), BaseExcept( wxsFormat( wxT("Address error, addr=0x%x [%s]"), ps2addr, onWrite ? wxT("store") : wxT("load") ) ),
OnWrite( onWrite ), OnWrite( onWrite ),
Address( ps2addr ) Address( ps2addr )
{} {}
@ -75,7 +78,7 @@ namespace R5900Exception
virtual ~TLBMiss() throw() {} virtual ~TLBMiss() throw() {}
explicit TLBMiss( u32 ps2addr, bool onWrite ) : explicit TLBMiss( u32 ps2addr, bool onWrite ) :
BaseExcept( fmt_string( "Tlb Miss, addr=0x%x [%s]", ps2addr, onWrite ? "store" : "load" ) ), BaseExcept( wxsFormat( wxT("Tlb Miss, addr=0x%x [%s]"), ps2addr, onWrite ? wxT("store") : wxT("load") ) ),
OnWrite( onWrite ), OnWrite( onWrite ),
Address( ps2addr ) Address( ps2addr )
{} {}
@ -94,7 +97,7 @@ namespace R5900Exception
// //
explicit BusError( u32 ps2addr, bool onWrite ) : explicit BusError( u32 ps2addr, bool onWrite ) :
BaseExcept( fmt_string( "Bus Error, addr=0x%x [%s]", ps2addr, onWrite ? "store" : "load" ) ), BaseExcept( wxsFormat( wxT("Bus Error, addr=0x%x [%s]"), ps2addr, onWrite ? wxT("store") : wxT("load") ) ),
OnWrite( onWrite ), OnWrite( onWrite ),
Address( ps2addr ) Address( ps2addr )
{} {}
@ -108,7 +111,7 @@ namespace R5900Exception
virtual ~SystemCall() throw() {} virtual ~SystemCall() throw() {}
explicit SystemCall() : explicit SystemCall() :
BaseExcept( "SystemCall [SYSCALL]" ) BaseExcept( wxT("SystemCall [SYSCALL]") )
{} {}
}; };
@ -124,14 +127,14 @@ namespace R5900Exception
// Generates a trap for immediate-style Trap opcodes // Generates a trap for immediate-style Trap opcodes
explicit Trap() : explicit Trap() :
BaseExcept( "Trap" ), BaseExcept( wxT("Trap") ),
TrapCode( 0 ) TrapCode( 0 )
{} {}
// Generates a trap for register-style Trap instructions, which contain an // Generates a trap for register-style Trap instructions, which contain an
// error code in the opcode // error code in the opcode
explicit Trap( u16 trapcode ) : explicit Trap( u16 trapcode ) :
BaseExcept( "Trap" ), BaseExcept( wxT("Trap") ),
TrapCode( trapcode ) TrapCode( trapcode )
{} {}
}; };
@ -144,7 +147,7 @@ namespace R5900Exception
virtual ~Break() throw() {} virtual ~Break() throw() {}
explicit Break() : explicit Break() :
BaseExcept( "Break Instruction" ) BaseExcept( wxT("Break Instruction") )
{} {}
}; };
@ -156,7 +159,7 @@ namespace R5900Exception
virtual ~Overflow() throw() {} virtual ~Overflow() throw() {}
explicit Overflow() : explicit Overflow() :
BaseExcept( "Overflow" ) BaseExcept( wxT("Overflow") )
{} {}
}; };
@ -168,7 +171,7 @@ namespace R5900Exception
virtual ~DebugBreakpoint() throw() {} virtual ~DebugBreakpoint() throw() {}
explicit DebugBreakpoint() : explicit DebugBreakpoint() :
BaseExcept( "Debug Breakpoint" ) BaseExcept( wxT("Debug Breakpoint") )
{} {}
}; };
} }

View File

@ -106,13 +106,10 @@ namespace R5900
static const int MMI_Div = 22*8; static const int MMI_Div = 22*8;
static const int MMI_Default = 14; static const int MMI_Default = 14;
static const int FPU_Mult = 12; static const int FPU_Mult = 4*8;
static const int Store = 28; static const int Store = 8;
static const int Load = 22; static const int Load = 8;
static const int StoreFast = 14;
static const int LoadFast = 12;
} }
using namespace Cycles; using namespace Cycles;
@ -263,28 +260,28 @@ namespace R5900
MakeOpcode( LB, Load ); MakeOpcode( LB, Load );
MakeOpcode( LH, Load ); MakeOpcode( LH, Load );
MakeOpcode( LWL, Load ); MakeOpcode( LWL, Load );
MakeOpcode( LW, LoadFast ); MakeOpcode( LW, Load );
MakeOpcode( LBU, Load ); MakeOpcode( LBU, Load );
MakeOpcode( LHU, Load ); MakeOpcode( LHU, Load );
MakeOpcode( LWR, Load ); MakeOpcode( LWR, Load );
MakeOpcode( LWU, Load ); MakeOpcode( LWU, Load );
MakeOpcode( LWC1, Load ); MakeOpcode( LWC1, Load );
MakeOpcode( LQC2, Load ); MakeOpcode( LQC2, Load );
MakeOpcode( LD, LoadFast ); MakeOpcode( LD, Load );
// Stores! // Stores!
MakeOpcode( SQ, Store ); MakeOpcode( SQ, Store );
MakeOpcode( SB, Store );//slow MakeOpcode( SB, Store );
MakeOpcode( SH, Store );//slow MakeOpcode( SH, Store );
MakeOpcode( SWL, Store ); MakeOpcode( SWL, Store );
MakeOpcode( SW, StoreFast ); MakeOpcode( SW, Store );
MakeOpcode( SDL, Store ); MakeOpcode( SDL, Store );
MakeOpcode( SDR, Store ); MakeOpcode( SDR, Store );
MakeOpcode( SWR, Store ); MakeOpcode( SWR, Store );
MakeOpcode( SWC1, Store ); MakeOpcode( SWC1, Store );
MakeOpcode( SQC2, Store ); MakeOpcode( SQC2, Store );
MakeOpcode( SD, StoreFast ); MakeOpcode( SD, Store );
// Multimedia Instructions! // Multimedia Instructions!
@ -435,9 +432,9 @@ namespace R5900
MakeOpcode1( MIN_S, CopDefault ); MakeOpcode1( MIN_S, CopDefault );
MakeOpcode1( MUL_S, FPU_Mult ); MakeOpcode1( MUL_S, FPU_Mult );
MakeOpcode1( DIV_S, 3*8 ); MakeOpcode1( DIV_S, 6*8 );
MakeOpcode1( SQRT_S, 3*8 ); MakeOpcode1( SQRT_S, 6*8 );
MakeOpcode1( RSQRT_S, 4*8 ); MakeOpcode1( RSQRT_S, 8*8 );
MakeOpcode1( MULA_S, FPU_Mult ); MakeOpcode1( MULA_S, FPU_Mult );
MakeOpcode1( MADD_S, FPU_Mult ); MakeOpcode1( MADD_S, FPU_Mult );
MakeOpcode1( MSUB_S, FPU_Mult ); MakeOpcode1( MSUB_S, FPU_Mult );

View File

@ -18,8 +18,6 @@
#ifndef _R5900_OPCODETABLES_H #ifndef _R5900_OPCODETABLES_H
#define _R5900_OPCODETABLES_H #define _R5900_OPCODETABLES_H
#include <string>
#include "PS2Etypes.h" #include "PS2Etypes.h"
// TODO : Move these into the OpcodeTables namespace // TODO : Move these into the OpcodeTables namespace

View File

@ -120,10 +120,10 @@ namespace StateRecovery {
// have likely been cleared out. So save from the Recovery buffer instead of // have likely been cleared out. So save from the Recovery buffer instead of
// doing a "standard" save: // doing a "standard" save:
gzFile fileptr = gzopen( file.c_str(), "wb" ); gzFile fileptr = gzopen( file.ToAscii().data(), "wb" );
if( fileptr == NULL ) if( fileptr == NULL )
{ {
Msgbox::Alert( "File permissions error while trying to save to file:\n\t%ts", params &file ); Msgbox::Alert( wxsFormat( _("Error while trying to save to file: %s"), file.c_str() ) );
return; return;
} }
gzwrite( fileptr, &g_SaveVersion, sizeof( u32 ) ); gzwrite( fileptr, &g_SaveVersion, sizeof( u32 ) );
@ -138,7 +138,7 @@ namespace StateRecovery {
{ {
if( !g_EmulationInProgress ) if( !g_EmulationInProgress )
{ {
Msgbox::Alert( "You need to start a game first before you can save it's state." ); Msgbox::Alert( _("No emulation state to save") ); // translate: You need to start a game first before you can save it's state
return; return;
} }
@ -187,9 +187,10 @@ namespace StateRecovery {
} }
catch( Exception::RuntimeError& ex ) catch( Exception::RuntimeError& ex )
{ {
Msgbox::Alert( Msgbox::Alert( wxsFormat( // fixme: this error needs proper translation stuffs.
"Pcsx2 gamestate recovery failed. Some options may have been reverted to protect your game's state.\n" wxT("Pcsx2 gamestate recovery failed. Some options may have been reverted to protect your game's state.\n")
"Error: %s", params ex.cMessage() ); wxT("Error: %s"), ex.DisplayMessage().c_str() )
);
safe_delete( g_RecoveryState ); safe_delete( g_RecoveryState );
} }
} }

View File

@ -23,10 +23,6 @@
#include "iR5900.h" #include "iR5900.h"
#include "VUmicro.h" #include "VUmicro.h"
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
#define spr1 ((DMACh*)&PS2MEM_HW[0xD400])
#define gif ((DMACh*)&PS2MEM_HW[0xA000])
extern void mfifoGIFtransfer(int); extern void mfifoGIFtransfer(int);
/* Both of these should be bools. Again, next savestate break. --arcum42 */ /* Both of these should be bools. Again, next savestate break. --arcum42 */
@ -66,12 +62,15 @@ int _SPR0chain()
if ((psHu32(DMAC_CTRL) & 0xC) >= 0x8) // 0x8 VIF1 MFIFO, 0xC GIF MFIFO if ((psHu32(DMAC_CTRL) & 0xC) >= 0x8) // 0x8 VIF1 MFIFO, 0xC GIF MFIFO
{ {
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("SPR MFIFO Write outside MFIFO area"); if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR))
Console::WriteLn("SPR MFIFO Write outside MFIFO area");
else
mfifotransferred += spr0->qwc;
hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); hwMFIFOWrite(spr0->madr, (u8*)&PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
spr0->madr += spr0->qwc << 4; spr0->madr += spr0->qwc << 4;
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
mfifotransferred += spr0->qwc;
} }
else else
{ {
@ -88,9 +87,11 @@ int _SPR0chain()
return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed
} }
#define SPR0chain() \ __forceinline void SPR0chain()
cycles += _SPR0chain(); \ {
_SPR0chain();
spr0->qwc = 0; spr0->qwc = 0;
}
void _SPR0interleave() void _SPR0interleave()
@ -98,7 +99,6 @@ void _SPR0interleave()
int qwc = spr0->qwc; int qwc = spr0->qwc;
int sqwc = psHu32(DMAC_SQWC) & 0xff; int sqwc = psHu32(DMAC_SQWC) & 0xff;
int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff;
//int cycles = 0;
u32 *pMem; u32 *pMem;
if (tqwc == 0) tqwc = qwc; if (tqwc == 0) tqwc = qwc;
@ -123,9 +123,8 @@ void _SPR0interleave()
TestClearVUs(spr0->madr, spr0->qwc << 2); TestClearVUs(spr0->madr, spr0->qwc << 2);
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4); memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
} }
//cycles += tqwc * BIAS;
spr0->sadr += spr0->qwc * 16; spr0->sadr += spr0->qwc * 16;
spr0->madr += (sqwc + spr0->qwc) * 16; //qwc-= sqwc; spr0->madr += (sqwc + spr0->qwc) * 16;
} }
spr0->qwc = 0; spr0->qwc = 0;
@ -142,15 +141,12 @@ static __forceinline void _dmaSPR0()
// Transfer Dn_QWC from SPR to Dn_MADR // Transfer Dn_QWC from SPR to Dn_MADR
if ((spr0->chcr & 0xc) == 0x0) // Normal Mode if ((spr0->chcr & 0xc) == 0x0) // Normal Mode
{ {
int cycles = 0;
SPR0chain(); SPR0chain();
spr0finished = 1; spr0finished = 1;
return; return;
} }
else if ((spr0->chcr & 0xc) == 0x4) else if ((spr0->chcr & 0xc) == 0x4)
{ {
int cycles = 0;
u32 *ptag; u32 *ptag;
int id; int id;
bool done = FALSE; bool done = FALSE;
@ -166,7 +162,6 @@ static __forceinline void _dmaSPR0()
spr0->sadr += 16; spr0->sadr += 16;
// Transfer dma tag if tte is set // Transfer dma tag if tte is set
spr0->chcr = (spr0->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 spr0->chcr = (spr0->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
@ -200,7 +195,6 @@ static __forceinline void _dmaSPR0()
{ {
//Console::WriteLn("SPR0 TIE"); //Console::WriteLn("SPR0 TIE");
done = TRUE; done = TRUE;
spr0->qwc = 0;
} }
spr0finished = (done) ? 1 : 0; spr0finished = (done) ? 1 : 0;
@ -208,9 +202,7 @@ static __forceinline void _dmaSPR0()
if (!done) if (!done)
{ {
ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
//spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag CPU_INT(8, ((u16)ptag[0]) / BIAS); // the lower 16bits of the tag / BIAS);
CPU_INT(8, ((u16)ptag[0]) / BIAS); //spr0->qwc / BIAS);
spr0->qwc = 0;
return; return;
} }
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx", SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
@ -226,23 +218,27 @@ void SPRFROMinterrupt()
{ {
_dmaSPR0(); _dmaSPR0();
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) // GIF MFIFO if(mfifotransferred != 0)
{ {
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area"); if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) // GIF MFIFO
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); {
//Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr); if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area");
mfifoGIFtransfer(mfifotransferred); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
mfifotransferred = 0; //Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr);
} mfifoGIFtransfer(mfifotransferred);
else mfifotransferred = 0;
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO return;
}
else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
{ {
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("VIF MFIFO Write outside MFIFO area"); if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("VIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR)); spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
//Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr); //Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
mfifoVIF1transfer(mfifotransferred); mfifoVIF1transfer(mfifotransferred);
mfifotransferred = 0; mfifotransferred = 0;
return;
} }
}
if (spr0finished == 0) return; if (spr0finished == 0) return;
spr0->chcr &= ~0x100; spr0->chcr &= ~0x100;
hwDmacIrq(8); hwDmacIrq(8);
@ -289,9 +285,11 @@ int _SPR1chain()
return (spr1->qwc) * BIAS; return (spr1->qwc) * BIAS;
} }
#define SPR1chain() \ __forceinline void SPR1chain()
cycles += _SPR1chain(); \ {
spr1->qwc = 0; _SPR1chain();
spr1->qwc = 0;
}
void _SPR1interleave() void _SPR1interleave()
@ -299,7 +297,6 @@ void _SPR1interleave()
int qwc = spr1->qwc; int qwc = spr1->qwc;
int sqwc = psHu32(DMAC_SQWC) & 0xff; int sqwc = psHu32(DMAC_SQWC) & 0xff;
int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff; int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff;
//int cycles = 0;
u32 *pMem; u32 *pMem;
if (tqwc == 0) tqwc = qwc; if (tqwc == 0) tqwc = qwc;
@ -313,8 +310,7 @@ void _SPR1interleave()
pMem = (u32*)dmaGetAddr(spr1->madr); pMem = (u32*)dmaGetAddr(spr1->madr);
memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc << 4); memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc << 4);
spr1->sadr += spr1->qwc * 16; spr1->sadr += spr1->qwc * 16;
//cycles += spr1->qwc * BIAS; spr1->madr += (sqwc + spr1->qwc) * 16;
spr1->madr += (sqwc + spr1->qwc) * 16; //qwc-= sqwc;
} }
spr1->qwc = 0; spr1->qwc = 0;
@ -325,7 +321,7 @@ void _dmaSPR1() // toSPR work function
{ {
if ((spr1->chcr & 0xc) == 0) // Normal Mode if ((spr1->chcr & 0xc) == 0) // Normal Mode
{ {
int cycles = 0; //int cycles = 0;
// Transfer Dn_QWC from Dn_MADR to SPR1 // Transfer Dn_QWC from Dn_MADR to SPR1
SPR1chain(); SPR1chain();
spr1finished = 1; spr1finished = 1;
@ -333,7 +329,6 @@ void _dmaSPR1() // toSPR work function
} }
else if ((spr1->chcr & 0xc) == 0x4) else if ((spr1->chcr & 0xc) == 0x4)
{ {
int cycles = 0;
u32 *ptag; u32 *ptag;
int id; int id;
bool done = FALSE; bool done = FALSE;
@ -360,7 +355,7 @@ void _dmaSPR1() // toSPR work function
spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15 spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag until SPR1chain is called in a few lines.
spr1->madr = ptag[1]; //MADR = ADDR field spr1->madr = ptag[1]; //MADR = ADDR field
// Transfer dma tag if tte is set // Transfer dma tag if tte is set
@ -381,7 +376,6 @@ void _dmaSPR1() // toSPR work function
SPR_LOG("dmaIrq Set"); SPR_LOG("dmaIrq Set");
//Console::WriteLn("SPR1 TIE"); //Console::WriteLn("SPR1 TIE");
spr1->qwc = 0;
done = TRUE; done = TRUE;
} }
@ -389,9 +383,7 @@ void _dmaSPR1() // toSPR work function
if (!done) if (!done)
{ {
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
//spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag CPU_INT(9, (((u16)ptag[0]) / BIAS));// the lower 16 bits of the tag / BIAS);
CPU_INT(9, (((u16)ptag[0]) / BIAS));// spr1->qwc / BIAS);
spr1->qwc = 0;
} }
} }
else // Interleave Mode else // Interleave Mode
@ -408,7 +400,7 @@ void dmaSPR1() // toSPR
spr1->chcr, spr1->madr, spr1->qwc, spr1->chcr, spr1->madr, spr1->qwc,
spr1->tadr, spr1->sadr); spr1->tadr, spr1->sadr);
if ((spr1->chcr & 0xc) == 0x4 && spr1->qwc == 0) if (((spr1->chcr & 0xc) == 0x4) && (spr1->qwc == 0))
{ {
u32 *ptag; u32 *ptag;
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR

View File

@ -76,25 +76,25 @@ public:
static const int DefaultChunkSize = 0x1000 * sizeof(T); static const int DefaultChunkSize = 0x1000 * sizeof(T);
public: public:
const std::string Name; // user-assigned block name const wxString Name; // user-assigned block name
int ChunkSize; int ChunkSize;
protected: protected:
T* m_ptr; T* m_ptr;
int m_size; // size of the allocation of memory int m_size; // size of the allocation of memory
const static std::string m_str_Unnamed; const static wxString m_str_Unnamed;
protected: protected:
// Internal constructor for use by derived classes. This allows a derived class to // Internal constructor for use by derived classes. This allows a derived class to
// use its own memory allocation (with an aligned memory, for example). // use its own memory allocation (with an aligned memory, for example).
// Throws: // Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL. // Exception::OutOfMemory if the allocated_mem pointer is NULL.
explicit SafeArray( const std::string& name, T* allocated_mem, int initSize ) : explicit SafeArray( const wxString& name, T* allocated_mem, int initSize ) :
Name( name ) Name( name )
, ChunkSize( DefaultChunkSize ) , ChunkSize( DefaultChunkSize )
, m_ptr( allocated_mem ) , m_ptr( allocated_mem )
, m_size( initSize ) , m_size( initSize )
{ {
if( m_ptr == NULL ) if( m_ptr == NULL )
throw Exception::OutOfMemory(); throw Exception::OutOfMemory();
@ -111,19 +111,37 @@ public:
safe_free( m_ptr ); safe_free( m_ptr );
} }
explicit SafeArray( const std::string& name="Unnamed" ) : explicit SafeArray( const wxString& name=wxT("Unnamed") ) :
Name( name ) Name( name )
, ChunkSize( DefaultChunkSize ) , ChunkSize( DefaultChunkSize )
, m_ptr( NULL ) , m_ptr( NULL )
, m_size( 0 ) , m_size( 0 )
{ {
} }
explicit SafeArray( int initialSize, const std::string& name="Unnamed" ) : explicit SafeArray( const char* name ) :
Name( name ) Name( wxString::FromAscii(name) )
, ChunkSize( DefaultChunkSize ) , ChunkSize( DefaultChunkSize )
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) , m_ptr( NULL )
, m_size( initialSize ) , m_size( 0 )
{
}
explicit SafeArray( int initialSize, const wxString& name=wxT("Unnamed") ) :
Name( name )
, ChunkSize( DefaultChunkSize )
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
, m_size( initialSize )
{
if( m_ptr == NULL )
throw Exception::OutOfMemory();
}
explicit SafeArray( int initialSize, const char* name ) :
Name( wxString::FromAscii(name) )
, ChunkSize( DefaultChunkSize )
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
, m_size( initialSize )
{ {
if( m_ptr == NULL ) if( m_ptr == NULL )
throw Exception::OutOfMemory(); throw Exception::OutOfMemory();
@ -145,9 +163,11 @@ public:
if( m_ptr == NULL ) if( m_ptr == NULL )
{ {
throw Exception::OutOfMemory( throw Exception::OutOfMemory(
"Out-of-memory on block re-allocation. " wxsFormat( // english (for diagnostic)
"Old size: " + to_string( m_size ) + " bytes, " wxT("Out-of-memory on SafeArray block re-allocation.\n")
"New size: " + to_string( newalloc ) + " bytes" wxT("Old size: %d bytes, New size: %d bytes."),
m_size, newalloc
)
); );
} }
m_size = newalloc; m_size = newalloc;
@ -181,15 +201,8 @@ protected:
T* _getPtr( uint i ) const T* _getPtr( uint i ) const
{ {
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
if( i >= (uint)m_size ) if( IsDevBuild && i >= (uint)m_size )
{ throw Exception::IndexBoundsFault( Name, i, m_size );
assert( 0 ); // makes debugging easier sometimes. :)
throw Exception::IndexBoundsFault(
"Index out of bounds on SafeArray: " + Name +
" (index=" + to_string(i) +
", size=" + to_string(m_size) + ")"
);
}
#endif #endif
return &m_ptr[i]; return &m_ptr[i];
} }
@ -206,7 +219,7 @@ public:
static const int DefaultChunkSize = 0x80 * sizeof(T); static const int DefaultChunkSize = 0x80 * sizeof(T);
public: public:
const std::string Name; // user-assigned block name const wxString Name; // user-assigned block name
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time. int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
protected: protected:
@ -214,7 +227,7 @@ protected:
int m_allocsize; // size of the allocation of memory int m_allocsize; // size of the allocation of memory
uint m_length; // length of the array (active items, not buffer allocation) uint m_length; // length of the array (active items, not buffer allocation)
const static std::string m_str_Unnamed; const static wxString m_str_Unnamed;
protected: protected:
virtual T* _virtual_realloc( int newsize ) virtual T* _virtual_realloc( int newsize )
@ -224,17 +237,8 @@ protected:
void _boundsCheck( uint i ) const void _boundsCheck( uint i ) const
{ {
#ifdef PCSX2_DEVBUILD if( IsDevBuild && i >= (uint)m_length )
if( i >= (uint)m_length ) throw Exception::IndexBoundsFault( Name, i, m_length );
{
assert( 0 ); // makes debugging easier sometimes. :)
throw Exception::IndexBoundsFault(
"Index out of bounds on SafeArray: " + Name +
" (index=" + to_string(i) +
", length=" + to_string(m_length) + ")"
);
}
#endif
} }
public: public:
@ -242,7 +246,7 @@ public:
{ {
} }
explicit SafeList( const std::string& name="Unnamed" ) : explicit SafeList( const wxString& name=wxT("Unnamed") ) :
Name( name ) Name( name )
, ChunkSize( DefaultChunkSize ) , ChunkSize( DefaultChunkSize )
, m_ptr( NULL ) , m_ptr( NULL )
@ -251,7 +255,16 @@ public:
{ {
} }
explicit SafeList( int initialSize, const std::string& name="Unnamed" ) : explicit SafeList( const char* name ) :
Name( wxString::FromAscii(name) )
, ChunkSize( DefaultChunkSize )
, m_ptr( NULL )
, m_allocsize( 0 )
, m_length( 0 )
{
}
explicit SafeList( int initialSize, const wxString& name=wxT("Unnamed") ) :
Name( name ) Name( name )
, ChunkSize( DefaultChunkSize ) , ChunkSize( DefaultChunkSize )
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) ) , m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
@ -262,6 +275,17 @@ public:
throw Exception::OutOfMemory(); throw Exception::OutOfMemory();
} }
explicit SafeList( int initialSize, const char* name ) :
Name( wxString::FromAscii(name) )
, ChunkSize( DefaultChunkSize )
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
, m_allocsize( initialSize )
, m_length( 0 )
{
if( m_ptr == NULL )
throw Exception::OutOfMemory();
}
// Returns the size of the list, as according to the array type. This includes // Returns the size of the list, as according to the array type. This includes
// mapped items only. The actual size of the allocation may differ. // mapped items only. The actual size of the allocation may differ.
int GetLength() const { return m_length; } int GetLength() const { return m_length; }
@ -281,9 +305,12 @@ public:
if( m_ptr == NULL ) if( m_ptr == NULL )
{ {
throw Exception::OutOfMemory( throw Exception::OutOfMemory(
"Out-of-memory on list re-allocation. " // English Diagonstic message:
"Old size: " + to_string( m_allocsize ) + " bytes, " wxsFormat(
"New size: " + to_string( newalloc ) + " bytes" wxT("Out-of-memory on SafeList block re-allocation.\n")
wxT("Old size: %d bytes, New size: %d bytes"),
m_allocsize, newalloc
)
); );
} }
m_allocsize = newalloc; m_allocsize = newalloc;
@ -350,12 +377,12 @@ protected:
// Appends "(align: xx)" to the name of the allocation in devel builds. // Appends "(align: xx)" to the name of the allocation in devel builds.
// Maybe useful,maybe not... no harm in attaching it. :D // Maybe useful,maybe not... no harm in attaching it. :D
string _getName( const string& src ) wxString _getName( const wxString& src )
{ {
#ifdef PCSX2_DEVBUILD if( IsDevBuild )
return src + "(align:" + to_string(Alignment) + ")"; return src + wxsFormat( wxT("(align: %d)"), Alignment );
#endif else
return src; return src;
} }
public: public:
@ -365,12 +392,17 @@ public:
// mptr is set to null, so the parent class's destructor won't re-free it. // mptr is set to null, so the parent class's destructor won't re-free it.
} }
explicit SafeAlignedArray( const std::string& name="Unnamed" ) : explicit SafeAlignedArray( const wxString& name=wxT("Unnamed") ) :
SafeArray<T>::SafeArray( name ) SafeArray<T>::SafeArray( name )
{ {
} }
explicit SafeAlignedArray( int initialSize, const std::string& name="Unnamed" ) : explicit SafeAlignedArray( const char* name ) :
SafeArray<T>::SafeArray( name )
{
}
explicit SafeAlignedArray( int initialSize, const wxString& name=wxT("Unnamed") ) :
SafeArray<T>::SafeArray( SafeArray<T>::SafeArray(
_getName(name), _getName(name),
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ), (T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
@ -379,6 +411,15 @@ public:
{ {
} }
explicit SafeAlignedArray( int initialSize, const char* name ) :
SafeArray<T>::SafeArray(
_getName(wxString::FromAscii(name)),
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
initialSize
)
{
}
virtual SafeAlignedArray<T,Alignment>* Clone() const virtual SafeAlignedArray<T,Alignment>* Clone() const
{ {
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size ); SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size );
@ -387,4 +428,9 @@ public:
} }
}; };
// For lack of a better place for now (they depend on SafeList so they can't go in StringUtil)
extern void SplitString( SafeList<wxString>& dest, const wxString& src, const wxString& delims );
extern void JoinString( wxString& dest, const SafeList<wxString>& src, const wxString& separator );
#endif #endif

View File

@ -6,7 +6,7 @@
// The profiler does not have a Linux version yet. // The profiler does not have a Linux version yet.
// So for now we turn it into duds for non-Win32 platforms. // So for now we turn it into duds for non-Win32 platforms.
#ifdef _WIN32 #ifdef WIN32
void ProfilerInit(); void ProfilerInit();
void ProfilerTerm(); void ProfilerTerm();

View File

@ -50,16 +50,15 @@ static void PostLoadPrep()
wxString SaveState::GetFilename( int slot ) wxString SaveState::GetFilename( int slot )
{ {
wxString arrgh; return (g_Conf.Folders.Savestates +
arrgh.Printf( "%8.8X.%3.3d", ElfCRC, slot ); wxsFormat( wxT("%8.8X.%3.3d"), ElfCRC, slot )).GetFullPath();
return Path::Combine( SSTATES_DIR, arrgh );
} }
SaveState::SaveState( const char* msg, const wxString& destination ) : SaveState::SaveState( const char* msg, const wxString& destination ) :
m_version( g_SaveVersion ) m_version( g_SaveVersion )
, m_tagspace( 128 ) , m_tagspace( 128 )
{ {
Console::WriteLn( "%s %hs", params msg, &destination ); Console::WriteLn( "%s %s", params msg, destination.ToAscii().data() );
} }
s32 CALLBACK gsSafeFreeze( int mode, freezeData *data ) s32 CALLBACK gsSafeFreeze( int mode, freezeData *data )
@ -92,7 +91,10 @@ void SaveState::FreezeTag( const char* src )
if( strcmp( m_tagspace.GetPtr(), src ) != 0 ) if( strcmp( m_tagspace.GetPtr(), src ) != 0 )
{ {
assert( 0 ); assert( 0 );
throw Exception::BadSavedState( string( "Tag: " )+src ); throw Exception::BadSavedState(
// Untranslated diagnostic msg (use default msg for translation)
wxT("Savestate data corruption detected while reading tag: ") + wxString::FromAscii(src)
);
} }
} }
@ -105,10 +107,10 @@ void SaveState::FreezeAll()
// doesn't match the bios currently being used (chances are it'll still // doesn't match the bios currently being used (chances are it'll still
// work fine, but some games are very picky). // work fine, but some games are very picky).
char descout[128], descin[128]; char descin[128];
memzero_obj( descout ); wxString descout;
IsBIOS( Config.Bios, descout ); IsBIOS( g_Conf.Files.Bios(), descout );
memcpy_fast( descin, descout, 128 ); memcpy_fast( descin, descout.ToAscii().data(), 128 );
Freeze( descin ); Freeze( descin );
if( memcmp( descin, descout, 128 ) != 0 ) if( memcmp( descin, descout, 128 ) != 0 )
@ -117,7 +119,7 @@ void SaveState::FreezeAll()
"\n\tWarning: BIOS Version Mismatch, savestate may be unstable!\n" "\n\tWarning: BIOS Version Mismatch, savestate may be unstable!\n"
"\t\tCurrent BIOS: %s\n" "\t\tCurrent BIOS: %s\n"
"\t\tSavestate BIOS: %s\n", "\t\tSavestate BIOS: %s\n",
params descout, descin params descout.ToAscii().data(), descin
); );
} }
@ -205,7 +207,7 @@ gzBaseStateInfo::~gzBaseStateInfo()
gzSavingState::gzSavingState( const wxString& filename ) : gzSavingState::gzSavingState( const wxString& filename ) :
gzBaseStateInfo( "Saving state to: ", filename ) gzBaseStateInfo( "Saving state to: ", filename )
{ {
m_file = gzopen(filename.c_str(), "wb"); m_file = gzopen(filename.ToAscii().data(), "wb");
if( m_file == NULL ) if( m_file == NULL )
throw Exception::FileNotFound(); throw Exception::FileNotFound();
@ -217,7 +219,7 @@ gzSavingState::gzSavingState( const wxString& filename ) :
gzLoadingState::gzLoadingState( const wxString& filename ) : gzLoadingState::gzLoadingState( const wxString& filename ) :
gzBaseStateInfo( "Loading state from: ", filename ) gzBaseStateInfo( "Loading state from: ", filename )
{ {
m_file = gzopen(filename.c_str(), "rb"); m_file = gzopen(filename.ToAscii().data(), "rb");
if( m_file == NULL ) if( m_file == NULL )
throw Exception::FileNotFound(); throw Exception::FileNotFound();
@ -299,9 +301,9 @@ void gzLoadingState::FreezePlugin( const char* name, s32 (CALLBACK *freezer)(int
// uncompressed to/from memory state saves implementation // uncompressed to/from memory state saves implementation
memBaseStateInfo::memBaseStateInfo( SafeArray<u8>& memblock, const char* msg ) : memBaseStateInfo::memBaseStateInfo( SafeArray<u8>& memblock, const char* msg ) :
SaveState( msg, "Memory" ) SaveState( msg, wxT("Memory") )
, m_memory( memblock ) , m_memory( memblock )
, m_idx( 0 ) , m_idx( 0 )
{ {
// Always clear the MTGS thread state. // Always clear the MTGS thread state.
mtgsWaitGS(); mtgsWaitGS();
@ -376,7 +378,7 @@ void memLoadingState::FreezePlugin( const char* name, s32 (CALLBACK *freezer)(in
if( ( fP.size + m_idx ) > m_memory.GetSizeInBytes() ) if( ( fP.size + m_idx ) > m_memory.GetSizeInBytes() )
{ {
assert(0); assert(0);
throw Exception::BadSavedState( "memory" ); throw Exception::BadSavedState( wxT("memory") );
} }
fP.data = ((s8*)m_memory.GetPtr()) + m_idx; fP.data = ((s8*)m_memory.GetPtr()) + m_idx;

View File

@ -217,4 +217,5 @@ namespace StateRecovery
extern void Clear(); extern void Clear();
} }
#endif #endif

View File

@ -34,7 +34,7 @@ bool States_isSlotUsed(int num)
if (ElfCRC == 0) if (ElfCRC == 0)
return false; return false;
else else
return Path::isFile(SaveState::GetFilename( num )); return wxFileExists( SaveState::GetFilename( num ) );
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -62,11 +62,11 @@ void States_Load( const wxString& file )
try try
{ {
_loadStateOrExcept( file ); _loadStateOrExcept( file );
HostGui::Notice( fmt_string( "*PCSX2*: Loaded State %s", file.c_str() ) ); HostGui::Notice( wxsFormat( _("Loaded State %s"), file.c_str() ) );
} }
catch( Exception::StateLoadError_Recoverable& ex) catch( Exception::StateLoadError_Recoverable& ex)
{ {
Console::Notice( "Could not load savestate file: %hs.\n\n%s", params &file, ex.cMessage() ); Console::Notice( ex.LogMessage() );
// At this point the cpu hasn't been reset, so we can return // At this point the cpu hasn't been reset, so we can return
// control to the user safely... (that's why we use a console notice instead of a popup) // control to the user safely... (that's why we use a console notice instead of a popup)
@ -76,16 +76,12 @@ void States_Load( const wxString& file )
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
// The emulation state is ruined. Might as well give them a popup and start the gui. // The emulation state is ruined. Might as well give them a popup and start the gui.
// Translation Tip: Since the savestate load was incomplete, the emulator has been reset.
string message( fmt_string( Msgbox::Alert(
"Encountered an error while loading savestate from file: %s.\n", file.c_str() ) ); wxsFormat( _("Error loading savestate from file: %s"), file.c_str() ) +
L"\n\n" + _("Error details:") + ex.DisplayMessage()
if( g_EmulationInProgress ) );
message += "Since the savestate load was incomplete, the emulator must reset.\n";
message += "\nError: " + ex.Message();
Msgbox::Alert( message.c_str() );
SysReset(); SysReset();
return; return;
} }
@ -94,9 +90,9 @@ void States_Load( const wxString& file )
void States_Load(int num) void States_Load(int num)
{ {
string file( SaveState::GetFilename( num ) ); wxString file( SaveState::GetFilename( num ) );
if( !Path::isFile( file ) ) if( !Path::IsFile( file ) )
{ {
Console::Notice( "Saveslot %d is empty.", params num ); Console::Notice( "Saveslot %d is empty.", params num );
return; return;
@ -105,11 +101,11 @@ void States_Load(int num)
try try
{ {
_loadStateOrExcept( file ); _loadStateOrExcept( file );
HostGui::Notice( fmt_string( "*PCSX2*: Loaded State %d", num ) ); HostGui::Notice( wxsFormat( _("Loaded State %d"), num ) );
} }
catch( Exception::StateLoadError_Recoverable& ex) catch( Exception::StateLoadError_Recoverable& ex)
{ {
Console::Notice( "Could not load savestate slot %d.\n\n%s", params num, ex.cMessage() ); Console::Notice( wxsFormat( L"Could not load savestate slot %d.\n\n%s", num, ex.LogMessage() ) );
// At this point the cpu hasn't been reset, so we can return // At this point the cpu hasn't been reset, so we can return
// control to the user safely... (that's why we use a console notice instead of a popup) // control to the user safely... (that's why we use a console notice instead of a popup)
@ -119,16 +115,13 @@ void States_Load(int num)
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
// The emulation state is ruined. Might as well give them a popup and start the gui. // The emulation state is ruined. Might as well give them a popup and start the gui.
// Translation Tip: Since the savestate load was incomplete, the emulator has been reset.
string message( fmt_string( Msgbox::Alert(
"Encountered an error while loading savestate from slot %d.\n", num ) ); wxsFormat( _("Error loading savestate from slot %d"), file.c_str() ) +
L"\n\n" + _("Error details:") + ex.DisplayMessage()
);
if( g_EmulationInProgress )
message += "Since the savestate load was incomplete, the emulator has been reset.\n";
message += "\nError: " + ex.Message();
Msgbox::Alert( message.c_str() );
SysEndExecution(); SysEndExecution();
return; return;
} }
@ -144,13 +137,23 @@ void States_Save( const wxString& file )
try try
{ {
StateRecovery::SaveToFile( file ); StateRecovery::SaveToFile( file );
HostGui::Notice( fmt_string( "State saved to file: %s", file.c_str() ) ); HostGui::Notice( wxsFormat( _("State saved to file: %s"), file.c_str() ) );
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
Console::Error( (fmt_string( // TODO: Implement a "pause the action and issue a popup" thing here.
"An error occurred while trying to save to file %s\n", file.c_str() ) + // *OR* some kind of GS overlay... [for now we use the console]
"Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str()
// Translation Tip: "Your emulation state has not been saved!"
/*Msgbox::Alert(
wxsFormat( _("Error saving state to file: %s"), file.c_str() ) +
L"\n\n" + _("Error details:") + ex.DisplayMessage()
);*/
Console::Error( wxsFormat(
L"An error occurred while trying to save to file %s\n", file.c_str() ) +
L"Your emulation state has not been saved!\n\nError: " + ex.LogMessage()
); );
} }
@ -163,14 +166,17 @@ void States_Save(int num)
try try
{ {
StateRecovery::SaveToSlot( num ); StateRecovery::SaveToSlot( num );
HostGui::Notice( fmt_string( "State saved to slot %d", num ) ); HostGui::Notice( wxsFormat( _("State saved to slot %d"), num ) );
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
Console::Error( (fmt_string( // TODO: Implement a "pause the action and issue a popup" thing here.
"An error occurred while trying to save to slot %d\n", num ) + // *OR* some kind of GS overlay... [for now we use the console]
"Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str()
); Console::Error( wxsFormat(
L"An error occurred while trying to save to slot %d\n", num ) +
L"Your emulation state has not been saved!\n\nError: " + ex.LogMessage()
);
} }
HostGui::ResetMenuSlots(); HostGui::ResetMenuSlots();
} }

View File

@ -25,10 +25,6 @@
using namespace std; using namespace std;
#define sif0dma ((DMACh*)&PS2MEM_HW[0xc000])
#define sif1dma ((DMACh*)&PS2MEM_HW[0xc400])
#define sif2dma ((DMACh*)&PS2MEM_HW[0xc800])
DMACh *sif0ch; DMACh *sif0ch;
DMACh *sif1ch; DMACh *sif1ch;
DMACh *sif2ch; DMACh *sif2ch;
@ -206,7 +202,10 @@ __forceinline void SIF0Dma()
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr); //SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
SIF_LOG("----------- %lX of %lX", readSize << 2, size << 2); SIF_LOG("----------- %lX of %lX", readSize << 2, size << 2);
_dmaGetAddr(sif0dma, ptag, sif0dma->madr, 5); ptag = _dmaGetAddr(sif0dma, sif0dma->madr, 5);
if (ptag == NULL) return;
//_dmaGetAddr(sif0dma, *ptag, sif0dma->madr, 5);
SIF0read((u32*)ptag, readSize << 2); SIF0read((u32*)ptag, readSize << 2);
@ -285,7 +284,12 @@ __forceinline void SIF1Dma()
{ {
// Process DMA tag at sif1dma->tadr // Process DMA tag at sif1dma->tadr
done = FALSE; done = FALSE;
_dmaGetAddr(sif1dma, ptag, sif1dma->tadr, 6); ptag = _dmaGetAddr(sif1dma, sif1dma->tadr, 6);
if (ptag == NULL) return;
//_dmaGetAddr(sif1dma, *ptag, sif1dma->tadr, 6);
sif1dma->chcr = (sif1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag sif1dma->chcr = (sif1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag
sif1dma->qwc = (u16)ptag[0]; sif1dma->qwc = (u16)ptag[0];
@ -348,7 +352,10 @@ __forceinline void SIF1Dma()
int qwTransfer = sif1dma->qwc; int qwTransfer = sif1dma->qwc;
u32 *data; u32 *data;
_dmaGetAddr(sif1dma, data, sif1dma->madr, 6); data = _dmaGetAddr(sif1dma, sif1dma->madr, 6);
if (data == NULL) return;
//_dmaGetAddr(sif1dma, *data, sif1dma->madr, 6);
if (qwTransfer > (FIFO_SIF1_W - sif1.fifoSize) / 4) // Copy part of sif1dma into FIFO if (qwTransfer > (FIFO_SIF1_W - sif1.fifoSize) / 4) // Copy part of sif1dma into FIFO
qwTransfer = (FIFO_SIF1_W - sif1.fifoSize) / 4; qwTransfer = (FIFO_SIF1_W - sif1.fifoSize) / 4;

View File

@ -152,7 +152,6 @@ void SIO_CommandWrite(u8 value,int way) {
case 3: case 3:
// No pad connected. // No pad connected.
sio.parp++; sio.parp++;
sio.bufcount = 6;
if (sio.parp == sio.bufcount) { sio.padst = 0; return; } if (sio.parp == sio.bufcount) { sio.padst = 0; return; }
SIO_INT(); SIO_INT();
return; return;
@ -451,16 +450,16 @@ void SIO_CommandWrite(u8 value,int way) {
break; break;
case 0x21: case 0x21:
// Set pad slot. // Set pad slot.
sio.mtapst = 0x21; sio.mtapst = value;
sio.bufcount = 6; // No idea why this is 6, saved from old code. sio.bufcount = 6; // No idea why this is 6, saved from old code.
break; break;
case 0x22: case 0x22:
// Set memcard slot. // Set memcard slot.
sio.mtapst = 0x22; sio.mtapst = value;
sio.bufcount = 6; // No idea why this is 6, saved from old code. sio.bufcount = 6; // No idea why this is 6, saved from old code.
break; break;
} }
// Commented out values are from original code. Break multitap in bios. // Commented out values are from original code. They break multitap in bios.
sio.buf[sio.bufcount-1]=0;//'+'; sio.buf[sio.bufcount-1]=0;//'+';
sio.buf[sio.bufcount]=0;//'Z'; sio.buf[sio.bufcount]=0;//'Z';
return; return;
@ -508,7 +507,7 @@ void InitializeSIO(u8 value)
sio.StatReg &= ~TX_EMPTY; // Now the Buffer is not empty sio.StatReg &= ~TX_EMPTY; // Now the Buffer is not empty
sio.StatReg |= RX_RDY; // Transfer is Ready sio.StatReg |= RX_RDY; // Transfer is Ready
sio.bufcount = 2; sio.bufcount = 4; // Default size, when no pad connected.
sio.parp = 0; sio.parp = 0;
sio.padst = 1; sio.padst = 1;
sio.packetsize = 1; sio.packetsize = 1;
@ -517,7 +516,7 @@ void InitializeSIO(u8 value)
switch (sio.CtrlReg&0x2002) { switch (sio.CtrlReg&0x2002) {
case 0x0002: case 0x0002:
if (!PAD1setSlot(1, 1+sio.activePadSlot[0])) { if (!PAD1setSlot(1, 1+sio.activePadSlot[0]) && sio.activePadSlot[0]) {
// Pad is not present. Don't send poll, just return a bunch of 0's. // Pad is not present. Don't send poll, just return a bunch of 0's.
sio2.packet.recvVal1 = 0x1D100; sio2.packet.recvVal1 = 0x1D100;
sio.padst = 3; sio.padst = 3;
@ -527,7 +526,7 @@ void InitializeSIO(u8 value)
} }
break; break;
case 0x2002: case 0x2002:
if (!PAD2setSlot(1, 1+sio.activePadSlot[1])) { if (!PAD2setSlot(2, 1+sio.activePadSlot[1]) && sio.activePadSlot[1]) {
// Pad is not present. Don't send poll, just return a bunch of 0's. // Pad is not present. Don't send poll, just return a bunch of 0's.
sio2.packet.recvVal1 = 0x1D100; sio2.packet.recvVal1 = 0x1D100;
sio.padst = 3; sio.padst = 3;
@ -554,6 +553,7 @@ void InitializeSIO(u8 value)
int port = sio.GetMultitapPort(); int port = sio.GetMultitapPort();
if (!IsMtapPresent(port)) if (!IsMtapPresent(port))
{ {
// If "unplug" multitap mid game, set active slots to 0.
sio.activePadSlot[port] = 0; sio.activePadSlot[port] = 0;
sio.activeMemcardSlot[port] = 0; sio.activeMemcardSlot[port] = 0;
} }

View File

@ -66,7 +66,7 @@ void __Log( const char* fmt, ... )
assert( length <= 2020 ); assert( length <= 2020 );
if( length > 2020 ) if( length > 2020 )
{ {
Msgbox::Alert("Source Log Stack Corruption Detected. Program execution may become unstable."); Msgbox::Alert( _("Source log buffer overrun") );
// fixme: should throw an exception here once we have proper exception handling implemented. // fixme: should throw an exception here once we have proper exception handling implemented.
} }
@ -97,7 +97,7 @@ static __forceinline void _vSourceLog( u16 protocol, u8 source, u32 cpuPc, u32 c
assert( length <= 2020 ); assert( length <= 2020 );
if( length > 2020 ) if( length > 2020 )
{ {
Msgbox::Alert("Source Log Stack Corruption Detected. Program execution may become unstable."); Msgbox::Alert( _("Source log buffer overrun") );
// fixme: should throw an exception here once we have proper exception handling implemented. // fixme: should throw an exception here once we have proper exception handling implemented.
} }

View File

@ -23,8 +23,6 @@
#include "IopCommon.h" #include "IopCommon.h"
#include "Stats.h" #include "Stats.h"
#include "Paths.h"
void statsOpen() { void statsOpen() {
stats.vsyncCount = 0; stats.vsyncCount = 0;
stats.vsyncTime = time(NULL); stats.vsyncTime = time(NULL);

View File

@ -36,6 +36,7 @@ std::string to_string(const T& value)
} }
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Helpers for wxWidgets stuff!
// //
extern wxString ToString( const wxPoint& src, const wxString& separator=wxT(",") ); extern wxString ToString( const wxPoint& src, const wxString& separator=wxT(",") );
extern wxString ToString( const wxSize& src, const wxString& separator=wxT(",") ); extern wxString ToString( const wxSize& src, const wxString& separator=wxT(",") );

View File

@ -37,12 +37,6 @@ SessionOverrideFlags g_Session = {false};
bool sysInitialized = false; bool sysInitialized = false;
namespace Exception
{
BaseException::~BaseException() throw() {}
}
// I can't believe I had to make my own version of trim. C++'s STL is totally whack. // I can't believe I had to make my own version of trim. C++'s STL is totally whack.
// And I still had to fix it too. I found three samples of trim online and *all* three // And I still had to fix it too. I found three samples of trim online and *all* three
// were buggy. People really need to learn to code before they start posting trim // were buggy. People really need to learn to code before they start posting trim
@ -172,16 +166,16 @@ bool SysAllocateMem()
psxMemAlloc(); psxMemAlloc();
vuMicroMemAlloc(); vuMicroMemAlloc();
} }
catch( Exception::OutOfMemory& ex ) catch( Exception::OutOfMemory& )
{ {
// TODO : Should this error be handled here or allowed to be handled by the main
// exception handler?
// Failures on the core initialization of memory is bad, since it means the emulator is // Failures on the core initialization of memory is bad, since it means the emulator is
// completely non-functional. If the failure is in the VM build then we can try running // completely non-functional.
// the VTLB build instead. If it's the VTLB build then ... ouch.
//Msgbox::Alert( "Failed to allocate memory needed to run pcsx2.\n\nError: %s", params ex.cMessage() );
// VTLB build must fail outright...
Msgbox::Alert( "Failed to allocate memory needed to run pcsx2.\n\nError: %s", params ex.cMessage() );
SysShutdownMem(); SysShutdownMem();
return false; return false;
} }
@ -207,14 +201,17 @@ void SysAllocateDynarecs()
recCpu.Allocate(); recCpu.Allocate();
psxRec.Allocate(); psxRec.Allocate();
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& )
{ {
Msgbox::Alert( // TODO : Fix this message. It should respond according to the user's
// currently configured recompiler.interpreter options, for example.
/*Msgbox::Alert(
"The EE/IOP recompiler failed to initialize with the following error:\n\n" "The EE/IOP recompiler failed to initialize with the following error:\n\n"
"%s" "%s"
"\n\nThe EE/IOP interpreter will be used instead (slow!).", params "\n\nThe EE/IOP interpreter will be used instead (slow!).", params
ex.cMessage() ex.cMessage()
); );*/
g_Session.ForceDisableEErec = true; g_Session.ForceDisableEErec = true;
@ -226,14 +223,19 @@ void SysAllocateDynarecs()
{ {
VU0micro::recAlloc(); VU0micro::recAlloc();
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& )
{ {
// TODO : Fix this message. It should respond according to the user's
// currently configured recompiler.interpreter options, for example.
/*
Msgbox::Alert( Msgbox::Alert(
"The VU0 recompiler failed to initialize with the following error:\n\n" "The VU0 recompiler failed to initialize with the following error:\n\n"
"%s" "%s"
"\n\nThe VU0 interpreter will be used for this session (may slow down some games).", params "\n\nThe VU0 interpreter will be used for this session (may slow down some games).", params
ex.cMessage() ex.cMessage()
); );
*/
g_Session.ForceDisableVU0rec = true; g_Session.ForceDisableVU0rec = true;
VU0micro::recShutdown(); VU0micro::recShutdown();
@ -243,14 +245,19 @@ void SysAllocateDynarecs()
{ {
VU1micro::recAlloc(); VU1micro::recAlloc();
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& )
{ {
// TODO : Fix this message. It should respond according to the user's
// currently configured recompiler.interpreter options, for example.
/*
Msgbox::Alert( Msgbox::Alert(
"The VU1 recompiler failed to initialize with the following error:\n\n" "The VU1 recompiler failed to initialize with the following error:\n\n"
"%s" "%s"
"\n\nThe VU1 interpreter will be used for this session (will slow down most games).", params "\n\nThe VU1 interpreter will be used for this session (will slow down most games).", params
ex.cMessage() ex.cMessage()
); );
*/
g_Session.ForceDisableVU1rec = true; g_Session.ForceDisableVU1rec = true;
VU1micro::recShutdown(); VU1micro::recShutdown();
@ -362,7 +369,7 @@ void SysExecute()
} }
catch( R5900Exception::BaseExcept& ex ) catch( R5900Exception::BaseExcept& ex )
{ {
Console::Error( ex.cMessage() ); Console::Error( ex.LogMessage() );
Console::Error( fmt_string( "(EE) PC: 0x%8.8x \tCycle: 0x%8.8x", ex.cpuState.pc, ex.cpuState.cycle ).c_str() ); Console::Error( fmt_string( "(EE) PC: 0x%8.8x \tCycle: 0x%8.8x", ex.cpuState.pc, ex.cpuState.cycle ).c_str() );
} }
} }
@ -383,7 +390,7 @@ void SysEndExecution()
// Used by Run::FromCD, and Run->Execute when no active emulation state is present. // Used by Run::FromCD, and Run->Execute when no active emulation state is present.
// elf_file - if NULL, the CDVD plugin is queried for the ELF file. // elf_file - if NULL, the CDVD plugin is queried for the ELF file.
// use_bios - forces the game to boot through the PS2 bios, instead of bypassing it. // use_bios - forces the game to boot through the PS2 bios, instead of bypassing it.
void SysPrepareExecution( const char* elf_file, bool use_bios ) void SysPrepareExecution( const wxString& elf_file, bool use_bios )
{ {
if( !g_EmulationInProgress ) if( !g_EmulationInProgress )
{ {
@ -393,22 +400,21 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
} }
catch( Exception::BaseException& ex ) catch( Exception::BaseException& ex )
{ {
Msgbox::Alert( ex.cMessage() ); Msgbox::Alert( ex.DisplayMessage() );
return; return;
} }
if (OpenPlugins(NULL) == -1) if (OpenPlugins(NULL) == -1)
return; return;
if( elf_file == NULL ) if( elf_file.IsEmpty() )
{ {
if( !StateRecovery::HasState() ) if( !StateRecovery::HasState() )
{ {
// Not recovering a state, so need to execute the bios and load the ELF information. // Not recovering a state, so need to execute the bios and load the ELF information.
// (note: gsRecoveries are done from ExecuteCpu) // (note: gsRecoveries are done from ExecuteCpu)
char ename[g_MaxPath]; wxString ename;
ename[0] = 0;
if( !use_bios ) if( !use_bios )
GetPS2ElfName( ename ); GetPS2ElfName( ename );
@ -440,8 +446,8 @@ void SysReset()
// so the status bar won't receive the WM_PAINT messages needed to update itself anyway. // so the status bar won't receive the WM_PAINT messages needed to update itself anyway.
// Oops! (air) // Oops! (air)
HostGui::Notice("Resetting..."); HostGui::Notice( _("Resetting...") );
Console::SetTitle("Resetting..."); Console::SetTitle( _("Resetting...") );
g_EmulationInProgress = false; g_EmulationInProgress = false;
StateRecovery::Clear(); StateRecovery::Clear();
@ -454,8 +460,8 @@ void SysReset()
// Note : No need to call cpuReset() here. It gets called automatically before the // Note : No need to call cpuReset() here. It gets called automatically before the
// emulator resumes execution. // emulator resumes execution.
HostGui::Notice("Ready"); HostGui::Notice( _("Ready") );
Console::SetTitle("*PCSX2* Emulation state is reset."); Console::SetTitle( _("Emulation state is reset.") );
} }
u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller) u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
@ -482,8 +488,3 @@ u8 *SysMmapEx(uptr base, u32 size, uptr bounds, const char *caller)
} }
return Mem; return Mem;
} }
void *SysLoadLibrary(const char *lib) { return HostSys::LoadLibrary( lib ); }
void *SysLoadSym(void *lib, const char *sym) { return HostSys::LoadSym( lib, sym ); }
const char *SysLibError() { return HostSys::LibError(); }
void SysCloseLibrary(void *lib) { HostSys::CloseLibrary( lib ); }

View File

@ -21,7 +21,6 @@
#include "PS2Etypes.h" #include "PS2Etypes.h"
#include "Pcsx2Config.h" #include "Pcsx2Config.h"
#include "Paths.h"
#include "SafeArray.h" #include "SafeArray.h"
#include "Misc.h" #include "Misc.h"
#include "Threading.h" // to use threading stuff, include the Threading namespace in your file. #include "Threading.h" // to use threading stuff, include the Threading namespace in your file.
@ -39,14 +38,6 @@ enum PageProtectionMode
// versions defined in System.h/cpp. // versions defined in System.h/cpp.
namespace HostSys namespace HostSys
{ {
// Damn windows.h namespace pollution!!
#undef LoadLibrary
extern void *LoadLibrary(const char *lib); // Loads Library
extern void *LoadSym(void *lib, const char *sym); // Loads Symbol from Library
extern const char *LibError(); // Gets previous error loading symbols
extern void CloseLibrary(void *lib); // Closes Library
// Maps a block of memory for use as a recompiled code buffer. // Maps a block of memory for use as a recompiled code buffer.
// The allocated block has code execution privileges. // The allocated block has code execution privileges.
// Returns NULL on allocation failure. // Returns NULL on allocation failure.
@ -76,7 +67,7 @@ extern void SysShutdownMem();
extern void SysRestorableReset(); // Saves the current emulation state prior to spu reset. extern void SysRestorableReset(); // Saves the current emulation state prior to spu reset.
extern void SysClearExecutionCache(); // clears recompiled execution caches! extern void SysClearExecutionCache(); // clears recompiled execution caches!
extern void SysEndExecution(); // terminates plugins, saves GS state (if enabled), and signals emulation loop to end. extern void SysEndExecution(); // terminates plugins, saves GS state (if enabled), and signals emulation loop to end.
extern void SysPrepareExecution( const char* elf_file, bool use_bios=false ); extern void SysPrepareExecution( const wxString& elf_file, bool use_bios=false );
// initiates high-speed execution of the emulation state. This function is currently // initiates high-speed execution of the emulation state. This function is currently
// designed to be run from an event loop, but will eventually be re-tooled with threading // designed to be run from an event loop, but will eventually be re-tooled with threading
@ -85,13 +76,6 @@ extern void SysPrepareExecution( const char* elf_file, bool use_bios=false );
extern void SysExecute(); extern void SysExecute();
// Library Helpers for HostSys functions, left in for now for convenience.
extern void *SysLoadLibrary(const char *lib); // Loads Library
extern void *SysLoadSym(void *lib, const char *sym); // Loads Symbol from Library
extern const char *SysLibError(); // Gets previous error loading symbols
extern void SysCloseLibrary(void *lib); // Closes Library
// Maps a block of memory for use as a recompiled code buffer, and ensures that the // Maps a block of memory for use as a recompiled code buffer, and ensures that the
// allocation is below a certain memory address (specified in "bounds" parameter). // allocation is below a certain memory address (specified in "bounds" parameter).
// The allocated block has code execution privileges. // The allocated block has code execution privileges.
@ -183,6 +167,16 @@ namespace Console
// Newline is automatically appended. // Newline is automatically appended.
extern bool Status( const char* fmt, VARG_PARAM dummy, ... ); extern bool Status( const char* fmt, VARG_PARAM dummy, ... );
extern bool __fastcall Status( const char* text ); extern bool __fastcall Status( const char* text );
extern bool __fastcall Write( const wxString& text );
extern bool __fastcall Write( Colors color, const wxString& text );
extern bool __fastcall WriteLn( const wxString& text );
extern bool __fastcall WriteLn( Colors color, const wxString& text );
extern bool __fastcall Error( const wxString& text );
extern bool __fastcall Notice( const wxString& text );
extern bool __fastcall Status( const wxString& text );
} }
// Different types of message boxes that the emulator can employ from the friendly confines // Different types of message boxes that the emulator can employ from the friendly confines
@ -193,12 +187,11 @@ namespace Msgbox
{ {
// Pops up an alert Dialog Box with a singular "OK" button. // Pops up an alert Dialog Box with a singular "OK" button.
// Always returns false. Replacement for SysMessage. // Always returns false. Replacement for SysMessage.
extern bool Alert( const char* fmt, VARG_PARAM dummy, ... ); extern bool Alert( const wxString& text );
extern bool Alert( const char* text );
// Pops up a dialog box with Ok/Cancel buttons. Returns the result of the inquiry, // Pops up a dialog box with Ok/Cancel buttons. Returns the result of the inquiry,
// true if OK, false if cancel. // true if OK, false if cancel.
extern bool OkCancel( const char* fmt, VARG_PARAM dummy, ... ); extern bool OkCancel( const wxString& text );
} }
using Console::Color_Red; using Console::Color_Red;
@ -209,35 +202,4 @@ using Console::Color_Cyan;
using Console::Color_Yellow; using Console::Color_Yellow;
using Console::Color_White; using Console::Color_White;
//////////////////////////////////////////////////////////////
// Dev / Debug conditionals --
// Consts for using if() statements instead of uglier #ifdef macros.
// Abbreviated macros for dev/debug only consoles and msgboxes.
#ifdef PCSX2_DEVBUILD
# define DevCon Console
# define DevMsg MsgBox
static const bool IsDevBuild = true;
#else
# define DevCon 0&&Console
# define DevMsg
static const bool IsDevBuild = false;
#endif
#ifdef _DEBUG
# define DbgCon Console
static const bool IsDebugBuild = true;
#else
# define DbgCon 0&&Console
static const bool IsDebugBuild = false;
#endif
#endif /* __SYSTEM_H__ */ #endif /* __SYSTEM_H__ */

View File

@ -0,0 +1,46 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
#include <wx/file.h>
//////////////////////////////////////////////////////////////////////////////////////////
// Helper class for wxFile which provides old-school ASCII interfaces (char* style),
// for saving some scrodom-kicking pain involved in converting log dumps and stuff over
// to unicode.
//
// This is an ideal solution on several fronts since it is both faster, and fully func-
// tional (since the dumps are only ever english/ascii only).
//
class AsciiFile : public wxFile
{
public:
using wxFile::Write;
AsciiFile( const wxString& src, OpenMode mode = read ) :
wxFile( src, mode ) {}
void Printf( const char* fmt, ... );
void Write( const char* fmt )
{
Write( fmt, strlen( fmt ) );
}
};

View File

@ -0,0 +1,29 @@
/* Pcsx2 - Pc Ps2 Emulator
* Copyright (C) 2002-2009 Pcsx2 Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "PrecompiledHeader.h"
#include "AsciiFile.h"
void AsciiFile::Printf( const char* fmt, ... )
{
va_list list;
va_start( list, fmt );
string writeme; vssprintf( writeme, fmt, list );
va_end( list );
Write( writeme.c_str(), writeme.length() );
}

View File

@ -0,0 +1,7 @@
Folder: pcsx2/Utilities
Purpose: To hold general non-pcsx2-specific utility classes which may (or may not) be shared out into a
common folder at a later date. This includes unicode utils, file manipulators, threading, etc.
Details: I plan to move files into this folder here ont he wxGui branch over time, and then move the
whole lot over to common as a whole library of sorts. I thinkit'll be easier that way than trying
to piecemeal individual files over (especially since some of them have inter-dependencies)

View File

@ -38,26 +38,6 @@ using namespace R5900;
#define VF_VAL(x) ((x==0x80000000)?0:(x)) #define VF_VAL(x) ((x==0x80000000)?0:(x))
void iDumpVU0Registers()
{
// fixme: This code is outdated, broken, and lacks printed labels.
// Needs heavy mods to be useful.
#if 0
int i;
for(i = 1; i < 32; ++i) {
__Log("v%d: %x %x %x %x, vi: ", i, VF_VAL(VU0.VF[i].UL[3]), VF_VAL(VU0.VF[i].UL[2]),
VF_VAL(VU0.VF[i].UL[1]), VF_VAL(VU0.VF[i].UL[0]));
if( i == REG_Q || i == REG_P ) __Log("%f\n", VU0.VI[i].F);
else if( i == REG_MAC_FLAG ) __Log("%x\n", 0);//VU0.VI[i].UL&0xff);
else if( i == REG_STATUS_FLAG ) __Log("%x\n", 0);//VU0.VI[i].UL&0x03);
else if( i == REG_CLIP_FLAG ) __Log("0\n");
else __Log("%x\n", VU0.VI[i].UL);
}
__Log("vfACC: %f %f %f %f\n", VU0.ACC.F[3], VU0.ACC.F[2], VU0.ACC.F[1], VU0.ACC.F[0]);
#endif
}
// This is called by the COP2 as per the CTC instruction // This is called by the COP2 as per the CTC instruction
void vu0ResetRegs() void vu0ResetRegs()
{ {

View File

@ -38,27 +38,6 @@ u32 vudump = 0;
#define VF_VAL(x) ((x==0x80000000)?0:(x)) #define VF_VAL(x) ((x==0x80000000)?0:(x))
void iDumpVU1Registers()
{
// fixme: This code is outdated, broken, and lacks printed labels.
// Needs heavy mods to be useful.
#if 0
int i;
// static int icount = 0;
// __Log("%x\n", icount);
for(i = 1; i < 32; ++i) {
// __Log("v%d: w%f(%x) z%f(%x) y%f(%x) x%f(%x), vi: ", i, VU1.VF[i].F[3], VU1.VF[i].UL[3], VU1.VF[i].F[2], VU1.VF[i].UL[2],
// VU1.VF[i].F[1], VU1.VF[i].UL[1], VU1.VF[i].F[0], VU1.VF[i].UL[0]);
//__Log("v%d: %f %f %f %f, vi: ", i, VU1.VF[i].F[3], VU1.VF[i].F[2], VU1.VF[i].F[1], VU1.VF[i].F[0]);
__Log("v%d: %x %x %x %x, vi: ", i, VF_VAL(VU1.VF[i].UL[3]), VF_VAL(VU1.VF[i].UL[2]), VF_VAL(VU1.VF[i].UL[1]), VF_VAL(VU1.VF[i].UL[0]));
if( i == REG_Q || i == REG_P ) __Log("%f\n", VU1.VI[i].F);
//else __Log("%x\n", VU1.VI[i].UL);
else __Log("%x\n", (i==REG_STATUS_FLAG||i==REG_MAC_FLAG||i==REG_CLIP_FLAG)?0:VU1.VI[i].UL);
}
__Log("vfACC: %f %f %f %f\n", VU1.ACC.F[3], VU1.ACC.F[2], VU1.ACC.F[1], VU1.ACC.F[0]);
#endif
}
// This is called by the COP2 as per the CTC instruction // This is called by the COP2 as per the CTC instruction
void vu1ResetRegs() void vu1ResetRegs()
{ {

View File

@ -1585,7 +1585,7 @@ void _vuLQ(VURegs * VU) {
if (_Ft_ == 0) return; if (_Ft_ == 0) return;
imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff);
addr = (imm + VU->VI[_Fs_].SS[0]) * 16; addr = ((imm + VU->VI[_Fs_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u32*)GET_VU_MEM(VU, addr); ptr = (u32*)GET_VU_MEM(VU, addr);
if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_X) VU->VF[_Ft_].UL[0] = ptr[0];
@ -1601,7 +1601,7 @@ void _vuLQD( VURegs * VU ) {
if (_Fs_ != 0) VU->VI[_Fs_].US[0]--; if (_Fs_ != 0) VU->VI[_Fs_].US[0]--;
if (_Ft_ == 0) return; if (_Ft_ == 0) return;
addr = VU->VI[_Fs_].US[0] * 16; addr = (VU->VI[_Fs_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u32*)GET_VU_MEM(VU, addr); ptr = (u32*)GET_VU_MEM(VU, addr);
if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_X) VU->VF[_Ft_].UL[0] = ptr[0];
if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1];
@ -1614,7 +1614,7 @@ void _vuLQI(VURegs * VU) {
u32 addr; u32 addr;
u32 *ptr; u32 *ptr;
addr = VU->VI[_Fs_].US[0] * 16; addr = (VU->VI[_Fs_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u32*)GET_VU_MEM(VU, addr); ptr = (u32*)GET_VU_MEM(VU, addr);
if (_X) VU->VF[_Ft_].UL[0] = ptr[0]; if (_X) VU->VF[_Ft_].UL[0] = ptr[0];
if (_Y) VU->VF[_Ft_].UL[1] = ptr[1]; if (_Y) VU->VF[_Ft_].UL[1] = ptr[1];
@ -1631,7 +1631,7 @@ void _vuSQ(VURegs * VU) {
u32 *ptr; u32 *ptr;
imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff);
addr = (imm + VU->VI[_Ft_].SS[0]) * 16; addr = ((imm + VU->VI[_Ft_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u32*)GET_VU_MEM(VU, addr); ptr = (u32*)GET_VU_MEM(VU, addr);
if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_X) ptr[0] = VU->VF[_Fs_].UL[0];
if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1];
@ -1644,7 +1644,7 @@ void _vuSQD(VURegs * VU) {
u32 *ptr; u32 *ptr;
if(_Ft_ != 0) VU->VI[_Ft_].US[0]--; if(_Ft_ != 0) VU->VI[_Ft_].US[0]--;
addr = VU->VI[_Ft_].US[0] * 16; addr = (VU->VI[_Ft_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u32*)GET_VU_MEM(VU, addr); ptr = (u32*)GET_VU_MEM(VU, addr);
if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_X) ptr[0] = VU->VF[_Fs_].UL[0];
if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1];
@ -1656,7 +1656,7 @@ void _vuSQI(VURegs * VU) {
u32 addr; u32 addr;
u32 *ptr; u32 *ptr;
addr = VU->VI[_Ft_].US[0] * 16; addr = (VU->VI[_Ft_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u32*)GET_VU_MEM(VU, addr); ptr = (u32*)GET_VU_MEM(VU, addr);
if (_X) ptr[0] = VU->VF[_Fs_].UL[0]; if (_X) ptr[0] = VU->VF[_Fs_].UL[0];
if (_Y) ptr[1] = VU->VF[_Fs_].UL[1]; if (_Y) ptr[1] = VU->VF[_Fs_].UL[1];
@ -1673,7 +1673,7 @@ void _vuILW(VURegs * VU) {
if (_Ft_ == 0) return; if (_Ft_ == 0) return;
imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff);
addr = (imm + VU->VI[_Fs_].SS[0]) * 16; addr = ((imm + VU->VI[_Fs_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u16*)GET_VU_MEM(VU, addr); ptr = (u16*)GET_VU_MEM(VU, addr);
if (_X) VU->VI[_Ft_].US[0] = ptr[0]; if (_X) VU->VI[_Ft_].US[0] = ptr[0];
if (_Y) VU->VI[_Ft_].US[0] = ptr[2]; if (_Y) VU->VI[_Ft_].US[0] = ptr[2];
@ -1687,7 +1687,7 @@ void _vuISW(VURegs * VU) {
u16 *ptr; u16 *ptr;
imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff); imm = (VU->code & 0x400) ? (VU->code & 0x3ff) | 0xfc00 : (VU->code & 0x3ff);
addr = (imm + VU->VI[_Fs_].SS[0]) * 16; addr = ((imm + VU->VI[_Fs_].SS[0]) * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u16*)GET_VU_MEM(VU, addr); ptr = (u16*)GET_VU_MEM(VU, addr);
if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; } if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; }
if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; } if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; }
@ -1700,7 +1700,7 @@ void _vuILWR(VURegs * VU) {
u16 *ptr; u16 *ptr;
if (_Ft_ == 0) return; if (_Ft_ == 0) return;
addr = VU->VI[_Fs_].US[0] * 16; addr = (VU->VI[_Fs_].US[0] * 16)& (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u16*)GET_VU_MEM(VU, addr); ptr = (u16*)GET_VU_MEM(VU, addr);
if (_X) VU->VI[_Ft_].US[0] = ptr[0]; if (_X) VU->VI[_Ft_].US[0] = ptr[0];
if (_Y) VU->VI[_Ft_].US[0] = ptr[2]; if (_Y) VU->VI[_Ft_].US[0] = ptr[2];
@ -1712,7 +1712,7 @@ void _vuISWR(VURegs * VU) {
u32 addr; u32 addr;
u16 *ptr; u16 *ptr;
addr = VU->VI[_Fs_].US[0] * 16; addr = (VU->VI[_Fs_].US[0] * 16) & (VU == &VU1 ? 0x3fff : 0xfff);
ptr = (u16*)GET_VU_MEM(VU, addr); ptr = (u16*)GET_VU_MEM(VU, addr);
if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; } if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; }
if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; } if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; }
@ -2045,9 +2045,20 @@ void _vuXITOP(VURegs * VU) {
void _vuXGKICK(VURegs * VU) void _vuXGKICK(VURegs * VU)
{ {
u32* ptr = (u32*)GET_VU_MEM(VU, (VU->VI[_Fs_].US[0]*16) & (VU == &VU1 ? 0x3fff : 0xfff));
// int temp = 0x4000 - ((VU->VI[_Fs_].US[0]*16) & 0x3fff);
// u32 tempmem[0x8000];
// flush all pipelines first (in the right order) // flush all pipelines first (in the right order)
_vuFlushAll(VU); _vuFlushAll(VU);
GSGIFTRANSFER1((u32*)VU->Mem, (VU->VI[_Fs_].US[0]*16) & 0x3fff);
//Gonna be slow but reshuffles the memory so overflows wont occur
/* memset(tempmem, 0, sizeof(tempmem));
memcpy(tempmem, ptr, temp);
ptr = (u32*)GET_VU_MEM(VU, 0);
memcpy(&tempmem[temp], ptr, ((VU->VI[_Fs_].US[0]*16) & 0x3fff));
GSGIFTRANSFER1((u32*)&tempmem[0], 0);
} else*/ GSGIFTRANSFER1((u32*)VU->Mem, (VU->VI[_Fs_].US[0]*16) & 0x3fff);
} }
void _vuXTOP(VURegs * VU) { void _vuXTOP(VURegs * VU) {
@ -2508,13 +2519,23 @@ void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->pipe = VUPIPE_FMAC; VUregsn->pipe = VUPIPE_FMAC;
VUregsn->VFwrite = 0; VUregsn->VFwrite = 0;
VUregsn->VFread0 = _Fs_; VUregsn->VFread0 = _Fs_;
VUregsn->VFr0xyzw= _XYZW; VUregsn->VFr0xyzw= 1 << (3-_Fsf_);
VUregsn->VFread1 = 0; VUregsn->VFread1 = 0;
VUregsn->VIwrite = 1 << _Ft_; VUregsn->VIwrite = 1 << _Ft_;
VUregsn->VIread = GET_VF0_FLAG(_Fs_); VUregsn->VIread = GET_VF0_FLAG(_Fs_);
} }
VUREGS_FTFS(MR32); void _vuRegsMR32(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->pipe = VUPIPE_FMAC;
VUregsn->VFwrite = _Ft_;
VUregsn->VFwxyzw = _XYZW;
VUregsn->VFread0 = _Fs_;
VUregsn->VFr0xyzw= (_XYZW >> 1) | ((_XYZW << 3) & 0xf); //rotate
VUregsn->VFread1 = 0;
VUregsn->VFr1xyzw = 0xff;
VUregsn->VIwrite = 0;
VUregsn->VIread = (_Ft_ ? GET_VF0_FLAG(_Fs_) : 0);
}
void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn) { void _vuRegsLQ(VURegs * VU, _VURegsNum *VUregsn) {
VUregsn->pipe = VUPIPE_FMAC; VUregsn->pipe = VUPIPE_FMAC;

Some files were not shown because too many files have changed in this diff Show More