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

Contents of /trunk/pcsx2/GS.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show 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 /* 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 enum CSR_FifoState
24 {
25 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 };
30
31 // --------------------------------------------------------------------------------------
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 {
40 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
50 // 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
58 // 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
67 // 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 u64 _u64;
130
131 struct
132 {
133 u32 _u32; // lower 32 bits (all useful content!)
134 u32 _unused32; // upper 32 bits (unused -- should probably be 0)
135 };
136
137 void SwapField()
138 {
139 _u32 ^= 0x2000;
140 }
141
142 void Reset()
143 {
144 _u64 = 0;
145 FIFO = CSR_FIFO_EMPTY;
146 REV = 0x1B; // GS Revision
147 ID = 0x55; // GS ID
148 }
149
150 bool HasAnyInterrupts() const { return (SIGNAL || FINISH || HSINT || VSINT || EDWINT); }
151
152 u32 GetInterruptMask() const
153 {
154 return _u32 & 0x1f;
155 }
156
157 void SetAllInterrupts(bool value=true)
158 {
159 SIGNAL = FINISH = HSINT = VSINT = EDWINT = value;
160 }
161
162 tGS_CSR(u64 val) { _u64 = val; }
163 tGS_CSR(u32 val) { _u32 = val; }
164 tGS_CSR() { Reset(); }
165 };
166
167 // --------------------------------------------------------------------------------------
168 // tGS_IMR
169 // --------------------------------------------------------------------------------------
170 union tGS_IMR
171 {
172 struct
173 {
174 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 };
183 u32 _u32;
184
185 void reset()
186 {
187 _u32 = 0;
188 SIGMSK = FINISHMSK = HSMSK = VSMSK = EDWMSK = true;
189 _undefined = 0x3;
190 }
191 void set(u32 value)
192 {
193 _u32 = (value & 0x1f00); // Set only the interrupt mask fields.
194 _undefined = 0x3; // These should always be set.
195 }
196
197 bool masked() const { return (SIGMSK || FINISHMSK || HSMSK || VSMSK || EDWMSK); }
198 };
199
200 // --------------------------------------------------------------------------------------
201 // GSRegSIGBLID
202 // --------------------------------------------------------------------------------------
203 struct GSRegSIGBLID
204 {
205 u32 SIGID;
206 u32 LBLID;
207 };
208
209 #define PS2MEM_GS g_RealGSMem
210 #define PS2GS_BASE(mem) (PS2MEM_GS+(mem&0x13ff))
211
212 #define CSRreg ((tGS_CSR&)*(PS2MEM_GS+0x1000))
213 #define GSIMRregs ((tGS_IMR&)*(PS2MEM_GS+0x1010))
214
215 #define GSCSRr ((u32&)*(PS2MEM_GS+0x1000))
216 #define GSIMR ((u32&)*(PS2MEM_GS+0x1010))
217 #define GSSIGLBLID ((GSRegSIGBLID&)*(PS2MEM_GS+0x1080))
218
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 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 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 // note: when m_ReadPos == m_WritePos, the fifo is empty
277 uint m_ReadPos; // cur pos gs is reading from
278 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 volatile s32 m_QueuedFrameCount;
285 volatile u32 m_VsyncSignalListener;
286
287 Mutex m_mtx_RingBufferBusy;
288 Semaphore m_sem_OnRingReset;
289 Semaphore m_sem_Vsync;
290
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 uint m_packet_startpos; // size of the packet (data only, ie. not including the 16 byte command!)
306 uint m_packet_size; // size of the packet (data only, ie. not including the 16 byte command!)
307 uint m_packet_writepos; // index of the data location in the ringbuffer.
308
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 void PrepDataPacket( MTGS_RingCommand cmd, u32 size );
323 void PrepDataPacket( GIF_PATH pathidx, u32 size );
324 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 void GenericStall( uint size );
351
352 // Used internally by SendSimplePacket type functions
353 void _FinishSimplePacket();
354 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 extern tGS_CSR CSRr;
404
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 // 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