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

Diff of /trunk/pcsx2/R3000A.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 29  u32 g_psxConstRegs[32]; Line 29  u32 g_psxConstRegs[32];
29  u32 g_psxHasConstReg, g_psxFlushedConstReg;  u32 g_psxHasConstReg, g_psxFlushedConstReg;
30    
31  // Controls when branch tests are performed.  // Controls when branch tests are performed.
32  u32 g_psxNextBranchCycle = 0;  u32 g_iopNextEventCycle = 0;
33    
34  // This value is used when the IOP execution is broken to return control to the EE.  // This value is used when the IOP execution is broken to return control to the EE.
35  // (which happens when the IOP throws EE-bound interrupts).  It holds the value of  // (which happens when the IOP throws EE-bound interrupts).  It holds the value of
36  // psxCycleEE (which is set to zero to facilitate the code break), so that the unrun  // iopCycleEE (which is set to zero to facilitate the code break), so that the unrun
37  // cycles can be accounted for later.  // cycles can be accounted for later.
38  s32 psxBreak = 0;  s32 iopBreak = 0;
39    
40  // tracks the IOP's current sync status with the EE.  When it dips below zero,  // tracks the IOP's current sync status with the EE.  When it dips below zero,
41  // control is returned to the EE.  // control is returned to the EE.
42  s32 psxCycleEE = -1;  s32 iopCycleEE = -1;
43    
44  // Used to signal to the EE when important actions that need IOP-attention have  // Used to signal to the EE when important actions that need IOP-attention have
45  // happened (hsyncs, vsyncs, IOP exceptions, etc).  IOP runs code whenever this  // happened (hsyncs, vsyncs, IOP exceptions, etc).  IOP runs code whenever this
46  // is true, even if it's already running ahead a bit.  // is true, even if it's already running ahead a bit.
47  bool iopBranchAction = false;  bool iopEventAction = false;
48    
49  bool iopEventTestIsActive = false;  bool iopEventTestIsActive = false;
50    
# Line 58  void psxReset() Line 58  void psxReset()
58          psxRegs.CP0.n.Status = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1          psxRegs.CP0.n.Status = 0x10900000; // COP0 enabled | BEV = 1 | TS = 1
59          psxRegs.CP0.n.PRid   = 0x0000001f; // PRevID = Revision ID, same as the IOP R3000A          psxRegs.CP0.n.PRid   = 0x0000001f; // PRevID = Revision ID, same as the IOP R3000A
60    
61          psxBreak = 0;          iopBreak = 0;
62          psxCycleEE = -1;          iopCycleEE = -1;
63          g_psxNextBranchCycle = psxRegs.cycle + 4;          g_iopNextEventCycle = psxRegs.cycle + 4;
64    
65          psxHwReset();          psxHwReset();
66    
# Line 108  void __fastcall psxException(u32 code, u Line 108  void __fastcall psxException(u32 code, u
108          }*/          }*/
109  }  }
110    
111  __forceinline void psxSetNextBranch( u32 startCycle, s32 delta )  __fi void psxSetNextBranch( u32 startCycle, s32 delta )
112  {  {
113          // typecast the conditional to signed so that things don't blow up          // typecast the conditional to signed so that things don't blow up
114          // if startCycle is greater than our next branch cycle.          // if startCycle is greater than our next branch cycle.
115    
116          if( (int)(g_psxNextBranchCycle - startCycle) > delta )          if( (int)(g_iopNextEventCycle - startCycle) > delta )
117                  g_psxNextBranchCycle = startCycle + delta;                  g_iopNextEventCycle = startCycle + delta;
118  }  }
119    
120  __forceinline void psxSetNextBranchDelta( s32 delta )  __fi void psxSetNextBranchDelta( s32 delta )
121  {  {
122          psxSetNextBranch( psxRegs.cycle, delta );          psxSetNextBranch( psxRegs.cycle, delta );
123  }  }
124    
125  __forceinline int psxTestCycle( u32 startCycle, s32 delta )  __fi int psxTestCycle( u32 startCycle, s32 delta )
126  {  {
127          // typecast the conditional to signed so that things don't explode          // typecast the conditional to signed so that things don't explode
128          // if the startCycle is ahead of our current cpu cycle.          // if the startCycle is ahead of our current cpu cycle.
# Line 130  __forceinline int psxTestCycle( u32 star Line 130  __forceinline int psxTestCycle( u32 star
130          return (int)(psxRegs.cycle - startCycle) >= delta;          return (int)(psxRegs.cycle - startCycle) >= delta;
131  }  }
132    
133  __forceinline void PSX_INT( IopEventId n, s32 ecycle )  __fi void PSX_INT( IopEventId n, s32 ecycle )
134  {  {
135          // Generally speaking games shouldn't throw ints that haven't been cleared yet.          // Generally speaking games shouldn't throw ints that haven't been cleared yet.
136          // It's usually indicative of something amiss in our emulation, so uncomment this          // It's usually indicative of something amiss in our emulation, so uncomment this
# Line 151  __forceinline void PSX_INT( IopEventId n Line 151  __forceinline void PSX_INT( IopEventId n
151    
152          psxSetNextBranchDelta( ecycle );          psxSetNextBranchDelta( ecycle );
153    
154          if( psxCycleEE < 0 )          if( iopCycleEE < 0 )
155          {          {
156                  // The EE called this int, so inform it to branch as needed:                  // The EE called this int, so inform it to branch as needed:
157                  // fixme - this doesn't take into account EE/IOP sync (the IOP may be running                  // fixme - this doesn't take into account EE/IOP sync (the IOP may be running
158                  // ahead or behind the EE as per the EEsCycles value)                  // ahead or behind the EE as per the EEsCycles value)
159                  s32 iopDelta = (g_psxNextBranchCycle-psxRegs.cycle)*8;                  s32 iopDelta = (g_iopNextEventCycle-psxRegs.cycle)*8;
160                  cpuSetNextBranchDelta( iopDelta );                  cpuSetNextEventDelta( iopDelta );
161          }          }
162  }  }
163    
164  static __forceinline void IopTestEvent( IopEventId n, void (*callback)() )  static __fi void IopTestEvent( IopEventId n, void (*callback)() )
165  {  {
166          if( !(psxRegs.interrupt & (1 << n)) ) return;          if( !(psxRegs.interrupt & (1 << n)) ) return;
167    
# Line 174  static __forceinline void IopTestEvent( Line 174  static __forceinline void IopTestEvent(
174                  psxSetNextBranch( psxRegs.sCycle[n], psxRegs.eCycle[n] );                  psxSetNextBranch( psxRegs.sCycle[n], psxRegs.eCycle[n] );
175  }  }
176    
177  static __forceinline void sifHackInterrupt()  static __fi void sifHackInterrupt()
178  {  {
179          // No reason -- just that sometimes the SIF fell asleep, and this wakes it up.          // No reason -- just that sometimes the SIF fell asleep, and this wakes it up.
180    
# Line 186  static __forceinline void sifHackInterru Line 186  static __forceinline void sifHackInterru
186          //PSX_INT( IopEvt_SIFhack, 128 );          //PSX_INT( IopEvt_SIFhack, 128 );
187  }  }
188    
189  static __forceinline void _psxTestInterrupts()  static __fi void _psxTestInterrupts()
190  {  {
191          IopTestEvent(IopEvt_SIF0,               sif0Interrupt); // SIF0          IopTestEvent(IopEvt_SIF0,               sif0Interrupt); // SIF0
192          IopTestEvent(IopEvt_SIF1,               sif1Interrupt); // SIF1          IopTestEvent(IopEvt_SIF1,               sif1Interrupt); // SIF1
# Line 195  static __forceinline void _psxTestInterr Line 195  static __forceinline void _psxTestInterr
195  #endif  #endif
196          IopTestEvent(IopEvt_CdvdRead,   cdvdReadInterrupt);          IopTestEvent(IopEvt_CdvdRead,   cdvdReadInterrupt);
197    
 #if IOP_ENABLE_SIF_HACK  
         IopTestEvent(IopEvt_SIFhack,    sifHackInterrupt);  
 #endif  
   
198          // Profile-guided Optimization (sorta)          // Profile-guided Optimization (sorta)
199          // The following ints are rarely called.  Encasing them in a conditional          // The following ints are rarely called.  Encasing them in a conditional
200          // as follows helps speed up most games.          // as follows helps speed up most games.
# Line 215  static __forceinline void _psxTestInterr Line 211  static __forceinline void _psxTestInterr
211          }          }
212  }  }
213    
214  __releaseinline void psxBranchTest()  __ri void iopEventTest()
215  {  {
216          if( psxTestCycle( psxNextsCounter, psxNextCounter ) )          if( psxTestCycle( psxNextsCounter, psxNextCounter ) )
217          {          {
218                  psxRcntUpdate();                  psxRcntUpdate();
219                  iopBranchAction = true;                  iopEventAction = true;
220          }          }
221          else          else
222          {          {
223          // start the next branch at the next counter event by default          // start the next branch at the next counter event by default
224          // the interrupt code below will assign nearer branches if needed.          // the interrupt code below will assign nearer branches if needed.
225                  g_psxNextBranchCycle = psxNextsCounter+psxNextCounter;                  g_iopNextEventCycle = psxNextsCounter+psxNextCounter;
226          }          }
227    
228    
# Line 243  __releaseinline void psxBranchTest() Line 239  __releaseinline void psxBranchTest()
239                  {                  {
240                          PSXCPU_LOG("Interrupt: %x  %x", psxHu32(0x1070), psxHu32(0x1074));                          PSXCPU_LOG("Interrupt: %x  %x", psxHu32(0x1070), psxHu32(0x1074));
241                          psxException(0, 0);                          psxException(0, 0);
242                          iopBranchAction = true;                          iopEventAction = true;
243    
244                          // No need to execute the SIFhack after cpuExceptions, since these by nature break SIF's                          // No need to execute the SIFhack after cpuExceptions, since these by nature break SIF's
245                          // thread sleep hangs and allow the IOP to "come back to life."                          // thread sleep hangs and allow the IOP to "come back to life."
246                          psxRegs.interrupt &= ~IopEvt_SIFhack;                          psxRegs.interrupt &= ~IopEvt_SIFhack;
247                  }                  }
248          }          }
   
         if( IOP_ENABLE_SIF_HACK && !iopBranchAction && !(psxRegs.interrupt & IopEvt_SIFhack) )  
         {  
                 // Safeguard: since we're not executing an exception vector, we should schedule a SIF wakeup  
                 // just in case.  (and don't reschedule it if it's already scheduled, since that would just  
                 // delay the previously scheduled one, and we don't want that)  
   
                 // (TODO: The endless loop in question is a branch instruction that branches to itself endlessly,  
                 //  waiting for SIF to wake it up via any cpuException.  We could check for that instruction  
                 //  location and only schedule a SIF fix when it's detected...  But for now this is easy and gives  
                 //  us good control over testing parameters...)  
   
                 PSX_INT( IopEvt_SIFhack, 96 );  
         }  
249  }  }
250    
251  void iopTestIntc()  void iopTestIntc()
# Line 276  void iopTestIntc() Line 258  void iopTestIntc()
258                  // An iop exception has occurred while the EE is running code.                  // An iop exception has occurred while the EE is running code.
259                  // Inform the EE to branch so the IOP can handle it promptly:                  // Inform the EE to branch so the IOP can handle it promptly:
260    
261                  cpuSetNextBranchDelta( 16 );                  cpuSetNextEventDelta( 16 );
262                  iopBranchAction = true;                  iopEventAction = true;
263                  //Console.Error( "** IOP Needs an EE EventText, kthx **  %d", psxCycleEE );                  //Console.Error( "** IOP Needs an EE EventText, kthx **  %d", iopCycleEE );
264    
265                  // Note: No need to set the iop's branch delta here, since the EE                  // Note: No need to set the iop's branch delta here, since the EE
266                  // will run an IOP branch test regardless.                  // will run an IOP branch test regardless.

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

  ViewVC Help
Powered by ViewVC 1.1.22