/[pcsx2_0.9.7]/trunk/pcsx2/GS.h
ViewVC logotype

Annotation of /trunk/pcsx2/GS.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (hide annotations) (download)
Tue Sep 7 11:08:22 2010 UTC (9 years, 5 months ago) by william
File MIME type: text/plain
File size: 12879 byte(s)
Auto Commited Import of: pcsx2-0.9.7-r3738-debug in ./trunk
1 william 31 /* PCSX2 - PS2 Emulator for PCs
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16     #pragma once
17    
18     #include "Common.h"
19     #include "System/SysThreads.h"
20    
21     extern __aligned16 u8 g_RealGSMem[Ps2MemSize::GSregs];
22    
23 william 62 enum CSR_FifoState
24 william 31 {
25 william 62 CSR_FIFO_NORMAL = 0, // Somwhere in between (Neither empty or almost full).
26     CSR_FIFO_EMPTY, // Empty
27     CSR_FIFO_FULL, // Almost Full
28     CSR_FIFO_RESERVED // Reserved / Unused.
29 william 31 };
30    
31 william 62 // --------------------------------------------------------------------------------------
32     // tGS_CSR
33     // --------------------------------------------------------------------------------------
34     // This is the Control Register for the GS. It is a dual-instance register that returns
35     // distinctly different values for most fields when read and written. In PCSX2 we house
36     // the written version in the gsRegs buffer, and generate the readback version on-demand
37     // from various other PCSX2 system statuses.
38     union tGS_CSR
39 william 31 {
40 william 62 struct
41     {
42     // Write:
43     // 0 - No action;
44     // 1 - Old event is cleared and event is enabled.
45     // Read:
46     // 0 - No SIGNAL pending.
47     // 1 - SIGNAL has been generated.
48     u64 SIGNAL :1;
49 william 31
50 william 62 // Write:
51     // 0 - No action;
52     // 1 - FINISH event is enabled.
53     // Read:
54     // 0 - No FINISH event pending.
55     // 1 - FINISH event has been generated.
56     u64 FINISH :1;
57 william 31
58 william 62 // Hsync Interrupt Control
59     // Write:
60     // 0 - No action;
61     // 1 - Hsync interrupt is enabled.
62     // Read:
63     // 0 - No Hsync interrupt pending.
64     // 1 - Hsync interrupt has been generated.
65     u64 HSINT :1;
66 william 31
67 william 62 // Vsync Interrupt Control
68     // Write:
69     // 0 - No action;
70     // 1 - Vsync interrupt is enabled.
71     // Read:
72     // 0 - No Vsync interrupt pending.
73     // 1 - Vsync interrupt has been generated.
74     u64 VSINT :1;
75    
76     // Rect Area Write Termination Control
77     // 0 - No action;
78     // 1 - Rect area write interrupt is enabled.
79     // Read:
80     // 0 - No RAWrite interrupt pending.
81     // 1 - RAWrite interrupt has been generated.
82     u64 EDWINT :1;
83    
84     u64 _zero1 :1;
85     u64 _zero2 :1;
86     u64 pad1 :1;
87    
88     // FLUSH (write-only!)
89     // Write:
90     // 0 - Resume drawing if suspended (?)
91     // 1 - Flush the GS FIFO and suspend drawing
92     // Read: Always returns 0. (?)
93     u64 FLUSH :1;
94    
95     // RESET (write-only!)
96     // Write:
97     // 0 - Do nothing.
98     // 1 - GS soft system reset. Clears FIFOs and resets IMR to all 1's.
99     // (PCSX2 implementation also clears GIFpaths, though that behavior may differ on real HW).
100     // Read: Always returns 0. (?)
101     u64 RESET :1;
102    
103     u64 _pad2 :2;
104    
105     // (I have no idea what this reg is-- air)
106     // Output value is updated by sampling the VSync. (?)
107     u64 NFIELD :1;
108    
109     // Current Field of Display [page flipping] (read-only?)
110     // 0 - EVEN
111     // 1 - ODD
112     u64 FIELD :1;
113    
114     // GS FIFO Status (read-only)
115     // 00 - Somewhere in between
116     // 01 - Empty
117     // 10 - Almost Full
118     // 11 - Reserved (unused)
119     // Assign values using the CSR_FifoState enum.
120     u64 FIFO :2;
121    
122     // Revision number of the GS (fairly arbitrary)
123     u64 REV :8;
124    
125     // ID of the GS (also fairly arbitrary)
126     u64 ID :8;
127     };
128    
129 william 31 u64 _u64;
130 william 62
131     struct
132 william 31 {
133 william 62 u32 _u32; // lower 32 bits (all useful content!)
134     u32 _unused32; // upper 32 bits (unused -- should probably be 0)
135     };
136 william 31
137 william 62 void SwapField()
138     {
139     _u32 ^= 0x2000;
140     }
141    
142     void Reset()
143 william 31 {
144 william 62 _u64 = 0;
145     FIFO = CSR_FIFO_EMPTY;
146     REV = 0x1B; // GS Revision
147     ID = 0x55; // GS ID
148 william 31 }
149    
150 william 62 bool HasAnyInterrupts() const { return (SIGNAL || FINISH || HSINT || VSINT || EDWINT); }
151 william 31
152 william 62 u32 GetInterruptMask() const
153     {
154     return _u32 & 0x1f;
155     }
156    
157     void SetAllInterrupts(bool value=true)
158 william 31 {
159     SIGNAL = FINISH = HSINT = VSINT = EDWINT = value;
160     }
161    
162     tGS_CSR(u64 val) { _u64 = val; }
163 william 62 tGS_CSR(u32 val) { _u32 = val; }
164     tGS_CSR() { Reset(); }
165 william 31 };
166    
167 william 62 // --------------------------------------------------------------------------------------
168     // tGS_IMR
169     // --------------------------------------------------------------------------------------
170 william 31 union tGS_IMR
171     {
172     struct
173     {
174 william 62 u32 _reserved1 : 8;
175     u32 SIGMSK : 1;
176     u32 FINISHMSK : 1;
177     u32 HSMSK : 1;
178     u32 VSMSK : 1;
179     u32 EDWMSK : 1;
180     u32 _undefined : 2; // Should both be set to 1.
181     u32 _reserved2 : 17;
182 william 31 };
183     u32 _u32;
184 william 62
185 william 31 void reset()
186     {
187     _u32 = 0;
188     SIGMSK = FINISHMSK = HSMSK = VSMSK = EDWMSK = true;
189 william 62 _undefined = 0x3;
190 william 31 }
191     void set(u32 value)
192     {
193     _u32 = (value & 0x1f00); // Set only the interrupt mask fields.
194 william 62 _undefined = 0x3; // These should always be set.
195 william 31 }
196    
197 william 62 bool masked() const { return (SIGMSK || FINISHMSK || HSMSK || VSMSK || EDWMSK); }
198 william 31 };
199    
200 william 62 // --------------------------------------------------------------------------------------
201     // GSRegSIGBLID
202     // --------------------------------------------------------------------------------------
203     struct GSRegSIGBLID
204     {
205     u32 SIGID;
206     u32 LBLID;
207     };
208    
209 william 31 #define PS2MEM_GS g_RealGSMem
210 william 62 #define PS2GS_BASE(mem) (PS2MEM_GS+(mem&0x13ff))
211 william 31
212 william 62 #define CSRreg ((tGS_CSR&)*(PS2MEM_GS+0x1000))
213     #define GSIMRregs ((tGS_IMR&)*(PS2MEM_GS+0x1010))
214 william 31
215 william 62 #define GSCSRr ((u32&)*(PS2MEM_GS+0x1000))
216     #define GSIMR ((u32&)*(PS2MEM_GS+0x1010))
217     #define GSSIGLBLID ((GSRegSIGBLID&)*(PS2MEM_GS+0x1080))
218 william 31
219     enum GS_RegionMode
220     {
221     Region_NTSC,
222     Region_PAL
223     };
224    
225     enum GIF_PATH
226     {
227     GIF_PATH_1 = 0,
228     GIF_PATH_2,
229     GIF_PATH_3,
230     };
231    
232 william 62 extern void GIFPath_Initialize();
233     extern int GIFPath_CopyTag(GIF_PATH pathidx, const u128* pMem, u32 size);
234     extern int GIFPath_ParseTagQuick(GIF_PATH pathidx, const u8* pMem, u32 size);
235 william 31 extern void GIFPath_Reset();
236     extern void GIFPath_Clear( GIF_PATH pathidx );
237    
238     extern GS_RegionMode gsRegionMode;
239    
240     /////////////////////////////////////////////////////////////////////////////
241     // MTGS Threaded Class Declaration
242    
243     // Uncomment this to enable the MTGS debug stack, which tracks to ensure reads
244     // and writes stay synchronized. Warning: the debug stack is VERY slow.
245     //#define RINGBUF_DEBUG_STACK
246    
247     enum MTGS_RingCommand
248     {
249     GS_RINGTYPE_P1
250     , GS_RINGTYPE_P2
251     , GS_RINGTYPE_P3
252     , GS_RINGTYPE_VSYNC
253     , GS_RINGTYPE_FRAMESKIP
254     , GS_RINGTYPE_FREEZE
255     , GS_RINGTYPE_RESET // issues a GSreset() command.
256     , GS_RINGTYPE_SOFTRESET // issues a soft reset for the GIF
257     , GS_RINGTYPE_MODECHANGE // for issued mode changes.
258     , GS_RINGTYPE_CRC
259     };
260    
261    
262     struct MTGS_FreezeData
263     {
264     freezeData* fdata;
265     s32 retval; // value returned from the call, valid only after an mtgsWaitGS()
266     };
267    
268     // --------------------------------------------------------------------------------------
269     // SysMtgsThread
270     // --------------------------------------------------------------------------------------
271     class SysMtgsThread : public SysThreadBase
272     {
273     typedef SysThreadBase _parent;
274    
275     public:
276 william 62 // note: when m_ReadPos == m_WritePos, the fifo is empty
277     uint m_ReadPos; // cur pos gs is reading from
278 william 31 uint m_WritePos; // cur pos ee thread is writing to
279    
280     volatile bool m_RingBufferIsBusy;
281     volatile u32 m_SignalRingEnable;
282     volatile s32 m_SignalRingPosition;
283    
284 william 62 volatile s32 m_QueuedFrameCount;
285     volatile u32 m_VsyncSignalListener;
286 william 31
287 william 62 Mutex m_mtx_RingBufferBusy;
288 william 31 Semaphore m_sem_OnRingReset;
289 william 62 Semaphore m_sem_Vsync;
290 william 31
291     // used to keep multiple threads from sending packets to the ringbuffer concurrently.
292     // (currently not used or implemented -- is a planned feature for a future threaded VU1)
293     //MutexLockRecursive m_PacketLocker;
294    
295     // Used to delay the sending of events. Performance is better if the ringbuffer
296     // has more than one command in it when the thread is kicked.
297     int m_CopyDataTally;
298    
299     Semaphore m_sem_OpenDone;
300     volatile bool m_PluginOpened;
301    
302     // These vars maintain instance data for sending Data Packets.
303     // Only one data packet can be constructed and uploaded at a time.
304    
305 william 62 uint m_packet_startpos; // size of the packet (data only, ie. not including the 16 byte command!)
306 william 31 uint m_packet_size; // size of the packet (data only, ie. not including the 16 byte command!)
307 william 62 uint m_packet_writepos; // index of the data location in the ringbuffer.
308 william 31
309     #ifdef RINGBUF_DEBUG_STACK
310     Threading::Mutex m_lock_Stack;
311     #endif
312    
313     public:
314     SysMtgsThread();
315     virtual ~SysMtgsThread() throw();
316    
317     // Waits for the GS to empty out the entire ring buffer contents.
318     // Used primarily for plugin startup/shutdown.
319     void WaitGS();
320     void ResetGS();
321    
322 william 62 void PrepDataPacket( MTGS_RingCommand cmd, u32 size );
323     void PrepDataPacket( GIF_PATH pathidx, u32 size );
324 william 31 void SendDataPacket();
325     void SendGameCRC( u32 crc );
326     void WaitForOpen();
327     void Freeze( int mode, MTGS_FreezeData& data );
328    
329     void SendSimplePacket( MTGS_RingCommand type, int data0, int data1, int data2 );
330     void SendPointerPacket( MTGS_RingCommand type, u32 data0, void* data1 );
331    
332     u8* GetDataPacketPtr() const;
333     void SetEvent();
334     void PostVsyncEnd();
335    
336     bool IsPluginOpened() const { return m_PluginOpened; }
337    
338     protected:
339     void OpenPlugin();
340     void ClosePlugin();
341    
342     void OnStart();
343     void OnResumeReady();
344    
345     void OnSuspendInThread();
346     void OnPauseInThread() {}
347     void OnResumeInThread( bool IsSuspended );
348     void OnCleanupInThread();
349    
350 william 62 void GenericStall( uint size );
351    
352 william 31 // Used internally by SendSimplePacket type functions
353 william 62 void _FinishSimplePacket();
354 william 31 void ExecuteTaskInThread();
355     };
356    
357     // GetMTGS() is a required external implementation. This function is *NOT* provided
358     // by the PCSX2 core library. It provides an interface for the linking User Interface
359     // apps or DLLs to reference their own instance of SysMtgsThread (also allowing them
360     // to extend the class and override virtual methods).
361     //
362     extern SysMtgsThread& GetMTGS();
363    
364     /////////////////////////////////////////////////////////////////////////////
365     // Generalized GS Functions and Stuff
366    
367     extern void gsInit();
368     extern s32 gsOpen();
369     extern void gsClose();
370     extern void gsReset();
371     extern void gsOnModeChanged( Fixed100 framerate, u32 newTickrate );
372     extern void gsSetRegionMode( GS_RegionMode isPal );
373     extern void gsResetFrameSkip();
374     extern void gsPostVsyncEnd();
375     extern void gsFrameSkip();
376    
377     // Some functions shared by both the GS and MTGS
378     extern void _gs_ResetFrameskip();
379    
380    
381     // used for resetting GIF fifo
382     extern void gsGIFReset();
383    
384     extern void gsWrite8(u32 mem, u8 value);
385     extern void gsWrite16(u32 mem, u16 value);
386     extern void gsWrite32(u32 mem, u32 value);
387    
388     extern void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value );
389     extern void __fastcall gsWrite64_page_01( u32 mem, const mem64_t* value );
390     extern void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value );
391    
392     extern void __fastcall gsWrite128_page_00( u32 mem, const mem128_t* value );
393     extern void __fastcall gsWrite128_page_01( u32 mem, const mem128_t* value );
394     extern void __fastcall gsWrite128_generic( u32 mem, const mem128_t* value );
395    
396     extern u8 gsRead8(u32 mem);
397     extern u16 gsRead16(u32 mem);
398     extern u32 gsRead32(u32 mem);
399     extern u64 gsRead64(u32 mem);
400    
401     void gsIrq();
402    
403 william 62 extern tGS_CSR CSRr;
404 william 31
405     // GS Playback
406     enum gsrun
407     {
408     GSRUN_TRANS1 = 1,
409     GSRUN_TRANS2,
410     GSRUN_TRANS3,
411     GSRUN_VSYNC
412     };
413    
414     #ifdef PCSX2_DEVBUILD
415    
416     extern int g_SaveGSStream;
417     extern int g_nLeftGSFrames;
418    
419     #endif
420    
421 william 62 // Size of the ringbuffer as a power of 2 -- size is a multiple of simd128s.
422     // (actual size is 1<<m_RingBufferSizeFactor simd vectors [128-bit values])
423     // A value of 19 is a 8meg ring buffer. 18 would be 4 megs, and 20 would be 16 megs.
424     // Default was 2mb, but some games with lots of MTGS activity want 8mb to run fast (rama)
425     static const uint RingBufferSizeFactor = 19;
426    
427     // size of the ringbuffer in simd128's.
428     static const uint RingBufferSize = 1<<RingBufferSizeFactor;
429    
430     // Mask to apply to ring buffer indices to wrap the pointer from end to
431     // start (the wrapping is what makes it a ringbuffer, yo!)
432     static const uint RingBufferMask = RingBufferSize - 1;
433    
434     struct MTGS_BufferedData
435     {
436     u128 m_Ring[RingBufferSize];
437     u8 Regs[Ps2MemSize::GSregs];
438    
439     MTGS_BufferedData() {}
440    
441     u128& operator[]( uint idx )
442     {
443     pxAssert( idx < RingBufferSize );
444     return m_Ring[idx];
445     }
446     };
447    
448     extern __aligned(32) MTGS_BufferedData RingBuffer;
449    
450     // FIXME: These belong in common with other memcpy tools. Will move them there later if no one
451     // else beats me to it. --air
452     extern void MemCopy_WrappedDest( const u128* src, u128* destBase, uint& destStart, uint destSize, uint len );
453     extern void MemCopy_WrappedSrc( const u128* srcBase, uint& srcStart, uint srcSize, u128* dest, uint len );

  ViewVC Help
Powered by ViewVC 1.1.22