mirror of
https://github.com/libretro/pcsx2.git
synced 2025-02-03 16:22:38 +00:00
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:
commit
5d36fe3839
@ -26,6 +26,7 @@
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
@ -52,7 +53,7 @@
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
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"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
@ -107,6 +108,7 @@
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@ -128,7 +130,7 @@
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="0"
|
||||
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"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@ -179,6 +181,7 @@
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
@ -204,7 +207,7 @@
|
||||
FavorSizeOrSpeed="2"
|
||||
WholeProgramOptimization="false"
|
||||
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"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
|
@ -20,7 +20,7 @@
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
@ -41,7 +41,7 @@
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
@ -62,7 +62,7 @@
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="10"
|
||||
CharacterSet="2"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
@ -102,7 +102,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
|
||||
CommandLine="cl /EP /nologo "$(InputPath)" > "..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h""
|
||||
CommandLine="cl /EP /nologo "$(InputPath)" > "..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
"
|
||||
Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@ -112,7 +112,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
|
||||
CommandLine="cl /EP /nologo "$(InputPath)" > "..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h""
|
||||
CommandLine="cl /EP /nologo "$(InputPath)" > "..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
"
|
||||
Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@ -122,7 +122,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating ..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
|
||||
CommandLine="cl /EP /nologo "$(InputPath)" > "..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h""
|
||||
CommandLine="cl /EP /nologo "$(InputPath)" > "..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
"
|
||||
Outputs="..\..\lib\vc_lib\mswd\wx\msw\rcdefs.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@ -136,7 +136,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating ..\..\lib\vc_lib\mswd\wx\setup.h"
|
||||
CommandLine="copy "$(InputPath)" ..\..\lib\vc_lib\mswd\wx\setup.h"
|
||||
CommandLine="copy "$(InputPath)" ..\..\lib\vc_lib\mswd\wx\setup.h
"
|
||||
Outputs="..\..\lib\vc_lib\mswd\wx\setup.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@ -146,7 +146,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating ..\..\lib\vc_lib\msw\wx\setup.h"
|
||||
CommandLine="copy "$(InputPath)" ..\..\lib\vc_lib\msw\wx\setup.h"
|
||||
CommandLine="copy "$(InputPath)" ..\..\lib\vc_lib\msw\wx\setup.h
"
|
||||
Outputs="..\..\lib\vc_lib\msw\wx\setup.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
@ -156,7 +156,7 @@
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
Description="Creating ..\..\lib\vc_lib\msw\wx\setup.h"
|
||||
CommandLine="copy "$(InputPath)" ..\..\lib\vc_lib\msw\wx\setup.h"
|
||||
CommandLine="copy "$(InputPath)" ..\..\lib\vc_lib\msw\wx\setup.h
"
|
||||
Outputs="..\..\lib\vc_lib\msw\wx\setup.h"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
|
@ -26,6 +26,7 @@
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
@ -47,7 +48,7 @@
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="0"
|
||||
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"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
@ -98,6 +99,7 @@
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
@ -124,7 +126,7 @@
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
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"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
@ -178,6 +180,7 @@
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
<Tool
|
||||
@ -203,7 +206,7 @@
|
||||
FavorSizeOrSpeed="2"
|
||||
WholeProgramOptimization="false"
|
||||
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"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
|
@ -55,8 +55,6 @@
|
||||
// disable the default case in a switch
|
||||
#define jNO_DEFAULT \
|
||||
{ \
|
||||
break; \
|
||||
\
|
||||
default: \
|
||||
jASSUME(0); \
|
||||
break; \
|
||||
@ -88,6 +86,7 @@ typedef unsigned int uint;
|
||||
|
||||
#define __naked __declspec(naked)
|
||||
#define __unused /*unused*/
|
||||
#define __noinline __declspec(noinline)
|
||||
#define CALLBACK __stdcall
|
||||
|
||||
#else // _MSC_VER
|
||||
@ -136,6 +135,7 @@ typedef union _LARGE_INTEGER
|
||||
#define __unused __attribute__((unused))
|
||||
#define _inline __inline__ __attribute__((unused))
|
||||
#define __forceinline __attribute__((always_inline,unused))
|
||||
#define __noinline __attribute__((noinline))
|
||||
#define __naked // GCC lacks the naked specifier
|
||||
#define CALLBACK // CALLBACK is win32-specific mess
|
||||
|
||||
|
@ -20,11 +20,11 @@
|
||||
#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.
|
||||
#ifdef PLUGIN_ONLY
|
||||
// .. and removed in favor of a less hackish approach (air)
|
||||
|
||||
#ifndef g_MaxPath
|
||||
#define g_MaxPath 255
|
||||
#else
|
||||
#include "Paths.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// Session Configuration Override Flags
|
||||
@ -44,7 +44,8 @@ extern SessionOverrideFlags g_Session;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// 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_EEREC 0x10
|
||||
#define PCSX2_VU0REC 0x20
|
||||
@ -55,19 +56,20 @@ extern SessionOverrideFlags g_Session;
|
||||
#define PCSX2_FRAMELIMIT_SKIP 0x800
|
||||
#define PCSX2_FRAMELIMIT_VUSKIP 0xc00
|
||||
|
||||
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK)
|
||||
|
||||
//------------ CPU Options!!! ---------------
|
||||
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
|
||||
#define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
|
||||
//------------ SPEED/MISC HACKS!!! ---------------
|
||||
#define CHECK_EE_CYCLERATE (Config.Hacks & 0x03)
|
||||
#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)
|
||||
#define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC)
|
||||
#define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC))
|
||||
|
||||
//------------ 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_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_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs.
|
||||
|
||||
//------------ Advanced Options!!! ---------------
|
||||
#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
|
||||
@ -80,14 +82,40 @@ extern SessionOverrideFlags g_Session;
|
||||
#define CHECK_FPU_FULL (Config.eeOptions & 0x4)
|
||||
#define DEFAULT_eeOptions 0x01
|
||||
#define DEFAULT_vuOptions 0x01
|
||||
|
||||
//------------ DEFAULT sseMXCSR VALUES!!! ---------------
|
||||
#define DEFAULT_sseMXCSR 0xffc0 //FPU 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 CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC))
|
||||
#define SHIFT_RECOMPILE // Speed majorly reduced if disabled
|
||||
#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.
|
||||
struct McdConfig
|
||||
@ -133,7 +161,15 @@ public:
|
||||
int PsxType;
|
||||
int Patch;
|
||||
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 CustomFrameSkip;
|
||||
int CustomConsecutiveFrames;
|
||||
|
251
pcsx2/AsciiString.cpp
Normal file
251
pcsx2/AsciiString.cpp
Normal 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
84
pcsx2/AsciiString.h
Normal 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 ); }
|
||||
};
|
@ -19,6 +19,7 @@
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <wx/datetime.h>
|
||||
|
||||
#include "IopCommon.h"
|
||||
#include "CDVDiso.h"
|
||||
@ -240,12 +241,12 @@ FILE *_cdvdOpenMechaVer() {
|
||||
FILE* fd;
|
||||
|
||||
// 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
|
||||
// [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);
|
||||
while (i > 0) { if (ptr[i] == '.') break; i--; }
|
||||
ptr[i+1] = '\0';
|
||||
@ -254,11 +255,14 @@ FILE *_cdvdOpenMechaVer() {
|
||||
// if file doesnt exist, create empty one
|
||||
fd = fopen(file, "r+b");
|
||||
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");
|
||||
if (fd == NULL) {
|
||||
Msgbox::Alert("_cdvdOpenMechaVer: Error creating %s", params file);
|
||||
exit(1);
|
||||
if (fd == NULL)
|
||||
{
|
||||
Console::Error( "\tMEC File Creation failed!" );
|
||||
throw Exception::CreateStream( file );
|
||||
//Msgbox::Alert( "_cdvdOpenMechaVer: Error creating %s", params file);
|
||||
//exit(1);
|
||||
}
|
||||
fputc(0x03, fd);
|
||||
fputc(0x06, fd);
|
||||
@ -285,12 +289,11 @@ FILE *_cdvdOpenNVM() {
|
||||
FILE* fd;
|
||||
|
||||
// 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
|
||||
// [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);
|
||||
while (i > 0) { if (ptr[i] == '.') break; i--; }
|
||||
ptr[i+1] = '\0';
|
||||
@ -301,9 +304,11 @@ FILE *_cdvdOpenNVM() {
|
||||
if (fd == NULL) {
|
||||
Console::Notice("NVM File Not Found , Creating Blank File");
|
||||
fd = fopen(file, "wb");
|
||||
if (fd == NULL) {
|
||||
Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file);
|
||||
exit(1);
|
||||
if (fd == NULL)
|
||||
{
|
||||
throw Exception::CreateStream( file );
|
||||
//Msgbox::Alert("_cdvdOpenNVM: Error creating %s", params file);
|
||||
//exit(1);
|
||||
}
|
||||
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) {
|
||||
char str[g_MaxPath];
|
||||
wxString fname;
|
||||
int numbers;
|
||||
int letters;
|
||||
unsigned int key_0_3;
|
||||
@ -479,7 +484,9 @@ void cdvdReadKey(u8 arg0, u16 arg1, u32 arg2, u8* key) {
|
||||
char exeName[12];
|
||||
|
||||
// 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]);
|
||||
DevCon::Notice("exeName = %s", params &str[8]);
|
||||
|
||||
@ -693,7 +700,7 @@ __forceinline void cdvdGetDiskType()
|
||||
cdvd.Type = CDVDgetDiskType();
|
||||
if (cdvd.Type == CDVD_TYPE_PS2CD) // && needReset == 1)
|
||||
{
|
||||
char str[g_MaxPath];
|
||||
wxString str;
|
||||
if (GetPS2ElfName(str) == 1)
|
||||
{
|
||||
cdvd.Type = CDVD_TYPE_PSCD;
|
||||
@ -768,12 +775,18 @@ void cdvdReset()
|
||||
cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM );
|
||||
|
||||
// any random valid date will do
|
||||
cdvd.RTC.hour = 1;
|
||||
cdvd.RTC.day = 25;
|
||||
cdvd.RTC.month = 5;
|
||||
cdvd.RTC.year = 7; //2007
|
||||
|
||||
cdvdSetSystemTime( cdvd );
|
||||
//cdvd.RTC.hour = 1;
|
||||
//cdvd.RTC.day = 25;
|
||||
//cdvd.RTC.month = 5;
|
||||
//cdvd.RTC.year = 7; //2007
|
||||
|
||||
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
|
||||
@ -805,7 +818,7 @@ void cdvdNewDiskCB()
|
||||
{
|
||||
cdvd.Type = CDVDgetDiskType();
|
||||
if(cdvd.Type == CDVD_TYPE_PS2CD) {
|
||||
char str[g_MaxPath];
|
||||
wxString str;
|
||||
if(GetPS2ElfName(str) == 1) {
|
||||
cdvd.Type = CDVD_TYPE_PSCD;
|
||||
} // ENDIF- Does the SYSTEM.CNF file only say "BOOT="? PS1 CD then.
|
||||
|
@ -141,7 +141,4 @@ void cdvdWrite17(u8 rt);
|
||||
void cdvdWrite18(u8 rt);
|
||||
void cdvdWrite3A(u8 rt);
|
||||
|
||||
// Platform dependent system time assignment (see WinMisc / LnxMisc)
|
||||
extern void cdvdSetSystemTime( cdvdStruct& setme );
|
||||
|
||||
#endif /* __CDVD_H__ */
|
||||
|
@ -308,8 +308,8 @@ namespace COP0 {
|
||||
void MFC0()
|
||||
{
|
||||
// Note on _Rd_ Condition 9: CP0.Count should be updated even if _Rt_ is 0.
|
||||
if( (_Rd_ != 9) && !_Rt_ ) return;
|
||||
if(_Rd_ != 9) { COP0_LOG("%s", disR5900Current.getCString() ); }
|
||||
if ((_Rd_ != 9) && !_Rt_ ) return;
|
||||
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_]);
|
||||
switch (_Rd_)
|
||||
@ -412,30 +412,37 @@ int CPCOND0() {
|
||||
|
||||
//#define CPCOND0 1
|
||||
|
||||
#define BC0(cond) \
|
||||
/*#define BC0(cond) \
|
||||
if (CPCOND0() cond) { \
|
||||
intDoBranch(_BranchTarget_); \
|
||||
}
|
||||
}*/
|
||||
|
||||
void BC0F() {
|
||||
BC0(== 0);
|
||||
if (CPCOND0() == 0) intDoBranch(_BranchTarget_);
|
||||
}
|
||||
|
||||
void BC0T() {
|
||||
BC0(== 1);
|
||||
if (CPCOND0() == 1) intDoBranch(_BranchTarget_);
|
||||
}
|
||||
|
||||
#define BC0L(cond) \
|
||||
/*#define BC0L(cond) \
|
||||
if (CPCOND0() cond) { \
|
||||
intDoBranch(_BranchTarget_); \
|
||||
} else cpuRegs.pc+= 4;
|
||||
|
||||
} else cpuRegs.pc+= 4;*/
|
||||
|
||||
void BC0FL() {
|
||||
BC0L(== 0);
|
||||
if (CPCOND0() == 0)
|
||||
intDoBranch(_BranchTarget_);
|
||||
else
|
||||
cpuRegs.pc+= 4;
|
||||
|
||||
}
|
||||
|
||||
void BC0TL() {
|
||||
BC0L(== 1);
|
||||
if (CPCOND0() == 1)
|
||||
intDoBranch(_BranchTarget_);
|
||||
else
|
||||
cpuRegs.pc+= 4;
|
||||
}
|
||||
|
||||
void TLBR() {
|
||||
@ -482,8 +489,7 @@ void TLBWR() {
|
||||
|
||||
void TLBP() {
|
||||
int i;
|
||||
|
||||
|
||||
|
||||
union {
|
||||
struct {
|
||||
u32 VPN2:19;
|
||||
@ -494,13 +500,13 @@ void TLBP() {
|
||||
u32 u;
|
||||
} EntryHi32;
|
||||
|
||||
EntryHi32.u=cpuRegs.CP0.n.EntryHi;
|
||||
EntryHi32.u = cpuRegs.CP0.n.EntryHi;
|
||||
|
||||
cpuRegs.CP0.n.Index=0xFFFFFFFF;
|
||||
for(i=0;i<48;i++){
|
||||
if(tlb[i].VPN2==((~tlb[i].Mask)&(EntryHi32.s.VPN2))
|
||||
&&((tlb[i].G&1)||((tlb[i].ASID & 0xff) == EntryHi32.s.ASID))) {
|
||||
cpuRegs.CP0.n.Index=i;
|
||||
if (tlb[i].VPN2 == ((~tlb[i].Mask) & (EntryHi32.s.VPN2))
|
||||
&& ((tlb[i].G&1) || ((tlb[i].ASID & 0xff) == EntryHi32.s.ASID))) {
|
||||
cpuRegs.CP0.n.Index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,6 @@
|
||||
#include "VUops.h"
|
||||
#include "VUmicro.h"
|
||||
|
||||
//namespace R5900 {
|
||||
//namespace Interpreter {
|
||||
//namespace OpcodeImpl{
|
||||
|
||||
using namespace R5900;
|
||||
using namespace R5900::Interpreter;
|
||||
|
||||
@ -85,5 +81,3 @@ void BC2TL()
|
||||
cpuRegs.pc+= 4;
|
||||
}
|
||||
}
|
||||
|
||||
//}}}
|
||||
|
@ -937,6 +937,34 @@ void psxDma3(u32 madr, u32 bcr, u32 chcr) {
|
||||
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() {
|
||||
memzero_obj(cdr);
|
||||
cdr.CurTrack=1;
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#define PCSX2_VERSION "(beta)"
|
||||
|
||||
#include "System.h"
|
||||
|
||||
#include "Plugins.h"
|
||||
#include "SaveState.h"
|
||||
|
||||
@ -40,7 +42,4 @@
|
||||
#include "Elfheader.h"
|
||||
#include "Patch.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "Pcsx2Config.h"
|
||||
|
||||
#endif /* __COMMON_H__ */
|
||||
|
190
pcsx2/Config.h
Normal file
190
pcsx2/Config.h
Normal 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;
|
@ -36,6 +36,7 @@ namespace Console
|
||||
MutexLock m_writelock;
|
||||
std::string m_format_buffer;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void __fastcall SetTitle( const wxString& title )
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -43,6 +44,7 @@ namespace Console
|
||||
FrameHandle->SetTitle( title );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void __fastcall SetColor( Colors color )
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -57,6 +59,7 @@ namespace Console
|
||||
FrameHandle->ClearColor();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Newline()
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -67,6 +70,7 @@ namespace Console
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Write( const char* fmt )
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -91,8 +95,34 @@ namespace Console
|
||||
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 )
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -106,8 +136,6 @@ namespace Console
|
||||
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 )
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -123,6 +151,38 @@ namespace Console
|
||||
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 )
|
||||
{
|
||||
ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame();
|
||||
@ -147,12 +207,13 @@ namespace Console
|
||||
if( color == Color_Red || color == Color_Yellow )
|
||||
fputs( cstr, stderr ); // log notices and errors to stderr
|
||||
|
||||
wxASSERT_MSG( 0, cstr );
|
||||
wxASSERT_MSG_A( 0, cstr );
|
||||
}
|
||||
|
||||
fputs( cstr, emuLog );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Write( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
@ -184,6 +245,7 @@ namespace Console
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool WriteLn( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
@ -198,7 +260,7 @@ namespace Console
|
||||
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, ... )
|
||||
{
|
||||
varg_assert();
|
||||
@ -210,8 +272,7 @@ namespace Console
|
||||
return false;
|
||||
}
|
||||
|
||||
// Displays a message in the console with red emphasis.
|
||||
// Newline is automatically appended.
|
||||
// ------------------------------------------------------------------------
|
||||
bool Error( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
@ -223,8 +284,7 @@ namespace Console
|
||||
return false;
|
||||
}
|
||||
|
||||
// Displays a message in the console with yellow emphasis.
|
||||
// Newline is automatically appended.
|
||||
// ------------------------------------------------------------------------
|
||||
bool Notice( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
@ -236,8 +296,7 @@ namespace Console
|
||||
return false;
|
||||
}
|
||||
|
||||
// Displays a message in the console with green emphasis.
|
||||
// Newline is automatically appended.
|
||||
// ------------------------------------------------------------------------
|
||||
bool Status( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
@ -249,57 +308,57 @@ namespace Console
|
||||
return false;
|
||||
}
|
||||
|
||||
// Displays a message in the console with red emphasis.
|
||||
// Newline is automatically appended.
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Error( const char* fmt )
|
||||
{
|
||||
WriteLn( Color_Red, fmt );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Displays a message in the console with yellow emphasis.
|
||||
// Newline is automatically appended.
|
||||
bool __fastcall Notice( const char* fmt )
|
||||
{
|
||||
WriteLn( Color_Yellow, fmt );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Displays a message in the console with green emphasis.
|
||||
// Newline is automatically appended.
|
||||
bool __fastcall Status( const char* fmt )
|
||||
{
|
||||
WriteLn( Color_Green, fmt );
|
||||
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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool Alert(const char* fmt, VARG_PARAM dummy, ...)
|
||||
bool OkCancel( const wxString& text )
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, dummy);
|
||||
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;
|
||||
int result = wxMessageBox( text, wxT("Pcsx2 Message"), wxOK | wxCANCEL, wxGetApp().GetTopWindow() );
|
||||
return result == wxOK;
|
||||
}
|
||||
}
|
@ -164,7 +164,7 @@ struct vSyncTimingInfo
|
||||
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
|
||||
// depending on user-set speedhack options, and it can break float/double code
|
||||
@ -270,8 +270,6 @@ u32 UpdateVSyncRate()
|
||||
return (u32)m_iTicks;
|
||||
}
|
||||
|
||||
extern u32 vu0time;
|
||||
|
||||
void frameLimitReset()
|
||||
{
|
||||
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.
|
||||
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;
|
||||
u64 uExpectedEnd;
|
||||
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;
|
||||
iEnd = GetCPUTicks();
|
||||
|
||||
@ -465,7 +463,7 @@ __forceinline bool rcntUpdate_vSync()
|
||||
return false;
|
||||
}
|
||||
|
||||
static __forceinline void __fastcall _cpuTestTarget( int i )
|
||||
static __forceinline void _cpuTestTarget( int i )
|
||||
{
|
||||
if (counters[i].count < counters[i].target) return;
|
||||
|
||||
@ -538,7 +536,7 @@ __forceinline bool rcntUpdate()
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void _rcntSetGate( int index )
|
||||
static __forceinline void _rcntSetGate( int index )
|
||||
{
|
||||
if (counters[index].mode.EnableGate)
|
||||
{
|
||||
@ -563,7 +561,7 @@ static void _rcntSetGate( int index )
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@ -624,7 +622,7 @@ void __fastcall rcntStartGate(bool isVblank, u32 sCycle)
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@ -665,7 +663,7 @@ void __fastcall rcntEndGate(bool isVblank , u32 sCycle)
|
||||
// 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.ClockSource != 0x3) {
|
||||
@ -696,7 +694,7 @@ void __fastcall rcntWmode(int index, u32 value)
|
||||
_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 );
|
||||
|
||||
@ -722,7 +720,7 @@ void __fastcall rcntWcount(int index, u32 value)
|
||||
_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);
|
||||
|
||||
@ -738,13 +736,13 @@ void __fastcall rcntWtarget(int index, u32 value)
|
||||
_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);
|
||||
counters[index].hold = value;
|
||||
}
|
||||
|
||||
u32 __fastcall rcntRcount(int index)
|
||||
__forceinline u32 rcntRcount(int index)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
@ -759,7 +757,7 @@ u32 __fastcall rcntRcount(int index)
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 __fastcall rcntCycle(int index)
|
||||
__forceinline u32 rcntCycle(int index)
|
||||
{
|
||||
if (counters[index].mode.IsCounting && (counters[index].mode.ClockSource != 0x3))
|
||||
return counters[index].count + ((cpuRegs.cycle - counters[index].sCycleT) / counters[index].rate);
|
||||
|
@ -139,14 +139,14 @@ extern bool rcntUpdate_vSync();
|
||||
extern bool rcntUpdate();
|
||||
|
||||
extern void rcntInit();
|
||||
extern void __fastcall rcntStartGate(bool mode, u32 sCycle);
|
||||
extern void __fastcall rcntEndGate(bool mode, u32 sCycle);
|
||||
extern void __fastcall rcntWcount(int index, u32 value);
|
||||
extern void __fastcall rcntWmode(int index, u32 value);
|
||||
extern void __fastcall rcntWtarget(int index, u32 value);
|
||||
extern void __fastcall rcntWhold(int index, u32 value);
|
||||
extern u32 __fastcall rcntRcount(int index);
|
||||
extern u32 __fastcall rcntCycle(int index);
|
||||
extern void rcntStartGate(bool mode, u32 sCycle);
|
||||
extern void rcntEndGate(bool mode, u32 sCycle);
|
||||
extern void rcntWcount(int index, u32 value);
|
||||
extern void rcntWmode(int index, u32 value);
|
||||
extern void rcntWtarget(int index, u32 value);
|
||||
extern void rcntWhold(int index, u32 value);
|
||||
extern u32 rcntRcount(int index);
|
||||
extern u32 rcntCycle(int index);
|
||||
|
||||
u32 UpdateVSyncRate();
|
||||
void frameLimitReset();
|
||||
|
@ -216,6 +216,8 @@ extern bool SrcLog_GPU( const char* fmt, ... );
|
||||
#define MEMCARDS_LOG 0&&
|
||||
#endif
|
||||
|
||||
//#define VIFUNPACKDEBUG //enable unpack debugging output
|
||||
|
||||
#ifdef VIFUNPACKDEBUG
|
||||
#define VIFUNPACK_LOG VIF_LOG
|
||||
#else
|
||||
|
@ -606,7 +606,7 @@ void (*COP2SPECIAL2PrintTable[128])( string& output ) =
|
||||
//**************************TABLES CALLS***********************
|
||||
|
||||
|
||||
void disR5900Fasm(string& output, u32 code, u32 pc)
|
||||
void disR5900Fasm( string& output, u32 code, u32 pc )
|
||||
{
|
||||
string dbuf;
|
||||
char obuf[48];
|
||||
|
303
pcsx2/Dump.cpp
Normal file
303
pcsx2/Dump.cpp
Normal 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
26
pcsx2/Dump.h
Normal 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 );
|
@ -127,6 +127,12 @@ struct Elf32_Rel {
|
||||
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)
|
||||
char args[256]="ez.m2v"; //to be accessed by other files
|
||||
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+strlen(argv[0]+1) the rest of params; i.e. a copy of 'args'
|
||||
// see above 'char args[256];'
|
||||
static uint parseCommandLine( const char *filename )
|
||||
static uint parseCommandLine( const wxString& filename )
|
||||
{
|
||||
if ( ( args_ptr != 0xFFFFFFFF ) && ( args_ptr > 264 ) )
|
||||
{ // 4 + 4 + 256
|
||||
@ -209,11 +215,12 @@ static uint parseCommandLine( const char *filename )
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
//---------------
|
||||
|
||||
struct ElfObject
|
||||
{
|
||||
string filename;
|
||||
wxString filename;
|
||||
SafeArray<u8> data;
|
||||
ELF_HEADER& header;
|
||||
ELF_PHR* proghead;
|
||||
@ -223,7 +230,7 @@ struct ElfObject
|
||||
// C++ does all the cleanup automagically for us.
|
||||
~ElfObject() { }
|
||||
|
||||
ElfObject( const string& srcfile, uint hdrsize ) :
|
||||
ElfObject( const wxString& srcfile, uint hdrsize ) :
|
||||
filename( srcfile )
|
||||
, data( hdrsize, "ELF headers" )
|
||||
, header( *(ELF_HEADER*)data.GetPtr() )
|
||||
@ -296,10 +303,11 @@ struct ElfObject
|
||||
void readFile()
|
||||
{
|
||||
int rsize = 0;
|
||||
if ((strnicmp( filename.c_str(), "cdrom0:", strlen("cdromN:")) == 0) ||
|
||||
(strnicmp( filename.c_str(), "cdrom1:", strlen("cdromN:")) == 0))
|
||||
const wxCharBuffer work( filename.ToAscii() );
|
||||
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 );
|
||||
|
||||
@ -311,7 +319,7 @@ struct ElfObject
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
f = fopen( filename.c_str(), "rb" );
|
||||
f = fopen( work.data(), "rb" );
|
||||
if( f == NULL ) Exception::FileNotFound( filename );
|
||||
|
||||
fseek( f, 0, SEEK_SET );
|
||||
@ -404,8 +412,9 @@ struct ElfObject
|
||||
{
|
||||
ELF_LOG( "Elf32 Section Header [%x] %s", i, §ions_names[ secthead[ i ].sh_name ] );
|
||||
|
||||
if ( secthead[i].sh_flags & 0x2 )
|
||||
args_ptr = min( args_ptr, secthead[ i ].sh_addr & 0x1ffffff );
|
||||
// used by parseCommandLine
|
||||
//if ( secthead[i].sh_flags & 0x2 )
|
||||
// args_ptr = min( args_ptr, secthead[ i ].sh_addr & 0x1ffffff );
|
||||
|
||||
#ifdef PCSX2_DEVBULD
|
||||
ELF_LOG("\n");
|
||||
@ -462,21 +471,20 @@ struct ElfObject
|
||||
|
||||
void ElfApplyPatches()
|
||||
{
|
||||
string filename;
|
||||
ssprintf( filename, "%8.8x", ElfCRC );
|
||||
wxString filename( wxsFormat( wxT("%8.8x"), ElfCRC ) );
|
||||
|
||||
// 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(LoadPatch( filename ) != 0)
|
||||
{
|
||||
Console::WriteLn("XML Loader returned an error. Trying to load a pnach...");
|
||||
inifile_read( filename.c_str() );
|
||||
Console::WriteLn( "XML Loader returned an error. Trying to load a pnach..." );
|
||||
inifile_read( filename.ToAscii().data() );
|
||||
}
|
||||
else
|
||||
Console::WriteLn("XML Loading success. Will not load from pnach...");
|
||||
Console::WriteLn( "XML Loading success. Will not load from pnach..." );
|
||||
|
||||
applypatch( 0 );
|
||||
}
|
||||
@ -491,20 +499,20 @@ u32 loadElfCRC( const char* filename )
|
||||
return 0;
|
||||
|
||||
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 );
|
||||
|
||||
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
|
||||
// slate, the happier the recompiler!
|
||||
|
||||
SysClearExecutionCache();
|
||||
|
||||
if( filename == NULL || filename[0] == 0 )
|
||||
if( filename.IsEmpty() )
|
||||
{
|
||||
Console::Notice( "Running the PS2 BIOS..." );
|
||||
return -1;
|
||||
@ -514,35 +522,42 @@ int loadElfFile(const char *filename)
|
||||
cpuExecuteBios();
|
||||
|
||||
int elfsize;
|
||||
Console::Status( wxsFormat( L"loadElfFile: %s", filename.c_str() ) );
|
||||
|
||||
Console::Status("loadElfFile: %s", params filename);
|
||||
if (strnicmp( filename, "cdrom0:", strlen( "cdromN:" ) ) &&
|
||||
strnicmp( filename, "cdrom1:", strlen( "cdromN:" ) ) )
|
||||
const wxCharBuffer buffer( filename.ToAscii() );
|
||||
const char* fnptr = buffer.data();
|
||||
|
||||
if( !filename.StartsWith( L"cdrom0:" ) && !filename.StartsWith( L"cdrom1:" ) )
|
||||
{
|
||||
// Loading from a file (or non-cd image)
|
||||
struct stat sbuf;
|
||||
if ( stat( filename, &sbuf ) != 0 )
|
||||
return -1;
|
||||
elfsize = sbuf.st_size;
|
||||
|
||||
elfsize = Path::GetFileSize( filename );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Loading from a CD rom or CD image.
|
||||
TocEntry toc;
|
||||
CDVDFS_init( );
|
||||
if ( CDVD_findfile( filename + strlen( "cdromN:" ), &toc ) == -1 )
|
||||
if ( CDVD_findfile( fnptr + strlen( "cdromN:" ), &toc ) == -1 )
|
||||
return -1;
|
||||
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 );
|
||||
|
||||
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)
|
||||
args_ptr = 0xFFFFFFFF; //big value, searching for minimum
|
||||
//args_ptr = 0xFFFFFFFF; //big value, searching for minimum [used by parseCommandLine]
|
||||
|
||||
elfobj.loadProgramHeaders();
|
||||
elfobj.loadSectionHeaders();
|
||||
@ -552,17 +567,19 @@ int loadElfFile(const char *filename)
|
||||
|
||||
cpuRegs.GPR.n.sp.UL[0] = 0x81f00000;
|
||||
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++ ) {
|
||||
if ( strcmp( "rom0:OSDSYS", (char*)PSM( i ) ) == 0 ) {
|
||||
strcpy( (char*)PSM( i ), filename );
|
||||
DevCon::Status( "addr %x \"%s\" -> \"%s\"", params i, "rom0:OSDSYS", filename );
|
||||
for( uint i = 0; i < 0x100000; i++ )
|
||||
{
|
||||
if( memcmp( "rom0:OSDSYS", (char*)PSM( i ), 11 ) == 0 )
|
||||
{
|
||||
strcpy( (char*)PSM( i ), fnptr );
|
||||
DevCon::Status( "loadElfFile: addr %x \"%s\" -> \"%s\"", params i, "rom0:OSDSYS", fnptr );
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
LoadGameSpecificSettings();
|
||||
|
@ -24,7 +24,7 @@ extern char args[256]; //to be filled by GUI
|
||||
extern unsigned int args_ptr;
|
||||
|
||||
//-------------------
|
||||
int loadElfFile(const char *filename);
|
||||
int loadElfFile(const wxString& filename);
|
||||
u32 loadElfCRC(const char *filename);
|
||||
void LoadGameSpecificSettings();
|
||||
void ElfApplyPatches();
|
||||
|
165
pcsx2/Exceptions.cpp
Normal file
165
pcsx2/Exceptions.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
|
@ -16,12 +16,9 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _PCSX2_EXCEPTIONS_H_
|
||||
#define _PCSX2_EXCEPTIONS_H_
|
||||
|
||||
#include <stdexcept>
|
||||
#include "StringUtils.h"
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This class provides an easy and clean method for ensuring objects are not copyable.
|
||||
class NoncopyableObject
|
||||
{
|
||||
@ -39,12 +36,12 @@ private:
|
||||
const NoncopyableObject& operator=( const NoncopyableObject& );
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Base class used to implement type-safe sealed classes.
|
||||
// This class should never be used directly. Use the Sealed
|
||||
// macro instead, which ensures all sealed classes derive from a unique BaseSealed
|
||||
// (preventing them from accidentally cirumventing sealing by inheriting from
|
||||
// multiple sealed classes.
|
||||
// This class should never be used directly. Use the Sealed macro instead, which ensures
|
||||
// all sealed classes derive from a unique BaseSealed (preventing them from accidentally
|
||||
// circumventing sealing by inheriting from multiple sealed classes.
|
||||
//
|
||||
template < int T >
|
||||
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
|
||||
// for every class that derives from it.
|
||||
#define Sealed private virtual __BaseSealed<__COUNTER__>
|
||||
|
||||
extern wxLocale* g_EnglishLocale;
|
||||
|
||||
extern wxString GetEnglish( const char* msg );
|
||||
extern wxString GetTranslation( const char* msg );
|
||||
|
||||
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.
|
||||
// Use Exception::RuntimeError or Exception::LogicError instead.
|
||||
// Use Exception::RuntimeError or Exception::LogicError instead for generic exceptions.
|
||||
//
|
||||
class BaseException
|
||||
{
|
||||
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:
|
||||
virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode.
|
||||
explicit BaseException( const wxString& msg="Unhandled exception." ) :
|
||||
m_message( msg )
|
||||
{
|
||||
// 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
|
||||
}
|
||||
|
||||
// copy construct
|
||||
BaseException( const BaseException& src ) :
|
||||
m_message_eng( src.m_message_eng ),
|
||||
m_message( src.m_message ),
|
||||
m_stacktrace( src.m_stacktrace ) { }
|
||||
|
||||
// Contruction using two pre-formatted pre-translated messages
|
||||
BaseException( const wxString& msg_eng, const wxString& msg_xlt );
|
||||
|
||||
const wxString& Message() const { return m_message; }
|
||||
const char* cMessage() const { return m_message.c_str(); }
|
||||
// Construction using one translation key.
|
||||
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).
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
virtual ~Ps2Generic() throw() {}
|
||||
|
||||
explicit Ps2Generic( const wxString& msg="The Ps2/MIPS state encountered a general exception." ) :
|
||||
Exception::BaseException( msg )
|
||||
{
|
||||
}
|
||||
explicit Ps2Generic( const char* msg="Ps2/MIPS cpu caused a general exception" ) :
|
||||
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 bool IsDelaySlot() const=0;
|
||||
@ -111,18 +126,29 @@ namespace Exception
|
||||
{
|
||||
public:
|
||||
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
|
||||
{
|
||||
public:
|
||||
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
|
||||
{
|
||||
public:
|
||||
explicit OutOfMemory( const wxString& msg="Out of memory!" ) :
|
||||
RuntimeError( msg ) {}
|
||||
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
|
||||
// is in an uninitialized state.
|
||||
class InvalidOperation : public LogicError
|
||||
{
|
||||
public:
|
||||
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 ) {}
|
||||
|
||||
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
|
||||
// is in an uninitialized state.
|
||||
class InvalidArgument : public LogicError
|
||||
{
|
||||
public:
|
||||
virtual ~InvalidArgument() throw() {}
|
||||
explicit InvalidArgument( const wxString& msg="Invalid argument passed to a function." ) :
|
||||
LogicError( msg ) {}
|
||||
explicit InvalidArgument( const char* msg="Invalid argument passed to a function." ) :
|
||||
LogicError( msg )
|
||||
{
|
||||
// assertions make debugging easier sometimes. :)
|
||||
wxASSERT( msg );
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Keep those array indexers in bounds when using the SafeArray type, or you'll be
|
||||
// seeing these.
|
||||
class IndexBoundsFault : public LogicError
|
||||
{
|
||||
public:
|
||||
const wxString ArrayName;
|
||||
const int ArrayLength;
|
||||
const int BadIndex;
|
||||
|
||||
public:
|
||||
virtual ~IndexBoundsFault() throw() {}
|
||||
explicit IndexBoundsFault( const wxString& msg="Array index is outsides the bounds of an array." ) :
|
||||
LogicError( msg ) {}
|
||||
explicit IndexBoundsFault( const wxString& objname, int index, int arrsize ) :
|
||||
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
|
||||
{
|
||||
public:
|
||||
virtual ~ParseError() throw() {}
|
||||
explicit ParseError( const wxString& msg="Parse error" ) :
|
||||
explicit ParseError( const char* msg="Parse error" ) :
|
||||
RuntimeError( msg ) {}
|
||||
};
|
||||
|
||||
@ -178,11 +233,12 @@ namespace Exception
|
||||
class HardwareDeficiency : public RuntimeError
|
||||
{
|
||||
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 ) {}
|
||||
virtual ~HardwareDeficiency() throw() {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 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
|
||||
// the user to the GUI.
|
||||
@ -190,66 +246,72 @@ namespace Exception
|
||||
{
|
||||
public:
|
||||
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 ) {}
|
||||
|
||||
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
|
||||
{
|
||||
public:
|
||||
wxString plugin_name; // name of the plugin
|
||||
|
||||
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 )
|
||||
, plugin_name( plugin ) {}
|
||||
, plugin_name( wxString::FromAscii(plugin) ) {}
|
||||
|
||||
virtual wxString LogMessage() const;
|
||||
virtual wxString DisplayMessage() const;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class ThreadCreationError : public RuntimeError
|
||||
{
|
||||
public:
|
||||
virtual ~ThreadCreationError() throw() {}
|
||||
explicit ThreadCreationError( const wxString& 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." ) :
|
||||
explicit ThreadCreationError( const char* msg="Thread could not be created." ) :
|
||||
RuntimeError( msg ) {}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// STREAMING EXCEPTIONS
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
wxString stream_name; // name of the stream (if applicable)
|
||||
wxString StreamName; // name of the stream (if applicable)
|
||||
|
||||
virtual ~Stream() throw() {}
|
||||
|
||||
// copy construct!
|
||||
Stream( const Stream& src ) :
|
||||
RuntimeError( src.Message() )
|
||||
, stream_name( src.stream_name ) {}
|
||||
RuntimeError( src ),
|
||||
StreamName( src.StreamName ) {}
|
||||
|
||||
explicit Stream(
|
||||
const wxString& objname=wxString(),
|
||||
const wxString& msg="Invalid stream object" ) :
|
||||
RuntimeError( msg + "\n\tFilename: " + objname )
|
||||
, stream_name( objname ) {}
|
||||
const char* msg="General file operation error" // general error while accessing or operating on a file or stream
|
||||
) :
|
||||
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
|
||||
// connection, or anything else that would indicate a failure to read the data after the
|
||||
// stream was successfully opened.
|
||||
@ -259,50 +321,63 @@ namespace Exception
|
||||
virtual ~BadStream() throw() {}
|
||||
explicit BadStream(
|
||||
const wxString& objname=wxString(),
|
||||
const wxString& msg="Stream data is corrupted or incomplete, or the stream connection closed unexpectedly" ) :
|
||||
Stream( objname, msg ) {}
|
||||
const char* msg="File data is corrupted or incomplete, or the stream connection closed unexpectedly"
|
||||
) :
|
||||
Stream( objname, msg ) {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// A generic exception for odd-ball stream creation errors.
|
||||
class CreateStream : public Stream
|
||||
{
|
||||
public:
|
||||
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(
|
||||
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 ) {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Exception thrown when an attempt to open a non-existent file is made.
|
||||
// (this exception can also mean file permissions are invalid)
|
||||
class FileNotFound : public CreateStream
|
||||
{
|
||||
public:
|
||||
virtual ~FileNotFound() throw() {}
|
||||
|
||||
explicit FileNotFound(
|
||||
const wxString& objname=wxString(),
|
||||
const wxString& msg="File not found" ) :
|
||||
const char* msg="File not found" ) :
|
||||
|
||||
CreateStream( objname, msg ) {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class AccessDenied : public CreateStream
|
||||
{
|
||||
public:
|
||||
virtual ~AccessDenied() throw() {}
|
||||
explicit AccessDenied(
|
||||
const wxString& objname=wxString(),
|
||||
const wxString& msg="Permission denied to file or stream" ) :
|
||||
const char* msg="Permission denied to file" ) :
|
||||
CreateStream( objname, msg ) {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Generic End of Stream exception (sometimes an error, and sometimes just used as a
|
||||
// shortcut for manual feof checks).
|
||||
class EndOfStream : public Stream
|
||||
{
|
||||
public:
|
||||
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 ) {}
|
||||
};
|
||||
|
||||
@ -316,10 +391,11 @@ namespace Exception
|
||||
virtual ~BadSavedState() throw() {}
|
||||
explicit BadSavedState(
|
||||
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 ) {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Exception thrown by SaveState class when a critical plugin or gzread
|
||||
class FreezePluginFailure : public RuntimeError
|
||||
{
|
||||
@ -328,12 +404,18 @@ namespace Exception
|
||||
wxString freeze_action;
|
||||
|
||||
virtual ~FreezePluginFailure() throw() {}
|
||||
explicit FreezePluginFailure( const wxString& plugin, const wxString& action ) :
|
||||
RuntimeError( plugin + " plugin returned an error while " + action + " the state." )
|
||||
, plugin_name( plugin )
|
||||
, freeze_action( action ){}
|
||||
explicit FreezePluginFailure( const char* plugin, const char* action,
|
||||
const wxString& msg_xlt=_("Plugin error occurred while loading/saving state") )
|
||||
:
|
||||
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 current emulation state. Recoverable errors are always thrown from the SaveState
|
||||
// object construction (and never from Freeze methods).
|
||||
@ -341,10 +423,11 @@ namespace Exception
|
||||
{
|
||||
public:
|
||||
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 ) {}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// A recoverable exception thrown when the savestate being loaded isn't supported.
|
||||
class UnsupportedStateVersion : public StateLoadError_Recoverable
|
||||
{
|
||||
@ -354,13 +437,15 @@ namespace Exception
|
||||
public:
|
||||
virtual ~UnsupportedStateVersion() throw() {}
|
||||
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 ) :
|
||||
StateLoadError_Recoverable( msg ) {}
|
||||
virtual wxString LogMessage() const;
|
||||
virtual wxString DisplayMessage() const;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// A recoverable exception thrown when the CRC of the savestate does not match the
|
||||
// CRC returned by the Cdvd driver.
|
||||
// [feature not implemented yet]
|
||||
@ -373,20 +458,12 @@ namespace Exception
|
||||
public:
|
||||
virtual ~StateCrcMismatch() throw() {}
|
||||
explicit StateCrcMismatch( u32 crc_save, u32 crc_cdvd )
|
||||
: StateLoadError_Recoverable( fmt_string(
|
||||
"Game/CDVD does not match the savestate CRC.\n"
|
||||
"\tCdvd CRC: 0x%X\n\tGame CRC: 0x%X\n", params crc_save, crc_cdvd
|
||||
) )
|
||||
: StateLoadError_Recoverable()
|
||||
, Crc_Savestate( crc_save )
|
||||
, Crc_Cdvd( crc_cdvd )
|
||||
{}
|
||||
|
||||
explicit StateCrcMismatch( u32 crc_save, u32 crc_cdvd, const wxString& msg )
|
||||
: StateLoadError_Recoverable( msg )
|
||||
, Crc_Savestate( crc_save )
|
||||
, Crc_Cdvd( crc_cdvd )
|
||||
{}
|
||||
virtual wxString LogMessage() const;
|
||||
virtual wxString DisplayMessage() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
34
pcsx2/GS.cpp
34
pcsx2/GS.cpp
@ -24,16 +24,27 @@
|
||||
#include "GS.h"
|
||||
#include "iR5900.h"
|
||||
#include "Counters.h"
|
||||
|
||||
#include "VifDma.h"
|
||||
|
||||
using namespace Threading;
|
||||
using namespace std;
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
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
|
||||
|
||||
// GS Playback
|
||||
@ -98,21 +109,6 @@ __forceinline void GSVSYNC(void) {
|
||||
}
|
||||
#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 )
|
||||
{
|
||||
m_iSlowStart = GetCPUTicks();
|
||||
@ -839,8 +835,6 @@ void RunGSState( gzLoadingState& f )
|
||||
list<GSStatePacket>::iterator it = packets.begin();
|
||||
g_SaveGSStream = 3;
|
||||
|
||||
//int skipfirst = 1;
|
||||
|
||||
// first extract the data
|
||||
while(1) {
|
||||
|
||||
@ -877,4 +871,4 @@ void RunGSState( gzLoadingState& f )
|
||||
|
||||
#endif
|
||||
|
||||
#undef GIFchain
|
||||
//#undef GIFchain
|
||||
|
105
pcsx2/Gif.cpp
105
pcsx2/Gif.cpp
@ -28,18 +28,17 @@
|
||||
|
||||
using std::min;
|
||||
|
||||
#define gif ((DMACh*)&psH[0xA000])
|
||||
#define spr0 ((DMACh*)&PS2MEM_HW[0xD000])
|
||||
|
||||
#define gifsplit 64
|
||||
enum gifstate_t
|
||||
{
|
||||
GIF_STATE_EMPTY = 0,
|
||||
GIF_STATE_STALL,
|
||||
GIF_STATE_DONE
|
||||
GIF_STATE_READY = 0,
|
||||
GIF_STATE_STALL = 1,
|
||||
GIF_STATE_DONE = 2,
|
||||
GIF_STATE_EMPTY = 0x10
|
||||
};
|
||||
|
||||
// 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
|
||||
|
||||
@ -49,6 +48,7 @@ static int gspath3done = 0;
|
||||
|
||||
static u32 gscycles = 0, prevcycles = 0, mfifocycles = 0;
|
||||
static u32 gifqwc = 0;
|
||||
bool gifmfifoirq = FALSE;
|
||||
|
||||
__forceinline void gsInterrupt() {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
if(gif->qwc > 0 || gspath3done == 0) {
|
||||
if( !(psHu32(DMAC_CTRL) & 0x1) ) {
|
||||
if (gif->qwc > 0 || gspath3done == 0) {
|
||||
if (!(psHu32(DMAC_CTRL) & 0x1)) {
|
||||
Console::Notice("gs dma masked, re-scheduling...");
|
||||
// re-raise the int shortly in the future
|
||||
CPU_INT( 2, 64 );
|
||||
@ -73,7 +73,7 @@ __forceinline void gsInterrupt() {
|
||||
/*if (!(vif1Regs->mskpath3 && (vif1ch->chcr & 0x100)) || (psHu32(GIF_MODE) & 0x1))
|
||||
CPU_INT( 2, 64 );*/
|
||||
#endif
|
||||
if(gspath3done == 0) return;
|
||||
if(gspath3done == 0 || gif->qwc > 0) return;
|
||||
}
|
||||
|
||||
gspath3done = 0;
|
||||
@ -85,6 +85,7 @@ __forceinline void gsInterrupt() {
|
||||
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
||||
psHu32(GIF_STAT)&= ~0x1F000000; // QFC=0
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
GIF_LOG("GIF DMA end");
|
||||
|
||||
}
|
||||
|
||||
@ -127,7 +128,7 @@ static void WRITERING_DMA(u32 *pMem, u32 qwc)
|
||||
|
||||
int _GIFchain() {
|
||||
#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
|
||||
u32 qwc = gif->qwc;
|
||||
#endif
|
||||
@ -151,7 +152,7 @@ int _GIFchain() {
|
||||
return (qwc)*2;
|
||||
}
|
||||
|
||||
__forceinline void GIFchain()
|
||||
static __forceinline void GIFchain()
|
||||
{
|
||||
FreezeRegs(1);
|
||||
if (gif->qwc) gscycles+= _GIFchain(); /* guessing */
|
||||
@ -163,7 +164,7 @@ static __forceinline void dmaGIFend()
|
||||
if ((psHu32(GIF_MODE) & 0x4) && gif->qwc != 0)
|
||||
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
|
||||
else
|
||||
CPU_INT(2, gif->qwc /** BIAS*/);
|
||||
CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/);
|
||||
}
|
||||
|
||||
// These could probably be consolidated into one function,
|
||||
@ -174,7 +175,7 @@ static __forceinline void GIFdmaEnd()
|
||||
if (psHu32(GIF_MODE) & 0x4)
|
||||
CPU_INT(2, min( 8, (int)gif->qwc ) /** BIAS*/);
|
||||
else
|
||||
CPU_INT(2, gif->qwc /** BIAS*/);
|
||||
CPU_INT(2, min( gifsplit, (int)gif->qwc ) /** BIAS*/);
|
||||
}
|
||||
|
||||
void GIFdma()
|
||||
@ -189,7 +190,7 @@ void GIFdma()
|
||||
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
|
||||
if ( !(psHu32(GIF_MODE) & 0x4) ) {
|
||||
@ -225,7 +226,7 @@ void GIFdma()
|
||||
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
|
||||
|
||||
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;
|
||||
}
|
||||
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();
|
||||
// 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) Console::WriteLn("Hurray!"); // We *know* it is 0!
|
||||
gspath3done = 0;
|
||||
gif->chcr &= ~0x100;
|
||||
GSCSRr &= ~0xC000;
|
||||
@ -272,17 +269,20 @@ void GIFdma()
|
||||
|
||||
if (((gif->qwc == 0) && (gif->chcr & 0xc) == 0))
|
||||
gspath3done = 1;
|
||||
else
|
||||
else if(gif->qwc > 0)
|
||||
{
|
||||
GIFdmaEnd();
|
||||
return;
|
||||
|
||||
}
|
||||
else {
|
||||
}
|
||||
if ((gif->chcr & 0xc) == 0x4 && gspath3done == 0)
|
||||
{
|
||||
// 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
|
||||
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;
|
||||
}
|
||||
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
|
||||
// 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
|
||||
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;
|
||||
@ -313,20 +313,20 @@ void GIFdma()
|
||||
}
|
||||
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");
|
||||
gspath3done = 1;
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
prevcycles = 0;
|
||||
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
|
||||
{
|
||||
@ -346,9 +346,9 @@ void GIFdma()
|
||||
void dmaGIF() {
|
||||
//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
|
||||
|
||||
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
|
||||
Console::WriteLn("GIF MFIFO");
|
||||
//Console::WriteLn("GIF MFIFO");
|
||||
gifMFIFOInterrupt();
|
||||
return;
|
||||
}
|
||||
@ -365,7 +365,8 @@ void dmaGIF() {
|
||||
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
|
||||
|
||||
dmaGIFend();
|
||||
//gspath3done = hwDmacSrcChainWithStack(gif, (ptag[0] >> 28) & 0x7);
|
||||
GIFdmaEnd();
|
||||
gif->qwc = 0;
|
||||
return;
|
||||
}
|
||||
@ -414,8 +415,8 @@ static __forceinline int mfifoGIFrbTransfer() {
|
||||
|
||||
gifqwc -= mfifoqwc;
|
||||
gif->qwc -= mfifoqwc;
|
||||
gif->madr+= mfifoqwc*16;
|
||||
mfifocycles+= (mfifoqwc) * 2; /* guessing */
|
||||
gif->madr += mfifoqwc*16;
|
||||
//mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -438,14 +439,13 @@ static __forceinline int mfifoGIFchain() {
|
||||
if (pMem == NULL) return -1;
|
||||
|
||||
WRITERING_DMA(pMem, mfifoqwc);
|
||||
gif->madr+= mfifoqwc*16;
|
||||
gif->madr += mfifoqwc*16;
|
||||
gif->qwc -= mfifoqwc;
|
||||
mfifocycles+= (mfifoqwc) * 2; /* guessing */
|
||||
mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
bool gifmfifoirq = FALSE;
|
||||
|
||||
void mfifoGIFtransfer(int qwc) {
|
||||
u32 *ptag;
|
||||
@ -457,14 +457,14 @@ void mfifoGIFtransfer(int qwc) {
|
||||
|
||||
if(qwc > 0 ) {
|
||||
gifqwc += qwc;
|
||||
if(!(gif->chcr & 0x100))return;
|
||||
if(gifstate == GIF_STATE_STALL) return;
|
||||
if (gifstate != GIF_STATE_EMPTY) return;
|
||||
gifstate &= ~GIF_STATE_EMPTY;
|
||||
}
|
||||
|
||||
SPR_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
|
||||
|
||||
if(gif->qwc == 0){
|
||||
if(gif->tadr == spr0->madr) {
|
||||
if (gif->qwc == 0) {
|
||||
if (gif->tadr == spr0->madr) {
|
||||
//if( gifqwc > 1 ) DevCon::WriteLn("gif mfifo tadr==madr but qwc = %d", params gifqwc);
|
||||
//hwDmacIrq(14);
|
||||
|
||||
@ -492,20 +492,20 @@ void mfifoGIFtransfer(int qwc) {
|
||||
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->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;
|
||||
|
||||
case 2: // Next - Transfer QWC following tag. TADR = 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->tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
gifstate = GIF_STATE_EMPTY;
|
||||
gifstate = GIF_STATE_READY;
|
||||
break;
|
||||
|
||||
case 3: // Ref - Transfer QWC from ADDR field
|
||||
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
|
||||
gifstate = GIF_STATE_EMPTY;
|
||||
gifstate = GIF_STATE_READY;
|
||||
break;
|
||||
|
||||
case 7: // End - Transfer QWC following the tag
|
||||
@ -521,12 +521,15 @@ void mfifoGIFtransfer(int qwc) {
|
||||
gifmfifoirq = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
FreezeRegs(1);
|
||||
|
||||
if (mfifoGIFchain() == -1) {
|
||||
Console::WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", params
|
||||
gif->qwc, gif->madr, gif->tadr);
|
||||
gifstate = GIF_STATE_STALL;
|
||||
}
|
||||
|
||||
FreezeRegs(0);
|
||||
|
||||
if(gif->qwc == 0 && gifstate == GIF_STATE_DONE) gifstate = GIF_STATE_STALL;
|
||||
@ -542,10 +545,16 @@ void gifMFIFOInterrupt()
|
||||
cpuRegs.interrupt &= ~(1 << 11);
|
||||
return ;
|
||||
}
|
||||
if((spr0->chcr & 0x100) && spr0->qwc == 0)
|
||||
{
|
||||
spr0->chcr &= ~0x100;
|
||||
hwDmacIrq(8);
|
||||
}
|
||||
|
||||
if(gifstate != GIF_STATE_STALL) {
|
||||
if(gifqwc <= 0) {
|
||||
//Console::WriteLn("Empty");
|
||||
gifstate |= GIF_STATE_EMPTY;
|
||||
psHu32(GIF_STAT)&= ~0xE00; // OPH=0 | APATH=0
|
||||
hwDmacIrq(14);
|
||||
return;
|
||||
@ -554,14 +563,14 @@ void gifMFIFOInterrupt()
|
||||
return;
|
||||
}
|
||||
#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!");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
//if(gifqwc > 0) Console::WriteLn("GIF MFIFO ending with stuff in it %x", params gifqwc);
|
||||
if (!gifmfifoirq) gifqwc = 0;
|
||||
gifstate = GIF_STATE_EMPTY;
|
||||
gifstate = GIF_STATE_READY;
|
||||
gif->chcr &= ~0x100;
|
||||
hwDmacIrq(DMAC_GIF);
|
||||
GSCSRr &= ~0xC000; //Clear FIFO stuff
|
||||
|
@ -93,8 +93,8 @@ namespace HostGui
|
||||
// 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
|
||||
// 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.
|
||||
extern void SetStatusMsg( const std::string& text );
|
||||
extern void SetStatusMsg( const wxString& text );
|
||||
};
|
669
pcsx2/Hw.cpp
669
pcsx2/Hw.cpp
@ -148,31 +148,31 @@ int hwMFIFOWrite(u32 addr, u8 *data, u32 size) {
|
||||
}
|
||||
|
||||
|
||||
int hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||
u32 temp;
|
||||
|
||||
bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||
switch (id) {
|
||||
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.
|
||||
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
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
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->tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
return 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
case 3: // Ref - Transfer QWC from ADDR field
|
||||
case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||
dma->tadr += 16; //Set TADR to next tag
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
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
|
||||
|
||||
@ -185,12 +185,12 @@ int hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
||||
dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1
|
||||
}else {
|
||||
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
|
||||
|
||||
return 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
case 6: // Ret - Transfer QWC following the tag, load next 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 0;
|
||||
return false;
|
||||
|
||||
case 7: // End - Transfer QWC following the tag
|
||||
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
|
||||
//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;
|
||||
|
||||
switch (id) {
|
||||
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.
|
||||
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
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
case 2: // Next - Transfer QWC following tag. TADR = ADDR
|
||||
temp = dma->madr; //Temporarily Store ADDR
|
||||
dma->madr = dma->tadr + 16; //Set MADR to QW following the tag
|
||||
dma->tadr = temp; //Copy temporarily stored ADDR to Tag
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
case 3: // Ref - Transfer QWC from ADDR field
|
||||
case 4: // Refs - Transfer QWC from ADDR field (Stall Control)
|
||||
dma->tadr += 16; //Set TADR to next tag
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
case 7: // End - Transfer QWC following the tag
|
||||
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
|
||||
//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;
|
||||
}
|
||||
}
|
||||
*/
|
384
pcsx2/Hw.h
384
pcsx2/Hw.h
@ -21,25 +21,16 @@
|
||||
|
||||
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 );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Hardware FIFOs (128 bit access only!)
|
||||
//
|
||||
// VIF0 -- 0x10004000 -- psH[0x4000]
|
||||
// VIF1 -- 0x10005000 -- psH[0x5000]
|
||||
// GIF -- 0x10006000 -- psH[0x6000]
|
||||
// IPUout -- 0x10007000 -- psH[0x7000]
|
||||
// IPUin -- 0x10007010 -- psH[0x7010]
|
||||
// VIF0 -- 0x10004000 -- PS2MEM_HW[0x4000]
|
||||
// VIF1 -- 0x10005000 -- PS2MEM_HW[0x5000]
|
||||
// GIF -- 0x10006000 -- PS2MEM_HW[0x6000]
|
||||
// IPUout -- 0x10007000 -- PS2MEM_HW[0x7000]
|
||||
// IPUin -- 0x10007010 -- PS2MEM_HW[0x7010]
|
||||
|
||||
void __fastcall ReadFIFO_page_4(u32 mem, mem128_t *out);
|
||||
void __fastcall ReadFIFO_page_5(u32 mem, mem128_t *out);
|
||||
@ -73,177 +64,183 @@ struct DMACh {
|
||||
};
|
||||
|
||||
// HW defines
|
||||
enum HWaddress
|
||||
{
|
||||
RCNT0_COUNT = 0x10000000,
|
||||
RCNT0_MODE = 0x10000010,
|
||||
RCNT0_TARGET = 0x10000020,
|
||||
RCNT0_HOLD = 0x10000030,
|
||||
|
||||
#define RCNT0_COUNT 0x10000000
|
||||
#define RCNT0_MODE 0x10000010
|
||||
#define RCNT0_TARGET 0x10000020
|
||||
#define RCNT0_HOLD 0x10000030
|
||||
RCNT1_COUNT = 0x10000800,
|
||||
RCNT1_MODE = 0x10000810,
|
||||
RCNT1_TARGET = 0x10000820,
|
||||
RCNT1_HOLD = 0x10000830,
|
||||
|
||||
#define RCNT1_COUNT 0x10000800
|
||||
#define RCNT1_MODE 0x10000810
|
||||
#define RCNT1_TARGET 0x10000820
|
||||
#define RCNT1_HOLD 0x10000830
|
||||
RCNT2_COUNT = 0x10001000,
|
||||
RCNT2_MODE = 0x10001010,
|
||||
RCNT2_TARGET = 0x10001020,
|
||||
|
||||
#define RCNT2_COUNT 0x10001000
|
||||
#define RCNT2_MODE 0x10001010
|
||||
#define RCNT2_TARGET 0x10001020
|
||||
RCNT3_COUNT = 0x10001800,
|
||||
RCNT3_MODE = 0x10001810,
|
||||
RCNT3_TARGET = 0x10001820,
|
||||
|
||||
#define RCNT3_COUNT 0x10001800
|
||||
#define RCNT3_MODE 0x10001810
|
||||
#define RCNT3_TARGET 0x10001820
|
||||
IPU_CMD = 0x10002000,
|
||||
IPU_CTRL = 0x10002010,
|
||||
IPU_BP = 0x10002020,
|
||||
IPU_TOP = 0x10002030,
|
||||
|
||||
#define IPU_CMD 0x10002000
|
||||
#define IPU_CTRL 0x10002010
|
||||
#define IPU_BP 0x10002020
|
||||
#define IPU_TOP 0x10002030
|
||||
GIF_CTRL = 0x10003000,
|
||||
GIF_MODE = 0x10003010,
|
||||
GIF_STAT = 0x10003020,
|
||||
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
|
||||
#define GIF_MODE 0x10003010
|
||||
#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
|
||||
IPUout_FIFO = 0x10007000,
|
||||
IPUin_FIFO = 0x10007010,
|
||||
|
||||
//VIF0
|
||||
#define D0_CHCR 0x10008000
|
||||
#define D0_MADR 0x10008010
|
||||
#define D0_QWC 0x10008020
|
||||
D0_CHCR = 0x10008000,
|
||||
D0_MADR = 0x10008010,
|
||||
D0_QWC = 0x10008020,
|
||||
|
||||
//VIF1
|
||||
#define D1_CHCR 0x10009000
|
||||
#define D1_MADR 0x10009010
|
||||
#define D1_QWC 0x10009020
|
||||
#define D1_TADR 0x10009030
|
||||
#define D1_ASR0 0x10009040
|
||||
#define D1_ASR1 0x10009050
|
||||
#define D1_SADR 0x10009080
|
||||
D1_CHCR = 0x10009000,
|
||||
D1_MADR = 0x10009010,
|
||||
D1_QWC = 0x10009020,
|
||||
D1_TADR = 0x10009030,
|
||||
D1_ASR0 = 0x10009040,
|
||||
D1_ASR1 = 0x10009050,
|
||||
D1_SADR = 0x10009080,
|
||||
|
||||
//GS
|
||||
#define D2_CHCR 0x1000A000
|
||||
#define D2_MADR 0x1000A010
|
||||
#define D2_QWC 0x1000A020
|
||||
#define D2_TADR 0x1000A030
|
||||
#define D2_ASR0 0x1000A040
|
||||
#define D2_ASR1 0x1000A050
|
||||
#define D2_SADR 0x1000A080
|
||||
D2_CHCR = 0x1000A000,
|
||||
D2_MADR = 0x1000A010,
|
||||
D2_QWC = 0x1000A020,
|
||||
D2_TADR = 0x1000A030,
|
||||
D2_ASR0 = 0x1000A040,
|
||||
D2_ASR1 = 0x1000A050,
|
||||
D2_SADR = 0x1000A080,
|
||||
|
||||
//fromIPU
|
||||
#define D3_CHCR 0x1000B000
|
||||
#define D3_MADR 0x1000B010
|
||||
#define D3_QWC 0x1000B020
|
||||
#define D3_TADR 0x1000B030
|
||||
#define D3_SADR 0x1000B080
|
||||
D3_CHCR = 0x1000B000,
|
||||
D3_MADR = 0x1000B010,
|
||||
D3_QWC = 0x1000B020,
|
||||
D3_TADR = 0x1000B030,
|
||||
D3_SADR = 0x1000B080,
|
||||
|
||||
//toIPU
|
||||
#define D4_CHCR 0x1000B400
|
||||
#define D4_MADR 0x1000B410
|
||||
#define D4_QWC 0x1000B420
|
||||
#define D4_TADR 0x1000B430
|
||||
#define D4_SADR 0x1000B480
|
||||
D4_CHCR = 0x1000B400,
|
||||
D4_MADR = 0x1000B410,
|
||||
D4_QWC = 0x1000B420,
|
||||
D4_TADR = 0x1000B430,
|
||||
D4_SADR = 0x1000B480,
|
||||
|
||||
//SIF0
|
||||
#define D5_CHCR 0x1000C000
|
||||
#define D5_MADR 0x1000C010
|
||||
#define D5_QWC 0x1000C020
|
||||
D5_CHCR = 0x1000C000,
|
||||
D5_MADR = 0x1000C010,
|
||||
D5_QWC = 0x1000C020,
|
||||
|
||||
//SIF1
|
||||
#define D6_CHCR 0x1000C400
|
||||
#define D6_MADR 0x1000C410
|
||||
#define D6_QWC 0x1000C420
|
||||
D6_CHCR = 0x1000C400,
|
||||
D6_MADR = 0x1000C410,
|
||||
D6_QWC = 0x1000C420,
|
||||
|
||||
//SIF2
|
||||
#define D7_CHCR 0x1000C800
|
||||
#define D7_MADR 0x1000C810
|
||||
#define D7_QWC 0x1000C820
|
||||
D7_CHCR = 0x1000C800,
|
||||
D7_MADR = 0x1000C810,
|
||||
D7_QWC = 0x1000C820,
|
||||
|
||||
//fromSPR
|
||||
#define D8_CHCR 0x1000D000
|
||||
#define D8_MADR 0x1000D010
|
||||
#define D8_QWC 0x1000D020
|
||||
#define D8_SADR 0x1000D080
|
||||
D8_CHCR = 0x1000D000,
|
||||
D8_MADR = 0x1000D010,
|
||||
D8_QWC = 0x1000D020,
|
||||
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
|
||||
#define DMAC_STAT 0x1000E010
|
||||
#define DMAC_PCR 0x1000E020
|
||||
#define DMAC_SQWC 0x1000E030
|
||||
#define DMAC_RBSR 0x1000E040
|
||||
#define DMAC_RBOR 0x1000E050
|
||||
#define DMAC_STADR 0x1000E060
|
||||
INTC_STAT = 0x1000F000,
|
||||
INTC_MASK = 0x1000F010,
|
||||
|
||||
#define INTC_STAT 0x1000F000
|
||||
#define INTC_MASK 0x1000F010
|
||||
SBUS_F220 = 0x1000F220,
|
||||
SBUS_SMFLG = 0x1000F230,
|
||||
SBUS_F240 = 0x1000F240,
|
||||
|
||||
#define SBUS_F220 0x1000F220
|
||||
#define SBUS_SMFLG 0x1000F230
|
||||
#define SBUS_F240 0x1000F240
|
||||
DMAC_ENABLER = 0x1000F520,
|
||||
DMAC_ENABLEW = 0x1000F590,
|
||||
|
||||
#define DMAC_ENABLER 0x1000F520
|
||||
#define DMAC_ENABLEW 0x1000F590
|
||||
GS_PMODE = 0x12000000,
|
||||
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_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
|
||||
#define SBFLG_IOPALIVE 0x10000
|
||||
#define SBFLG_IOPSYNC 0x40000
|
||||
|
||||
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_MEIS (1<<14) // mfifo empty
|
||||
#define DMAC_STAT_BEIS (1<<15) // bus error
|
||||
#define DMAC_STAT_SIM (1<<29) // stall mask
|
||||
#define DMAC_STAT_MEIM (1<<30) // mfifo mask
|
||||
|
||||
#define DMAC_VIF0 0
|
||||
#define DMAC_VIF1 1
|
||||
#define DMAC_GIF 2
|
||||
#define DMAC_FROM_IPU 3
|
||||
#define DMAC_TO_IPU 4
|
||||
#define DMAC_SIF0 5
|
||||
#define DMAC_SIF1 6
|
||||
#define DMAC_SIF2 7
|
||||
#define DMAC_FROM_SPR 8
|
||||
#define DMAC_TO_SPR 9
|
||||
#define DMAC_ERROR 15
|
||||
enum DMACIrqs
|
||||
{
|
||||
DMAC_VIF0 = 0,
|
||||
DMAC_VIF1,
|
||||
DMAC_GIF,
|
||||
DMAC_FROM_IPU,
|
||||
DMAC_TO_IPU,
|
||||
DMAC_SIF0,
|
||||
DMAC_SIF1,
|
||||
DMAC_SIF2,
|
||||
DMAC_FROM_SPR,
|
||||
DMAC_TO_SPR,
|
||||
DMAC_ERROR = 15,
|
||||
};
|
||||
|
||||
#define VIF0_STAT_VPS_W (1)
|
||||
#define VIF0_STAT_VPS_D (2)
|
||||
@ -275,35 +272,39 @@ struct DMACh {
|
||||
#define VIF1_STAT_ER1 (1<<13)
|
||||
#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
|
||||
#define BEISintr (0x8000)
|
||||
#define VIF0intr (0x10001)
|
||||
#define VIF1intr (0x20002)
|
||||
#define GIFintr (0x40004)
|
||||
#define IPU0intr (0x80008)
|
||||
#define IPU1intr (0x100010)
|
||||
#define SIF0intr (0x200020)
|
||||
#define SIF1intr (0x400040)
|
||||
#define SIF2intr (0x800080)
|
||||
#define SPR0intr (0x1000100)
|
||||
#define SPR1intr (0x2000200)
|
||||
#define SISintr (0x20002000)
|
||||
#define MEISintr (0x40004000)
|
||||
|
||||
#define DMAend(dma, num) { \
|
||||
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);
|
||||
enum DMAInter
|
||||
{
|
||||
BEISintr = 0x8000,
|
||||
VIF0intr = 0x10001,
|
||||
VIF1intr = 0x20002,
|
||||
GIFintr = 0x40004,
|
||||
IPU0intr = 0x80008,
|
||||
IPU1intr = 0x100010,
|
||||
SIF0intr = 0x200020,
|
||||
SIF1intr =0x400040,
|
||||
SIF2intr = 0x800080,
|
||||
SPR0intr = 0x1000100,
|
||||
SPR1intr = 0x2000200,
|
||||
SISintr = 0x20002000,
|
||||
MEISintr = 0x40004000
|
||||
};
|
||||
|
||||
#ifdef PCSX2_VIRTUAL_MEM
|
||||
|
||||
@ -348,20 +349,35 @@ static __forceinline void *dmaGetAddr(u32 addr) {
|
||||
u8 *ptr;
|
||||
|
||||
// if (addr & 0xf) { DMA_LOG("*PCSX2*: DMA address not 128bit aligned: %8.8x", addr); }
|
||||
|
||||
if (addr & 0x80000000) { // teh sux why the f00k 0xE0000000
|
||||
return (void*)&psS[addr & 0x3ff0];
|
||||
}
|
||||
|
||||
// teh sux why the f00k 0xE0000000
|
||||
if (addr & 0x80000000) return (void*)&psS[addr & 0x3ff0];
|
||||
|
||||
ptr = (u8*)vtlb_GetPhyPtr(addr&0x1FFFFFF0);
|
||||
if (ptr == NULL) {
|
||||
Console::Error("*PCSX2*: DMA error: %8.8x", params addr);
|
||||
Console::Error( "*PCSX2*: DMA error: %8.8x", params addr);
|
||||
return NULL;
|
||||
}
|
||||
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 hwReset();
|
||||
@ -422,8 +438,8 @@ void hwDmacIrq(int n);
|
||||
int hwMFIFORead(u32 addr, u8 *data, u32 size);
|
||||
int hwMFIFOWrite(u32 addr, u8 *data, u32 size);
|
||||
|
||||
int hwDmacSrcChainWithStack(DMACh *dma, int id);
|
||||
int hwDmacSrcChain(DMACh *dma, int id);
|
||||
bool hwDmacSrcChainWithStack(DMACh *dma, int id);
|
||||
bool hwDmacSrcChain(DMACh *dma, int id);
|
||||
|
||||
int hwConstRead8 (u32 x86reg, u32 mem, u32 sign);
|
||||
int hwConstRead16(u32 x86reg, u32 mem, u32 sign);
|
||||
|
@ -61,34 +61,35 @@ __forceinline u8 hwRead8(u32 mem)
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case 0x10000000: ret = (u8)rcntRcount(0); break;
|
||||
case 0x10000010: ret = (u8)counters[0].modeval; break;
|
||||
case 0x10000020: ret = (u8)counters[0].target; break;
|
||||
case 0x10000030: ret = (u8)counters[0].hold; break;
|
||||
// Note: the values without defines = the defines + 1.
|
||||
case RCNT0_COUNT: ret = (u8)rcntRcount(0); break;
|
||||
case RCNT0_MODE: ret = (u8)counters[0].modeval; 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 0x10000011: ret = (u8)(counters[0].modeval>>8); break;
|
||||
case 0x10000021: ret = (u8)(counters[0].target>>8); break;
|
||||
case 0x10000031: ret = (u8)(counters[0].hold>>8); break;
|
||||
|
||||
case 0x10000800: ret = (u8)rcntRcount(1); break;
|
||||
case 0x10000810: ret = (u8)counters[1].modeval; break;
|
||||
case 0x10000820: ret = (u8)counters[1].target; break;
|
||||
case 0x10000830: ret = (u8)counters[1].hold; break;
|
||||
case RCNT1_COUNT: ret = (u8)rcntRcount(1); break;
|
||||
case RCNT1_MODE: ret = (u8)counters[1].modeval; break;
|
||||
case RCNT1_TARGET: ret = (u8)counters[1].target; break;
|
||||
case RCNT1_HOLD: ret = (u8)counters[1].hold; break;
|
||||
case 0x10000801: ret = (u8)(rcntRcount(1)>>8); break;
|
||||
case 0x10000811: ret = (u8)(counters[1].modeval>>8); break;
|
||||
case 0x10000821: ret = (u8)(counters[1].target>>8); break;
|
||||
case 0x10000831: ret = (u8)(counters[1].hold>>8); break;
|
||||
|
||||
case 0x10001000: ret = (u8)rcntRcount(2); break;
|
||||
case 0x10001010: ret = (u8)counters[2].modeval; break;
|
||||
case 0x10001020: ret = (u8)counters[2].target; break;
|
||||
case RCNT2_COUNT: ret = (u8)rcntRcount(2); break;
|
||||
case RCNT2_MODE: ret = (u8)counters[2].modeval; break;
|
||||
case RCNT2_TARGET: ret = (u8)counters[2].target; break;
|
||||
case 0x10001001: ret = (u8)(rcntRcount(2)>>8); break;
|
||||
case 0x10001011: ret = (u8)(counters[2].modeval>>8); break;
|
||||
case 0x10001021: ret = (u8)(counters[2].target>>8); break;
|
||||
|
||||
case 0x10001800: ret = (u8)rcntRcount(3); break;
|
||||
case 0x10001810: ret = (u8)counters[3].modeval; break;
|
||||
case 0x10001820: ret = (u8)counters[3].target; break;
|
||||
case RCNT3_COUNT: ret = (u8)rcntRcount(3); break;
|
||||
case RCNT3_MODE: ret = (u8)counters[3].modeval; break;
|
||||
case RCNT3_TARGET: ret = (u8)counters[3].target; break;
|
||||
case 0x10001801: ret = (u8)(rcntRcount(3)>>8); break;
|
||||
case 0x10001811: ret = (u8)(counters[3].modeval>>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 == 0x1000f260) ret = 0;
|
||||
else if(mem == 0x1000F240) {
|
||||
else if(mem == SBUS_F240) {
|
||||
ret = psHu32(mem);
|
||||
//psHu32(mem) &= ~0x4000;
|
||||
}
|
||||
@ -120,34 +121,34 @@ __forceinline u16 hwRead16(u32 mem)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
if( mem >= 0x10002000 && mem < 0x10008000 )
|
||||
if( mem >= IPU_CMD && mem < D0_CHCR )
|
||||
Console::Notice("Unexpected hwRead16 from 0x%x", params mem);
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case 0x10000000: ret = (u16)rcntRcount(0); break;
|
||||
case 0x10000010: ret = (u16)counters[0].modeval; break;
|
||||
case 0x10000020: ret = (u16)counters[0].target; break;
|
||||
case 0x10000030: ret = (u16)counters[0].hold; break;
|
||||
case RCNT0_COUNT: ret = (u16)rcntRcount(0); break;
|
||||
case RCNT0_MODE: ret = (u16)counters[0].modeval; break;
|
||||
case RCNT0_TARGET: ret = (u16)counters[0].target; break;
|
||||
case RCNT0_HOLD: ret = (u16)counters[0].hold; break;
|
||||
|
||||
case 0x10000800: ret = (u16)rcntRcount(1); break;
|
||||
case 0x10000810: ret = (u16)counters[1].modeval; break;
|
||||
case 0x10000820: ret = (u16)counters[1].target; break;
|
||||
case 0x10000830: ret = (u16)counters[1].hold; break;
|
||||
case RCNT1_COUNT: ret = (u16)rcntRcount(1); break;
|
||||
case RCNT1_MODE: ret = (u16)counters[1].modeval; break;
|
||||
case RCNT1_TARGET: ret = (u16)counters[1].target; break;
|
||||
case RCNT1_HOLD: ret = (u16)counters[1].hold; break;
|
||||
|
||||
case 0x10001000: ret = (u16)rcntRcount(2); break;
|
||||
case 0x10001010: ret = (u16)counters[2].modeval; break;
|
||||
case 0x10001020: ret = (u16)counters[2].target; break;
|
||||
case RCNT2_COUNT: ret = (u16)rcntRcount(2); break;
|
||||
case RCNT2_MODE: ret = (u16)counters[2].modeval; break;
|
||||
case RCNT2_TARGET: ret = (u16)counters[2].target; break;
|
||||
|
||||
case 0x10001800: ret = (u16)rcntRcount(3); break;
|
||||
case 0x10001810: ret = (u16)counters[3].modeval; break;
|
||||
case 0x10001820: ret = (u16)counters[3].target; break;
|
||||
case RCNT3_COUNT: ret = (u16)rcntRcount(3); break;
|
||||
case RCNT3_MODE: ret = (u16)counters[3].modeval; break;
|
||||
case RCNT3_TARGET: ret = (u16)counters[3].target; break;
|
||||
|
||||
default:
|
||||
if ((mem & 0xffffff0f) == 0x1000f200)
|
||||
{
|
||||
if(mem == 0x1000f260) ret = 0;
|
||||
else if(mem == 0x1000F240) {
|
||||
else if(mem == SBUS_F240) {
|
||||
ret = psHu16(mem) | 0x0102;
|
||||
psHu32(mem) &= ~0x4000;
|
||||
}
|
||||
|
@ -40,11 +40,22 @@ using namespace R5900;
|
||||
// dark cloud2 uses 8 bit DMAs register writes
|
||||
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
|
||||
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 );
|
||||
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;
|
||||
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 )
|
||||
{
|
||||
u32 qwcRegister = mem | 0x20;
|
||||
|
||||
//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) {
|
||||
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;
|
||||
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 )
|
||||
{
|
||||
u32 qwcRegister = mem | 0x20;
|
||||
|
||||
//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) {
|
||||
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*/
|
||||
if( (value & 0xc) == 0x4 && (value & 0xffff0000) == 0)
|
||||
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 );
|
||||
|
||||
switch (mem) {
|
||||
case 0x10000000: rcntWcount(0, value); break;
|
||||
case 0x10000010: rcntWmode(0, (counters[0].modeval & 0xff00) | value); break;
|
||||
case RCNT0_COUNT: rcntWcount(0, 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 0x10000020: rcntWtarget(0, value); break;
|
||||
case 0x10000030: rcntWhold(0, value); break;
|
||||
case RCNT0_TARGET: rcntWtarget(0, value); break;
|
||||
case RCNT0_HOLD: rcntWhold(0, value); break;
|
||||
|
||||
case 0x10000800: rcntWcount(1, value); break;
|
||||
case 0x10000810: rcntWmode(1, (counters[1].modeval & 0xff00) | value); break;
|
||||
case RCNT1_COUNT: rcntWcount(1, 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 0x10000820: rcntWtarget(1, value); break;
|
||||
case 0x10000830: rcntWhold(1, value); break;
|
||||
case RCNT1_TARGET: rcntWtarget(1, value); break;
|
||||
case RCNT1_HOLD: rcntWhold(1, value); break;
|
||||
|
||||
case 0x10001000: rcntWcount(2, value); break;
|
||||
case 0x10001010: rcntWmode(2, (counters[2].modeval & 0xff00) | value); break;
|
||||
case RCNT2_COUNT: rcntWcount(2, 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 0x10001020: rcntWtarget(2, value); break;
|
||||
case RCNT2_TARGET: rcntWtarget(2, value); break;
|
||||
|
||||
case 0x10001800: rcntWcount(3, value); break;
|
||||
case 0x10001810: rcntWmode(3, (counters[3].modeval & 0xff00) | value); break;
|
||||
case RCNT3_COUNT: rcntWcount(3, 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 0x10001820: rcntWtarget(3, value); break;
|
||||
case RCNT3_TARGET: rcntWtarget(3, value); break;
|
||||
|
||||
case 0x1000f180:
|
||||
if (value == '\n') {
|
||||
@ -166,7 +199,7 @@ void hwWrite8(u32 mem, u8 value) {
|
||||
DevCon::Notice("8 bit VIF1 DMA Start while DMAC Disabled\n");
|
||||
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);
|
||||
break;
|
||||
|
||||
@ -288,25 +321,25 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
|
||||
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 RCNT0_COUNT: rcntWcount(0, value); break;
|
||||
case RCNT0_MODE: rcntWmode(0, value); break;
|
||||
case RCNT0_TARGET: rcntWtarget(0, value); break;
|
||||
case RCNT0_HOLD: 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 RCNT1_COUNT: rcntWcount(1, value); break;
|
||||
case RCNT1_MODE: rcntWmode(1, value); break;
|
||||
case RCNT1_TARGET: rcntWtarget(1, value); break;
|
||||
case RCNT1_HOLD: rcntWhold(1, value); break;
|
||||
|
||||
case 0x10001000: rcntWcount(2, value); break;
|
||||
case 0x10001010: rcntWmode(2, value); break;
|
||||
case 0x10001020: rcntWtarget(2, value); break;
|
||||
case RCNT2_COUNT: rcntWcount(2, value); break;
|
||||
case RCNT2_MODE: rcntWmode(2, value); break;
|
||||
case RCNT2_TARGET: rcntWtarget(2, value); break;
|
||||
|
||||
case 0x10001800: rcntWcount(3, value); break;
|
||||
case 0x10001810: rcntWmode(3, value); break;
|
||||
case 0x10001820: rcntWtarget(3, value); break;
|
||||
case RCNT3_COUNT: rcntWcount(3, value); break;
|
||||
case RCNT3_MODE: rcntWmode(3, value); break;
|
||||
case RCNT3_TARGET: rcntWtarget(3, value); break;
|
||||
|
||||
case 0x10008000: // dma0 - vif0
|
||||
case D0_CHCR: // dma0 - vif0
|
||||
DMA_LOG("VIF0dma %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -316,46 +349,46 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
DmaExec16(dmaVIF0, mem, value);
|
||||
break;
|
||||
|
||||
case 0x10009000: // dma1 - vif1 - chcr
|
||||
case D1_CHCR: // dma1 - vif1 - chcr
|
||||
DMA_LOG("VIF1dma CHCR %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
DevCon::Notice("16 bit VIF1 DMA Start while DMAC Disabled\n");
|
||||
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);
|
||||
break;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
case 0x10009010: // dma1 - vif1 - madr
|
||||
case D1_MADR: // dma1 - vif1 - madr
|
||||
HW_LOG("VIF1dma Madr %lx", value);
|
||||
psHu16(mem) = value;//dma1 madr
|
||||
break;
|
||||
case 0x10009020: // dma1 - vif1 - qwc
|
||||
case D1_QWC: // dma1 - vif1 - qwc
|
||||
HW_LOG("VIF1dma QWC %lx", value);
|
||||
psHu16(mem) = value;//dma1 qwc
|
||||
break;
|
||||
case 0x10009030: // dma1 - vif1 - tadr
|
||||
case D1_TADR: // dma1 - vif1 - tadr
|
||||
HW_LOG("VIF1dma TADR %lx", value);
|
||||
psHu16(mem) = value;//dma1 tadr
|
||||
break;
|
||||
case 0x10009040: // dma1 - vif1 - asr0
|
||||
case D1_ASR0: // dma1 - vif1 - asr0
|
||||
HW_LOG("VIF1dma ASR0 %lx", value);
|
||||
psHu16(mem) = value;//dma1 asr0
|
||||
break;
|
||||
case 0x10009050: // dma1 - vif1 - asr1
|
||||
case D1_ASR1: // dma1 - vif1 - asr1
|
||||
HW_LOG("VIF1dma ASR1 %lx", value);
|
||||
psHu16(mem) = value;//dma1 asr1
|
||||
break;
|
||||
case 0x10009080: // dma1 - vif1 - sadr
|
||||
case D1_SADR: // dma1 - vif1 - sadr
|
||||
HW_LOG("VIF1dma SADR %lx", value);
|
||||
psHu16(mem) = value;//dma1 sadr
|
||||
break;
|
||||
#endif
|
||||
// ---------------------------------------------------
|
||||
|
||||
case 0x1000a000: // dma2 - gif
|
||||
case D2_CHCR: // dma2 - gif
|
||||
DMA_LOG("0x%8.8x hwWrite32: GSdma %lx", cpuRegs.cycle, value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -366,33 +399,33 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
break;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
case 0x1000a010:
|
||||
case D2_MADR:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
HW_LOG("Hardware write DMA2_MADR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000a020:
|
||||
psHu16(mem) = value;//dma2 qwc
|
||||
HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000a030:
|
||||
psHu16(mem) = value;//dma2 taddr
|
||||
HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000a040:
|
||||
psHu16(mem) = value;//dma2 asr0
|
||||
HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000a050:
|
||||
psHu16(mem) = value;//dma2 asr1
|
||||
HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000a080:
|
||||
psHu16(mem) = value;//dma2 saddr
|
||||
HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case D2_QWC:
|
||||
psHu16(mem) = value;//dma2 qwc
|
||||
HW_LOG("Hardware write DMA2_QWC 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case D2_TADR:
|
||||
psHu16(mem) = value;//dma2 taddr
|
||||
HW_LOG("Hardware write DMA2_TADDR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case D2_ASR0:
|
||||
psHu16(mem) = value;//dma2 asr0
|
||||
HW_LOG("Hardware write DMA2_ASR0 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case D2_ASR1:
|
||||
psHu16(mem) = value;//dma2 asr1
|
||||
HW_LOG("Hardware write DMA2_ASR1 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case D2_SADR:
|
||||
psHu16(mem) = value;//dma2 saddr
|
||||
HW_LOG("Hardware write DMA2_SADDR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0x1000b000: // dma3 - fromIPU
|
||||
case D3_CHCR: // dma3 - fromIPU
|
||||
DMA_LOG("IPU0dma %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -403,25 +436,25 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
break;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
case 0x1000b010:
|
||||
case D3_MADR:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
HW_LOG("Hardware write IPU0DMA_MADR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000b020:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
case D3_QWC:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
HW_LOG("Hardware write IPU0DMA_QWC 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000b030:
|
||||
case D3_TADR:
|
||||
psHu16(mem) = value;//dma2 tadr
|
||||
HW_LOG("Hardware write IPU0DMA_TADR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000b080:
|
||||
case D3_SADR:
|
||||
psHu16(mem) = value;//dma2 saddr
|
||||
HW_LOG("Hardware write IPU0DMA_SADDR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0x1000b400: // dma4 - toIPU
|
||||
case D4_CHCR: // dma4 - toIPU
|
||||
DMA_LOG("IPU1dma %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -432,24 +465,24 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
break;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
case 0x1000b410:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
case D4_MADR:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
HW_LOG("Hardware write IPU1DMA_MADR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000b420:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
case D4_QWC:
|
||||
psHu16(mem) = value;//dma2 madr
|
||||
HW_LOG("Hardware write IPU1DMA_QWC 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000b430:
|
||||
case D4_TADR:
|
||||
psHu16(mem) = value;//dma2 tadr
|
||||
HW_LOG("Hardware write IPU1DMA_TADR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
case 0x1000b480:
|
||||
case D4_SADR:
|
||||
psHu16(mem) = value;//dma2 saddr
|
||||
HW_LOG("Hardware write IPU1DMA_SADDR 32bit at %x with value %x",mem,value);
|
||||
break;
|
||||
#endif
|
||||
case 0x1000c000: // dma5 - sif0
|
||||
case D5_CHCR: // dma5 - sif0
|
||||
DMA_LOG("SIF0dma %lx", value);
|
||||
// if (value == 0) psxSu32(0x30) = 0x40000;
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
@ -463,7 +496,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
case 0x1000c002:
|
||||
//?
|
||||
break;
|
||||
case 0x1000c400: // dma6 - sif1
|
||||
case D6_CHCR: // dma6 - sif1
|
||||
DMA_LOG("SIF1dma %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -474,7 +507,8 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
break;
|
||||
|
||||
#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);
|
||||
psHu16(mem) = value;
|
||||
break;
|
||||
@ -485,7 +519,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 0x1000c800: // dma7 - sif2
|
||||
case D7_CHCR: // dma7 - sif2
|
||||
DMA_LOG("SIF2dma %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -497,7 +531,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
case 0x1000c802:
|
||||
//?
|
||||
break;
|
||||
case 0x1000d000: // dma8 - fromSPR
|
||||
case D8_CHCR: // dma8 - fromSPR
|
||||
DMA_LOG("fromSPRdma %lx", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -532,13 +566,13 @@ __forceinline void hwWrite16(u32 mem, u16 value)
|
||||
psHu16(mem) = value;
|
||||
break;
|
||||
|
||||
case 0x1000f220:
|
||||
case SBUS_F220:
|
||||
psHu16(mem) |= value;
|
||||
break;
|
||||
case 0x1000f230:
|
||||
case SBUS_SMFLG:
|
||||
psHu16(mem) &= ~value;
|
||||
break;
|
||||
case 0x1000f240:
|
||||
case SBUS_F240:
|
||||
if(!(value & 0x100))
|
||||
psHu16(mem) &= ~0x100;
|
||||
else
|
||||
@ -762,13 +796,13 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
|
||||
case HELPSWITCH(0x1000f200):
|
||||
psHu32(mem) = value;
|
||||
break;
|
||||
case HELPSWITCH(0x1000f220):
|
||||
case HELPSWITCH(SBUS_F220):
|
||||
psHu32(mem) |= value;
|
||||
break;
|
||||
case HELPSWITCH(0x1000f230):
|
||||
case HELPSWITCH(SBUS_SMFLG):
|
||||
psHu32(mem) &= ~value;
|
||||
break;
|
||||
case HELPSWITCH(0x1000f240):
|
||||
case HELPSWITCH(SBUS_F240):
|
||||
if(!(value & 0x100))
|
||||
psHu32(mem) &= ~0x100;
|
||||
else
|
||||
@ -782,7 +816,7 @@ void __fastcall hwWrite32_page_0F( u32 mem, u32 value )
|
||||
psHu32(mem) = value;
|
||||
break;
|
||||
|
||||
case HELPSWITCH(0x1000f590): // DMAC_ENABLEW
|
||||
case HELPSWITCH(DMAC_ENABLEW): // DMAC_ENABLEW
|
||||
HW_LOG("DMAC_ENABLEW Write 32bit %lx", value);
|
||||
psHu32(0xf590) = value;
|
||||
psHu32(0xf520) = value;
|
||||
@ -826,7 +860,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
||||
}
|
||||
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);
|
||||
return;
|
||||
@ -850,14 +884,14 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
||||
return;
|
||||
|
||||
case D2_MADR: regName = "GIFdma MADR"; break;
|
||||
case D2_QWC: regName = "GIFdma QWC"; break;
|
||||
case D2_TADR: regName = "GIFdma TADDR"; break;
|
||||
case D2_ASR0: regName = "GIFdma ASR0"; break;
|
||||
case D2_ASR1: regName = "GIFdma ASR1"; break;
|
||||
case D2_SADR: regName = "GIFdma SADDR"; break;
|
||||
case D2_QWC: regName = "GIFdma QWC"; break;
|
||||
case D2_TADR: regName = "GIFdma TADDR"; break;
|
||||
case D2_ASR0: regName = "GIFdma ASR0"; break;
|
||||
case D2_ASR1: regName = "GIFdma ASR1"; 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);
|
||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
@ -868,7 +902,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
||||
DmaExec(dmaSIF0, mem, value);
|
||||
return;
|
||||
//------------------------------------------------------------------
|
||||
case 0x1000c400: // dma6 - sif1
|
||||
case D6_CHCR: // dma6 - sif1
|
||||
DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -878,11 +912,12 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
||||
DmaExec(dmaSIF1, mem, value);
|
||||
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 0x1000c800: // dma7 - sif2
|
||||
case D7_CHCR: // dma7 - sif2
|
||||
DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -892,7 +927,7 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
|
||||
DmaExec(dmaSIF2, mem, value);
|
||||
return;
|
||||
//------------------------------------------------------------------
|
||||
case 0x1000d000: // dma8 - fromSPR
|
||||
case D8_CHCR: // dma8 - fromSPR
|
||||
DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
|
||||
if ((value & 0x100) && !(psHu32(DMAC_CTRL) & 0x1))
|
||||
{
|
||||
@ -1015,7 +1050,7 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case 0x1000a000: // dma2 - gif
|
||||
case D2_CHCR: // dma2 - gif
|
||||
DMA_LOG("0x%8.8x hwWrite64: GSdma %x", cpuRegs.cycle, value);
|
||||
DmaExec(dmaGIF, mem, value);
|
||||
break;
|
||||
@ -1037,7 +1072,7 @@ void __fastcall hwWrite64_generic( u32 mem, const mem64_t* srcval )
|
||||
case 0x1000f430:
|
||||
break;
|
||||
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
case DMAC_ENABLEW: // DMAC_ENABLEW
|
||||
psHu32(0xf590) = value;
|
||||
psHu32(0xf520) = value;
|
||||
break;
|
||||
@ -1070,7 +1105,7 @@ void __fastcall hwWrite128_generic(u32 mem, const mem128_t *srcval)
|
||||
cpuTestINTCInts();
|
||||
break;
|
||||
|
||||
case 0x1000f590: // DMAC_ENABLEW
|
||||
case DMAC_ENABLEW: // DMAC_ENABLEW
|
||||
psHu32(0xf590) = srcval[0];
|
||||
psHu32(0xf520) = srcval[0];
|
||||
break;
|
||||
|
@ -48,11 +48,6 @@ using namespace std; // for min / max
|
||||
# define IPU_FORCEINLINE __forceinline
|
||||
#endif
|
||||
|
||||
//IPUregisters g_ipuRegsReal;
|
||||
|
||||
#define ipu0dma ((DMACh *)&PS2MEM_HW[0xb000])
|
||||
#define ipu1dma ((DMACh *)&PS2MEM_HW[0xb400])
|
||||
|
||||
#define IPU_DMA_GIFSTALL 1
|
||||
#define IPU_DMA_TIE0 2
|
||||
#define IPU_DMA_TIE1 4
|
||||
@ -369,7 +364,7 @@ __forceinline void ipuWrite64(u32 mem, u64 value)
|
||||
|
||||
switch (mem)
|
||||
{
|
||||
case 0x10:
|
||||
case 0x00:
|
||||
IPU_LOG("Ipu write64: IPU_CMD=0x%08X", value);
|
||||
IPUCMD_WRITE((u32)value);
|
||||
break;
|
||||
@ -1372,9 +1367,11 @@ int FIFOto_write(u32* pMem, int size)
|
||||
g_nDMATransfer |= IPU_DMA_ACTV1; \
|
||||
return totalqwc; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
extern void gsInterrupt();
|
||||
|
||||
int IPU1dma()
|
||||
{
|
||||
u32 *ptag, *pMem;
|
||||
@ -1388,6 +1385,13 @@ int IPU1dma()
|
||||
|
||||
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
|
||||
if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0)
|
||||
{
|
||||
@ -1404,8 +1408,6 @@ int IPU1dma()
|
||||
return totalqwc;
|
||||
}
|
||||
|
||||
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
|
||||
|
||||
if ((ipu1dma->chcr&0xc) == 0)
|
||||
{
|
||||
IPU_INT_TO(totalqwc*BIAS);
|
||||
@ -1449,6 +1451,8 @@ int IPU1dma()
|
||||
return totalqwc;
|
||||
}
|
||||
}
|
||||
|
||||
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
|
||||
}
|
||||
|
||||
if ((ipu1dma->chcr & 0xc) == 0 && ipu1dma->qwc == 0) // Normal Mode
|
||||
|
@ -112,7 +112,8 @@ void __fastcall intDoBranch(u32 target)
|
||||
}
|
||||
}
|
||||
|
||||
void intSetBranch() {
|
||||
void intSetBranch()
|
||||
{
|
||||
branch2 = /*cpuRegs.branch =*/ 1;
|
||||
}
|
||||
|
||||
@ -133,90 +134,223 @@ namespace OpcodeImpl {
|
||||
* Format: OP target *
|
||||
*********************************************************/
|
||||
|
||||
void J() {
|
||||
void J()
|
||||
{
|
||||
doBranch(_JumpTarget_);
|
||||
}
|
||||
|
||||
void JAL() {
|
||||
_SetLink(31); doBranch(_JumpTarget_);
|
||||
void JAL()
|
||||
{
|
||||
_SetLink(31);
|
||||
doBranch(_JumpTarget_);
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Register branch logic *
|
||||
* 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() { RepBranchi32(!=) } // Branch if Rs != Rt
|
||||
void BNE() // Branch if Rs != Rt
|
||||
{
|
||||
if (cpuRegs.GPR.r[_Rs_].SD[0] != cpuRegs.GPR.r[_Rt_].SD[0])
|
||||
doBranch(_BranchTarget_);
|
||||
else
|
||||
intEventTest();
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* Register branch logic *
|
||||
* 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); \
|
||||
if(cpuRegs.GPR.r[_Rs_].SD[0] op 0) { \
|
||||
doBranch(_BranchTarget_); \
|
||||
if (cpuRegs.GPR.r[_Rs_].SD[0] < 0)
|
||||
{
|
||||
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 *
|
||||
* 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 BNEL() { RepBranchi32Likely(!=) } // Branch if Rs != Rt
|
||||
void BLEZL() { RepZBranchi32Likely(<=) } // Branch if Rs <= 0
|
||||
void BGTZL() { RepZBranchi32Likely(>) } // Branch if Rs > 0
|
||||
void BLTZL() { RepZBranchi32Likely(<) } // Branch if Rs < 0
|
||||
void BGEZL() { RepZBranchi32Likely(>=) } // Branch if Rs >= 0
|
||||
void BLTZALL() { RepZBranchLinki32Likely(<) } // Branch if Rs < 0 and link
|
||||
void BGEZALL() { RepZBranchLinki32Likely(>=) } // Branch if Rs >= 0 and link
|
||||
void BEQL() // 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 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 *
|
||||
* Format: OP rs, rd *
|
||||
*********************************************************/
|
||||
void JR() {
|
||||
void JR()
|
||||
{
|
||||
doBranch(cpuRegs.GPR.r[_Rs_].UL[0]);
|
||||
}
|
||||
|
||||
void JALR() {
|
||||
void JALR()
|
||||
{
|
||||
u32 temp = cpuRegs.GPR.r[_Rs_].UL[0];
|
||||
if (_Rd_) { _SetLink(_Rd_); }
|
||||
|
||||
if (_Rd_) _SetLink(_Rd_);
|
||||
|
||||
doBranch(temp);
|
||||
}
|
||||
|
||||
@ -235,7 +369,7 @@ void intReset()
|
||||
branch2 = 0;
|
||||
}
|
||||
|
||||
bool intEventTest()
|
||||
bool intEventTest()
|
||||
{
|
||||
// Perform counters, ints, and IOP updates:
|
||||
return _cpuBranchTest_Shared();
|
||||
|
@ -29,10 +29,10 @@
|
||||
#include "Sio.h"
|
||||
#include "Sif.h"
|
||||
|
||||
#include "IopDma.h"
|
||||
#include "IopMem.h"
|
||||
#include "IopHw.h"
|
||||
#include "IopBios.h"
|
||||
#include "IopDma.h"
|
||||
#include "IopCounters.h"
|
||||
#include "IopSio2.h"
|
||||
|
||||
|
@ -38,8 +38,7 @@
|
||||
#define PSXPIXEL ((int)(PSXCLK / 13500000))
|
||||
#define PSXSOUNDCLK ((int)(48000))
|
||||
|
||||
|
||||
psxCounter psxCounters[8];
|
||||
psxCounter psxCounters[NUM_COUNTERS];
|
||||
s32 psxNextCounter;
|
||||
u32 psxNextsCounter;
|
||||
u8 psxhblankgate = 0;
|
||||
@ -141,6 +140,12 @@ void psxRcntInit() {
|
||||
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++)
|
||||
psxCounters[i].sCycleT = psxRegs.cycle;
|
||||
|
||||
@ -453,6 +458,24 @@ void psxRcntUpdate()
|
||||
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 );
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,13 @@ struct psxCounter {
|
||||
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 u32 psxNextsCounter;
|
||||
|
||||
|
241
pcsx2/IopDma.cpp
241
pcsx2/IopDma.cpp
@ -28,6 +28,7 @@ using namespace R3000A;
|
||||
|
||||
// Should be a bool, and will be next time I break savestate. --arcum42
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
{
|
||||
psxDmaGeneric(madr, bcr, chcr, 0, SPU2writeDMA4Mem, SPU2readDMA4Mem);
|
||||
@ -87,12 +96,6 @@ int psxDma4Interrupt()
|
||||
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)
|
||||
{
|
||||
u32 *mem = (u32 *)iopPhysMem(madr);
|
||||
@ -130,7 +133,32 @@ int psxDma7Interrupt()
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
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()
|
||||
void dev9Interrupt()
|
||||
{
|
||||
if ((dev9Handler != NULL) && (dev9Handler() != 1)) return;
|
||||
|
||||
@ -202,7 +207,7 @@ void dev9Irq(int cycles)
|
||||
PSX_INT(IopEvt_DEV9, cycles);
|
||||
}
|
||||
|
||||
void usbInterrupt()
|
||||
void usbInterrupt()
|
||||
{
|
||||
if (usbHandler != NULL && (usbHandler() != 1)) return;
|
||||
|
||||
@ -253,35 +258,96 @@ void iopIntcIrq(uint irqType)
|
||||
//
|
||||
|
||||
// fixme: Is this in progress?
|
||||
#if FALSE
|
||||
#ifdef ENABLE_NEW_IOPDMA
|
||||
|
||||
typedef s32(* DmaHandler)(s32 channel, u32* data, u32 wordsLeft, u32* wordsProcessed);
|
||||
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
|
||||
s32 spu2DmaRead(s32 channel, u32* data, u32 bytesLeft, u32* bytesProcessed)
|
||||
{
|
||||
DmaHandler Read;
|
||||
DmaHandler Write;
|
||||
DmaIHandler Interrupt;
|
||||
};
|
||||
// FIXME: change the plugin interfaces so that they are aware of this new dma handler
|
||||
|
||||
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;
|
||||
u32 Width; // bytes/word, for timing purposes
|
||||
u32 MemAddr;
|
||||
u32 ByteCount;
|
||||
u32 Target;
|
||||
};
|
||||
// FIXME: change the plugin interfaces so that they are aware of this new dma handler
|
||||
|
||||
// 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?
|
||||
|
||||
@ -295,9 +361,9 @@ DmaHandlerInfo IopDmaHandlers[DMA_CHANNEL_MAX] =
|
||||
{0}, //5
|
||||
{0}, //6: OT?
|
||||
{spu2DmaRead, spu2DmaWrite, spu2DmaInterrupt}, //7: Spu Core1
|
||||
{dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9
|
||||
{sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0
|
||||
{sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1
|
||||
{0},//{dev9DmaRead, dev9DmaWrite, dev9DmaInterrupt}, //8: Dev9
|
||||
{0},//{sif0DmaRead, sif0DmaWrite, sif0DmaInterrupt}, //9: SIF0
|
||||
{0},//{sif1DmaRead, sif1DmaWrite, sif1DmaInterrupt}, //10: SIF1
|
||||
{0}, // Sio2
|
||||
{0}, // Sio2
|
||||
};
|
||||
@ -319,26 +385,37 @@ const char* IopDmaNames[DMA_CHANNEL_MAX] =
|
||||
"Sio2",
|
||||
"?", "?", "?"
|
||||
};
|
||||
};
|
||||
|
||||
// Prototypes. To be implemented later (or in other parts of the emulator)
|
||||
void SetDmaUpdateTarget(u32 delay);
|
||||
void RaiseDmaIrq(u32 channel);
|
||||
void SetDmaUpdateTarget(u32 delay)
|
||||
{
|
||||
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!
|
||||
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?
|
||||
int size = (bcr >> 16) * (bcr & 0xFFFF);
|
||||
int size = 4* (bcr >> 16) * (bcr & 0xFFFF);
|
||||
|
||||
IopChannels[channel].Control = chcr | DMA_CTRL_ACTIVE;
|
||||
IopChannels[channel].MemAddr = madr;
|
||||
IopChannels[channel].ByteCount = size;
|
||||
|
||||
SetDmaUpdateTarget(0);
|
||||
}
|
||||
|
||||
void IopDmaUpdate(u32 elapsed)
|
||||
{
|
||||
u32 MinDelay = 0xFFFFFFFF;
|
||||
s32 MinDelay = 0x7FFFFFFF;
|
||||
|
||||
for (int i = 0;i < DMA_CHANNEL_MAX;i++)
|
||||
{
|
||||
@ -358,12 +435,17 @@ void IopDmaUpdate(u32 elapsed)
|
||||
else
|
||||
{
|
||||
// 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;
|
||||
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)
|
||||
{
|
||||
// TODO: ... What to do if the plugin errors? :P
|
||||
@ -373,29 +455,38 @@ void IopDmaUpdate(u32 elapsed)
|
||||
ch->MemAddr += 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,46 @@
|
||||
|
||||
#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 psxDma3(u32 madr, u32 bcr, u32 chcr);
|
||||
void psxDma4(u32 madr, u32 bcr, u32 chcr);
|
||||
|
324
pcsx2/IopHw.cpp
324
pcsx2/IopHw.cpp
@ -41,7 +41,7 @@ void psxHwReset() {
|
||||
u8 psxHwRead8(u32 add) {
|
||||
u8 hard;
|
||||
|
||||
if (add >= 0x1f801600 && add < 0x1f801700) {
|
||||
if (add >= HW_USB_START && add < HW_USB_END) {
|
||||
return USBread8(add);
|
||||
}
|
||||
|
||||
@ -53,24 +53,24 @@ u8 psxHwRead8(u32 add) {
|
||||
return DEV9read8(add);
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
case 0x1f801100:
|
||||
case 0x1f801104:
|
||||
case 0x1f801108:
|
||||
case 0x1f801110:
|
||||
case 0x1f801114:
|
||||
case 0x1f801118:
|
||||
case 0x1f801120:
|
||||
case 0x1f801124:
|
||||
case 0x1f801128:
|
||||
case 0x1f801480:
|
||||
case 0x1f801484:
|
||||
case 0x1f801488:
|
||||
case 0x1f801490:
|
||||
case 0x1f801494:
|
||||
case 0x1f801498:
|
||||
case 0x1f8014a0:
|
||||
case 0x1f8014a4:
|
||||
case 0x1f8014a8:
|
||||
case IOP_T0_COUNT:
|
||||
case IOP_T0_MODE:
|
||||
case IOP_T0_TARGET:
|
||||
case IOP_T1_COUNT:
|
||||
case IOP_T1_MODE:
|
||||
case IOP_T1_TARGET:
|
||||
case IOP_T2_COUNT:
|
||||
case IOP_T2_MODE:
|
||||
case IOP_T2_TARGET:
|
||||
case IOP_T3_COUNT:
|
||||
case IOP_T3_MODE:
|
||||
case IOP_T3_TARGET:
|
||||
case IOP_T4_COUNT:
|
||||
case IOP_T4_MODE:
|
||||
case IOP_T4_TARGET:
|
||||
case IOP_T5_COUNT:
|
||||
case IOP_T5_MODE:
|
||||
case IOP_T5_TARGET:
|
||||
DevCon::Notice( "IOP Counter Read8 from addr0x%x = 0x%x", params add, psxHu8(add) );
|
||||
return psxHu8(add);
|
||||
#endif
|
||||
@ -102,7 +102,7 @@ u8 psxHwRead8(u32 add) {
|
||||
u16 psxHwRead16(u32 add) {
|
||||
u16 hard;
|
||||
|
||||
if (add >= 0x1f801600 && add < 0x1f801700) {
|
||||
if (add >= HW_USB_START && add < HW_USB_END) {
|
||||
return USBread16(add);
|
||||
}
|
||||
|
||||
@ -136,50 +136,50 @@ u16 psxHwRead16(u32 add) {
|
||||
return hard;
|
||||
|
||||
//Serial port stuff not support now ;P
|
||||
// case 0x1f801050: hard = serial_read16(); break;
|
||||
// case 0x1f801054: hard = serial_status_read(); break;
|
||||
// case 0x1f80105a: hard = serial_control_read(); break;
|
||||
// case 0x1f80105e: hard = serial_baud_read(); break;
|
||||
// case 0x1f801050: hard = serial_read16(); break;
|
||||
// case 0x1f801054: hard = serial_status_read(); break;
|
||||
// case 0x1f80105a: hard = serial_control_read(); break;
|
||||
// case 0x1f80105e: hard = serial_baud_read(); break;
|
||||
|
||||
case 0x1f801100:
|
||||
case IOP_T0_COUNT:
|
||||
hard = (u16)psxRcntRcount16(0);
|
||||
PSXCNT_LOG("T0 count read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801104:
|
||||
case IOP_T0_MODE:
|
||||
hard = psxCounters[0].mode;
|
||||
psxCounters[0].mode &= ~0x1800;
|
||||
psxCounters[0].mode &= ~0x1800;
|
||||
psxCounters[0].mode |= 0x400;
|
||||
PSXCNT_LOG("T0 mode read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801108:
|
||||
case IOP_T0_TARGET:
|
||||
hard = psxCounters[0].target;
|
||||
PSXCNT_LOG("T0 target read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801110:
|
||||
case IOP_T1_COUNT:
|
||||
hard = (u16)psxRcntRcount16(1);
|
||||
PSXCNT_LOG("T1 count read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801114:
|
||||
case IOP_T1_MODE:
|
||||
hard = psxCounters[1].mode;
|
||||
psxCounters[1].mode &= ~0x1800;
|
||||
psxCounters[1].mode |= 0x400;
|
||||
PSXCNT_LOG("T1 mode read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801118:
|
||||
case IOP_T1_TARGET:
|
||||
hard = psxCounters[1].target;
|
||||
PSXCNT_LOG("T1 target read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801120:
|
||||
case IOP_T2_COUNT:
|
||||
hard = (u16)psxRcntRcount16(2);
|
||||
PSXCNT_LOG("T2 count read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801124:
|
||||
case IOP_T2_MODE:
|
||||
hard = psxCounters[2].mode;
|
||||
psxCounters[2].mode &= ~0x1800;
|
||||
psxCounters[2].mode |= 0x400;
|
||||
PSXCNT_LOG("T2 mode read16: %x", hard);
|
||||
return hard;
|
||||
case 0x1f801128:
|
||||
case IOP_T2_TARGET:
|
||||
hard = psxCounters[2].target;
|
||||
PSXCNT_LOG("T2 target read16: %x", hard);
|
||||
return hard;
|
||||
@ -187,45 +187,45 @@ u16 psxHwRead16(u32 add) {
|
||||
case 0x1f80146e: // DEV9_R_REV
|
||||
return DEV9read16(add);
|
||||
|
||||
case 0x1f801480:
|
||||
case IOP_T3_COUNT:
|
||||
hard = (u16)psxRcntRcount32(3);
|
||||
PSXCNT_LOG("T3 count read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801484:
|
||||
case IOP_T3_MODE:
|
||||
hard = psxCounters[3].mode;
|
||||
psxCounters[3].mode &= ~0x1800;
|
||||
psxCounters[3].mode |= 0x400;
|
||||
PSXCNT_LOG("T3 mode read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801488:
|
||||
case IOP_T3_TARGET:
|
||||
hard = psxCounters[3].target;
|
||||
PSXCNT_LOG("T3 target read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801490:
|
||||
case IOP_T4_COUNT:
|
||||
hard = (u16)psxRcntRcount32(4);
|
||||
PSXCNT_LOG("T4 count read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801494:
|
||||
case IOP_T4_MODE:
|
||||
hard = psxCounters[4].mode;
|
||||
psxCounters[4].mode &= ~0x1800;
|
||||
psxCounters[4].mode |= 0x400;
|
||||
PSXCNT_LOG("T4 mode read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801498:
|
||||
case IOP_T4_TARGET:
|
||||
hard = psxCounters[4].target;
|
||||
PSXCNT_LOG("T4 target read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f8014a0:
|
||||
case IOP_T5_COUNT:
|
||||
hard = (u16)psxRcntRcount32(5);
|
||||
PSXCNT_LOG("T5 count read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f8014a4:
|
||||
case IOP_T5_MODE:
|
||||
hard = psxCounters[5].mode;
|
||||
psxCounters[5].mode &= ~0x1800;
|
||||
psxCounters[5].mode |= 0x400;
|
||||
PSXCNT_LOG("T5 mode read16: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f8014a8:
|
||||
case IOP_T5_TARGET:
|
||||
hard = psxCounters[5].target;
|
||||
PSXCNT_LOG("T5 target read16: %lx", hard);
|
||||
return hard;
|
||||
@ -238,11 +238,11 @@ u16 psxHwRead16(u32 add) {
|
||||
hard = psxHu16(0x1506);
|
||||
PSXHW_LOG("DMA7 BCR_count 16bit read %lx", hard);
|
||||
return hard;
|
||||
//case 0x1f802030: hard = //int_2000????
|
||||
//case 0x1f802040: hard =//dip switches...??
|
||||
// case 0x1f802030: hard = //int_2000????
|
||||
// case 0x1f802040: hard =//dip switches...??
|
||||
|
||||
default:
|
||||
if (add>=0x1f801c00 && add<0x1f801e00) {
|
||||
if (add>=HW_SPU2_START && add<HW_SPU2_END) {
|
||||
hard = SPU2read(add);
|
||||
} else {
|
||||
hard = psxHu16(add);
|
||||
@ -259,10 +259,10 @@ u16 psxHwRead16(u32 add) {
|
||||
u32 psxHwRead32(u32 add) {
|
||||
u32 hard;
|
||||
|
||||
if (add >= 0x1f801600 && add < 0x1f801700) {
|
||||
if (add >= HW_USB_START && add < HW_USB_END) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -275,7 +275,7 @@ u32 psxHwRead32(u32 add) {
|
||||
PAD_LOG("sio read32 ;ret = %lx", hard);
|
||||
return hard;
|
||||
|
||||
// case 0x1f801050: hard = serial_read32(); break;//serial port
|
||||
// case 0x1f801050: hard = serial_read32(); break;//serial port
|
||||
case 0x1f801060:
|
||||
PSXHW_LOG("RAM size read %lx", psxHu32(0x1060));
|
||||
return psxHu32(0x1060);
|
||||
@ -289,18 +289,17 @@ u32 psxHwRead32(u32 add) {
|
||||
psxHu32(0x1078) = 0;
|
||||
return hard;
|
||||
|
||||
/* case 0x1f801810:
|
||||
// case 0x1f801810:
|
||||
// hard = GPU_readData();
|
||||
PSXHW_LOG("GPU DATA 32bit read %lx", hard);
|
||||
return hard;*/
|
||||
/* case 0x1f801814:
|
||||
hard = GPU_readStatus();
|
||||
PSXHW_LOG("GPU STATUS 32bit read %lx", hard);
|
||||
return hard;
|
||||
*/
|
||||
/* case 0x1f801820: hard = mdecRead0(); break;
|
||||
case 0x1f801824: hard = mdecRead1(); break;
|
||||
*/
|
||||
// PSXHW_LOG("GPU DATA 32bit read %lx", hard);
|
||||
// return hard;
|
||||
// case 0x1f801814:
|
||||
// hard = GPU_readStatus();
|
||||
// PSXHW_LOG("GPU STATUS 32bit read %lx", hard);
|
||||
// return hard;
|
||||
//
|
||||
// case 0x1f801820: hard = mdecRead0(); break;
|
||||
// case 0x1f801824: hard = mdecRead1(); break;
|
||||
|
||||
case 0x1f8010a0:
|
||||
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);
|
||||
return HW_DMA_ICR;
|
||||
|
||||
//SSBus registers
|
||||
//SSBus registers
|
||||
case 0x1f801000:
|
||||
hard = psxHu32(0x1000);
|
||||
PSXHW_LOG("SSBUS <spd_addr> 32bit read %lx", hard);
|
||||
@ -432,79 +431,78 @@ u32 psxHwRead32(u32 add) {
|
||||
|
||||
case 0x1f8010c8:
|
||||
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 :)
|
||||
case 0x1f801100:
|
||||
case IOP_T0_COUNT:
|
||||
hard = (u16)psxRcntRcount16(0);
|
||||
PSXCNT_LOG("T0 count read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801104:
|
||||
case IOP_T0_MODE:
|
||||
hard = (u16)psxCounters[0].mode;
|
||||
PSXCNT_LOG("T0 mode read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801108:
|
||||
case IOP_T0_TARGET:
|
||||
hard = psxCounters[0].target;
|
||||
PSXCNT_LOG("T0 target read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801110:
|
||||
case IOP_T1_COUNT:
|
||||
hard = (u16)psxRcntRcount16(1);
|
||||
PSXCNT_LOG("T1 count read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801114:
|
||||
case IOP_T1_MODE:
|
||||
hard = (u16)psxCounters[1].mode;
|
||||
PSXCNT_LOG("T1 mode read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801118:
|
||||
case IOP_T1_TARGET:
|
||||
hard = psxCounters[1].target;
|
||||
PSXCNT_LOG("T1 target read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801120:
|
||||
case IOP_T2_COUNT:
|
||||
hard = (u16)psxRcntRcount16(2);
|
||||
PSXCNT_LOG("T2 count read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801124:
|
||||
case IOP_T2_MODE:
|
||||
hard = (u16)psxCounters[2].mode;
|
||||
PSXCNT_LOG("T2 mode read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801128:
|
||||
case IOP_T2_TARGET:
|
||||
hard = psxCounters[2].target;
|
||||
PSXCNT_LOG("T2 target read32: %lx", hard);
|
||||
return hard;
|
||||
|
||||
case 0x1f801480:
|
||||
case IOP_T3_COUNT:
|
||||
hard = (u32)psxRcntRcount32(3);
|
||||
PSXCNT_LOG("T3 count read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801484:
|
||||
case IOP_T3_MODE:
|
||||
hard = (u16)psxCounters[3].mode;
|
||||
PSXCNT_LOG("T3 mode read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801488:
|
||||
case IOP_T3_TARGET:
|
||||
hard = psxCounters[3].target;
|
||||
PSXCNT_LOG("T3 target read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801490:
|
||||
case IOP_T4_COUNT:
|
||||
hard = (u32)psxRcntRcount32(4);
|
||||
PSXCNT_LOG("T4 count read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801494:
|
||||
case IOP_T4_MODE:
|
||||
hard = (u16)psxCounters[4].mode;
|
||||
PSXCNT_LOG("T4 mode read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f801498:
|
||||
case IOP_T4_TARGET:
|
||||
hard = psxCounters[4].target;
|
||||
PSXCNT_LOG("T4 target read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f8014a0:
|
||||
case IOP_T5_COUNT:
|
||||
hard = (u32)psxRcntRcount32(5);
|
||||
PSXCNT_LOG("T5 count read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f8014a4:
|
||||
case IOP_T5_MODE:
|
||||
hard = (u16)psxCounters[5].mode;
|
||||
PSXCNT_LOG("T5 mode read32: %lx", hard);
|
||||
return hard;
|
||||
case 0x1f8014a8:
|
||||
case IOP_T5_TARGET:
|
||||
hard = psxCounters[5].target;
|
||||
PSXCNT_LOG("T5 target read32: %lx", hard);
|
||||
return hard;
|
||||
@ -619,18 +617,11 @@ u32 psxHwRead32(u32 add) {
|
||||
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];
|
||||
|
||||
#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); \
|
||||
} \
|
||||
}
|
||||
|
||||
int g_pbufi;
|
||||
void psxHwWrite8(u32 add, u8 value) {
|
||||
if (add >= 0x1f801600 && add < 0x1f801700) {
|
||||
if (add >= HW_USB_START && add < HW_USB_END) {
|
||||
USBwrite8(add, value); return;
|
||||
}
|
||||
if((add & 0xf) == 0xa)
|
||||
@ -638,28 +629,28 @@ void psxHwWrite8(u32 add, u8 value) {
|
||||
|
||||
switch (add) {
|
||||
case 0x1f801040:
|
||||
sioWrite8(value);
|
||||
break;
|
||||
// case 0x1f801050: serial_write8(value); break;//serial port
|
||||
sioWrite8(value);
|
||||
break;
|
||||
// case 0x1f801050: serial_write8(value); break;//serial port
|
||||
|
||||
case 0x1f801100:
|
||||
case 0x1f801104:
|
||||
case 0x1f801108:
|
||||
case 0x1f801110:
|
||||
case 0x1f801114:
|
||||
case 0x1f801118:
|
||||
case 0x1f801120:
|
||||
case 0x1f801124:
|
||||
case 0x1f801128:
|
||||
case 0x1f801480:
|
||||
case 0x1f801484:
|
||||
case 0x1f801488:
|
||||
case 0x1f801490:
|
||||
case 0x1f801494:
|
||||
case 0x1f801498:
|
||||
case 0x1f8014a0:
|
||||
case 0x1f8014a4:
|
||||
case 0x1f8014a8:
|
||||
case IOP_T0_COUNT:
|
||||
case IOP_T0_MODE:
|
||||
case IOP_T0_TARGET:
|
||||
case IOP_T1_COUNT:
|
||||
case IOP_T1_MODE:
|
||||
case IOP_T1_TARGET:
|
||||
case IOP_T2_COUNT:
|
||||
case IOP_T2_MODE:
|
||||
case IOP_T2_TARGET:
|
||||
case IOP_T3_COUNT:
|
||||
case IOP_T3_MODE:
|
||||
case IOP_T3_TARGET:
|
||||
case IOP_T4_COUNT:
|
||||
case IOP_T4_MODE:
|
||||
case IOP_T4_TARGET:
|
||||
case IOP_T5_COUNT:
|
||||
case IOP_T5_MODE:
|
||||
case IOP_T5_TARGET:
|
||||
DevCon::Notice( "IOP Counter Write8 to addr 0x%x = 0x%x", params add, value );
|
||||
psxHu8(add) = value;
|
||||
return;
|
||||
@ -676,17 +667,19 @@ void psxHwWrite8(u32 add, u8 value) {
|
||||
|
||||
case 0x1f80380c:
|
||||
if (value == '\r') break;
|
||||
if (value == '\n' || g_pbufi >= 1023) {
|
||||
g_pbuf[g_pbufi++] = 0; g_pbufi = 0;
|
||||
if (value == '\n' || g_pbufi >= 1023) { // A line break, or the buffer is about to overflow.
|
||||
g_pbuf[g_pbufi++] = 0;
|
||||
g_pbufi = 0;
|
||||
DevCon::WriteLn( Color_Cyan, g_pbuf );
|
||||
}
|
||||
else g_pbuf[g_pbufi++] = value;
|
||||
psxHu8(add) = value;
|
||||
psxHu8(add) = value;
|
||||
return;
|
||||
|
||||
case 0x1F808260:
|
||||
PSXHW_LOG("SIO2 write8 DATAIN <- %08X", value);
|
||||
sio2_serialIn(value);return;//serial data feed/fifo
|
||||
sio2_serialIn(value);
|
||||
return;//serial data feed/fifo
|
||||
|
||||
default:
|
||||
psxHu8(add) = value;
|
||||
@ -698,7 +691,7 @@ void psxHwWrite8(u32 add, u8 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;
|
||||
}
|
||||
|
||||
@ -727,10 +720,10 @@ void psxHwWrite16(u32 add, u16 value) {
|
||||
return;
|
||||
|
||||
//serial port ;P
|
||||
// case 0x1f801050: serial_write16(value); break;
|
||||
// case 0x1f80105a: serial_control_write(value);break;
|
||||
// case 0x1f80105e: serial_baud_write(value); break;
|
||||
// case 0x1f801054: serial_status_write(value); break;
|
||||
// case 0x1f801050: serial_write16(value); break;
|
||||
// case 0x1f80105a: serial_control_write(value);break;
|
||||
// case 0x1f80105e: serial_baud_write(value); break;
|
||||
// case 0x1f801054: serial_status_write(value); break;
|
||||
|
||||
case 0x1f801070:
|
||||
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);
|
||||
psxHu16(0x10c6) = value; return; // DMA4 bcr_count
|
||||
|
||||
case 0x1f801100:
|
||||
case IOP_T0_COUNT:
|
||||
PSXCNT_LOG("COUNTER 0 COUNT 16bit write %x", value);
|
||||
psxRcntWcount16(0, value); return;
|
||||
case 0x1f801104:
|
||||
case IOP_T0_MODE:
|
||||
PSXCNT_LOG("COUNTER 0 MODE 16bit write %x", value);
|
||||
psxRcnt0Wmode(value); return;
|
||||
case 0x1f801108:
|
||||
case IOP_T0_TARGET:
|
||||
PSXCNT_LOG("COUNTER 0 TARGET 16bit write %x", value);
|
||||
psxRcntWtarget16(0, value); return;
|
||||
|
||||
case 0x1f801110:
|
||||
case IOP_T1_COUNT:
|
||||
PSXCNT_LOG("COUNTER 1 COUNT 16bit write %x", value);
|
||||
psxRcntWcount16(1, value); return;
|
||||
case 0x1f801114:
|
||||
case IOP_T1_MODE:
|
||||
PSXCNT_LOG("COUNTER 1 MODE 16bit write %x", value);
|
||||
psxRcnt1Wmode(value); return;
|
||||
case 0x1f801118:
|
||||
case IOP_T1_TARGET:
|
||||
PSXCNT_LOG("COUNTER 1 TARGET 16bit write %x", value);
|
||||
psxRcntWtarget16(1, value); return;
|
||||
|
||||
case 0x1f801120:
|
||||
case IOP_T2_COUNT:
|
||||
PSXCNT_LOG("COUNTER 2 COUNT 16bit write %x", value);
|
||||
psxRcntWcount16(2, value); return;
|
||||
case 0x1f801124:
|
||||
case IOP_T2_MODE:
|
||||
PSXCNT_LOG("COUNTER 2 MODE 16bit write %x", value);
|
||||
psxRcnt2Wmode(value); return;
|
||||
case 0x1f801128:
|
||||
case IOP_T2_TARGET:
|
||||
PSXCNT_LOG("COUNTER 2 TARGET 16bit write %x", value);
|
||||
psxRcntWtarget16(2, value); return;
|
||||
|
||||
@ -795,33 +788,33 @@ void psxHwWrite16(u32 add, u16 value) {
|
||||
psxHu16(0x1450) = value/* & (~0x8)*/;
|
||||
return;
|
||||
|
||||
case 0x1f801480:
|
||||
case IOP_T3_COUNT:
|
||||
PSXCNT_LOG("COUNTER 3 COUNT 16bit write %lx", value);
|
||||
psxRcntWcount32(3, value); return;
|
||||
case 0x1f801484:
|
||||
case IOP_T3_MODE:
|
||||
PSXCNT_LOG("COUNTER 3 MODE 16bit write %lx", value);
|
||||
psxRcnt3Wmode(value); return;
|
||||
case 0x1f801488:
|
||||
case IOP_T3_TARGET:
|
||||
PSXCNT_LOG("COUNTER 3 TARGET 16bit write %lx", value);
|
||||
psxRcntWtarget32(3, value); return;
|
||||
|
||||
case 0x1f801490:
|
||||
case IOP_T4_COUNT:
|
||||
PSXCNT_LOG("COUNTER 4 COUNT 16bit write %lx", value);
|
||||
psxRcntWcount32(4, value); return;
|
||||
case 0x1f801494:
|
||||
case IOP_T4_MODE:
|
||||
PSXCNT_LOG("COUNTER 4 MODE 16bit write %lx", value);
|
||||
psxRcnt4Wmode(value); return;
|
||||
case 0x1f801498:
|
||||
case IOP_T4_TARGET:
|
||||
PSXCNT_LOG("COUNTER 4 TARGET 16bit write %lx", value);
|
||||
psxRcntWtarget32(4, value); return;
|
||||
|
||||
case 0x1f8014a0:
|
||||
case IOP_T5_COUNT:
|
||||
PSXCNT_LOG("COUNTER 5 COUNT 16bit write %lx", value);
|
||||
psxRcntWcount32(5, value); return;
|
||||
case 0x1f8014a4:
|
||||
case IOP_T5_MODE:
|
||||
PSXCNT_LOG("COUNTER 5 MODE 16bit write %lx", value);
|
||||
psxRcnt5Wmode(value); return;
|
||||
case 0x1f8014a8:
|
||||
case IOP_T5_TARGET:
|
||||
PSXCNT_LOG("COUNTER 5 TARGET 16bit write %lx", value);
|
||||
psxRcntWtarget32(5, value); return;
|
||||
|
||||
@ -834,7 +827,7 @@ void psxHwWrite16(u32 add, u16 value) {
|
||||
PSXHW_LOG("DMA7 BCR_count 16bit write %lx", value);
|
||||
return;
|
||||
default:
|
||||
if (add>=0x1f801c00 && add<0x1f801e00) {
|
||||
if (add>=HW_SPU2_START && add<HW_SPU2_END) {
|
||||
SPU2write(add, value);
|
||||
return;
|
||||
}
|
||||
@ -847,18 +840,11 @@ void psxHwWrite16(u32 add, u16 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) {
|
||||
if (add >= 0x1f801600 && add < 0x1f801700) {
|
||||
if (add >= HW_USB_START && add < HW_USB_END) {
|
||||
USBwrite32(add, value); return;
|
||||
}
|
||||
if (add >= 0x1f808400 && add <= 0x1f808550) {
|
||||
if (add >= HW_FW_START && add <= HW_FW_END) {
|
||||
FWwrite32(add, value); return;
|
||||
}
|
||||
switch (add) {
|
||||
@ -1034,7 +1020,7 @@ void psxHwWrite32(u32 add, u32 value) {
|
||||
case 0x1f8010c8:
|
||||
PSXHW_LOG("DMA4 CHCR 32bit write %lx", value);
|
||||
HW_DMA4_CHCR = value; // DMA4 chcr (SPU DMA)
|
||||
DmaExec(4);
|
||||
DmaExecNew(4);
|
||||
return;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -1067,7 +1053,7 @@ void psxHwWrite32(u32 add, u32 value) {
|
||||
case 0x1f801508:
|
||||
PSXHW_LOG("DMA7 CHCR 32bit write %lx", value);
|
||||
HW_DMA7_CHCR = value; // DMA7 chcr (SPU2)
|
||||
DmaExec2(7);
|
||||
DmaExecNew2(7);
|
||||
return;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
@ -1179,63 +1165,63 @@ void psxHwWrite32(u32 add, u32 value) {
|
||||
case 0x1f801824:
|
||||
mdecWrite1(value); break;
|
||||
*/
|
||||
case 0x1f801100:
|
||||
case IOP_T0_COUNT:
|
||||
PSXCNT_LOG("COUNTER 0 COUNT 32bit write %lx", value);
|
||||
psxRcntWcount16(0, value ); return;
|
||||
case 0x1f801104:
|
||||
case IOP_T0_MODE:
|
||||
PSXCNT_LOG("COUNTER 0 MODE 32bit write %lx", value);
|
||||
psxRcnt0Wmode(value); return;
|
||||
case 0x1f801108:
|
||||
case IOP_T0_TARGET:
|
||||
PSXCNT_LOG("COUNTER 0 TARGET 32bit write %lx", value);
|
||||
psxRcntWtarget16(0, value ); return;
|
||||
|
||||
case 0x1f801110:
|
||||
case IOP_T1_COUNT:
|
||||
PSXCNT_LOG("COUNTER 1 COUNT 32bit write %lx", value);
|
||||
psxRcntWcount16(1, value ); return;
|
||||
case 0x1f801114:
|
||||
case IOP_T1_MODE:
|
||||
PSXCNT_LOG("COUNTER 1 MODE 32bit write %lx", value);
|
||||
psxRcnt1Wmode(value); return;
|
||||
case 0x1f801118:
|
||||
case IOP_T1_TARGET:
|
||||
PSXCNT_LOG("COUNTER 1 TARGET 32bit write %lx", value);
|
||||
psxRcntWtarget16(1, value ); return;
|
||||
|
||||
case 0x1f801120:
|
||||
case IOP_T2_COUNT:
|
||||
PSXCNT_LOG("COUNTER 2 COUNT 32bit write %lx", value);
|
||||
psxRcntWcount16(2, value ); return;
|
||||
case 0x1f801124:
|
||||
case IOP_T2_MODE:
|
||||
PSXCNT_LOG("COUNTER 2 MODE 32bit write %lx", value);
|
||||
psxRcnt2Wmode(value); return;
|
||||
case 0x1f801128:
|
||||
case IOP_T2_TARGET:
|
||||
PSXCNT_LOG("COUNTER 2 TARGET 32bit write %lx", value);
|
||||
psxRcntWtarget16(2, value); return;
|
||||
|
||||
case 0x1f801480:
|
||||
case IOP_T3_COUNT:
|
||||
PSXCNT_LOG("COUNTER 3 COUNT 32bit write %lx", value);
|
||||
psxRcntWcount32(3, value); return;
|
||||
case 0x1f801484:
|
||||
case IOP_T3_MODE:
|
||||
PSXCNT_LOG("COUNTER 3 MODE 32bit write %lx", value);
|
||||
psxRcnt3Wmode(value); return;
|
||||
case 0x1f801488:
|
||||
case IOP_T3_TARGET:
|
||||
PSXCNT_LOG("COUNTER 3 TARGET 32bit write %lx", value);
|
||||
psxRcntWtarget32(3, value); return;
|
||||
|
||||
case 0x1f801490:
|
||||
case IOP_T4_COUNT:
|
||||
PSXCNT_LOG("COUNTER 4 COUNT 32bit write %lx", value);
|
||||
psxRcntWcount32(4, value); return;
|
||||
case 0x1f801494:
|
||||
case IOP_T4_MODE:
|
||||
PSXCNT_LOG("COUNTER 4 MODE 32bit write %lx", value);
|
||||
psxRcnt4Wmode(value); return;
|
||||
case 0x1f801498:
|
||||
case IOP_T4_TARGET:
|
||||
PSXCNT_LOG("COUNTER 4 TARGET 32bit write %lx", value);
|
||||
psxRcntWtarget32(4, value); return;
|
||||
|
||||
case 0x1f8014a0:
|
||||
case IOP_T5_COUNT:
|
||||
PSXCNT_LOG("COUNTER 5 COUNT 32bit write %lx", value);
|
||||
psxRcntWcount32(5, value); return;
|
||||
case 0x1f8014a4:
|
||||
case IOP_T5_MODE:
|
||||
PSXCNT_LOG("COUNTER 5 MODE 32bit write %lx", value);
|
||||
psxRcnt5Wmode(value); return;
|
||||
case 0x1f8014a8:
|
||||
case IOP_T5_TARGET:
|
||||
PSXCNT_LOG("COUNTER 5 TARGET 32bit write %lx", value);
|
||||
psxRcntWtarget32(5, value); return;
|
||||
|
||||
|
@ -22,6 +22,72 @@
|
||||
#include "R3000A.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_BCR (psxHu32(0x1084))
|
||||
#define HW_DMA0_CHCR (psxHu32(0x1088))
|
||||
|
@ -53,59 +53,65 @@ void on_Game_Fix_OK(GtkButton *button, gpointer user_data)
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
case 0:
|
||||
set_checked(SpeedHacksDlg, "check_default_cycle_rate", true);
|
||||
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_range_set_value(vuScale, Config.Hacks.VUCycleSteal);
|
||||
on_vu_slider_changed(vuScale, NULL);
|
||||
gtk_range_set_value(eeScale, Config.Hacks.EECycleRate);
|
||||
on_ee_slider_changed(eeScale, NULL);
|
||||
|
||||
gtk_widget_show_all(SpeedHacksDlg);
|
||||
gtk_widget_set_sensitive(MainWindow, FALSE);
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void on_Speed_Hack_OK(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
Config.Hacks = 0;
|
||||
|
||||
if is_checked(SpeedHacksDlg, "check_default_cycle_rate")
|
||||
Config.Hacks = 0;
|
||||
else if is_checked(SpeedHacksDlg, "check_1_5_cycle_rate")
|
||||
Config.Hacks = 1;
|
||||
else if is_checked(SpeedHacksDlg, "check_2_cycle_rate")
|
||||
Config.Hacks = 2;
|
||||
else if is_checked(SpeedHacksDlg, "check_3_cycle_rate")
|
||||
Config.Hacks = 3;
|
||||
|
||||
Config.Hacks |= is_checked(SpeedHacksDlg, "check_iop_cycle_rate") << 3;
|
||||
Config.Hacks |= is_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack") << 4;
|
||||
Config.Hacks |= is_checked(SpeedHacksDlg, "check_intc_sync_hack") << 5;
|
||||
Config.Hacks |= is_checked(SpeedHacksDlg, "check_ESC_hack") << 10;
|
||||
|
||||
SaveConfig();
|
||||
|
||||
PcsxConfig::Hacks_t newhacks;
|
||||
newhacks.EECycleRate = 0;
|
||||
|
||||
newhacks.IOPCycleDouble = is_checked(SpeedHacksDlg, "check_iop_cycle_rate");
|
||||
newhacks.WaitCycleExt = is_checked(SpeedHacksDlg, "check_wait_cycles_sync_hack");
|
||||
newhacks.INTCSTATSlow = is_checked(SpeedHacksDlg, "check_intc_sync_hack");
|
||||
newhacks.IdleLoopFF = is_checked(SpeedHacksDlg, "check_idle_loop_fastforward");
|
||||
|
||||
newhacks.VUCycleSteal = gtk_range_get_value(GTK_RANGE(lookup_widget(SpeedHacksDlg, "VUCycleHackScale")));
|
||||
newhacks.EECycleRate = gtk_range_get_value(GTK_RANGE(lookup_widget(SpeedHacksDlg, "EECycleHackScale")));
|
||||
|
||||
if (memcmp(&newhacks, &Config.Hacks, sizeof(newhacks)))
|
||||
{
|
||||
SysRestorableReset();
|
||||
Config.Hacks = newhacks;
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
gtk_widget_destroy(SpeedHacksDlg);
|
||||
gtk_widget_set_sensitive(MainWindow, TRUE);
|
||||
gtk_main_quit();
|
||||
|
@ -101,6 +101,21 @@ char iop_log_names[9][32] =
|
||||
"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
|
||||
#define FLAG_VU_ADD_SUB 0x1
|
||||
// Persona3/4 - IDC_GAMEFIX4
|
||||
|
@ -39,18 +39,3 @@ u64 GetCPUTicks()
|
||||
gettimeofday(&t, NULL);
|
||||
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;
|
||||
}
|
||||
|
@ -100,7 +100,19 @@ int LoadConfig()
|
||||
GetValuel("varLog", varLog);
|
||||
#endif
|
||||
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("CustomFps", Config.CustomFps);
|
||||
@ -162,7 +174,14 @@ void SaveConfig()
|
||||
|
||||
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("Patch", Config.Patch);
|
||||
|
@ -13,6 +13,14 @@ void
|
||||
On_Dialog_Cancelled (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ee_slider_changed (GtkRange *range,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_vu_slider_changed (GtkRange *range,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Speed_Hack_OK (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
@ -615,21 +615,21 @@ create_SpeedHacksDlg (void)
|
||||
GtkWidget *vbox59;
|
||||
GtkWidget *label88;
|
||||
GtkWidget *hbox39;
|
||||
GtkWidget *vbox72;
|
||||
GtkWidget *frame37;
|
||||
GtkWidget *alignment32;
|
||||
GtkWidget *vbox61;
|
||||
GtkWidget *check_default_cycle_rate;
|
||||
GSList *check_default_cycle_rate_group = NULL;
|
||||
GtkWidget *label98;
|
||||
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 *EECycleHackScale;
|
||||
GtkWidget *ee_cycle_label;
|
||||
GtkWidget *hseparator2;
|
||||
GtkWidget *label91;
|
||||
GtkWidget *label105;
|
||||
GtkWidget *frame39;
|
||||
GtkWidget *alignment34;
|
||||
GtkWidget *vbox73;
|
||||
GtkWidget *VUCycleHackScale;
|
||||
GtkWidget *vu_cycle_stealing_label;
|
||||
GtkWidget *label111;
|
||||
GtkWidget *vbox60;
|
||||
GtkWidget *check_iop_cycle_rate;
|
||||
GtkWidget *label96;
|
||||
@ -637,10 +637,10 @@ create_SpeedHacksDlg (void)
|
||||
GtkWidget *label97;
|
||||
GtkWidget *check_intc_sync_hack;
|
||||
GtkWidget *label101;
|
||||
GtkWidget *frame36;
|
||||
GtkWidget *alignment31;
|
||||
GtkWidget *check_ESC_hack;
|
||||
GtkWidget *label89;
|
||||
GtkWidget *vbox71;
|
||||
GtkWidget *check_idle_loop_fastforward;
|
||||
GtkWidget *label110;
|
||||
GtkWidget *hseparator1;
|
||||
GtkWidget *dialog_action_area3;
|
||||
GtkWidget *button99;
|
||||
GtkWidget *button98;
|
||||
@ -669,10 +669,15 @@ create_SpeedHacksDlg (void)
|
||||
gtk_widget_show (hbox39);
|
||||
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);
|
||||
gtk_widget_set_name (frame37, "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);
|
||||
gtk_widget_set_name (alignment32, "alignment32");
|
||||
@ -685,68 +690,25 @@ create_SpeedHacksDlg (void)
|
||||
gtk_widget_show (vbox61);
|
||||
gtk_container_add (GTK_CONTAINER (alignment32), vbox61);
|
||||
|
||||
check_default_cycle_rate = gtk_radio_button_new_with_mnemonic (NULL, _("Default Cycle Rate"));
|
||||
gtk_widget_set_name (check_default_cycle_rate, "check_default_cycle_rate");
|
||||
gtk_widget_show (check_default_cycle_rate);
|
||||
gtk_box_pack_start (GTK_BOX (vbox61), check_default_cycle_rate, FALSE, FALSE, 0);
|
||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (check_default_cycle_rate), check_default_cycle_rate_group);
|
||||
check_default_cycle_rate_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (check_default_cycle_rate));
|
||||
EECycleHackScale = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, 0, 2, 1, 0, 0)));
|
||||
gtk_widget_set_name (EECycleHackScale, "EECycleHackScale");
|
||||
gtk_widget_show (EECycleHackScale);
|
||||
gtk_box_pack_start (GTK_BOX (vbox61), EECycleHackScale, FALSE, FALSE, 0);
|
||||
gtk_scale_set_draw_value (GTK_SCALE (EECycleHackScale), FALSE);
|
||||
gtk_scale_set_digits (GTK_SCALE (EECycleHackScale), 0);
|
||||
|
||||
label98 = gtk_label_new (_("Most compatible option - recommended for everyone with high-end machines."));
|
||||
gtk_widget_set_name (label98, "label98");
|
||||
gtk_widget_show (label98);
|
||||
gtk_box_pack_start (GTK_BOX (vbox61), label98, FALSE, FALSE, 0);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label98), TRUE);
|
||||
gtk_misc_set_alignment (GTK_MISC (label98), 0.29, 0.5);
|
||||
ee_cycle_label = gtk_label_new (_("Most compatible option - recommended for everyone with high-end machines."));
|
||||
gtk_widget_set_name (ee_cycle_label, "ee_cycle_label");
|
||||
gtk_widget_show (ee_cycle_label);
|
||||
gtk_box_pack_start (GTK_BOX (vbox61), ee_cycle_label, FALSE, FALSE, 0);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (ee_cycle_label), TRUE);
|
||||
|
||||
check_1_5_cycle_rate = gtk_radio_button_new_with_mnemonic (NULL, _("Use x1.5 Cycle Rate"));
|
||||
gtk_widget_set_name (check_1_5_cycle_rate, "check_1_5_cycle_rate");
|
||||
gtk_widget_show (check_1_5_cycle_rate);
|
||||
gtk_box_pack_start (GTK_BOX (vbox61), check_1_5_cycle_rate, 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));
|
||||
hseparator2 = gtk_hseparator_new ();
|
||||
gtk_widget_set_name (hseparator2, "hseparator2");
|
||||
gtk_widget_show (hseparator2);
|
||||
gtk_box_pack_start (GTK_BOX (vbox61), hseparator2, FALSE, FALSE, 0);
|
||||
|
||||
label93 = gtk_label_new (_("Moderate speedup, and works well with most games."));
|
||||
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)."));
|
||||
label91 = gtk_label_new (_("Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies."));
|
||||
gtk_widget_set_name (label91, "label91");
|
||||
gtk_widget_show (label91);
|
||||
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_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);
|
||||
gtk_widget_set_name (vbox60, "vbox60");
|
||||
gtk_widget_show (vbox60);
|
||||
@ -785,7 +782,7 @@ create_SpeedHacksDlg (void)
|
||||
gtk_box_pack_start (GTK_BOX (vbox60), label97, FALSE, FALSE, 0);
|
||||
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_show (check_intc_sync_hack);
|
||||
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_label_set_line_wrap (GTK_LABEL (label101), TRUE);
|
||||
|
||||
frame36 = gtk_frame_new (NULL);
|
||||
gtk_widget_set_name (frame36, "frame36");
|
||||
gtk_widget_show (frame36);
|
||||
gtk_box_pack_start (GTK_BOX (vbox59), frame36, FALSE, FALSE, 0);
|
||||
vbox71 = gtk_vbox_new (FALSE, 0);
|
||||
gtk_widget_set_name (vbox71, "vbox71");
|
||||
gtk_widget_show (vbox71);
|
||||
gtk_box_pack_start (GTK_BOX (vbox60), vbox71, TRUE, TRUE, 0);
|
||||
|
||||
alignment31 = gtk_alignment_new (0.5, 0.5, 1, 1);
|
||||
gtk_widget_set_name (alignment31, "alignment31");
|
||||
gtk_widget_show (alignment31);
|
||||
gtk_container_add (GTK_CONTAINER (frame36), alignment31);
|
||||
gtk_alignment_set_padding (GTK_ALIGNMENT (alignment31), 0, 0, 12, 0);
|
||||
check_idle_loop_fastforward = gtk_check_button_new_with_mnemonic (_("Idle Loop Fast-Forward (experimental)"));
|
||||
gtk_widget_set_name (check_idle_loop_fastforward, "check_idle_loop_fastforward");
|
||||
gtk_widget_show (check_idle_loop_fastforward);
|
||||
gtk_box_pack_start (GTK_BOX (vbox71), check_idle_loop_fastforward, FALSE, FALSE, 0);
|
||||
|
||||
check_ESC_hack = gtk_check_button_new_with_mnemonic (_("Escape Hack - Use Esc key to fully exit PCSX2."));
|
||||
gtk_widget_set_name (check_ESC_hack, "check_ESC_hack");
|
||||
gtk_widget_show (check_ESC_hack);
|
||||
gtk_container_add (GTK_CONTAINER (alignment31), check_ESC_hack);
|
||||
label110 = gtk_label_new (_("Speedup for a few games, including FFX with no known side effects. More later."));
|
||||
gtk_widget_set_name (label110, "label110");
|
||||
gtk_widget_show (label110);
|
||||
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>"));
|
||||
gtk_widget_set_name (label89, "label89");
|
||||
gtk_widget_show (label89);
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame36), label89);
|
||||
gtk_label_set_use_markup (GTK_LABEL (label89), TRUE);
|
||||
hseparator1 = gtk_hseparator_new ();
|
||||
gtk_widget_set_name (hseparator1, "hseparator1");
|
||||
gtk_widget_show (hseparator1);
|
||||
gtk_box_pack_start (GTK_BOX (vbox60), hseparator1, FALSE, FALSE, 0);
|
||||
|
||||
dialog_action_area3 = GTK_DIALOG (SpeedHacksDlg)->action_area;
|
||||
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_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_CALLBACK (on_Speed_Hack_OK),
|
||||
NULL);
|
||||
@ -848,20 +850,21 @@ create_SpeedHacksDlg (void)
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox59, "vbox59");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label88, "label88");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hbox39, "hbox39");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox72, "vbox72");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame37, "frame37");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment32, "alignment32");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox61, "vbox61");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_default_cycle_rate, "check_default_cycle_rate");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label98, "label98");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_1_5_cycle_rate, "check_1_5_cycle_rate");
|
||||
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, EECycleHackScale, "EECycleHackScale");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, ee_cycle_label, "ee_cycle_label");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hseparator2, "hseparator2");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label91, "label91");
|
||||
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, check_iop_cycle_rate, "check_iop_cycle_rate");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label96, "label96");
|
||||
@ -869,10 +872,10 @@ create_SpeedHacksDlg (void)
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label97, "label97");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_intc_sync_hack, "check_intc_sync_hack");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label101, "label101");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, frame36, "frame36");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, alignment31, "alignment31");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_ESC_hack, "check_ESC_hack");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label89, "label89");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, vbox71, "vbox71");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, check_idle_loop_fastforward, "check_idle_loop_fastforward");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, label110, "label110");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, hseparator1, "hseparator1");
|
||||
GLADE_HOOKUP_OBJECT_NO_REF (SpeedHacksDlg, dialog_action_area3, "dialog_action_area3");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button99, "button99");
|
||||
GLADE_HOOKUP_OBJECT (SpeedHacksDlg, button98, "button98");
|
||||
|
@ -1275,270 +1275,250 @@ If you have problems, Disable all of these and try again.</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame37">
|
||||
<widget class="GtkVBox" id="vbox72">
|
||||
<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>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment32">
|
||||
<widget class="GtkFrame" id="frame37">
|
||||
<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>
|
||||
<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="GtkVBox" id="vbox61">
|
||||
<widget class="GtkAlignment" id="alignment32">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</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="GtkRadioButton" id="check_default_cycle_rate">
|
||||
<widget class="GtkVBox" id="vbox61">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Default 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>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label98">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Most compatible option - recommended for everyone with high-end machines.</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.289999991655</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="GtkHScale" id="EECycleHackScale">
|
||||
<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 2 1 0 0</property>
|
||||
<signal name="value_changed" handler="on_ee_slider_changed" last_modification_time="Wed, 22 Apr 2009 03:03:42 GMT"/>
|
||||
</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_1_5_cycle_rate">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Use x1.5 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="ee_cycle_label">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Most compatible option - recommended for everyone with high-end machines.</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 class="GtkLabel" id="label93">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Moderate speedup, and works well with most 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.289999991655</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="hseparator2">
|
||||
<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="GtkRadioButton" id="check_2_cycle_rate">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Use x2 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>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label91">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies.</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">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 & 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>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label105">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>EmotionEngine (EE) Sync Hacks</b></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">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label105">
|
||||
<widget class="GtkFrame" id="frame39">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>EmotionEngine (EE) Sync Hacks</b></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>
|
||||
<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="alignment34">
|
||||
<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="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"><b>VU Cycle Stealing (Speedup for 3d geometry)</b></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="type">label_item</property>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</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">
|
||||
<property name="visible">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="relief">GTK_RELIEF_NORMAL</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>
|
||||
</packing>
|
||||
</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>
|
||||
<packing>
|
||||
<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>
|
||||
</packing>
|
||||
</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"><b>Miscellaneous</b></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>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
|
@ -177,11 +177,15 @@ void PLZCW() {
|
||||
_PLZCW (1);
|
||||
}
|
||||
|
||||
#define PMFHL_CLAMP(dst, src) \
|
||||
if ((int)src > (int)0x00007fff) dst = 0x7fff; \
|
||||
else \
|
||||
if ((int)src < (int)0xffff8000) dst = 0x8000; \
|
||||
else dst = (u16)src;
|
||||
__forceinline void PMFHL_CLAMP(u16 dst, u16 src)
|
||||
{
|
||||
if ((int)src > (int)0x00007fff)
|
||||
dst = 0x7fff;
|
||||
else if ((int)src < (int)0xffff8000)
|
||||
dst = 0x8000;
|
||||
else
|
||||
dst = (u16)src;
|
||||
}
|
||||
|
||||
void PMFHL() {
|
||||
if (!_Rd_) return;
|
||||
|
@ -224,7 +224,7 @@ void mtgsThreadObject::Start()
|
||||
m_post_InitDone.Wait();
|
||||
|
||||
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()
|
||||
|
@ -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 \
|
||||
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 \
|
||||
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 \
|
||||
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 \
|
||||
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
|
||||
#Linux
|
@ -42,6 +42,7 @@ BIOS
|
||||
#pragma warning(disable:4799) // No EMMS at end of function
|
||||
|
||||
#include <vector>
|
||||
#include <wx/file.h>
|
||||
|
||||
#include "IopCommon.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
|
||||
// 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;
|
||||
|
||||
string Bios( Path::Combine( Config.BiosDir, Config.Bios ) );
|
||||
|
||||
// Try first a basic extension concatenation (normally results in something like name.bin.rom1)
|
||||
ssprintf(Bios1, "%hs.%s", &Bios, ext);
|
||||
if( (filesize=Path::getFileSize( Bios1 ) ) <= 0 )
|
||||
const wxString Bios( g_Conf.Files.Bios() );
|
||||
Bios1.Printf( wxS("%s.%s"), Bios.c_str(), ext);
|
||||
|
||||
if( (filesize=Path::GetFileSize( Bios1 ) ) <= 0 )
|
||||
{
|
||||
// Try the name properly extensioned next (name.rom1)
|
||||
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)
|
||||
Bios1 = Path::Combine( Config.BiosDir, ext ) + ".bin";
|
||||
if( (filesize=Path::getFileSize( Bios1 ) ) <= 0 )
|
||||
Bios1 = Path::Combine( g_Conf.Folders.Bios, (wxString)ext ) + wxT(".bin");
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
|
||||
FILE *fp = fopen(Bios1.c_str(), "rb");
|
||||
fread(dest, 1, min( maxSize, filesize ), fp);
|
||||
fclose(fp);
|
||||
wxFile fp( Bios1 );
|
||||
fp.Read( dest, min( maxSize, filesize ) );
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
// [TODO] : Profile this code and see how often the VUs get written, and how
|
||||
// often it changes the values being written (invoking a cpuClear).
|
||||
// Profiled VU writes: Happen very infrequently, with exception of BIOS initialization (at most twice per
|
||||
// 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>
|
||||
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
|
||||
);
|
||||
|
||||
vtlbMemR32FP* page0F32( CHECK_INTC_STAT_HACK ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
|
||||
vtlbMemR64FP* page0F64( CHECK_INTC_STAT_HACK ? hwRead64_generic_INTC_HACK : hwRead64_generic );
|
||||
vtlbMemR32FP* page0F32( Config.Hacks.INTCSTATSlow ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
|
||||
vtlbMemR64FP* page0F64( Config.Hacks.INTCSTATSlow ? hwRead64_generic_INTC_HACK : hwRead64_generic );
|
||||
|
||||
hw_by_page[0xf] = vtlb_RegisterHandler(
|
||||
_ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic,
|
||||
@ -780,29 +780,28 @@ void memReset()
|
||||
vtlb_VMap(0x00000000,0x00000000,0x20000000);
|
||||
vtlb_VMapUnmap(0x20000000,0x60000000);
|
||||
|
||||
FILE *fp;
|
||||
string Bios( Path::Combine( Config.BiosDir, Config.Bios ) );
|
||||
wxString Bios( g_Conf.Files.Bios() );
|
||||
|
||||
long filesize;
|
||||
if( ( filesize = Path::getFileSize( Bios ) ) <= 0 )
|
||||
long filesize = Path::GetFileSize( Bios );
|
||||
if( filesize <= 0 )
|
||||
{
|
||||
//Console::Error("Unable to load bios: '%s', PCSX2 can't run without that", params Bios);
|
||||
throw Exception::FileNotFound( Bios,
|
||||
"The specified Bios file was not found. A bios is required for Pcsx2 to run.\n\nFile not found" );
|
||||
wxFile fp( Bios.c_str() );
|
||||
fp.Read( PS2MEM_ROM, min( (long)Ps2MemSize::Rom, filesize ) );
|
||||
}
|
||||
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();
|
||||
Console::Status("Bios Version %d.%d", params BiosVersion >> 8, BiosVersion & 0xff);
|
||||
|
||||
//injectIRX("host.irx"); //not fully tested; still buggy
|
||||
|
||||
loadBiosRom("rom1", PS2MEM_ROM1, Ps2MemSize::Rom1);
|
||||
loadBiosRom("rom2", PS2MEM_ROM2, Ps2MemSize::Rom2);
|
||||
loadBiosRom("erom", PS2MEM_EROM, Ps2MemSize::ERom);
|
||||
loadBiosRom( wxT("rom1"), PS2MEM_ROM1, Ps2MemSize::Rom1 );
|
||||
loadBiosRom( wxT("rom2"), PS2MEM_ROM2, Ps2MemSize::Rom2 );
|
||||
loadBiosRom( wxT("erom"), PS2MEM_EROM, Ps2MemSize::ERom );
|
||||
}
|
||||
|
||||
int mmap_GetRamPageInfo(void* ptr)
|
||||
@ -820,6 +819,7 @@ void mmap_MarkCountedRamPage(void* ptr,u32 vaddr)
|
||||
|
||||
u32 offset=((u8*)ptr-psM);
|
||||
offset>>=12;
|
||||
psMPWC[(offset/32)] &= ~(1<<(offset&31));
|
||||
|
||||
for (u32 i=0;i<psMPWVA[offset].size();i++)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
#endif
|
||||
|
||||
//#define ENABLECACHE
|
||||
#include "vtlb.h"
|
||||
|
||||
namespace Ps2MemSize
|
||||
{
|
||||
@ -57,9 +58,40 @@ extern u8 *psS; //0.015 mb, scratch pad
|
||||
|
||||
extern u8 g_RealGSMem[Ps2MemSize::GSregs];
|
||||
#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 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 psMs16(mem) (*(s16*)&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 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 memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error.
|
||||
extern void memShutdown();
|
||||
@ -134,8 +157,6 @@ extern void memClearPageAddr(u32 vaddr);
|
||||
|
||||
extern void memMapVUmicro();
|
||||
|
||||
#include "vtlb.h"
|
||||
|
||||
extern int mmap_GetRamPageInfo(void* ptr);
|
||||
extern void mmap_MarkCountedRamPage(void* ptr,u32 vaddr);
|
||||
extern void mmap_ResetBlockTracking();
|
||||
|
@ -20,13 +20,14 @@
|
||||
|
||||
#include "System.h"
|
||||
#include "MemoryCard.h"
|
||||
#include "Paths.h"
|
||||
|
||||
#include <wx/file.h>
|
||||
|
||||
#ifdef WIN32
|
||||
extern void NTFS_CompressFile( const char* file, bool compressMode );
|
||||
extern void NTFS_CompressFile( const wxString& file, bool compressMode );
|
||||
#endif
|
||||
|
||||
FILE* MemoryCard::cardfile[2] = { NULL, NULL };
|
||||
wxFile MemoryCard::cardfile[2];
|
||||
|
||||
|
||||
// Ensures memory card files are created/initialized.
|
||||
@ -34,8 +35,8 @@ void MemoryCard::Init()
|
||||
{
|
||||
for( int i=0; i<2; i++ )
|
||||
{
|
||||
if( Config.Mcd[i].Enabled && cardfile[i] == NULL )
|
||||
cardfile[i] = Load(i);
|
||||
if( Config.Mcd[i].Enabled && !cardfile[i].IsOpened() )
|
||||
Load( i );
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,88 +49,79 @@ void MemoryCard::Shutdown()
|
||||
void MemoryCard::Unload( uint mcd )
|
||||
{
|
||||
jASSUME( mcd < 2 );
|
||||
|
||||
if(cardfile[mcd] == NULL) return;
|
||||
fclose( cardfile[mcd] );
|
||||
cardfile[mcd] = NULL;
|
||||
cardfile[mcd].Close();
|
||||
}
|
||||
|
||||
bool MemoryCard::IsPresent( uint mcd )
|
||||
{
|
||||
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 );
|
||||
string str( Config.Mcd[mcd].Filename );
|
||||
wxFileName fname( g_Conf.Files.Mcd( mcd ) );
|
||||
wxString str( fname.GetFullPath() );
|
||||
|
||||
if( str.empty() )
|
||||
str = Path::Combine( MEMCARDS_DIR, fmt_string( "Mcd00%d.ps2", mcd ) );
|
||||
|
||||
if( !Path::Exists(str) )
|
||||
Create( str.c_str() );
|
||||
if( !fname.FileExists() )
|
||||
Create( str );
|
||||
|
||||
#ifdef WIN32
|
||||
NTFS_CompressFile( str.c_str(), Config.McdEnableNTFS );
|
||||
NTFS_CompressFile( str, Config.McdEnableNTFS );
|
||||
#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);
|
||||
return NULL;
|
||||
// Translation note: detailed description should mention that the memory card will be disabled
|
||||
// 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;
|
||||
|
||||
fseek(f, 0, SEEK_END); size = ftell(f);
|
||||
u32 size = f.Length();
|
||||
|
||||
if (size == MCD_SIZE + 64)
|
||||
fseek(f, adr + 64, SEEK_SET);
|
||||
f.Seek( adr + 64 );
|
||||
else if (size == MCD_SIZE + 3904)
|
||||
fseek(f, adr + 3904, SEEK_SET);
|
||||
f.Seek( adr + 3904 );
|
||||
else
|
||||
fseek(f, adr, SEEK_SET);
|
||||
f.Seek( adr );
|
||||
}
|
||||
|
||||
void MemoryCard::Read( uint mcd, u8 *data, u32 adr, int size )
|
||||
{
|
||||
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);
|
||||
return;
|
||||
}
|
||||
Seek(mcfp, adr);
|
||||
fread(data, 1, size, mcfp);
|
||||
mcfp.Read( data, size );
|
||||
}
|
||||
|
||||
void MemoryCard::Save( uint mcd, const u8 *data, u32 adr, int size )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
Seek(mcfp, adr);
|
||||
u8 *currentdata = (u8 *)malloc(size);
|
||||
fread(currentdata, 1, size, mcfp);
|
||||
mcfp.Read( currentdata, size);
|
||||
|
||||
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);
|
||||
fwrite(currentdata, 1, size, mcfp);
|
||||
mcfp.Write( currentdata, size );
|
||||
free(currentdata);
|
||||
}
|
||||
|
||||
@ -150,46 +142,51 @@ void MemoryCard::Erase( uint mcd, u32 adr )
|
||||
memset8_obj<0xff>(data); // clears to -1's
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
FILE* fp = fopen( mcdFile, "wb" );
|
||||
if( fp == NULL ) return;
|
||||
wxFile fp( mcdFile, wxFile::write );
|
||||
if( !fp.IsOpened() ) return;
|
||||
|
||||
u8 effeffs[528];
|
||||
memset8_obj<0xff>( effeffs );
|
||||
|
||||
for( uint i=0; i<16384; i++ )
|
||||
{
|
||||
for( uint j=0; j<528; j++ ) fputc( 0xFF,fp );
|
||||
// for(j=0; j<16; j++) fputc(enc[j],fp);
|
||||
for( uint j=0; j<528; j++ )
|
||||
fp.Write( effeffs, sizeof(effeffs) );
|
||||
|
||||
//for(j=0; j<16; j++) fputc(enc[j],fp);
|
||||
}
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
u64 MemoryCard::GetCRC( uint mcd )
|
||||
{
|
||||
jASSUME( mcd < 2 );
|
||||
|
||||
FILE* const mcfp = cardfile[mcd];
|
||||
if( mcfp == NULL ) return 0;
|
||||
wxFile& mcfp( cardfile[mcd] );
|
||||
if( !mcfp.IsOpened() ) return 0;
|
||||
|
||||
Seek( mcfp, 0 );
|
||||
|
||||
u64 retval = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -25,11 +25,12 @@ static const int MC2_SIZE = 1024 * 528 * 16;
|
||||
class MemoryCard
|
||||
{
|
||||
protected:
|
||||
static FILE* cardfile[2];
|
||||
|
||||
static FILE* Load( uint mcdId );
|
||||
static void Seek( FILE* mcdfp, u32 adr );
|
||||
static void Create( const char *mcd );
|
||||
static wxFile cardfile[2];
|
||||
|
||||
public:
|
||||
static void Load( uint mcdId );
|
||||
static void Seek( wxFile& mcdfp, u32 adr );
|
||||
static void Create( const wxString& mcd );
|
||||
|
||||
public:
|
||||
static void Init();
|
||||
|
142
pcsx2/Misc.cpp
142
pcsx2/Misc.cpp
@ -25,6 +25,7 @@
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <wx/file.h>
|
||||
|
||||
#include "IopCommon.h"
|
||||
#include "HostGui.h"
|
||||
@ -40,14 +41,13 @@
|
||||
#include "COP0.h"
|
||||
#include "Cache.h"
|
||||
|
||||
#include "Paths.h"
|
||||
#include "Dump.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace R5900;
|
||||
|
||||
PcsxConfig Config;
|
||||
u32 BiosVersion;
|
||||
char CdromId[12];
|
||||
static int g_Pcsx2Recording = 0; // true 1 if recording video and sound
|
||||
bool renderswitch = 0;
|
||||
|
||||
@ -64,7 +64,8 @@ extern wxString strgametitle;
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
|
||||
struct romdir{
|
||||
struct romdir
|
||||
{
|
||||
char fileName[10];
|
||||
u16 extInfoSize;
|
||||
u32 fileSize;
|
||||
@ -115,43 +116,46 @@ u32 GetBiosVersion() {
|
||||
}
|
||||
|
||||
//2002-09-22 (Florin)
|
||||
int IsBIOS(const char *filename, char *description)
|
||||
bool IsBIOS(const wxString& filename, wxString& description)
|
||||
{
|
||||
char ROMVER[14+1];
|
||||
FILE *fp;
|
||||
unsigned int fileOffset=0, found=FALSE;
|
||||
struct romdir rd;
|
||||
uint fileOffset=0;
|
||||
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( biosFileSize <= 0) return FALSE;
|
||||
if( !fp.IsOpened() ) return FALSE;
|
||||
|
||||
fp = fopen(Bios.c_str(), "rb");
|
||||
if (fp == NULL) return FALSE;
|
||||
int biosFileSize = fp.Length();
|
||||
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)
|
||||
break; /* found romdir */
|
||||
break; // found romdir
|
||||
}
|
||||
|
||||
if ((strcmp(rd.fileName, "RESET") != 0) || (rd.fileSize == 0)) {
|
||||
fclose(fp);
|
||||
return FALSE; //Unable to locate ROMDIR structure in file or a ioprpXXX.img
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
|
||||
while(strlen(rd.fileName) > 0)
|
||||
{
|
||||
if (strcmp(rd.fileName, "ROMVER") == 0) // found romver
|
||||
{
|
||||
uint filepos = ftell(fp);
|
||||
fseek(fp, fileOffset, SEEK_SET);
|
||||
if (fread(&ROMVER, 14, 1, fp) == 0) break;
|
||||
fseek(fp, filepos, SEEK_SET);//go back
|
||||
char aROMVER[14+1]; // ascii version loaded from disk.
|
||||
|
||||
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;
|
||||
|
||||
switch(ROMVER[4])
|
||||
switch(aROMVER[4])
|
||||
{
|
||||
case 'T': zone = "T10K "; break;
|
||||
case 'X': zone = "Test "; break;
|
||||
@ -163,15 +167,17 @@ int IsBIOS(const char *filename, char *description)
|
||||
case 'C': zone = "China "; break;
|
||||
}
|
||||
|
||||
sprintf(description, "%s v%c%c.%c%c(%c%c/%c%c/%c%c%c%c) %s", zone,
|
||||
ROMVER[0], ROMVER[1], // ver major
|
||||
ROMVER[2], ROMVER[3], // ver minor
|
||||
ROMVER[12], ROMVER[13], // day
|
||||
ROMVER[10], ROMVER[11], // month
|
||||
ROMVER[6], ROMVER[7], ROMVER[8], ROMVER[9], // year!
|
||||
(ROMVER[5]=='C') ? "Console" : (ROMVER[5]=='D') ? "Devel" : ""
|
||||
const wxString romver( wxString::FromAscii(aROMVER) );
|
||||
|
||||
description.Printf( wxT("%s v%c%c.%c%c(%c%c/%c%c/%c%c%c%c) %s"), wxString::FromAscii(zone).ToAscii().data(),
|
||||
romver[0], romver[1], // ver major
|
||||
romver[2], romver[3], // ver minor
|
||||
romver[12], romver[13], // day
|
||||
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)
|
||||
@ -179,29 +185,26 @@ int IsBIOS(const char *filename, char *description)
|
||||
else
|
||||
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;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (found)
|
||||
{
|
||||
char percent[6];
|
||||
|
||||
if ( biosFileSize < (int)fileOffset)
|
||||
{
|
||||
sprintf(percent, " %d%%", biosFileSize*100/(int)fileOffset);
|
||||
strcat(description, percent);//we force users to have correct bioses,
|
||||
//not that lame scph10000 of 513KB ;-)
|
||||
description << ((biosFileSize*100)/(int)fileOffset) << wxT("%");
|
||||
// we force users to have correct bioses,
|
||||
// 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;
|
||||
char buffer[g_MaxPath];//if a file is longer...it should be shorter :D
|
||||
char *pos;
|
||||
@ -231,18 +234,17 @@ int GetPS2ElfName(char *name){
|
||||
return 1;
|
||||
}
|
||||
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++;
|
||||
if (!pos || *pos==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
|
||||
FILE *fp;
|
||||
int i;
|
||||
@ -281,7 +283,7 @@ void SaveGSState(const wxString& file)
|
||||
if( g_SaveGSStream ) return;
|
||||
|
||||
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 );
|
||||
|
||||
@ -305,9 +307,9 @@ void LoadGSState(const wxString& file)
|
||||
catch( Exception::FileNotFound& )
|
||||
{
|
||||
// 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
|
||||
// the caller to deal with...
|
||||
@ -350,9 +352,7 @@ char* mystrlwr( char* string )
|
||||
|
||||
static wxString GetGSStateFilename()
|
||||
{
|
||||
wxString gsText;
|
||||
gsText.Printf( "/%8.8X.%d.gs", ElfCRC, StatesC );
|
||||
return Path::Combine( SSTATES_DIR, gsText );
|
||||
return Path::Combine( g_Conf.Folders.Savestates, wxsFormat( wxT("/%8.8X.%d.gs"), ElfCRC, StatesC ) );
|
||||
}
|
||||
|
||||
void CycleFrameLimit(int dir)
|
||||
@ -430,10 +430,11 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
|
||||
catch( Exception::BaseException& ex )
|
||||
{
|
||||
// 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( ex.cMessage() );
|
||||
Console::Error( "Error! Could not save state to slot %d", params StatesC );
|
||||
Console::Error( ex.LogMessage() );
|
||||
}
|
||||
break;
|
||||
|
||||
@ -446,7 +447,7 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
|
||||
Console::Notice( " > Selected savestate slot %d", params StatesC);
|
||||
|
||||
if( GSchangeSaveState != NULL )
|
||||
GSchangeSaveState(StatesC, SaveState::GetFilename(StatesC).c_str());
|
||||
GSchangeSaveState(StatesC, SaveState::GetFilename(StatesC).mb_str());
|
||||
break;
|
||||
|
||||
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
|
||||
// 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 );
|
||||
|
||||
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;
|
||||
|
||||
@ -490,7 +490,7 @@ void ProcessFKeys(int fkey, struct KeyModifiers *keymod)
|
||||
|
||||
// note: VK_F5-VK_F7 are reserved for GS
|
||||
case 8:
|
||||
GSmakeSnapshot( SNAPSHOTS_DIR "/" );
|
||||
GSmakeSnapshot( g_Conf.Folders.Snapshots.ToAscii().data() );
|
||||
break;
|
||||
|
||||
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
|
||||
wxString gsText;
|
||||
|
||||
wxStringTokenizer parts( strgametitle, " " );
|
||||
wxStringTokenizer parts( strgametitle, L" " );
|
||||
|
||||
wxString name( parts.GetNextToken() ); // first part
|
||||
wxString part2( parts.GetNextToken() );
|
||||
|
||||
if( !!part2 )
|
||||
name += "_" + part2;
|
||||
|
||||
gsText.Printf( "%s.%d.gs", name.c_str(), StatesC );
|
||||
Text = Path::Combine( SSTATES_DIR, gsText );
|
||||
if( !!part2 )
|
||||
name += wxT("_") + part2;
|
||||
|
||||
gsText.Printf( wxT("%s.%d.gs"), name.c_str(), StatesC );
|
||||
Text = Path::Combine( g_Conf.Folders.Savestates, gsText );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ extern uptr pDsp; //Used in GS, MTGS, Plugins, Misc
|
||||
|
||||
u32 GetBiosVersion(); // Used in Misc, Memory
|
||||
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.
|
||||
void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR);
|
||||
@ -65,7 +65,7 @@ extern u64 GetTickFrequency();
|
||||
|
||||
// Used in Misc,and Windows/Linux files.
|
||||
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 *LabelGreets;
|
||||
|
@ -63,4 +63,5 @@ void DispatcherReg();
|
||||
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -24,190 +24,7 @@
|
||||
#include "System.h"
|
||||
|
||||
class MainEmuFrame;
|
||||
|
||||
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 );
|
||||
};
|
||||
class IniInterface;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
@ -229,6 +46,7 @@ public:
|
||||
virtual void OnClear(wxCommandEvent& event);
|
||||
|
||||
virtual void Write( const wxChar* text );
|
||||
virtual void Write( const char* text );
|
||||
void Newline();
|
||||
|
||||
void SetColor( Console::Colors color );
|
||||
@ -264,8 +82,12 @@ protected:
|
||||
public:
|
||||
Pcsx2App();
|
||||
|
||||
wxFrame* GetMainWindow() const;
|
||||
|
||||
bool OnInit();
|
||||
int OnExit();
|
||||
void OnInitCmdLine( wxCmdLineParser& parser );
|
||||
bool OnCmdLineParsed( wxCmdLineParser& parser );
|
||||
|
||||
const wxBitmap& GetLogoBitmap() const;
|
||||
MainEmuFrame& GetMainFrame() const
|
||||
@ -281,5 +103,3 @@ public:
|
||||
};
|
||||
|
||||
DECLARE_APP(Pcsx2App)
|
||||
|
||||
extern AppConfig g_Conf;
|
||||
|
@ -18,147 +18,130 @@
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "App.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();
|
||||
}
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PathDefs Namespace -- contains default values for various pcsx2 path names and locations.
|
||||
//
|
||||
|
||||
IniLoader::IniLoader( wxConfigBase& config ) : IniInterface( config )
|
||||
// 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
|
||||
{
|
||||
}
|
||||
|
||||
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 ? "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 )
|
||||
const wxDirName Snapshots( wxT("snaps") );
|
||||
const wxDirName Savestates( wxT("sstates") );
|
||||
const wxDirName MemoryCards( wxT("memcards") );
|
||||
const wxDirName Configs( wxT("inis") );
|
||||
const wxDirName Plugins( wxT("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.
|
||||
wxDirName GetDocuments()
|
||||
{
|
||||
Console::Notice( "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;
|
||||
return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
|
||||
}
|
||||
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() {}
|
||||
IniSaver::~IniSaver() {}
|
||||
return wxGetApp().GetAppName() + wxT(".ini");
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
m_Config.Write( var, ToString( value ) );
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
wxString AppConfig::FullpathHelpers::Bios() const { return Path::Combine( m_conf.Folders.Bios, m_conf.BaseFilenames.Bios ); }
|
||||
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 )
|
||||
{
|
||||
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] );
|
||||
}
|
||||
wxString AppConfig::FullpathHelpers::Mcd( uint mcdidx ) const { return Path::Combine( m_conf.Folders.MemoryCards, m_conf.MemoryCards.Mcd[mcdidx].Filename ); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
@ -59,7 +59,7 @@ static bool OpenLogFile(wxFile& file, wxString& filename, wxWindow *parent)
|
||||
return false;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( "invalid message box return value" );
|
||||
wxFAIL_MSG( L"invalid message box return value" );
|
||||
}
|
||||
|
||||
return ( bAppend ) ?
|
||||
@ -211,3 +211,14 @@ void ConsoleLogFrame::Write( const wxChar* 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) );
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ AboutBoxDialog::AboutBoxDialog( wxWindow* parent, int id ):
|
||||
m_bitmap_ps2system( this, wxID_ANY, wxBitmap( EmbeddedImage<png_ps2_silver>().GetImage() ),
|
||||
wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN )
|
||||
{
|
||||
static const wxString LabelAuthors = _(
|
||||
static const wxString LabelAuthors = wxString::FromAscii(
|
||||
"PCSX2, a PS2 emulator\n\n"
|
||||
"Active Devs: Arcum42, Refraction,"
|
||||
"drk||raziel, cottonvibes, gigaherz,"
|
||||
@ -69,7 +69,7 @@ AboutBoxDialog::AboutBoxDialog( wxWindow* parent, int id ):
|
||||
"Webmasters: CKemu, Falcon4ever"
|
||||
);
|
||||
|
||||
static const wxString LabelGreets = _(
|
||||
static const wxString LabelGreets = wxString::FromAscii(
|
||||
"Contributors: Hiryu and Sjeep for libcvd (the iso parsing and\n"
|
||||
"filesystem driver code), nneeve, pseudonym\n"
|
||||
"\n"
|
||||
|
52
pcsx2/NewGUI/HostGui.cpp
Normal file
52
pcsx2/NewGUI/HostGui.cpp
Normal 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 )
|
||||
{
|
||||
}
|
||||
}
|
165
pcsx2/NewGUI/IniInterface.cpp
Normal file
165
pcsx2/NewGUI/IniInterface.cpp
Normal 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
109
pcsx2/NewGUI/IniInterface.h
Normal 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 );
|
||||
};
|
@ -140,7 +140,7 @@ void MainEmuFrame::OnLogBoxHidden()
|
||||
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),
|
||||
|
||||
m_logbox( this, "Pcsx2 Log" ),
|
||||
m_logbox( this, L"Pcsx2 Log" ),
|
||||
|
||||
m_statusbar( *CreateStatusBar(2, 0) ),
|
||||
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_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 );
|
||||
|
@ -17,12 +17,13 @@
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "IniInterface.h"
|
||||
#include "MainFrame.h"
|
||||
|
||||
#include "Resources/EmbeddedImage.h"
|
||||
#include "Resources/BackgroundLogo.h"
|
||||
|
||||
#include <wx/stdpaths.h>
|
||||
#include <wx/cmdline.h>
|
||||
|
||||
IMPLEMENT_APP(Pcsx2App)
|
||||
|
||||
@ -30,81 +31,14 @@ AppConfig g_Conf;
|
||||
|
||||
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() :
|
||||
m_ConsoleFrame( NULL )
|
||||
{
|
||||
SetAppName( "Pcsx2" );
|
||||
SetAppName( L"Pcsx2" );
|
||||
}
|
||||
|
||||
wxFrame* Pcsx2App::GetMainWindow() const { return m_MainFrame; }
|
||||
|
||||
wxFileConfig* OpenConfig( const wxString& filename )
|
||||
{
|
||||
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())
|
||||
bool Pcsx2App::TryOpenConfigCwd()
|
||||
{
|
||||
wxString inipath_cwd( Path::Combine( wxGetCwd(), PathDefs::Configs ) );
|
||||
if( !Path::isDirectory( inipath_cwd ) ) return false;
|
||||
wxDirName inipath_cwd( (wxDirName)wxGetCwd() + PathDefs::Configs );
|
||||
if( !inipath_cwd.IsReadable() ) return false;
|
||||
|
||||
wxString inifile_cwd( Path::Combine( inipath_cwd, FilenameDefs::GetConfig() ) );
|
||||
if( !Path::isFile( inifile_cwd ) ) return false;
|
||||
if( Path::getFileSize( inifile_cwd ) <= 1 ) return false;
|
||||
if( !Path::IsFile( inifile_cwd ) ) return false;
|
||||
if( Path::GetFileSize( inifile_cwd ) <= 1 ) return false;
|
||||
|
||||
wxConfigBase::Set( OpenConfig( inifile_cwd ) );
|
||||
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()
|
||||
{
|
||||
wxInitAllImageHandlers();
|
||||
|
||||
wxApp::OnInit();
|
||||
|
||||
// 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
|
||||
// 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() )
|
||||
{
|
||||
Path::CreateDirectory( PathDefs::GetDocuments() );
|
||||
Path::CreateDirectory( PathDefs::GetConfigs() );
|
||||
PathDefs::GetDocuments().Mkdir();
|
||||
PathDefs::GetConfigs().Mkdir();
|
||||
|
||||
// Allow wx to use our config, and enforces auto-cleanup as well
|
||||
wxConfigBase::Set( OpenConfig( Path::Combine( PathDefs::GetConfigs(), FilenameDefs::GetConfig() ) ) );
|
||||
|
@ -24,7 +24,6 @@
|
||||
#define _PC_ // disables MIPS opcode macros.
|
||||
|
||||
#include "IopCommon.h"
|
||||
#include "Paths.h"
|
||||
#include "Patch.h"
|
||||
#include "VU.h"
|
||||
|
||||
@ -462,20 +461,25 @@ void patchFunc_comment( char * text1, char * text2 )
|
||||
void patchFunc_gametitle( char * text1, char * text2 )
|
||||
{
|
||||
Console::WriteLn( "gametitle: %s", params text2 );
|
||||
strgametitle = text2;
|
||||
Console::SetTitle(strgametitle);
|
||||
strgametitle.FromAscii( text2 );
|
||||
Console::SetTitle( strgametitle );
|
||||
}
|
||||
|
||||
void patchFunc_patch( char * cmd, char * param )
|
||||
{
|
||||
char * pText;
|
||||
char* pText;
|
||||
|
||||
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 );
|
||||
return;
|
||||
}
|
||||
|
||||
//SafeList<wxString> pieces;
|
||||
//SplitString( pieces, param, "," );
|
||||
|
||||
pText = strtok( param, "," );
|
||||
pText = param;
|
||||
|
||||
@ -536,7 +540,10 @@ void inifile_command( char * cmd )
|
||||
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 * pEnd = NULL;
|
||||
@ -574,6 +581,33 @@ void inifile_trim( char * buffer )
|
||||
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 )
|
||||
{
|
||||
char buffer[ 1024 ];
|
||||
@ -621,7 +655,7 @@ void inifile_read( const char * name )
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -115,8 +115,8 @@ extern int g_ZeroGSOptions;
|
||||
extern u32 g_sseMXCSR;
|
||||
extern u32 g_sseVUMXCSR;
|
||||
|
||||
void SetRoundMode(u32 ee, u32 vu);
|
||||
int LoadPatch(const std::string& patchfile);
|
||||
extern void SetRoundMode(u32 ee, u32 vu);
|
||||
extern int LoadPatch(const wxString& patchfile);
|
||||
|
||||
#endif /* __PATCH_H__ */
|
||||
|
||||
|
@ -36,65 +36,79 @@ namespace Path
|
||||
|
||||
#ifdef WIN32
|
||||
// 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.
|
||||
static const wxString Delimiters( "\\/" );
|
||||
static const wxString Delimiters( wxT("\\/") );
|
||||
|
||||
static const wxChar SeparatorExt( wxT('.') );
|
||||
|
||||
#else
|
||||
static const char Separator = '/';
|
||||
static const char Delimiters( '/' );
|
||||
#endif
|
||||
|
||||
static bool IsPathSeparator( wxChar src )
|
||||
{
|
||||
#ifdef WIN32
|
||||
return (src == Separator) || (src == wxT('/'));
|
||||
#else
|
||||
return src == Separator;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Exists( const wxString& path )
|
||||
{
|
||||
struct stat sbuf;
|
||||
return stat( path.c_str(), &sbuf ) == 0;
|
||||
wxStructStat sbuf;
|
||||
return wxStat( path.c_str(), &sbuf ) == 0;
|
||||
}
|
||||
|
||||
// This function returns false if the path does not exist, or if the path exists and
|
||||
// is a file.
|
||||
bool isDirectory( const wxString& path )
|
||||
bool IsDirectory( const wxString& path )
|
||||
{
|
||||
struct stat sbuf;
|
||||
if( stat( path.c_str(), &sbuf ) == -1 ) return false;
|
||||
wxStructStat sbuf;
|
||||
if( wxStat( path.c_str(), &sbuf ) == -1 ) return false;
|
||||
return !!(sbuf.st_mode & _S_IFDIR);
|
||||
}
|
||||
|
||||
// This function returns false if the path does not exist, or if the path exists and
|
||||
// is a directory.
|
||||
bool isFile( const wxString& path )
|
||||
bool IsFile( const wxString& path )
|
||||
{
|
||||
struct stat sbuf;
|
||||
if( stat( path.c_str(), &sbuf ) == -1 ) return false;
|
||||
wxStructStat sbuf;
|
||||
if( wxStat( path.c_str(), &sbuf ) == -1 ) return false;
|
||||
return !!(sbuf.st_mode & _S_IFREG);
|
||||
}
|
||||
|
||||
// Returns the length of the file.
|
||||
// returns -1 if the file is not found.
|
||||
int getFileSize( const wxString& path )
|
||||
int GetFileSize( const wxString& path )
|
||||
{
|
||||
struct stat sbuf;
|
||||
if( stat( path.c_str(), &sbuf ) == -1 ) return -1;
|
||||
wxStructStat sbuf;
|
||||
if( wxStat( path.c_str(), &sbuf ) == -1 ) return -1;
|
||||
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
|
||||
// a colon, it's a safe bet we're rooted.
|
||||
|
||||
if( path[0] == 0 ) return FALSE;
|
||||
if( path[0] == 0 ) return false;
|
||||
#ifdef WIN32
|
||||
return (path[0] == '/') || (path[0] == '\\') || (path[1] == ':');
|
||||
return IsPathSeparator(path[0]) || ( (path[1] == ':') && IsPathSeparator(path[2]) );
|
||||
#else
|
||||
return (path[0] == Separator);
|
||||
return IsPathSeparator(path[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Concatenates two pathnames together, inserting delimiters (backslash on win32)
|
||||
// as needed! Assumes the 'dest' is allocated to at least g_MaxPath length.
|
||||
wxString Combine( const wxString& srcPath, const wxString& srcFile )
|
||||
{
|
||||
int pathlen, guesslen;
|
||||
#if 0
|
||||
int pathlen;
|
||||
|
||||
if( srcFile.empty() )
|
||||
{
|
||||
@ -102,7 +116,7 @@ wxString Combine( const wxString& srcPath, const wxString& srcFile )
|
||||
return srcPath;
|
||||
}
|
||||
|
||||
if( isRooted( srcFile ) || srcPath.empty() )
|
||||
if( IsRooted( srcFile ) || srcPath.empty() )
|
||||
{
|
||||
// No source path? Or source filename is rooted?
|
||||
// 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?
|
||||
|
||||
pathlen = srcPath.length();
|
||||
while( pathlen > 0 && ((srcPath[pathlen-1] == '\\') || (srcPath[pathlen-1] == '/')) )
|
||||
while( pathlen > 0 && IsPathSeparator(srcPath[pathlen-1]) )
|
||||
--pathlen;
|
||||
|
||||
// Concatenate strings:
|
||||
@ -129,14 +143,31 @@ wxString Combine( const wxString& srcPath, const wxString& srcFile )
|
||||
dest += Separator;
|
||||
dest += srcFile;
|
||||
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.
|
||||
// This function works for path names as well as file names.
|
||||
wxString ReplaceExtension( const wxString& src, const wxString& ext )
|
||||
{
|
||||
wxString dest;
|
||||
|
||||
int pos = src.find_last_of( '.' );
|
||||
int pos = src.find_last_of( SeparatorExt );
|
||||
if( pos == wxString::npos || pos == 0 )
|
||||
dest = src;
|
||||
else
|
||||
@ -151,97 +182,32 @@ wxString ReplaceExtension( const wxString& src, const wxString& ext )
|
||||
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 dest;
|
||||
int pos = _findFilenamePosition( src );
|
||||
// Implementation note: use wxWidgets to do this job.
|
||||
|
||||
if( pos == 0 )
|
||||
dest = src;
|
||||
else
|
||||
dest.assign( src.begin(), src.begin()+pos );
|
||||
|
||||
if( !newfilename.empty() )
|
||||
{
|
||||
dest += Separator;
|
||||
dest += newfilename;
|
||||
}
|
||||
return dest;
|
||||
wxFileName jojo( src );
|
||||
jojo.SetFullName( newfilename );
|
||||
return jojo.GetFullPath();
|
||||
}
|
||||
|
||||
wxString GetFilename( const wxString& src )
|
||||
{
|
||||
int pos = _findFilenamePosition( src );
|
||||
return wxString( src.begin()+pos, src.end() );
|
||||
return wxFileName(src).GetFullName();
|
||||
}
|
||||
|
||||
wxString GetFilenameWithoutExt( const wxString& src )
|
||||
{
|
||||
wxString fname( GetFilename( src ) );
|
||||
|
||||
int pos = fname.find_last_of( '.' );
|
||||
if( pos == wxString::npos || pos == 0 )
|
||||
return fname;
|
||||
else
|
||||
return wxString( fname.begin(), fname.begin()+pos );
|
||||
return wxFileName(src).GetName();
|
||||
}
|
||||
|
||||
wxString GetDirectory( const wxString& src )
|
||||
{
|
||||
int pos = _findFilenamePosition( src );
|
||||
if( pos == 0 )
|
||||
return wxString();
|
||||
else
|
||||
return wxString( src.begin(), src.begin()+pos );
|
||||
return wxFileName(src).GetPath();
|
||||
}
|
||||
|
||||
// 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 )
|
||||
{
|
||||
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.
|
||||
// returns the base/root directory of the given path.
|
||||
// Example /this/that/something.txt -> dest == "/"
|
||||
wxString GetRootDirectory( const wxString& src )
|
||||
{
|
||||
@ -254,11 +220,12 @@ wxString GetRootDirectory( const wxString& src )
|
||||
|
||||
void CreateDirectory( const wxString& src )
|
||||
{
|
||||
#ifdef _WIN32
|
||||
_mkdir( src.c_str() );
|
||||
#else
|
||||
mkdir( src.c_str(), 0755);
|
||||
#endif
|
||||
wxFileName::Mkdir( src );
|
||||
}
|
||||
|
||||
void RemoveDirectory( const wxString& src )
|
||||
{
|
||||
wxFileName::Rmdir( src );
|
||||
}
|
||||
|
||||
}
|
||||
|
162
pcsx2/Paths.h
162
pcsx2/Paths.h
@ -7,6 +7,11 @@
|
||||
extern char MAIN_DIR[g_MaxPath];
|
||||
#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_BIOS_DIR "bios"
|
||||
#define DEFAULT_PLUGINS_DIR "plugins"
|
||||
@ -25,25 +30,170 @@ extern char MAIN_DIR[g_MaxPath];
|
||||
// Windows.h namespace pollution!
|
||||
#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
|
||||
{
|
||||
extern bool isRooted( const wxString& path );
|
||||
extern bool isDirectory( const wxString& path );
|
||||
extern bool isFile( const wxString& path );
|
||||
extern bool IsRooted( const wxString& path );
|
||||
extern bool IsDirectory( const wxString& path );
|
||||
extern bool IsFile( 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 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 ReplaceFilename( const wxString& src, const wxString& newfilename );
|
||||
extern wxString GetFilename( const wxString& src );
|
||||
extern wxString GetDirectory( const wxString& src );
|
||||
extern wxString GetFilenameWithoutExt( const string& 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 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
|
||||
|
@ -216,6 +216,9 @@ _FWabout FWabout;
|
||||
|
||||
DEV9handler dev9Handler;
|
||||
USBhandler usbHandler;
|
||||
uptr pDsp;
|
||||
|
||||
#ifdef _not_wxWidgets_Land_
|
||||
|
||||
#define Sfy(x) #x
|
||||
#define Strfy(x) Sfy(x)
|
||||
@ -695,7 +698,6 @@ void ShutdownPlugins()
|
||||
initp = false;
|
||||
}
|
||||
|
||||
uptr pDsp;
|
||||
extern void spu2DMA4Irq();
|
||||
extern void spu2DMA7Irq();
|
||||
extern void spu2Irq();
|
||||
@ -922,3 +924,25 @@ void PluginsResetGS()
|
||||
int ret = GSinit();
|
||||
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
|
@ -36,12 +36,16 @@
|
||||
#include <wx/string.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#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.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include the STL junk that's actually handy.
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
@ -67,10 +71,19 @@ using std::max;
|
||||
|
||||
typedef int BOOL;
|
||||
|
||||
# undef TRUE
|
||||
# undef FALSE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
#define TRUE 1
|
||||
#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
|
||||
@ -79,6 +92,8 @@ typedef int BOOL;
|
||||
|
||||
#include "zlib/zlib.h"
|
||||
#include "PS2Etypes.h"
|
||||
#include "Paths.h"
|
||||
#include "Config.h"
|
||||
#include "StringUtils.h"
|
||||
#include "Exceptions.h"
|
||||
#include "MemcpyFast.h"
|
||||
@ -141,24 +156,33 @@ static __forceinline u32 timeGetTime()
|
||||
# define __releaseinline __forceinline
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Emitter Instance Identifiers. If you add a new emitter, do it here also.
|
||||
// Note: Currently most of the instances map back to 0, since existing dynarec code all
|
||||
// shares iCore and must therefore all share the same emitter instance.
|
||||
// (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,
|
||||
//////////////////////////////////////////////////////////////
|
||||
// Dev / Debug conditionals --
|
||||
// Consts for using if() statements instead of uglier #ifdef macros.
|
||||
// Abbreviated macros for dev/debug only consoles and msgboxes.
|
||||
|
||||
// Air's eventual IopRec, which will also be iCore-free
|
||||
EmitterId_R3000air,
|
||||
|
||||
EmitterId_Count // must always be last!
|
||||
};
|
||||
#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
|
||||
|
@ -224,7 +224,7 @@ static __forceinline void _psxTestInterrupts()
|
||||
}
|
||||
}
|
||||
|
||||
void psxBranchTest()
|
||||
__releaseinline void psxBranchTest()
|
||||
{
|
||||
if( psxTestCycle( psxNextsCounter, psxNextCounter ) )
|
||||
{
|
||||
|
@ -126,14 +126,14 @@ extern s32 psxCycleEE; // tracks IOP's current sych status with the EE
|
||||
|
||||
#ifndef _PC_
|
||||
|
||||
#define _i32(x) (s32)x
|
||||
#define _u32(x) (u32)x
|
||||
#define _i32(x) (s32)x //R3000A
|
||||
#define _u32(x) (u32)x //R3000A
|
||||
|
||||
#define _i16(x) (s16)x
|
||||
#define _u16(x) (u16)x
|
||||
#define _i16(x) (s16)x // Not used
|
||||
#define _u16(x) (u16)x // Not used
|
||||
|
||||
#define _i8(x) (s8)x
|
||||
#define _u8(x) (u8)x
|
||||
#define _i8(x) (s8)x // Not used
|
||||
#define _u8(x) (u8)x //R3000A - once
|
||||
|
||||
/**** R3000A Instruction Macros ****/
|
||||
#define _PC_ psxRegs.pc // The next PC to be executed
|
||||
@ -200,7 +200,7 @@ extern R3000Acpu psxRec;
|
||||
void psxReset();
|
||||
void psxShutdown();
|
||||
void psxException(u32 code, u32 step);
|
||||
void psxBranchTest();
|
||||
extern void psxBranchTest();
|
||||
void psxExecuteBios();
|
||||
void psxMemReset();
|
||||
|
||||
|
@ -35,8 +35,6 @@
|
||||
#include "SPR.h"
|
||||
#include "Sif.h"
|
||||
|
||||
#include "Paths.h"
|
||||
|
||||
#include "R5900Exceptions.h"
|
||||
|
||||
using namespace R5900; // for R5900 disasm tools
|
||||
@ -82,11 +80,11 @@ void cpuReset()
|
||||
g_nextBranchCycle = cpuRegs.cycle + 4;
|
||||
EEsCycle = 0;
|
||||
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
|
||||
// the WaitCycles value here for x2 and x3 modes:
|
||||
if( CHECK_EE_CYCLERATE > 1 )
|
||||
if( Config.Hacks.EECycleRate > 1 )
|
||||
eeWaitCycles += 1024;
|
||||
|
||||
hwReset();
|
||||
@ -106,7 +104,7 @@ void cpuShutdown()
|
||||
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.
|
||||
bool errLevel2, checkStatus;
|
||||
@ -244,7 +242,7 @@ void cpuTestMissingHwInts() {
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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 )
|
||||
{
|
||||
g_nextBranchCycle = startCycle + delta;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
||||
// 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
|
||||
// if the startCycle is ahead of our current cpu cycle.
|
||||
@ -279,7 +275,7 @@ __forceinline void cpuSetBranch()
|
||||
g_nextBranchCycle = cpuRegs.cycle;
|
||||
}
|
||||
|
||||
void cpuClearInt( uint i )
|
||||
__forceinline void cpuClearInt( uint i )
|
||||
{
|
||||
jASSUME( i < 32 );
|
||||
cpuRegs.interrupt &= ~(1 << i);
|
||||
|
@ -121,16 +121,16 @@ union CP0regs {
|
||||
};
|
||||
|
||||
struct cpuRegisters {
|
||||
GPRregs GPR; // GPR regs
|
||||
GPRregs GPR; // GPR regs
|
||||
// NOTE: don't change order since recompiler uses it
|
||||
GPR_reg HI;
|
||||
GPR_reg LO; // hi & log 128bit wide
|
||||
CP0regs CP0; // is COP0 32bit?
|
||||
u32 sa; // shift amount (32bit), needs to be 16 byte aligned
|
||||
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 code; // current instruction
|
||||
PERFregs PERF;
|
||||
u32 pc; // Program counter, when changing offset in struct, check iR5900-X.S to make sure offset is correct
|
||||
u32 code; // current instruction
|
||||
PERFregs PERF;
|
||||
u32 eCycle[32];
|
||||
u32 sCycle[32]; // for internal counters
|
||||
u32 cycle; // calculate cpucycles..
|
||||
@ -180,7 +180,7 @@ struct tlbs
|
||||
|
||||
#ifndef _PC_
|
||||
|
||||
#define _i64(x) (s64)x
|
||||
/*#define _i64(x) (s64)x
|
||||
#define _u64(x) (u64)x
|
||||
|
||||
#define _i32(x) (s32)x
|
||||
@ -190,12 +190,12 @@ struct tlbs
|
||||
#define _u16(x) (u16)x
|
||||
|
||||
#define _i8(x) (s8)x
|
||||
#define _u8(x) (u8)x
|
||||
#define _u8(x) (u8)x*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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 _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 cpuShutdown();
|
||||
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 cpuTlbMissW(u32 addr, u32 bd);
|
||||
extern void cpuTestHwInts();
|
||||
|
||||
extern int __fastcall cpuSetNextBranch( u32 startCycle, s32 delta );
|
||||
extern int __fastcall cpuSetNextBranchDelta( s32 delta );
|
||||
extern int __fastcall cpuTestCycle( u32 startCycle, s32 delta );
|
||||
extern void cpuSetNextBranch( u32 startCycle, s32 delta );
|
||||
extern void cpuSetNextBranchDelta( s32 delta );
|
||||
extern int cpuTestCycle( u32 startCycle, s32 delta );
|
||||
extern void cpuSetBranch();
|
||||
|
||||
extern bool _cpuBranchTest_Shared(); // for internal use by the Dynarecs and Ints inside R5900:
|
||||
|
@ -23,10 +23,13 @@ namespace R5900Exception
|
||||
{
|
||||
using Exception::Ps2Generic;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Abstract base class for R5900 exceptions; contains the cpuRegs instance at the
|
||||
// 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
|
||||
{
|
||||
public:
|
||||
@ -35,8 +38,8 @@ namespace R5900Exception
|
||||
public:
|
||||
virtual ~BaseExcept() throw()=0;
|
||||
|
||||
explicit BaseExcept( const std::string& msg ) :
|
||||
Exception::Ps2Generic( "(EE) " + msg ),
|
||||
explicit BaseExcept( const wxString& msg ) :
|
||||
Exception::Ps2Generic( wxT("(EE) ") + msg ),
|
||||
cpuState( cpuRegs )
|
||||
{
|
||||
}
|
||||
@ -57,7 +60,7 @@ namespace R5900Exception
|
||||
virtual ~AddressError() throw() {}
|
||||
|
||||
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 ),
|
||||
Address( ps2addr )
|
||||
{}
|
||||
@ -75,7 +78,7 @@ namespace R5900Exception
|
||||
virtual ~TLBMiss() throw() {}
|
||||
|
||||
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 ),
|
||||
Address( ps2addr )
|
||||
{}
|
||||
@ -94,7 +97,7 @@ namespace R5900Exception
|
||||
|
||||
//
|
||||
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 ),
|
||||
Address( ps2addr )
|
||||
{}
|
||||
@ -108,7 +111,7 @@ namespace R5900Exception
|
||||
virtual ~SystemCall() throw() {}
|
||||
|
||||
explicit SystemCall() :
|
||||
BaseExcept( "SystemCall [SYSCALL]" )
|
||||
BaseExcept( wxT("SystemCall [SYSCALL]") )
|
||||
{}
|
||||
};
|
||||
|
||||
@ -124,14 +127,14 @@ namespace R5900Exception
|
||||
|
||||
// Generates a trap for immediate-style Trap opcodes
|
||||
explicit Trap() :
|
||||
BaseExcept( "Trap" ),
|
||||
BaseExcept( wxT("Trap") ),
|
||||
TrapCode( 0 )
|
||||
{}
|
||||
|
||||
// Generates a trap for register-style Trap instructions, which contain an
|
||||
// error code in the opcode
|
||||
explicit Trap( u16 trapcode ) :
|
||||
BaseExcept( "Trap" ),
|
||||
BaseExcept( wxT("Trap") ),
|
||||
TrapCode( trapcode )
|
||||
{}
|
||||
};
|
||||
@ -144,7 +147,7 @@ namespace R5900Exception
|
||||
virtual ~Break() throw() {}
|
||||
|
||||
explicit Break() :
|
||||
BaseExcept( "Break Instruction" )
|
||||
BaseExcept( wxT("Break Instruction") )
|
||||
{}
|
||||
};
|
||||
|
||||
@ -156,7 +159,7 @@ namespace R5900Exception
|
||||
virtual ~Overflow() throw() {}
|
||||
|
||||
explicit Overflow() :
|
||||
BaseExcept( "Overflow" )
|
||||
BaseExcept( wxT("Overflow") )
|
||||
{}
|
||||
};
|
||||
|
||||
@ -168,7 +171,7 @@ namespace R5900Exception
|
||||
virtual ~DebugBreakpoint() throw() {}
|
||||
|
||||
explicit DebugBreakpoint() :
|
||||
BaseExcept( "Debug Breakpoint" )
|
||||
BaseExcept( wxT("Debug Breakpoint") )
|
||||
{}
|
||||
};
|
||||
}
|
||||
|
@ -106,13 +106,10 @@ namespace R5900
|
||||
static const int MMI_Div = 22*8;
|
||||
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 Load = 22;
|
||||
|
||||
static const int StoreFast = 14;
|
||||
static const int LoadFast = 12;
|
||||
static const int Store = 8;
|
||||
static const int Load = 8;
|
||||
}
|
||||
|
||||
using namespace Cycles;
|
||||
@ -263,28 +260,28 @@ namespace R5900
|
||||
MakeOpcode( LB, Load );
|
||||
MakeOpcode( LH, Load );
|
||||
MakeOpcode( LWL, Load );
|
||||
MakeOpcode( LW, LoadFast );
|
||||
MakeOpcode( LW, Load );
|
||||
MakeOpcode( LBU, Load );
|
||||
MakeOpcode( LHU, Load );
|
||||
MakeOpcode( LWR, Load );
|
||||
MakeOpcode( LWU, Load );
|
||||
MakeOpcode( LWC1, Load );
|
||||
MakeOpcode( LQC2, Load );
|
||||
MakeOpcode( LD, LoadFast );
|
||||
MakeOpcode( LD, Load );
|
||||
|
||||
// Stores!
|
||||
|
||||
MakeOpcode( SQ, Store );
|
||||
MakeOpcode( SB, Store );//slow
|
||||
MakeOpcode( SH, Store );//slow
|
||||
MakeOpcode( SB, Store );
|
||||
MakeOpcode( SH, Store );
|
||||
MakeOpcode( SWL, Store );
|
||||
MakeOpcode( SW, StoreFast );
|
||||
MakeOpcode( SW, Store );
|
||||
MakeOpcode( SDL, Store );
|
||||
MakeOpcode( SDR, Store );
|
||||
MakeOpcode( SWR, Store );
|
||||
MakeOpcode( SWC1, Store );
|
||||
MakeOpcode( SQC2, Store );
|
||||
MakeOpcode( SD, StoreFast );
|
||||
MakeOpcode( SD, Store );
|
||||
|
||||
|
||||
// Multimedia Instructions!
|
||||
@ -435,9 +432,9 @@ namespace R5900
|
||||
MakeOpcode1( MIN_S, CopDefault );
|
||||
|
||||
MakeOpcode1( MUL_S, FPU_Mult );
|
||||
MakeOpcode1( DIV_S, 3*8 );
|
||||
MakeOpcode1( SQRT_S, 3*8 );
|
||||
MakeOpcode1( RSQRT_S, 4*8 );
|
||||
MakeOpcode1( DIV_S, 6*8 );
|
||||
MakeOpcode1( SQRT_S, 6*8 );
|
||||
MakeOpcode1( RSQRT_S, 8*8 );
|
||||
MakeOpcode1( MULA_S, FPU_Mult );
|
||||
MakeOpcode1( MADD_S, FPU_Mult );
|
||||
MakeOpcode1( MSUB_S, FPU_Mult );
|
||||
|
@ -18,8 +18,6 @@
|
||||
#ifndef _R5900_OPCODETABLES_H
|
||||
#define _R5900_OPCODETABLES_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "PS2Etypes.h"
|
||||
|
||||
// TODO : Move these into the OpcodeTables namespace
|
||||
|
@ -120,10 +120,10 @@ namespace StateRecovery {
|
||||
// have likely been cleared out. So save from the Recovery buffer instead of
|
||||
// doing a "standard" save:
|
||||
|
||||
gzFile fileptr = gzopen( file.c_str(), "wb" );
|
||||
gzFile fileptr = gzopen( file.ToAscii().data(), "wb" );
|
||||
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;
|
||||
}
|
||||
gzwrite( fileptr, &g_SaveVersion, sizeof( u32 ) );
|
||||
@ -138,7 +138,7 @@ namespace StateRecovery {
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -187,9 +187,10 @@ namespace StateRecovery {
|
||||
}
|
||||
catch( Exception::RuntimeError& ex )
|
||||
{
|
||||
Msgbox::Alert(
|
||||
"Pcsx2 gamestate recovery failed. Some options may have been reverted to protect your game's state.\n"
|
||||
"Error: %s", params ex.cMessage() );
|
||||
Msgbox::Alert( wxsFormat( // fixme: this error needs proper translation stuffs.
|
||||
wxT("Pcsx2 gamestate recovery failed. Some options may have been reverted to protect your game's state.\n")
|
||||
wxT("Error: %s"), ex.DisplayMessage().c_str() )
|
||||
);
|
||||
safe_delete( g_RecoveryState );
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,6 @@
|
||||
#include "iR5900.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);
|
||||
|
||||
/* 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 ((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);
|
||||
spr0->madr += spr0->qwc << 4;
|
||||
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
|
||||
mfifotransferred += spr0->qwc;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -88,9 +87,11 @@ int _SPR0chain()
|
||||
return (spr0->qwc) * BIAS; // bus is 1/2 the ee speed
|
||||
}
|
||||
|
||||
#define SPR0chain() \
|
||||
cycles += _SPR0chain(); \
|
||||
__forceinline void SPR0chain()
|
||||
{
|
||||
_SPR0chain();
|
||||
spr0->qwc = 0;
|
||||
}
|
||||
|
||||
|
||||
void _SPR0interleave()
|
||||
@ -98,7 +99,6 @@ void _SPR0interleave()
|
||||
int qwc = spr0->qwc;
|
||||
int sqwc = psHu32(DMAC_SQWC) & 0xff;
|
||||
int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff;
|
||||
//int cycles = 0;
|
||||
u32 *pMem;
|
||||
|
||||
if (tqwc == 0) tqwc = qwc;
|
||||
@ -123,9 +123,8 @@ void _SPR0interleave()
|
||||
TestClearVUs(spr0->madr, spr0->qwc << 2);
|
||||
memcpy_fast((u8*)pMem, &PS2MEM_SCRATCH[spr0->sadr & 0x3fff], spr0->qwc << 4);
|
||||
}
|
||||
//cycles += tqwc * BIAS;
|
||||
spr0->sadr += spr0->qwc * 16;
|
||||
spr0->madr += (sqwc + spr0->qwc) * 16; //qwc-= sqwc;
|
||||
spr0->madr += (sqwc + spr0->qwc) * 16;
|
||||
}
|
||||
|
||||
spr0->qwc = 0;
|
||||
@ -142,15 +141,12 @@ static __forceinline void _dmaSPR0()
|
||||
// Transfer Dn_QWC from SPR to Dn_MADR
|
||||
if ((spr0->chcr & 0xc) == 0x0) // Normal Mode
|
||||
{
|
||||
int cycles = 0;
|
||||
SPR0chain();
|
||||
spr0finished = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
else if ((spr0->chcr & 0xc) == 0x4)
|
||||
{
|
||||
int cycles = 0;
|
||||
u32 *ptag;
|
||||
int id;
|
||||
bool done = FALSE;
|
||||
@ -166,7 +162,6 @@ static __forceinline void _dmaSPR0()
|
||||
spr0->sadr += 16;
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
|
||||
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
|
||||
@ -200,7 +195,6 @@ static __forceinline void _dmaSPR0()
|
||||
{
|
||||
//Console::WriteLn("SPR0 TIE");
|
||||
done = TRUE;
|
||||
spr0->qwc = 0;
|
||||
}
|
||||
|
||||
spr0finished = (done) ? 1 : 0;
|
||||
@ -208,9 +202,7 @@ static __forceinline void _dmaSPR0()
|
||||
if (!done)
|
||||
{
|
||||
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); //spr0->qwc / BIAS);
|
||||
spr0->qwc = 0;
|
||||
CPU_INT(8, ((u16)ptag[0]) / BIAS); // the lower 16bits of the tag / BIAS);
|
||||
return;
|
||||
}
|
||||
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
@ -226,23 +218,27 @@ void SPRFROMinterrupt()
|
||||
{
|
||||
_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");
|
||||
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);
|
||||
mfifoGIFtransfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
}
|
||||
else
|
||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
|
||||
if ((psHu32(DMAC_CTRL) & 0xC) == 0xC) // GIF MFIFO
|
||||
{
|
||||
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area");
|
||||
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);
|
||||
mfifoGIFtransfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
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");
|
||||
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);
|
||||
mfifoVIF1transfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (spr0finished == 0) return;
|
||||
spr0->chcr &= ~0x100;
|
||||
hwDmacIrq(8);
|
||||
@ -289,9 +285,11 @@ int _SPR1chain()
|
||||
return (spr1->qwc) * BIAS;
|
||||
}
|
||||
|
||||
#define SPR1chain() \
|
||||
cycles += _SPR1chain(); \
|
||||
spr1->qwc = 0;
|
||||
__forceinline void SPR1chain()
|
||||
{
|
||||
_SPR1chain();
|
||||
spr1->qwc = 0;
|
||||
}
|
||||
|
||||
|
||||
void _SPR1interleave()
|
||||
@ -299,7 +297,6 @@ void _SPR1interleave()
|
||||
int qwc = spr1->qwc;
|
||||
int sqwc = psHu32(DMAC_SQWC) & 0xff;
|
||||
int tqwc = (psHu32(DMAC_SQWC) >> 16) & 0xff;
|
||||
//int cycles = 0;
|
||||
u32 *pMem;
|
||||
|
||||
if (tqwc == 0) tqwc = qwc;
|
||||
@ -313,8 +310,7 @@ void _SPR1interleave()
|
||||
pMem = (u32*)dmaGetAddr(spr1->madr);
|
||||
memcpy_fast(&PS2MEM_SCRATCH[spr1->sadr & 0x3fff], (u8*)pMem, spr1->qwc << 4);
|
||||
spr1->sadr += spr1->qwc * 16;
|
||||
//cycles += spr1->qwc * BIAS;
|
||||
spr1->madr += (sqwc + spr1->qwc) * 16; //qwc-= sqwc;
|
||||
spr1->madr += (sqwc + spr1->qwc) * 16;
|
||||
}
|
||||
|
||||
spr1->qwc = 0;
|
||||
@ -325,7 +321,7 @@ void _dmaSPR1() // toSPR work function
|
||||
{
|
||||
if ((spr1->chcr & 0xc) == 0) // Normal Mode
|
||||
{
|
||||
int cycles = 0;
|
||||
//int cycles = 0;
|
||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||
SPR1chain();
|
||||
spr1finished = 1;
|
||||
@ -333,7 +329,6 @@ void _dmaSPR1() // toSPR work function
|
||||
}
|
||||
else if ((spr1->chcr & 0xc) == 0x4)
|
||||
{
|
||||
int cycles = 0;
|
||||
u32 *ptag;
|
||||
int id;
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
@ -381,7 +376,6 @@ void _dmaSPR1() // toSPR work function
|
||||
SPR_LOG("dmaIrq Set");
|
||||
|
||||
//Console::WriteLn("SPR1 TIE");
|
||||
spr1->qwc = 0;
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
@ -389,9 +383,7 @@ void _dmaSPR1() // toSPR work function
|
||||
if (!done)
|
||||
{
|
||||
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));// spr1->qwc / BIAS);
|
||||
spr1->qwc = 0;
|
||||
CPU_INT(9, (((u16)ptag[0]) / BIAS));// the lower 16 bits of the tag / BIAS);
|
||||
}
|
||||
}
|
||||
else // Interleave Mode
|
||||
@ -408,7 +400,7 @@ void dmaSPR1() // toSPR
|
||||
spr1->chcr, spr1->madr, spr1->qwc,
|
||||
spr1->tadr, spr1->sadr);
|
||||
|
||||
if ((spr1->chcr & 0xc) == 0x4 && spr1->qwc == 0)
|
||||
if (((spr1->chcr & 0xc) == 0x4) && (spr1->qwc == 0))
|
||||
{
|
||||
u32 *ptag;
|
||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
|
@ -76,25 +76,25 @@ public:
|
||||
static const int DefaultChunkSize = 0x1000 * sizeof(T);
|
||||
|
||||
public:
|
||||
const std::string Name; // user-assigned block name
|
||||
const wxString Name; // user-assigned block name
|
||||
int ChunkSize;
|
||||
|
||||
protected:
|
||||
T* m_ptr;
|
||||
int m_size; // size of the allocation of memory
|
||||
|
||||
const static std::string m_str_Unnamed;
|
||||
const static wxString m_str_Unnamed;
|
||||
|
||||
protected:
|
||||
// Internal constructor for use by derived classes. This allows a derived class to
|
||||
// use its own memory allocation (with an aligned memory, for example).
|
||||
// Throws:
|
||||
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
|
||||
explicit SafeArray( const std::string& name, T* allocated_mem, int initSize ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( allocated_mem )
|
||||
, m_size( initSize )
|
||||
explicit SafeArray( const wxString& name, T* allocated_mem, int initSize ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( allocated_mem )
|
||||
, m_size( initSize )
|
||||
{
|
||||
if( m_ptr == NULL )
|
||||
throw Exception::OutOfMemory();
|
||||
@ -111,19 +111,37 @@ public:
|
||||
safe_free( m_ptr );
|
||||
}
|
||||
|
||||
explicit SafeArray( const std::string& name="Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, m_size( 0 )
|
||||
explicit SafeArray( const wxString& name=wxT("Unnamed") ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, m_size( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeArray( int initialSize, const std::string& name="Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
|
||||
, m_size( initialSize )
|
||||
explicit SafeArray( const char* name ) :
|
||||
Name( wxString::FromAscii(name) )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, 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 )
|
||||
throw Exception::OutOfMemory();
|
||||
@ -145,9 +163,11 @@ public:
|
||||
if( m_ptr == NULL )
|
||||
{
|
||||
throw Exception::OutOfMemory(
|
||||
"Out-of-memory on block re-allocation. "
|
||||
"Old size: " + to_string( m_size ) + " bytes, "
|
||||
"New size: " + to_string( newalloc ) + " bytes"
|
||||
wxsFormat( // english (for diagnostic)
|
||||
wxT("Out-of-memory on SafeArray block re-allocation.\n")
|
||||
wxT("Old size: %d bytes, New size: %d bytes."),
|
||||
m_size, newalloc
|
||||
)
|
||||
);
|
||||
}
|
||||
m_size = newalloc;
|
||||
@ -181,15 +201,8 @@ protected:
|
||||
T* _getPtr( uint i ) const
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if( i >= (uint)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) + ")"
|
||||
);
|
||||
}
|
||||
if( IsDevBuild && i >= (uint)m_size )
|
||||
throw Exception::IndexBoundsFault( Name, i, m_size );
|
||||
#endif
|
||||
return &m_ptr[i];
|
||||
}
|
||||
@ -206,7 +219,7 @@ public:
|
||||
static const int DefaultChunkSize = 0x80 * sizeof(T);
|
||||
|
||||
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.
|
||||
|
||||
protected:
|
||||
@ -214,7 +227,7 @@ protected:
|
||||
int m_allocsize; // size of the allocation of memory
|
||||
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:
|
||||
virtual T* _virtual_realloc( int newsize )
|
||||
@ -224,17 +237,8 @@ protected:
|
||||
|
||||
void _boundsCheck( uint i ) const
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if( i >= (uint)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
|
||||
if( IsDevBuild && i >= (uint)m_length )
|
||||
throw Exception::IndexBoundsFault( Name, i, m_length );
|
||||
}
|
||||
|
||||
public:
|
||||
@ -242,7 +246,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeList( const std::string& name="Unnamed" ) :
|
||||
explicit SafeList( const wxString& name=wxT("Unnamed") ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, 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 )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
|
||||
@ -262,6 +275,17 @@ public:
|
||||
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
|
||||
// mapped items only. The actual size of the allocation may differ.
|
||||
int GetLength() const { return m_length; }
|
||||
@ -281,9 +305,12 @@ public:
|
||||
if( m_ptr == NULL )
|
||||
{
|
||||
throw Exception::OutOfMemory(
|
||||
"Out-of-memory on list re-allocation. "
|
||||
"Old size: " + to_string( m_allocsize ) + " bytes, "
|
||||
"New size: " + to_string( newalloc ) + " bytes"
|
||||
// English Diagonstic message:
|
||||
wxsFormat(
|
||||
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;
|
||||
@ -350,12 +377,12 @@ protected:
|
||||
|
||||
// Appends "(align: xx)" to the name of the allocation in devel builds.
|
||||
// Maybe useful,maybe not... no harm in attaching it. :D
|
||||
string _getName( const string& src )
|
||||
wxString _getName( const wxString& src )
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
return src + "(align:" + to_string(Alignment) + ")";
|
||||
#endif
|
||||
return src;
|
||||
if( IsDevBuild )
|
||||
return src + wxsFormat( wxT("(align: %d)"), Alignment );
|
||||
else
|
||||
return src;
|
||||
}
|
||||
|
||||
public:
|
||||
@ -365,12 +392,17 @@ public:
|
||||
// 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 )
|
||||
{
|
||||
}
|
||||
|
||||
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(
|
||||
_getName(name),
|
||||
(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
|
||||
{
|
||||
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
|
||||
|
@ -6,7 +6,7 @@
|
||||
// The profiler does not have a Linux version yet.
|
||||
// So for now we turn it into duds for non-Win32 platforms.
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef WIN32
|
||||
|
||||
void ProfilerInit();
|
||||
void ProfilerTerm();
|
||||
|
@ -50,16 +50,15 @@ static void PostLoadPrep()
|
||||
|
||||
wxString SaveState::GetFilename( int slot )
|
||||
{
|
||||
wxString arrgh;
|
||||
arrgh.Printf( "%8.8X.%3.3d", ElfCRC, slot );
|
||||
return Path::Combine( SSTATES_DIR, arrgh );
|
||||
return (g_Conf.Folders.Savestates +
|
||||
wxsFormat( wxT("%8.8X.%3.3d"), ElfCRC, slot )).GetFullPath();
|
||||
}
|
||||
|
||||
SaveState::SaveState( const char* msg, const wxString& destination ) :
|
||||
m_version( g_SaveVersion )
|
||||
, 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 )
|
||||
@ -92,7 +91,10 @@ void SaveState::FreezeTag( const char* src )
|
||||
if( strcmp( m_tagspace.GetPtr(), src ) != 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
|
||||
// work fine, but some games are very picky).
|
||||
|
||||
char descout[128], descin[128];
|
||||
memzero_obj( descout );
|
||||
IsBIOS( Config.Bios, descout );
|
||||
memcpy_fast( descin, descout, 128 );
|
||||
char descin[128];
|
||||
wxString descout;
|
||||
IsBIOS( g_Conf.Files.Bios(), descout );
|
||||
memcpy_fast( descin, descout.ToAscii().data(), 128 );
|
||||
Freeze( descin );
|
||||
|
||||
if( memcmp( descin, descout, 128 ) != 0 )
|
||||
@ -117,7 +119,7 @@ void SaveState::FreezeAll()
|
||||
"\n\tWarning: BIOS Version Mismatch, savestate may be unstable!\n"
|
||||
"\t\tCurrent 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 ) :
|
||||
gzBaseStateInfo( "Saving state to: ", filename )
|
||||
{
|
||||
m_file = gzopen(filename.c_str(), "wb");
|
||||
m_file = gzopen(filename.ToAscii().data(), "wb");
|
||||
if( m_file == NULL )
|
||||
throw Exception::FileNotFound();
|
||||
|
||||
@ -217,7 +219,7 @@ gzSavingState::gzSavingState( const wxString& filename ) :
|
||||
gzLoadingState::gzLoadingState( const wxString& filename ) :
|
||||
gzBaseStateInfo( "Loading state from: ", filename )
|
||||
{
|
||||
m_file = gzopen(filename.c_str(), "rb");
|
||||
m_file = gzopen(filename.ToAscii().data(), "rb");
|
||||
if( m_file == NULL )
|
||||
throw Exception::FileNotFound();
|
||||
|
||||
@ -299,9 +301,9 @@ void gzLoadingState::FreezePlugin( const char* name, s32 (CALLBACK *freezer)(int
|
||||
// uncompressed to/from memory state saves implementation
|
||||
|
||||
memBaseStateInfo::memBaseStateInfo( SafeArray<u8>& memblock, const char* msg ) :
|
||||
SaveState( msg, "Memory" )
|
||||
, m_memory( memblock )
|
||||
, m_idx( 0 )
|
||||
SaveState( msg, wxT("Memory") )
|
||||
, m_memory( memblock )
|
||||
, m_idx( 0 )
|
||||
{
|
||||
// Always clear the MTGS thread state.
|
||||
mtgsWaitGS();
|
||||
@ -376,7 +378,7 @@ void memLoadingState::FreezePlugin( const char* name, s32 (CALLBACK *freezer)(in
|
||||
if( ( fP.size + m_idx ) > m_memory.GetSizeInBytes() )
|
||||
{
|
||||
assert(0);
|
||||
throw Exception::BadSavedState( "memory" );
|
||||
throw Exception::BadSavedState( wxT("memory") );
|
||||
}
|
||||
|
||||
fP.data = ((s8*)m_memory.GetPtr()) + m_idx;
|
||||
|
@ -217,4 +217,5 @@ namespace StateRecovery
|
||||
extern void Clear();
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -34,7 +34,7 @@ bool States_isSlotUsed(int num)
|
||||
if (ElfCRC == 0)
|
||||
return false;
|
||||
else
|
||||
return Path::isFile(SaveState::GetFilename( num ));
|
||||
return wxFileExists( SaveState::GetFilename( num ) );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -62,11 +62,11 @@ void States_Load( const wxString& file )
|
||||
try
|
||||
{
|
||||
_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)
|
||||
{
|
||||
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
|
||||
// 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 )
|
||||
{
|
||||
// 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(
|
||||
"Encountered an error while loading savestate from file: %s.\n", file.c_str() ) );
|
||||
|
||||
if( g_EmulationInProgress )
|
||||
message += "Since the savestate load was incomplete, the emulator must reset.\n";
|
||||
|
||||
message += "\nError: " + ex.Message();
|
||||
|
||||
Msgbox::Alert( message.c_str() );
|
||||
Msgbox::Alert(
|
||||
wxsFormat( _("Error loading savestate from file: %s"), file.c_str() ) +
|
||||
L"\n\n" + _("Error details:") + ex.DisplayMessage()
|
||||
);
|
||||
SysReset();
|
||||
return;
|
||||
}
|
||||
@ -94,9 +90,9 @@ void States_Load( const wxString& file )
|
||||
|
||||
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 );
|
||||
return;
|
||||
@ -105,11 +101,11 @@ void States_Load(int num)
|
||||
try
|
||||
{
|
||||
_loadStateOrExcept( file );
|
||||
HostGui::Notice( fmt_string( "*PCSX2*: Loaded State %d", num ) );
|
||||
HostGui::Notice( wxsFormat( _("Loaded State %d"), num ) );
|
||||
}
|
||||
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
|
||||
// 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 )
|
||||
{
|
||||
// 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(
|
||||
"Encountered an error while loading savestate from slot %d.\n", num ) );
|
||||
Msgbox::Alert(
|
||||
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();
|
||||
return;
|
||||
}
|
||||
@ -144,13 +137,23 @@ void States_Save( const wxString& file )
|
||||
try
|
||||
{
|
||||
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 )
|
||||
{
|
||||
Console::Error( (fmt_string(
|
||||
"An error occurred while trying to save to file %s\n", file.c_str() ) +
|
||||
"Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str()
|
||||
// TODO: Implement a "pause the action and issue a popup" thing here.
|
||||
// *OR* some kind of GS overlay... [for now we use the console]
|
||||
|
||||
// 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
|
||||
{
|
||||
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 )
|
||||
{
|
||||
Console::Error( (fmt_string(
|
||||
"An error occurred while trying to save to slot %d\n", num ) +
|
||||
"Your emulation state has not been saved!\n\nError: " + ex.Message()).c_str()
|
||||
);
|
||||
// TODO: Implement a "pause the action and issue a popup" thing here.
|
||||
// *OR* some kind of GS overlay... [for now we use the console]
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define sif0dma ((DMACh*)&PS2MEM_HW[0xc000])
|
||||
#define sif1dma ((DMACh*)&PS2MEM_HW[0xc400])
|
||||
#define sif2dma ((DMACh*)&PS2MEM_HW[0xc800])
|
||||
|
||||
DMACh *sif0ch;
|
||||
DMACh *sif1ch;
|
||||
DMACh *sif2ch;
|
||||
@ -206,7 +202,10 @@ __forceinline void SIF0Dma()
|
||||
//SIF_LOG(" EE SIF doing transfer %04Xqw to %08X", readSize, sif0dma->madr);
|
||||
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);
|
||||
|
||||
@ -285,7 +284,12 @@ __forceinline void SIF1Dma()
|
||||
{
|
||||
// Process DMA tag at sif1dma->tadr
|
||||
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->qwc = (u16)ptag[0];
|
||||
|
||||
@ -348,7 +352,10 @@ __forceinline void SIF1Dma()
|
||||
int qwTransfer = sif1dma->qwc;
|
||||
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
|
||||
qwTransfer = (FIFO_SIF1_W - sif1.fifoSize) / 4;
|
||||
|
@ -152,7 +152,6 @@ void SIO_CommandWrite(u8 value,int way) {
|
||||
case 3:
|
||||
// No pad connected.
|
||||
sio.parp++;
|
||||
sio.bufcount = 6;
|
||||
if (sio.parp == sio.bufcount) { sio.padst = 0; return; }
|
||||
SIO_INT();
|
||||
return;
|
||||
@ -451,16 +450,16 @@ void SIO_CommandWrite(u8 value,int way) {
|
||||
break;
|
||||
case 0x21:
|
||||
// Set pad slot.
|
||||
sio.mtapst = 0x21;
|
||||
sio.mtapst = value;
|
||||
sio.bufcount = 6; // No idea why this is 6, saved from old code.
|
||||
break;
|
||||
case 0x22:
|
||||
// Set memcard slot.
|
||||
sio.mtapst = 0x22;
|
||||
sio.mtapst = value;
|
||||
sio.bufcount = 6; // No idea why this is 6, saved from old code.
|
||||
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]=0;//'Z';
|
||||
return;
|
||||
@ -508,7 +507,7 @@ void InitializeSIO(u8 value)
|
||||
sio.StatReg &= ~TX_EMPTY; // Now the Buffer is not empty
|
||||
sio.StatReg |= RX_RDY; // Transfer is Ready
|
||||
|
||||
sio.bufcount = 2;
|
||||
sio.bufcount = 4; // Default size, when no pad connected.
|
||||
sio.parp = 0;
|
||||
sio.padst = 1;
|
||||
sio.packetsize = 1;
|
||||
@ -517,7 +516,7 @@ void InitializeSIO(u8 value)
|
||||
|
||||
switch (sio.CtrlReg&0x2002) {
|
||||
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.
|
||||
sio2.packet.recvVal1 = 0x1D100;
|
||||
sio.padst = 3;
|
||||
@ -527,7 +526,7 @@ void InitializeSIO(u8 value)
|
||||
}
|
||||
break;
|
||||
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.
|
||||
sio2.packet.recvVal1 = 0x1D100;
|
||||
sio.padst = 3;
|
||||
@ -554,6 +553,7 @@ void InitializeSIO(u8 value)
|
||||
int port = sio.GetMultitapPort();
|
||||
if (!IsMtapPresent(port))
|
||||
{
|
||||
// If "unplug" multitap mid game, set active slots to 0.
|
||||
sio.activePadSlot[port] = 0;
|
||||
sio.activeMemcardSlot[port] = 0;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ void __Log( const char* fmt, ... )
|
||||
assert( 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.
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ static __forceinline void _vSourceLog( u16 protocol, u8 source, u32 cpuPc, u32 c
|
||||
assert( 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.
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
#include "IopCommon.h"
|
||||
#include "Stats.h"
|
||||
|
||||
#include "Paths.h"
|
||||
|
||||
void statsOpen() {
|
||||
stats.vsyncCount = 0;
|
||||
stats.vsyncTime = time(NULL);
|
||||
|
@ -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 wxSize& src, const wxString& separator=wxT(",") );
|
||||
|
@ -37,12 +37,6 @@ SessionOverrideFlags g_Session = {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.
|
||||
// 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
|
||||
@ -172,16 +166,16 @@ bool SysAllocateMem()
|
||||
psxMemAlloc();
|
||||
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
|
||||
// completely non-functional. If the failure is in the VM build then we can try running
|
||||
// the VTLB build instead. If it's the VTLB build then ... ouch.
|
||||
|
||||
// VTLB build must fail outright...
|
||||
Msgbox::Alert( "Failed to allocate memory needed to run pcsx2.\n\nError: %s", params ex.cMessage() );
|
||||
// completely non-functional.
|
||||
|
||||
//Msgbox::Alert( "Failed to allocate memory needed to run pcsx2.\n\nError: %s", params ex.cMessage() );
|
||||
SysShutdownMem();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -207,14 +201,17 @@ void SysAllocateDynarecs()
|
||||
recCpu.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"
|
||||
"%s"
|
||||
"\n\nThe EE/IOP interpreter will be used instead (slow!).", params
|
||||
ex.cMessage()
|
||||
);
|
||||
);*/
|
||||
|
||||
g_Session.ForceDisableEErec = true;
|
||||
|
||||
@ -226,14 +223,19 @@ void SysAllocateDynarecs()
|
||||
{
|
||||
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(
|
||||
"The VU0 recompiler failed to initialize with the following error:\n\n"
|
||||
"%s"
|
||||
"\n\nThe VU0 interpreter will be used for this session (may slow down some games).", params
|
||||
ex.cMessage()
|
||||
);
|
||||
*/
|
||||
|
||||
g_Session.ForceDisableVU0rec = true;
|
||||
VU0micro::recShutdown();
|
||||
@ -243,14 +245,19 @@ void SysAllocateDynarecs()
|
||||
{
|
||||
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(
|
||||
"The VU1 recompiler failed to initialize with the following error:\n\n"
|
||||
"%s"
|
||||
"\n\nThe VU1 interpreter will be used for this session (will slow down most games).", params
|
||||
ex.cMessage()
|
||||
);
|
||||
*/
|
||||
|
||||
g_Session.ForceDisableVU1rec = true;
|
||||
VU1micro::recShutdown();
|
||||
@ -362,7 +369,7 @@ void SysExecute()
|
||||
}
|
||||
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() );
|
||||
}
|
||||
}
|
||||
@ -383,7 +390,7 @@ void SysEndExecution()
|
||||
// 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.
|
||||
// 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 )
|
||||
{
|
||||
@ -393,22 +400,21 @@ void SysPrepareExecution( const char* elf_file, bool use_bios )
|
||||
}
|
||||
catch( Exception::BaseException& ex )
|
||||
{
|
||||
Msgbox::Alert( ex.cMessage() );
|
||||
Msgbox::Alert( ex.DisplayMessage() );
|
||||
return;
|
||||
}
|
||||
|
||||
if (OpenPlugins(NULL) == -1)
|
||||
return;
|
||||
|
||||
if( elf_file == NULL )
|
||||
if( elf_file.IsEmpty() )
|
||||
{
|
||||
if( !StateRecovery::HasState() )
|
||||
{
|
||||
// Not recovering a state, so need to execute the bios and load the ELF information.
|
||||
// (note: gsRecoveries are done from ExecuteCpu)
|
||||
|
||||
char ename[g_MaxPath];
|
||||
ename[0] = 0;
|
||||
wxString ename;
|
||||
if( !use_bios )
|
||||
GetPS2ElfName( ename );
|
||||
|
||||
@ -440,8 +446,8 @@ void SysReset()
|
||||
// so the status bar won't receive the WM_PAINT messages needed to update itself anyway.
|
||||
// Oops! (air)
|
||||
|
||||
HostGui::Notice("Resetting...");
|
||||
Console::SetTitle("Resetting...");
|
||||
HostGui::Notice( _("Resetting...") );
|
||||
Console::SetTitle( _("Resetting...") );
|
||||
|
||||
g_EmulationInProgress = false;
|
||||
StateRecovery::Clear();
|
||||
@ -454,8 +460,8 @@ void SysReset()
|
||||
// Note : No need to call cpuReset() here. It gets called automatically before the
|
||||
// emulator resumes execution.
|
||||
|
||||
HostGui::Notice("Ready");
|
||||
Console::SetTitle("*PCSX2* Emulation state is reset.");
|
||||
HostGui::Notice( _("Ready") );
|
||||
Console::SetTitle( _("Emulation state is reset.") );
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 ); }
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "PS2Etypes.h"
|
||||
#include "Pcsx2Config.h"
|
||||
#include "Paths.h"
|
||||
#include "SafeArray.h"
|
||||
#include "Misc.h"
|
||||
#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.
|
||||
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.
|
||||
// The allocated block has code execution privileges.
|
||||
// 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 SysClearExecutionCache(); // clears recompiled execution caches!
|
||||
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
|
||||
// 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();
|
||||
|
||||
|
||||
// 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
|
||||
// allocation is below a certain memory address (specified in "bounds" parameter).
|
||||
// The allocated block has code execution privileges.
|
||||
@ -183,6 +167,16 @@ namespace Console
|
||||
// Newline is automatically appended.
|
||||
extern bool Status( const char* fmt, VARG_PARAM dummy, ... );
|
||||
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
|
||||
@ -193,12 +187,11 @@ namespace Msgbox
|
||||
{
|
||||
// Pops up an alert Dialog Box with a singular "OK" button.
|
||||
// Always returns false. Replacement for SysMessage.
|
||||
extern bool Alert( const char* fmt, VARG_PARAM dummy, ... );
|
||||
extern bool Alert( const char* text );
|
||||
extern bool Alert( const wxString& text );
|
||||
|
||||
// Pops up a dialog box with Ok/Cancel buttons. Returns the result of the inquiry,
|
||||
// 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;
|
||||
@ -209,35 +202,4 @@ using Console::Color_Cyan;
|
||||
using Console::Color_Yellow;
|
||||
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__ */
|
||||
|
46
pcsx2/Utilities/AsciiFile.h
Normal file
46
pcsx2/Utilities/AsciiFile.h
Normal 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 ) );
|
||||
}
|
||||
|
||||
};
|
29
pcsx2/Utilities/FileUtils.cpp
Normal file
29
pcsx2/Utilities/FileUtils.cpp
Normal 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() );
|
||||
}
|
7
pcsx2/Utilities/folderdesc.txt
Normal file
7
pcsx2/Utilities/folderdesc.txt
Normal 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)
|
@ -38,26 +38,6 @@ using namespace R5900;
|
||||
|
||||
#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
|
||||
void vu0ResetRegs()
|
||||
{
|
||||
|
@ -38,27 +38,6 @@ u32 vudump = 0;
|
||||
|
||||
#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
|
||||
void vu1ResetRegs()
|
||||
{
|
||||
|
@ -1585,7 +1585,7 @@ void _vuLQ(VURegs * VU) {
|
||||
if (_Ft_ == 0) return;
|
||||
|
||||
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);
|
||||
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 (_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);
|
||||
if (_X) VU->VF[_Ft_].UL[0] = ptr[0];
|
||||
if (_Y) VU->VF[_Ft_].UL[1] = ptr[1];
|
||||
@ -1614,7 +1614,7 @@ void _vuLQI(VURegs * VU) {
|
||||
u32 addr;
|
||||
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);
|
||||
if (_X) VU->VF[_Ft_].UL[0] = ptr[0];
|
||||
if (_Y) VU->VF[_Ft_].UL[1] = ptr[1];
|
||||
@ -1631,7 +1631,7 @@ void _vuSQ(VURegs * VU) {
|
||||
u32 *ptr;
|
||||
|
||||
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);
|
||||
if (_X) ptr[0] = VU->VF[_Fs_].UL[0];
|
||||
if (_Y) ptr[1] = VU->VF[_Fs_].UL[1];
|
||||
@ -1644,7 +1644,7 @@ void _vuSQD(VURegs * VU) {
|
||||
u32 *ptr;
|
||||
|
||||
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);
|
||||
if (_X) ptr[0] = VU->VF[_Fs_].UL[0];
|
||||
if (_Y) ptr[1] = VU->VF[_Fs_].UL[1];
|
||||
@ -1656,7 +1656,7 @@ void _vuSQI(VURegs * VU) {
|
||||
u32 addr;
|
||||
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);
|
||||
if (_X) ptr[0] = VU->VF[_Fs_].UL[0];
|
||||
if (_Y) ptr[1] = VU->VF[_Fs_].UL[1];
|
||||
@ -1673,7 +1673,7 @@ void _vuILW(VURegs * VU) {
|
||||
if (_Ft_ == 0) return;
|
||||
|
||||
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);
|
||||
if (_X) VU->VI[_Ft_].US[0] = ptr[0];
|
||||
if (_Y) VU->VI[_Ft_].US[0] = ptr[2];
|
||||
@ -1687,7 +1687,7 @@ void _vuISW(VURegs * VU) {
|
||||
u16 *ptr;
|
||||
|
||||
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);
|
||||
if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 0; }
|
||||
if (_Y) { ptr[2] = VU->VI[_Ft_].US[0]; ptr[3] = 0; }
|
||||
@ -1700,7 +1700,7 @@ void _vuILWR(VURegs * VU) {
|
||||
u16 *ptr;
|
||||
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);
|
||||
if (_X) VU->VI[_Ft_].US[0] = ptr[0];
|
||||
if (_Y) VU->VI[_Ft_].US[0] = ptr[2];
|
||||
@ -1712,7 +1712,7 @@ void _vuISWR(VURegs * VU) {
|
||||
u32 addr;
|
||||
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);
|
||||
if (_X) { ptr[0] = VU->VI[_Ft_].US[0]; ptr[1] = 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)
|
||||
{
|
||||
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)
|
||||
_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) {
|
||||
@ -2508,13 +2519,23 @@ void _vuRegsMTIR(VURegs * VU, _VURegsNum *VUregsn) {
|
||||
VUregsn->pipe = VUPIPE_FMAC;
|
||||
VUregsn->VFwrite = 0;
|
||||
VUregsn->VFread0 = _Fs_;
|
||||
VUregsn->VFr0xyzw= _XYZW;
|
||||
VUregsn->VFr0xyzw= 1 << (3-_Fsf_);
|
||||
VUregsn->VFread1 = 0;
|
||||
VUregsn->VIwrite = 1 << _Ft_;
|
||||
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) {
|
||||
VUregsn->pipe = VUPIPE_FMAC;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user