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

Diff of /trunk/pcsx2/GS.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 31 by william, Tue Sep 7 03:24:11 2010 UTC revision 62 by william, Tue Sep 7 11:08:22 2010 UTC
# Line 25  Line 25 
25  using namespace Threading;  using namespace Threading;
26  using namespace R5900;  using namespace R5900;
27    
 u32 CSRw;  
   
28  __aligned16 u8 g_RealGSMem[0x2000];  __aligned16 u8 g_RealGSMem[0x2000];
 extern int m_nCounters[];  
29    
30  void gsOnModeChanged( Fixed100 framerate, u32 newTickrate )  void gsOnModeChanged( Fixed100 framerate, u32 newTickrate )
31  {  {
# Line 54  void gsInit() Line 51  void gsInit()
51          memzero(g_RealGSMem);          memzero(g_RealGSMem);
52  }  }
53    
54    extern bool SIGNAL_IMR_Pending;
55    extern u32 SIGNAL_Data_Pending[2];
56    
57    void gsGIFReset()
58    {
59            gifRegs.stat.reset();
60            gifRegs.ctrl.reset();
61            gifRegs.mode.reset();
62    }
63    
64  void gsReset()  void gsReset()
65  {  {
66          GetMTGS().ResetGS();          GetMTGS().ResetGS();
67    
68          UpdateVSyncRate();          UpdateVSyncRate();
69          GSTransferStatus = (STOPPED_MODE<<4) | (STOPPED_MODE<<2) | STOPPED_MODE;          GSTransferStatus = (STOPPED_MODE<<8) | (STOPPED_MODE<<4) | STOPPED_MODE;
70          memzero(g_RealGSMem);          memzero(g_RealGSMem);
71    
72          GSCSRr = 0x551B4000;   // Set the FINISH bit to 1 for now          SIGNAL_IMR_Pending = false;
73    
74            CSRreg.Reset();
75          GSIMR = 0x7f00;          GSIMR = 0x7f00;
         gifRegs->stat.reset();  
         gifRegs->ctrl.reset();  
         gifRegs->mode.reset();  
 }  
76    
77  void gsGIFReset()          // FIXME: This really doesn't belong here, and I seriously doubt it's needed.
78  {          // If it is needed it should be in the GIF portion of hwReset().  --air
79          gifRegs->stat.reset();          gsGIFReset();
         gifRegs->ctrl.reset();  
         gifRegs->mode.reset();  
80  }  }
81    
82  void gsCSRwrite(u32 value)  static __fi void gsCSRwrite( const tGS_CSR& csr )
83  {  {
84          if (value & 0x200) { // resetGS          if (csr.RESET) {
85    
86                  // perform a soft reset -- which is a clearing of all GIFpaths -- and fall back to doing                  // perform a soft reset -- which is a clearing of all GIFpaths -- and fall back to doing
87                  // a full reset if the plugin doesn't support soft resets.                  // a full reset if the plugin doesn't support soft resets.
# Line 94  void gsCSRwrite(u32 value) Line 97  void gsCSRwrite(u32 value)
97                          GetMTGS().SendSimplePacket( GS_RINGTYPE_RESET, 0, 0, 0 );                          GetMTGS().SendSimplePacket( GS_RINGTYPE_RESET, 0, 0, 0 );
98                  }                  }
99    
100                  CSRw |= 0x1f;                  SIGNAL_IMR_Pending = false;
101                  GSCSRr = 0x551B4000;   // Set the FINISH bit to 1 - GS is always at a finish state as we don't have a FIFO(saqib)                  CSRreg.Reset();
102                  GSIMR = 0x7F00; //This is bits 14-8 thats all that should be 1                  GSIMR = 0x7F00;                 //This is bits 14-8 thats all that should be 1
103          }          }
104          else if( value & 0x100 ) // FLUSH  
105            if(csr.FLUSH)
106          {          {
107                  // Our emulated GS has no FIFO, but if it did, it would flush it here...                  // Our emulated GS has no FIFO, but if it did, it would flush it here...
108                  //Console.WriteLn("GS_CSR FLUSH GS fifo: %x (CSRr=%x)", value, GSCSRr);                  //Console.WriteLn("GS_CSR FLUSH GS fifo: %x (CSRr=%x)", value, GSCSRr);
109          }          }
110          else          
111            if(csr.SIGNAL)
112          {          {
113                  CSRw |= value & 0x1f;                  // SIGNAL : What's not known here is whether or not the SIGID register should be updated
114                  GetMTGS().SendSimplePacket( GS_RINGTYPE_WRITECSR, CSRw, 0, 0 );                  //  here or when the IMR is cleared (below).
115                  GSCSRr = ((GSCSRr&~value)&0x1f)|(GSCSRr&~0x1f);  
116          }                  if(SIGNAL_IMR_Pending == true)
117                    {
118                            //DevCon.Warning("Firing pending signal");
119                            GIF_LOG("GS SIGNAL (pending) data=%x_%x IMR=%x CSRr=%x",SIGNAL_Data_Pending[0], SIGNAL_Data_Pending[1], GSIMR, GSCSRr);
120                            GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~SIGNAL_Data_Pending[1])|(SIGNAL_Data_Pending[0]&SIGNAL_Data_Pending[1]);
121    
122                            if (!(GSIMR&0x100))
123                            gsIrq();
124    
125                            CSRreg.SIGNAL = true; //Just to be sure :P
126                    }
127                    else CSRreg.SIGNAL = false;
128                    
129                    SIGNAL_IMR_Pending = false;
130    
131                    if(gifRegs.stat.P1Q && gifRegs.stat.APATH <= GIF_APATH1) gsPath1Interrupt();
132            }
133            
134            if(csr.FINISH)  CSRreg.FINISH   = false;
135            if(csr.HSINT)   CSRreg.HSINT    = false;
136            if(csr.VSINT)   CSRreg.VSINT    = false;
137            if(csr.EDWINT)  CSRreg.EDWINT   = false;
138  }  }
139    
140  static void IMRwrite(u32 value)  static __fi void IMRwrite(u32 value)
141  {  {
142          GSIMR = (value & 0x1f00)|0x6000;          GSIMR = (value & 0x1f00)|0x6000;
143    
144          if((GSCSRr & 0x1f) & (~(GSIMR >> 8) & 0x1f))          if(CSRreg.GetInterruptMask() & (~(GSIMR >> 8) & 0x1f))
145                    gsIrq();
146    
147            if( SIGNAL_IMR_Pending && !(GSIMR & 0x100))
148          {          {
149                    // Note: PS2 apps are expected to write a successive 1 and 0 to the IMR in order to
150                    //  trigger the gsInt and clear the second pending SIGNAL interrupt -- if they fail
151                    //  to do so, the GS will freeze again upon the very next SIGNAL).
152                    //
153                    // What's not known here is whether or not the SIGID register should be updated
154                    //  here or when the GS is resumed during CSR write (above).
155    
156                    //GIF_LOG("GS SIGNAL (pending) data=%x_%x IMR=%x CSRr=%x\n",CSR_SIGNAL_Data[0], CSR_SIGNAL_Data[1], GSIMR, GSCSRr);
157                    //GSSIGLBLID.SIGID = (GSSIGLBLID.SIGID&~CSR_SIGNAL_Data[1])|(CSR_SIGNAL_Data[0]&CSR_SIGNAL_Data[1]);
158    
159                    CSRreg.SIGNAL = true;
160                  gsIrq();                  gsIrq();
161          }          }
         // don't update mtgs mem  
162  }  }
163    
164  __forceinline void gsWrite8(u32 mem, u8 value)  __fi void gsWrite8(u32 mem, u8 value)
165  {  {
166          switch (mem)          switch (mem)
167          {          {
168                    // CSR 8-bit write handlers.
169                    // I'm quite sure these whould just write the CSR portion with the other
170                    // bits set to 0 (no action).  The previous implementation masked the 8-bit
171                    // write value against the previous CSR write value, but that really doesn't
172                    // make any sense, given that the real hardware's CSR circuit probably has no
173                    // real "memory" where it saves anything.  (for example, you can't write to
174                    // and change the GS revision or ID portions -- they're all hard wired.) --air
175            
176                  case GS_CSR: // GS_CSR                  case GS_CSR: // GS_CSR
177                          gsCSRwrite((CSRw & ~0x000000ff) | value); break;                          gsCSRwrite( tGS_CSR((u32)value) );                      break;
178                  case GS_CSR + 1: // GS_CSR                  case GS_CSR + 1: // GS_CSR
179                          gsCSRwrite((CSRw & ~0x0000ff00) | (value <<  8)); break;                          gsCSRwrite( tGS_CSR(((u32)value) <<  8) );      break;
180                  case GS_CSR + 2: // GS_CSR                  case GS_CSR + 2: // GS_CSR
181                          gsCSRwrite((CSRw & ~0x00ff0000) | (value << 16)); break;                          gsCSRwrite( tGS_CSR(((u32)value) << 16) );      break;
182                  case GS_CSR + 3: // GS_CSR                  case GS_CSR + 3: // GS_CSR
183                          gsCSRwrite((CSRw & ~0xff000000) | (value << 24)); break;                          gsCSRwrite( tGS_CSR(((u32)value) << 24) );      break;
184    
185                  default:                  default:
186                          *PS2GS_BASE(mem) = value;                          *PS2GS_BASE(mem) = value;
187                          GetMTGS().SendSimplePacket(GS_RINGTYPE_MEMWRITE8, mem&0x13ff, value, 0);                  break;
188          }          }
189          GIF_LOG("GS write 8 at %8.8lx with data %8.8lx", mem, value);          GIF_LOG("GS write 8 at %8.8lx with data %8.8lx", mem, value);
190  }  }
191    
192  __forceinline void _gsSMODEwrite( u32 mem, u32 value )  static __fi void _gsSMODEwrite( u32 mem, u32 value )
193  {  {
194          switch (mem)          switch (mem)
195          {          {
# Line 159  __forceinline void _gsSMODEwrite( u32 me Line 206  __forceinline void _gsSMODEwrite( u32 me
206  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////
207  // GS Write 16 bit  // GS Write 16 bit
208    
209  __forceinline void gsWrite16(u32 mem, u16 value)  __fi void gsWrite16(u32 mem, u16 value)
210  {  {
211          GIF_LOG("GS write 16 at %8.8lx with data %8.8lx", mem, value);          GIF_LOG("GS write 16 at %8.8lx with data %8.8lx", mem, value);
212    
# Line 167  __forceinline void gsWrite16(u32 mem, u1 Line 214  __forceinline void gsWrite16(u32 mem, u1
214    
215          switch (mem)          switch (mem)
216          {          {
217                    // See note above about CSR 8 bit writes, and handling them as zero'd bits
218                    // for all but the written parts.
219                    
220                  case GS_CSR:                  case GS_CSR:
221                          gsCSRwrite( (CSRw&0xffff0000) | value);                          gsCSRwrite( tGS_CSR((u32)value) );
222                  return; // do not write to MTGS memory                  return; // do not write to MTGS memory
223    
224                  case GS_CSR+2:                  case GS_CSR+2:
225                          gsCSRwrite( (CSRw&0xffff) | ((u32)value<<16));                          gsCSRwrite( tGS_CSR(((u32)value) << 16) );
226                  return; // do not write to MTGS memory                  return; // do not write to MTGS memory
227    
228                  case GS_IMR:                  case GS_IMR:
# Line 181  __forceinline void gsWrite16(u32 mem, u1 Line 231  __forceinline void gsWrite16(u32 mem, u1
231          }          }
232    
233          *(u16*)PS2GS_BASE(mem) = value;          *(u16*)PS2GS_BASE(mem) = value;
         GetMTGS().SendSimplePacket(GS_RINGTYPE_MEMWRITE16, mem&0x13ff, value, 0);  
234  }  }
235    
236  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////
237  // GS Write 32 bit  // GS Write 32 bit
238    
239  __forceinline void gsWrite32(u32 mem, u32 value)  __fi void gsWrite32(u32 mem, u32 value)
240  {  {
241          jASSUME( (mem & 3) == 0 );          pxAssume( (mem & 3) == 0 );
242          GIF_LOG("GS write 32 at %8.8lx with data %8.8lx", mem, value);          GIF_LOG("GS write 32 at %8.8lx with data %8.8lx", mem, value);
243    
244          _gsSMODEwrite( mem, value );          _gsSMODEwrite( mem, value );
# Line 197  __forceinline void gsWrite32(u32 mem, u3 Line 246  __forceinline void gsWrite32(u32 mem, u3
246          switch (mem)          switch (mem)
247          {          {
248                  case GS_CSR:                  case GS_CSR:
249                          gsCSRwrite(value);                          gsCSRwrite(tGS_CSR(value));
250                  return;                  return;
251    
252                  case GS_IMR:                  case GS_IMR:
# Line 206  __forceinline void gsWrite32(u32 mem, u3 Line 255  __forceinline void gsWrite32(u32 mem, u3
255          }          }
256    
257          *(u32*)PS2GS_BASE(mem) = value;          *(u32*)PS2GS_BASE(mem) = value;
         GetMTGS().SendSimplePacket(GS_RINGTYPE_MEMWRITE32, mem&0x13ff, value, 0);  
258  }  }
259    
260  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////
261  // GS Write 64 bit  // GS Write 64 bit
262    
263    void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value )
264    {
265            const u32* const srcval32 = (u32*)value;
266            GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x", mem, srcval32[1], srcval32[0]);
267    
268            *(u64*)PS2GS_BASE(mem) = *value;
269    }
270    
271  void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value )  void __fastcall gsWrite64_page_00( u32 mem, const mem64_t* value )
272  {  {
273          gsWrite64_generic( mem, value );          gsWrite64_generic( mem, value );
# Line 224  void __fastcall gsWrite64_page_01( u32 m Line 280  void __fastcall gsWrite64_page_01( u32 m
280    
281          switch( mem )          switch( mem )
282          {          {
283                    case 0x12001040: //busdir
284    
285                            //This is probably a complete hack, however writing to BUSDIR "should" start a transfer
286                            //Only problem is it kills killzone :(.
287                            // (yes it *is* a complete hack; both lines here in fact --air)
288                            //=========================================================================
289                            //gifRegs.stat.OPH = true; // Bleach wants it, Killzone hates it.
290                            
291                            gifRegs.stat.DIR = (u32)value[0];
292                            //=========================================================================
293                            // BUSDIR INSANITY !! MTGS FLUSH NEEDED
294                            //
295                            // Yup folks.  BUSDIR is evil.  The only safe way to handle it is to flush the whole MTGS
296                            // and ensure complete MTGS and EEcore thread synchronization  This is very slow, no doubt,
297                            // but on the birght side BUSDIR is used quite rately, indeed.
298    
299                            // Important: writeback to gsRegs area *prior* to flushing the MTGS.  The flush will sync
300                            // the GS and MTGS register states, and upload our screwy busdir register in the process. :)
301                            gsWrite64_generic( mem, value );
302                            GetMTGS().WaitGS();
303                    return;
304    
305                  case GS_CSR:                  case GS_CSR:
306                          gsCSRwrite((u32)value[0]);                          gsCSRwrite(tGS_CSR(*value));
307                  return;                  return;
308    
309                  case GS_IMR:                  case GS_IMR:
# Line 236  void __fastcall gsWrite64_page_01( u32 m Line 314  void __fastcall gsWrite64_page_01( u32 m
314          gsWrite64_generic( mem, value );          gsWrite64_generic( mem, value );
315  }  }
316    
 void __fastcall gsWrite64_generic( u32 mem, const mem64_t* value )  
 {  
         const u32* const srcval32 = (u32*)value;  
         GIF_LOG("GS Write64 at %8.8lx with data %8.8x_%8.8x", mem, srcval32[1], srcval32[0]);  
   
         *(u64*)PS2GS_BASE(mem) = *value;  
         GetMTGS().SendSimplePacket(GS_RINGTYPE_MEMWRITE64, mem&0x13ff, srcval32[0], srcval32[1]);  
 }  
   
317  //////////////////////////////////////////////////////////////////////////  //////////////////////////////////////////////////////////////////////////
318  // GS Write 128 bit  // GS Write 128 bit
319    
# Line 277  void __fastcall gsWrite128_generic( u32 Line 346  void __fastcall gsWrite128_generic( u32
346          GIF_LOG("GS Write128 at %8.8lx with data %8.8x_%8.8x_%8.8x_%8.8x", mem,          GIF_LOG("GS Write128 at %8.8lx with data %8.8x_%8.8x_%8.8x_%8.8x", mem,
347                  srcval32[3], srcval32[2], srcval32[1], srcval32[0]);                  srcval32[3], srcval32[2], srcval32[1], srcval32[0]);
348    
349          const uint masked_mem = mem & 0x13ff;          CopyQWC(PS2GS_BASE(mem), value);
         u64* writeTo = (u64*)(&g_RealGSMem[masked_mem]);  
   
         writeTo[0] = value[0];  
         writeTo[1] = value[1];  
   
         GetMTGS().SendSimplePacket(GS_RINGTYPE_MEMWRITE64, masked_mem, srcval32[0], srcval32[1]);  
         GetMTGS().SendSimplePacket(GS_RINGTYPE_MEMWRITE64, masked_mem+8, srcval32[2], srcval32[3]);  
350  }  }
351    
352  __forceinline u8 gsRead8(u32 mem)  __fi u8 gsRead8(u32 mem)
353  {  {
354          GIF_LOG("GS read 8 from %8.8lx  value: %8.8lx", mem, *(u8*)PS2GS_BASE(mem));          GIF_LOG("GS read 8 from %8.8lx  value: %8.8lx", mem, *(u8*)PS2GS_BASE(mem));
355          return *(u8*)PS2GS_BASE(mem);          return *(u8*)PS2GS_BASE(mem);
356  }  }
357    
358  __forceinline u16 gsRead16(u32 mem)  __fi u16 gsRead16(u32 mem)
359  {  {
360          GIF_LOG("GS read 16 from %8.8lx  value: %8.8lx", mem, *(u16*)PS2GS_BASE(mem));          GIF_LOG("GS read 16 from %8.8lx  value: %8.8lx", mem, *(u16*)PS2GS_BASE(mem));
361          return *(u16*)PS2GS_BASE(mem);          return *(u16*)PS2GS_BASE(mem);
362  }  }
363    
364  __forceinline u32 gsRead32(u32 mem)  __fi u32 gsRead32(u32 mem)
365  {  {
366          GIF_LOG("GS read 32 from %8.8lx  value: %8.8lx", mem, *(u32*)PS2GS_BASE(mem));          GIF_LOG("GS read 32 from %8.8lx  value: %8.8lx", mem, *(u32*)PS2GS_BASE(mem));
367          return *(u32*)PS2GS_BASE(mem);          return *(u32*)PS2GS_BASE(mem);
368  }  }
369    
370  __forceinline u64 gsRead64(u32 mem)  __fi u64 gsRead64(u32 mem)
371  {  {
372          // fixme - PS2GS_BASE(mem+4) = (g_RealGSMem+(mem + 4 & 0x13ff))          // fixme - PS2GS_BASE(mem+4) = (g_RealGSMem+(mem + 4 & 0x13ff))
373          GIF_LOG("GS read 64 from %8.8lx  value: %8.8lx_%8.8lx", mem, *(u32*)PS2GS_BASE(mem+4), *(u32*)PS2GS_BASE(mem) );          GIF_LOG("GS read 64 from %8.8lx  value: %8.8lx_%8.8lx", mem, *(u32*)PS2GS_BASE(mem+4), *(u32*)PS2GS_BASE(mem) );
# Line 336  void gsIrq() { Line 398  void gsIrq() {
398  //   functions are performed by the EE, which itself uses thread sleep logic to avoid spin  //   functions are performed by the EE, which itself uses thread sleep logic to avoid spin
399  //   waiting as much as possible (maximizes CPU resource availability for the GS).  //   waiting as much as possible (maximizes CPU resource availability for the GS).
400    
401  __forceinline void gsFrameSkip()  __fi void gsFrameSkip()
402  {  {
   
         if( !EmuConfig.GS.FrameSkipEnable ) return;  
   
403          static int consec_skipped = 0;          static int consec_skipped = 0;
404          static int consec_drawn = 0;          static int consec_drawn = 0;
405          static bool isSkipping = false;          static bool isSkipping = false;
406    
407            if( !EmuConfig.GS.FrameSkipEnable )
408            {
409                    if( isSkipping )
410                    {
411                            // Frameskipping disabled on-the-fly .. make sure the GS is restored to non-skip
412                            // behavior.
413                            GSsetFrameSkip( false );
414                            isSkipping = false;
415                    }
416                    return;
417            }
418    
419          GSsetFrameSkip( isSkipping );          GSsetFrameSkip( isSkipping );
420    
421          if( isSkipping )          if( isSkipping )
# Line 369  __forceinline void gsFrameSkip() Line 440  __forceinline void gsFrameSkip()
440    
441  void gsPostVsyncEnd()  void gsPostVsyncEnd()
442  {  {
443          *(u32*)(PS2MEM_GS+0x1000) ^= 0x2000; // swap the vsync field          CSRreg.SwapField();
444          GetMTGS().PostVsyncEnd();          GetMTGS().PostVsyncEnd();
445  }  }
446    
# Line 387  void gsResetFrameSkip() Line 458  void gsResetFrameSkip()
458  void SaveStateBase::gsFreeze()  void SaveStateBase::gsFreeze()
459  {  {
460          FreezeMem(PS2MEM_GS, 0x2000);          FreezeMem(PS2MEM_GS, 0x2000);
461          Freeze(CSRw);          Freeze(SIGNAL_IMR_Pending);
462            Freeze(gsRegionMode);
463    
464          gifPathFreeze();          gifPathFreeze();
465  }  }

Legend:
Removed from v.31  
changed lines
  Added in v.62

  ViewVC Help
Powered by ViewVC 1.1.22