2009-09-08 12:08:10 +00:00
|
|
|
/* PCSX2 - PS2 Emulator for PCs
|
|
|
|
* Copyright (C) 2002-2009 PCSX2 Dev Team
|
2009-09-21 09:48:31 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* PCSX2 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.
|
2009-02-09 21:15:56 +00:00
|
|
|
*
|
2009-09-08 12:08:10 +00:00
|
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
2009-02-09 21:15:56 +00:00
|
|
|
*/
|
|
|
|
|
2009-08-04 08:21:10 +00:00
|
|
|
#pragma once
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
#include "Common.h"
|
2009-09-23 12:11:37 +00:00
|
|
|
#include "System/SysThreads.h"
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-10-05 02:15:49 +00:00
|
|
|
extern __aligned16 u8 g_RealGSMem[Ps2MemSize::GSregs];
|
2009-09-23 09:53:21 +00:00
|
|
|
|
|
|
|
#define PS2MEM_GS g_RealGSMem
|
|
|
|
#define PS2GS_BASE(mem) (g_RealGSMem+(mem&0x13ff))
|
|
|
|
|
|
|
|
#define GSCSRr ((u64&)*(g_RealGSMem+0x1000))
|
|
|
|
#define GSIMR ((u32&)*(g_RealGSMem+0x1010))
|
|
|
|
#define GSSIGLBLID ((GSRegSIGBLID&)*(g_RealGSMem+0x1080))
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-08-04 08:21:10 +00:00
|
|
|
enum GS_RegionMode
|
|
|
|
{
|
|
|
|
Region_NTSC,
|
|
|
|
Region_PAL
|
|
|
|
};
|
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
enum GIF_PATH
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-09-23 09:53:21 +00:00
|
|
|
GIF_PATH_1 = 0,
|
|
|
|
GIF_PATH_2,
|
|
|
|
GIF_PATH_3,
|
2009-02-09 21:15:56 +00:00
|
|
|
};
|
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
extern int GIFPath_ParseTag(GIF_PATH pathidx, const u8* pMem, u32 size);
|
|
|
|
extern void GIFPath_Reset();
|
|
|
|
extern void GIFPath_Clear( GIF_PATH pathidx );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
extern GS_RegionMode gsRegionMode;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// MTGS Threaded Class Declaration
|
|
|
|
|
|
|
|
// Uncomment this to enable the MTGS debug stack, which tracks to ensure reads
|
|
|
|
// and writes stay synchronized. Warning: the debug stack is VERY slow.
|
|
|
|
//#define RINGBUF_DEBUG_STACK
|
|
|
|
|
2009-11-21 07:56:29 +00:00
|
|
|
enum MTGS_RingCommand
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
2009-11-21 07:56:29 +00:00
|
|
|
GS_RINGTYPE_P1
|
2009-02-09 21:15:56 +00:00
|
|
|
, GS_RINGTYPE_P2
|
|
|
|
, GS_RINGTYPE_P3
|
2009-11-21 07:56:29 +00:00
|
|
|
, GS_RINGTYPE_MEMWRITE64
|
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
, GS_RINGTYPE_MEMWRITE8
|
|
|
|
, GS_RINGTYPE_MEMWRITE16
|
|
|
|
, GS_RINGTYPE_MEMWRITE32
|
2009-11-21 07:56:29 +00:00
|
|
|
|
|
|
|
, GS_RINGTYPE_RESTART
|
|
|
|
, GS_RINGTYPE_VSYNC
|
|
|
|
, GS_RINGTYPE_FRAMESKIP
|
2009-02-09 21:15:56 +00:00
|
|
|
, GS_RINGTYPE_FREEZE
|
|
|
|
, GS_RINGTYPE_RECORD
|
2009-11-21 07:56:29 +00:00
|
|
|
, GS_RINGTYPE_RESET // issues a GSreset() command.
|
|
|
|
, GS_RINGTYPE_SOFTRESET // issues a soft reset for the GIF
|
2009-02-09 21:15:56 +00:00
|
|
|
, GS_RINGTYPE_WRITECSR
|
2009-11-21 07:56:29 +00:00
|
|
|
, GS_RINGTYPE_MODECHANGE // for issued mode changes.
|
2009-09-23 09:53:21 +00:00
|
|
|
, GS_RINGTYPE_CRC
|
2009-11-21 07:56:29 +00:00
|
|
|
, GS_RINGTYPE_STARTTIME // special case for min==max fps frameskip settings
|
2009-02-09 21:15:56 +00:00
|
|
|
};
|
|
|
|
|
2009-09-16 17:23:02 +00:00
|
|
|
|
|
|
|
struct MTGS_FreezeData
|
|
|
|
{
|
|
|
|
freezeData* fdata;
|
|
|
|
s32 retval; // value returned from the call, valid only after an mtgsWaitGS()
|
|
|
|
};
|
|
|
|
|
2009-11-23 06:54:24 +00:00
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
// SysMtgsThread
|
|
|
|
// --------------------------------------------------------------------------------------
|
|
|
|
class SysMtgsThread : public SysThreadBase
|
2009-02-09 21:15:56 +00:00
|
|
|
{
|
User Interface:
* Fixed and added better Emulation/System menu updating. Suspend/Resume is more consistent, and Reset grays itself out after being used.
* Entering plugin configurations auto-suspends the emulator.
* Changing plugins in the Configuration PAnel takes effect now without a restart.
* Added preliminary support for an ExtensibleConfirmation Dialog box (contains a sizer you can add content to, and also has an optional "[x] Do not show this again" checkbox).
Bugfixes:
* Added some mutex protection to cdvdNewDiskCB; "just in case."
* Resolved several recursion and deadlock scenarios when (very!) rapidly suspending, resuming, and resetting the emu.
Developments / Code Cleanups:
* Renamed SysCoreThread ExecutionModes: Suspend/Resume are now Opened/Closed (which more accurately reflects the fact they opena nd close the plugins, and helps avoid ambiguity with the "Paused" state).
* Added Exception::ThreadTimedOut, which is now thrown from Semaphore::Wait when recursive wxApp::Yield() calls are detected, and a deadlock occurs (basically cancels the current action which, most of the time, allows for full recovery).
* Major Threading namespace cleanups, documentations, etc.
* Removed wxScopedArray (scopedarray.h) and replaced it with a better implemeneted ScopedArray class.
* Removed toUTF8 class, which I only added a couple weeks ago because I didn't realize wxCharBuffer had an implicit typecast to (char*).
* Implemented more Source/Listener events for Pcsx2App. CoreThread events are sourced properly now, and added SettingsApplied and SettingsLoadSave Sources.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2010 96395faa-99c1-11dd-bbfe-3dabce05a288
2009-10-16 03:58:29 +00:00
|
|
|
typedef SysThreadBase _parent;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-24 08:43:36 +00:00
|
|
|
public:
|
|
|
|
// note: when m_RingPos == m_WritePos, the fifo is empty
|
|
|
|
uint m_RingPos; // cur pos gs is reading from
|
|
|
|
uint m_WritePos; // cur pos ee thread is writing to
|
|
|
|
|
|
|
|
volatile bool m_RingBufferIsBusy;
|
|
|
|
volatile u32 m_SignalRingEnable;
|
|
|
|
volatile s32 m_SignalRingPosition;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-24 22:49:05 +00:00
|
|
|
int m_QueuedFrameCount;
|
2009-11-24 08:43:36 +00:00
|
|
|
u32 m_RingWrapSpot;
|
|
|
|
|
|
|
|
Mutex m_lock_RingBufferBusy;
|
|
|
|
Semaphore m_sem_OnRingReset;
|
2009-09-21 09:48:31 +00:00
|
|
|
|
2009-07-03 06:05:48 +00:00
|
|
|
// used to keep multiple threads from sending packets to the ringbuffer concurrently.
|
2009-11-24 08:43:36 +00:00
|
|
|
// (currently not used or implemented -- is a planned feature for a future threaded VU1)
|
|
|
|
//MutexLockRecursive m_PacketLocker;
|
2009-09-21 09:48:31 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
// Used to delay the sending of events. Performance is better if the ringbuffer
|
|
|
|
// has more than one command in it when the thread is kicked.
|
2009-11-24 08:43:36 +00:00
|
|
|
int m_CopyDataTally;
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-24 08:43:36 +00:00
|
|
|
Semaphore m_sem_OpenDone;
|
|
|
|
volatile bool m_PluginOpened;
|
2009-02-20 04:36:55 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
// These vars maintain instance data for sending Data Packets.
|
|
|
|
// Only one data packet can be constructed and uploaded at a time.
|
|
|
|
|
2009-11-24 08:43:36 +00:00
|
|
|
uint m_packet_size; // size of the packet (data only, ie. not including the 16 byte command!)
|
|
|
|
uint m_packet_ringpos; // index of the data location in the ringbuffer.
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
#ifdef RINGBUF_DEBUG_STACK
|
2009-10-31 19:18:29 +00:00
|
|
|
Threading::Mutex m_lock_Stack;
|
2009-02-09 21:15:56 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
public:
|
2009-11-23 06:54:24 +00:00
|
|
|
SysMtgsThread();
|
|
|
|
virtual ~SysMtgsThread() throw();
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-23 06:54:24 +00:00
|
|
|
static SysMtgsThread& Get();
|
2009-10-23 20:24:59 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
// Waits for the GS to empty out the entire ring buffer contents.
|
|
|
|
// Used primarily for plugin startup/shutdown.
|
|
|
|
void WaitGS();
|
2009-09-23 09:53:21 +00:00
|
|
|
void ResetGS();
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-09-15 06:24:41 +00:00
|
|
|
int PrepDataPacket( GIF_PATH pathidx, const u8* srcdata, u32 size );
|
2009-02-09 21:15:56 +00:00
|
|
|
int PrepDataPacket( GIF_PATH pathidx, const u32* srcdata, u32 size );
|
|
|
|
void SendDataPacket();
|
2009-09-23 09:53:21 +00:00
|
|
|
void SendGameCRC( u32 crc );
|
|
|
|
void WaitForOpen();
|
|
|
|
void Freeze( int mode, MTGS_FreezeData& data );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
2009-11-24 17:13:07 +00:00
|
|
|
void RestartRingbuffer( uint packsize=0 );
|
2009-11-21 07:56:29 +00:00
|
|
|
void SendSimplePacket( MTGS_RingCommand type, int data0, int data1, int data2 );
|
|
|
|
void SendPointerPacket( MTGS_RingCommand type, u32 data0, void* data1 );
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
u8* GetDataPacketPtr() const;
|
|
|
|
void SetEvent();
|
2009-02-20 04:36:55 +00:00
|
|
|
void PostVsyncEnd( bool updategs );
|
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
protected:
|
2009-09-23 09:53:21 +00:00
|
|
|
void OpenPlugin();
|
2009-10-19 01:50:52 +00:00
|
|
|
void ClosePlugin();
|
|
|
|
|
|
|
|
void OnStart();
|
|
|
|
void OnResumeReady();
|
|
|
|
|
2009-09-23 09:53:21 +00:00
|
|
|
void OnSuspendInThread();
|
2009-10-07 19:20:11 +00:00
|
|
|
void OnPauseInThread() {}
|
|
|
|
void OnResumeInThread( bool IsSuspended );
|
2009-10-19 01:50:52 +00:00
|
|
|
void OnCleanupInThread();
|
2009-09-23 09:53:21 +00:00
|
|
|
|
2009-02-09 21:15:56 +00:00
|
|
|
// Used internally by SendSimplePacket type functions
|
|
|
|
uint _PrepForSimplePacket();
|
|
|
|
void _FinishSimplePacket( uint future_writepos );
|
2009-10-09 15:17:53 +00:00
|
|
|
void ExecuteTaskInThread();
|
2009-02-09 21:15:56 +00:00
|
|
|
};
|
|
|
|
|
2009-11-23 06:54:24 +00:00
|
|
|
// GetMtgsThread() is a required external implementation. This function is *NOT*
|
|
|
|
// provided by the PCSX2 core library. It provides an interface for the linking User
|
|
|
|
// Interface apps or DLLs to reference their own instance of SysMtgsThread (also allowing
|
|
|
|
// them to extend the class and override virtual methods).
|
|
|
|
//
|
|
|
|
SysMtgsThread& GetMTGS();
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Generalized GS Functions and Stuff
|
|
|
|
|
|
|
|
extern void gsInit();
|
|
|
|
extern s32 gsOpen();
|
|
|
|
extern void gsClose();
|
|
|
|
extern void gsReset();
|
|
|
|
extern void gsOnModeChanged( u32 framerate, u32 newTickrate );
|
2009-08-04 08:21:10 +00:00
|
|
|
extern void gsSetRegionMode( GS_RegionMode isPal );
|
2009-02-09 21:15:56 +00:00
|
|
|
extern void gsResetFrameSkip();
|
|
|
|
extern void gsSyncLimiterLostTime( s32 deltaTime );
|
|
|
|
extern void gsDynamicSkipEnable();
|
|
|
|
extern void gsPostVsyncEnd( bool updategs );
|
|
|
|
extern void gsFrameSkip( bool forceskip );
|
|
|
|
|
|
|
|
// Some functions shared by both the GS and MTGS
|
|
|
|
extern void _gs_ResetFrameskip();
|
|
|
|
extern void _gs_ChangeTimings( u32 framerate, u32 iTicks );
|
|
|
|
|
|
|
|
|
|
|
|
// used for resetting GIF fifo
|
2009-10-05 02:15:49 +00:00
|
|
|
extern void gsGIFReset();
|
|
|
|
extern void gsCSRwrite(u32 value);
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
extern void gsWrite8(u32 mem, u8 value);
|
|
|
|
extern void gsWrite16(u32 mem, u16 value);
|
|
|
|
extern void gsWrite32(u32 mem, u32 value);
|
|
|
|
|
|
|
|
extern void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value );
|
|
|
|
extern void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value );
|
|
|
|
extern void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value );
|
|
|
|
|
|
|
|
extern void __fastcall gsWrite128_page_00( u32 mem, const mem128_t* value );
|
|
|
|
extern void __fastcall gsWrite128_page_01( u32 mem, const mem128_t* value );
|
|
|
|
extern void __fastcall gsWrite128_generic( u32 mem, const mem128_t* value );
|
|
|
|
|
|
|
|
extern u8 gsRead8(u32 mem);
|
|
|
|
extern u16 gsRead16(u32 mem);
|
|
|
|
extern u32 gsRead32(u32 mem);
|
|
|
|
extern u64 gsRead64(u32 mem);
|
|
|
|
|
|
|
|
void gsIrq();
|
|
|
|
|
|
|
|
extern u32 CSRw;
|
|
|
|
extern u64 m_iSlowStart;
|
|
|
|
|
|
|
|
// GS Playback
|
2009-08-25 09:19:45 +00:00
|
|
|
enum gsrun
|
|
|
|
{
|
|
|
|
GSRUN_TRANS1 = 1,
|
|
|
|
GSRUN_TRANS2,
|
|
|
|
GSRUN_TRANS3,
|
|
|
|
GSRUN_VSYNC
|
|
|
|
};
|
2009-02-09 21:15:56 +00:00
|
|
|
|
|
|
|
#ifdef PCSX2_DEVBUILD
|
|
|
|
|
|
|
|
extern int g_SaveGSStream;
|
|
|
|
extern int g_nLeftGSFrames;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|