Advertisement
Guest User

Untitled

a guest
Oct 27th, 2010
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 51.26 KB | None | 0 0
  1. Index: Source/Core/Common/Src/Atomic_GCC.h
  2. ===================================================================
  3. --- Source/Core/Common/Src/Atomic_GCC.h (revision 6314)
  4. +++ Source/Core/Common/Src/Atomic_GCC.h (working copy)
  5. @@ -41,10 +41,14 @@
  6.     __sync_add_and_fetch(&target, value);
  7.  }
  8.  
  9. -inline void AtomicAnd(volatile u32& target, u32 value) {
  10. -   __sync_and_and_fetch(&target, value);
  11. +inline void * AtomicCompareExchange(void *& dest, void * value, void * comp) {
  12. +   return __sync_val_compare_and_swap(&dest, comp, value);
  13.  }
  14.  
  15. +inline u32 AtomicAnd(volatile u32& target, u32 value) {
  16. +   return __sync_fetch_and_and(&target, value);
  17. +}
  18. +
  19.  inline void AtomicDecrement(volatile u32& target) {
  20.     __sync_add_and_fetch(&target, -1);
  21.  }
  22. @@ -61,8 +65,8 @@
  23.     return src;
  24.  }
  25.  
  26. -inline void AtomicOr(volatile u32& target, u32 value) {
  27. -   __sync_or_and_fetch(&target, value);
  28. +inline u32 AtomicOr(volatile u32& target, u32 value) {
  29. +   return __sync_fetch_and_or(&target, value);
  30.  }
  31.  
  32.  inline void AtomicStore(volatile u32& dest, u32 value) {
  33. Index: Source/Core/Common/Src/Atomic_Win32.h
  34. ===================================================================
  35. --- Source/Core/Common/Src/Atomic_Win32.h   (revision 6314)
  36. +++ Source/Core/Common/Src/Atomic_Win32.h   (working copy)
  37. @@ -47,10 +47,14 @@
  38.     InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value);
  39.  }
  40.  
  41. -inline void AtomicAnd(volatile u32& target, u32 value) {
  42. -   _InterlockedAnd((volatile LONG*)&target, (LONG)value);
  43. +inline void * AtomicCompareExchange(void * & dest, void * value, void * comp) {
  44. +   return InterlockedCompareExchangePointer(&dest, value, comp);
  45.  }
  46.  
  47. +inline u32 AtomicAnd(volatile u32& target, u32 value) {
  48. +   return (u32)_InterlockedAnd((volatile LONG*)&target, (LONG)value);
  49. +}
  50. +
  51.  inline void AtomicIncrement(volatile u32& target) {
  52.     InterlockedIncrement((volatile LONG*)&target);
  53.  }
  54. @@ -68,8 +72,8 @@
  55.     return result;
  56.  }
  57.  
  58. -inline void AtomicOr(volatile u32& target, u32 value) {
  59. -   _InterlockedOr((volatile LONG*)&target, (LONG)value);
  60. +inline u32 AtomicOr(volatile u32& target, u32 value) {
  61. +   return (u32)_InterlockedOr((volatile LONG*)&target, (LONG)value);
  62.  }
  63.  
  64.  inline void AtomicStore(volatile u32& dest, u32 value) {
  65. Index: Source/Core/Core/Src/CoreTiming.cpp
  66. ===================================================================
  67. --- Source/Core/Core/Src/CoreTiming.cpp (revision 6314)
  68. +++ Source/Core/Core/Src/CoreTiming.cpp (working copy)
  69. @@ -42,7 +42,6 @@
  70.     s64 time;
  71.     u64 userdata;
  72.     int type;
  73. -   bool fifoWait;
  74.  // Event *next;
  75.  };
  76.  
  77. @@ -66,7 +65,7 @@
  78.  
  79.  Common::CriticalSection externalEventSection;
  80.  
  81. -void (*advanceCallback)(int cyclesExecuted) = NULL;
  82. +void (*advanceCallback)(s64 cyclesExecuted) = NULL;
  83.  
  84.  Event* GetNewEvent()
  85.  {
  86. @@ -178,7 +177,6 @@
  87.             p.Do(ev->time);
  88.             p.Do(ev->type);
  89.             p.Do(ev->userdata);
  90. -           p.Do(ev->fifoWait);
  91.             ev->next = 0;
  92.             prev = ev;
  93.             ev = ev->next;
  94. @@ -196,7 +194,6 @@
  95.             p.Do(ev->time);
  96.             p.Do(ev->type);
  97.             p.Do(ev->userdata);
  98. -           p.Do(ev->fifoWait);
  99.             ev = ev->next;
  100.         }
  101.         more_events = 0;
  102. @@ -219,7 +216,7 @@
  103.  
  104.  // This is to be called when outside threads, such as the graphics thread, wants to
  105.  // schedule things to be executed on the main thread.
  106. -void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata, bool fifoWait)
  107. +void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata)
  108.  {
  109.     externalEventSection.Enter();
  110.     Event *ne = GetNewTsEvent();
  111. @@ -227,13 +224,16 @@
  112.     ne->type = event_type;
  113.     ne->next = 0;
  114.     ne->userdata = userdata;
  115. -   ne->fifoWait = fifoWait;
  116.     if(!tsFirst)
  117.         tsFirst = ne;
  118.     if(tsLast)
  119.         tsLast->next = ne;
  120.     tsLast = ne;
  121.     externalEventSection.Leave();
  122. +
  123. +   // Tell PowerPC to synchronize with new timing data if required
  124. +   if (cyclesIntoFuture < downcount)
  125. +       PowerPC::Synchronize();
  126.  }
  127.  
  128.  // Same as ScheduleEvent_Threadsafe(0, ...) EXCEPT if we are already on the main thread
  129. @@ -247,7 +247,7 @@
  130.         externalEventSection.Leave();
  131.     }
  132.     else
  133. -       ScheduleEvent_Threadsafe(0, event_type, userdata, false);
  134. +       ScheduleEvent_Threadsafe(0, event_type, userdata);
  135.  }
  136.  
  137.  void ClearPendingEvents()
  138. @@ -281,17 +281,20 @@
  139.  // This must be run ONLY from within the cpu thread
  140.  // cyclesIntoFuture may be VERY inaccurate if called from anything else
  141.  // than Advance
  142. -void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata)
  143. +void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata)
  144.  {
  145.     Event *ne = GetNewEvent();
  146.     ne->userdata = userdata;
  147.     ne->type = event_type;
  148.     ne->time = globalTimer + cyclesIntoFuture;
  149. -   ne->fifoWait = false;
  150.     AddEventToQueue(ne);
  151. +
  152. +   // Tell PowerPC to synchronize with new timing data
  153. +   if (cyclesIntoFuture < downcount)
  154. +       PowerPC::Synchronize();
  155.  }
  156.  
  157. -void RegisterAdvanceCallback(void (*callback)(int cyclesExecuted))
  158. +void RegisterAdvanceCallback(void (*callback)(s64 cyclesExecuted))
  159.  {
  160.     advanceCallback = callback;
  161.  }
  162. @@ -394,30 +397,6 @@
  163.     maxSliceLength = MAX_SLICE_LENGTH;
  164.  }
  165.  
  166. -
  167. -//This raise only the events required while the fifo is processing data
  168. -void ProcessFifoWaitEvents()
  169. -{
  170. -   MoveEvents();
  171. -
  172. -   while (first)
  173. -   {
  174. -       if ((first->time <= globalTimer) && first->fifoWait)
  175. -       {
  176. -          
  177. -           Event* evt = first;
  178. -           first = first->next;
  179. -           event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
  180. -           FreeEvent(evt);
  181. -       }
  182. -       else
  183. -       {
  184. -           break;
  185. -       }
  186. -   }
  187. -
  188. -}
  189. -
  190.  void MoveEvents()
  191.  {
  192.  
  193. @@ -444,47 +423,44 @@
  194.  
  195.  }
  196.  
  197. -void Advance()
  198. +void AdvanceCycles(s64 cyclesExecuted)
  199.  { 
  200. -
  201. -   MoveEvents();      
  202. -
  203. -   int cyclesExecuted = slicelength - downcount;
  204.     globalTimer += cyclesExecuted;
  205. -   downcount = slicelength;
  206. -
  207. -   while (first)
  208. +  
  209. +   while (first && (first->time <= globalTimer))
  210.     {
  211. -       if (first->time <= globalTimer)
  212. -       {
  213.  //         LOG(GEKKO, "[Scheduler] %s     (%lld, %lld) ",
  214.  //             first->name ? first->name : "?", (u64)globalTimer, (u64)first->time);
  215. -           Event* evt = first;
  216. -           first = first->next;
  217. -           event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
  218. -           FreeEvent(evt);
  219. -       }
  220. -       else
  221. -       {
  222. -           break;
  223. -       }
  224. +       Event* evt = first;
  225. +       first = first->next;
  226. +       event_types[evt->type].callback(evt->userdata, (int)(globalTimer - evt->time));
  227. +       FreeEvent(evt);
  228.     }
  229. -   if (!first)
  230. +   if (!first)
  231.     {
  232. -       WARN_LOG(POWERPC, "WARNING - no events in queue. Setting downcount to 10000");
  233. -       downcount += 10000;
  234. +       WARN_LOG(POWERPC, "WARNING - no events in queue. Setting slicelength to maxSliceLength;");
  235. +       slicelength = maxSliceLength;
  236.     }
  237.     else
  238.     {
  239.         slicelength = (int)(first->time - globalTimer);
  240.         if (slicelength > maxSliceLength)
  241.             slicelength = maxSliceLength;
  242. -       downcount = slicelength;
  243.     }
  244. +   downcount = slicelength;
  245. +
  246.     if (advanceCallback)
  247.         advanceCallback(cyclesExecuted);
  248.  }
  249.  
  250. +void Advance()
  251. +{
  252. +   MoveEvents();
  253. +
  254. +   int cyclesExecuted = slicelength - downcount;
  255. +   AdvanceCycles(cyclesExecuted);
  256. +}
  257. +
  258.  void LogPendingEvents()
  259.  {
  260.     Event *ptr = first;
  261. @@ -498,20 +474,24 @@
  262.  void Idle()
  263.  {
  264.     //DEBUG_LOG(POWERPC, "Idle");
  265. -  
  266. -   //When the FIFO is processing data we must not advance because in this way
  267. -   //the VI will be desynchronized. So, We are waiting until the FIFO finish and
  268. -   //while we process only the events required by the FIFO.
  269. -   while (CPluginManager::GetInstance().GetVideo()->Video_IsFifoBusy())
  270. +
  271. +   // Get asynchronous events
  272. +   MoveEvents();
  273. +
  274. +   // Idle until the next scheduled event (if it occurs before the end of the current time slice)
  275. +   // Otherwise, idle until the end of the current time slice
  276. +   if (first && ((first->time - globalTimer) < slicelength))
  277.     {
  278. -       ProcessFifoWaitEvents();       
  279. -       Common::YieldCPU();
  280. +       s64 cycles = first->time - globalTimer;
  281. +       if (cycles > downcount)
  282. +           idledCycles += cycles - downcount;
  283. +       AdvanceCycles(cycles);
  284.     }
  285. -
  286. -   idledCycles += downcount;
  287. -   downcount = 0;
  288. -  
  289. -   Advance();
  290. +   else
  291. +   {
  292. +       idledCycles += downcount;
  293. +       AdvanceCycles(slicelength);
  294. +   }
  295.  }
  296.  
  297.  std::string GetScheduledEventsSummary()
  298. Index: Source/Core/Core/Src/CoreTiming.h
  299. ===================================================================
  300. --- Source/Core/Core/Src/CoreTiming.h   (revision 6314)
  301. +++ Source/Core/Core/Src/CoreTiming.h   (working copy)
  302. @@ -56,8 +56,8 @@
  303.  
  304.  // userdata MAY NOT CONTAIN POINTERS. userdata might get written and reloaded from disk,
  305.  // when we implement state saves.
  306. -void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata=0);
  307. -void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata=0, bool fifoWait=false);
  308. +void ScheduleEvent(s64 cyclesIntoFuture, int event_type, u64 userdata=0);
  309. +void ScheduleEvent_Threadsafe(s64 cyclesIntoFuture, int event_type, u64 userdata=0);
  310.  void ScheduleEvent_Threadsafe_Immediate(int event_type, u64 userdata=0);
  311.  
  312.  // We only permit one event of each type in the queue at a time.
  313. @@ -67,7 +67,6 @@
  314.  bool IsScheduled(int event_type);
  315.  void Advance();
  316.  void MoveEvents();
  317. -void ProcessFifoWaitEvents();
  318.  
  319.  // Pretend that the main CPU has executed enough cycles to reach the next event.
  320.  void Idle();
  321. Index: Source/Core/Core/Src/HW/MemmapFunctions.cpp
  322. ===================================================================
  323. --- Source/Core/Core/Src/HW/MemmapFunctions.cpp (revision 6314)
  324. +++ Source/Core/Core/Src/HW/MemmapFunctions.cpp (working copy)
  325. @@ -602,7 +602,7 @@
  326.  
  327.     PowerPC::ppcState.spr[SPR_DAR] = _EffectiveAddress;
  328.  
  329. -   Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI);
  330. +   PowerPC::SetException(EXCEPTION_DSI, true);
  331.  }
  332.  
  333.  
  334. @@ -611,7 +611,7 @@
  335.     // Address of instruction could not be translated
  336.     NPC = _EffectiveAddress;
  337.  
  338. -   Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ISI);
  339. +   PowerPC::SetException(EXCEPTION_ISI, true);
  340.  }
  341.  
  342.  
  343. Index: Source/Core/Core/Src/HW/ProcessorInterface.cpp
  344. ===================================================================
  345. --- Source/Core/Core/Src/HW/ProcessorInterface.cpp  (revision 6314)
  346. +++ Source/Core/Core/Src/HW/ProcessorInterface.cpp  (working copy)
  347. @@ -57,6 +57,8 @@
  348.  u32 m_FlipperRev;
  349.  u32 m_Unknown;
  350.  
  351. +int et_UpdateException;
  352. +void UpdateExceptionCallback(u64 userdata, int cyclesLate);
  353.  
  354.  // ID and callback for scheduling reset button presses/releases
  355.  static int toggleResetButton;
  356. @@ -100,6 +102,7 @@
  357.     m_InterruptCause = INT_CAUSE_RST_BUTTON | INT_CAUSE_VI;
  358.  
  359.     toggleResetButton = CoreTiming::RegisterEvent("ToggleResetButton", &ToggleResetButtonCallback);
  360. +   et_UpdateException = CoreTiming::RegisterEvent("UpdateException", &UpdateExceptionCallback);
  361.  }
  362.  
  363.  void Read32(u32& _uReturnValue, const u32 _iAddress)
  364. @@ -201,12 +204,14 @@
  365.     }
  366.  }
  367.  
  368. +void UpdateExceptionCallback(u64 userdata, int cyclesLate)
  369. +{
  370. +   PowerPC::SetException(EXCEPTION_EXTERNAL_INT, !!userdata);
  371. +}
  372. +
  373.  void UpdateException()
  374.  {
  375. -   if ((m_InterruptCause & m_InterruptMask) != 0)
  376. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_EXTERNAL_INT);
  377. -   else
  378. -       Common::AtomicAnd(PowerPC::ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT);
  379. +   CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateException, ((m_InterruptCause & m_InterruptMask) != 0));
  380.  }
  381.  
  382.  static const char *Debug_GetInterruptName(u32 _causemask)
  383. Index: Source/Core/Core/Src/HW/SystemTimers.cpp
  384. ===================================================================
  385. --- Source/Core/Core/Src/HW/SystemTimers.cpp    (revision 6314)
  386. +++ Source/Core/Core/Src/HW/SystemTimers.cpp    (working copy)
  387. @@ -194,7 +194,7 @@
  388.  void DecrementerCallback(u64 userdata, int cyclesLate)
  389.  {
  390.     PowerPC::ppcState.spr[SPR_DEC] = 0xFFFFFFFF;
  391. -   Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER);
  392. +   PowerPC::SetException(EXCEPTION_DECREMENTER, true);
  393.  }
  394.  
  395.  void DecrementerSet()
  396. Index: Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp
  397. ===================================================================
  398. --- Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp    (revision 6314)
  399. +++ Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp    (working copy)
  400. @@ -140,7 +140,7 @@
  401.             }
  402.             else
  403.             {
  404. -               Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE);
  405. +               PowerPC::SetException(EXCEPTION_FPU_UNAVAILABLE, true);
  406.                 PowerPC::CheckExceptions();
  407.                 m_EndBlock = true;
  408.             }
  409. Index: Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp
  410. ===================================================================
  411. --- Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp (revision 6314)
  412. +++ Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp (working copy)
  413. @@ -135,7 +135,7 @@
  414.  // We do it anyway, though :P
  415.  void Interpreter::sc(UGeckoInstruction _inst)
  416.  {
  417. -   Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_SYSCALL);
  418. +   PowerPC::SetException(EXCEPTION_SYSCALL, true);
  419.     PowerPC::CheckExceptions();
  420.     m_EndBlock = true;
  421.  }
  422. Index: Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp
  423. ===================================================================
  424. --- Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp    (revision 6314)
  425. +++ Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp    (working copy)
  426. @@ -175,7 +175,7 @@
  427.         || (((u32)a <(u32)b) && (TO & 0x02))
  428.         || (((u32)a >(u32)b) && (TO & 0x01)))
  429.     {
  430. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_PROGRAM);
  431. +       PowerPC::SetException(EXCEPTION_PROGRAM, true);
  432.         PowerPC::CheckExceptions();
  433.         m_EndBlock = true; // Dunno about this
  434.     }
  435. @@ -403,7 +403,7 @@
  436.         || (((u32)a <(u32)b) && (TO & 0x02))
  437.         || (((u32)a >(u32)b) && (TO & 0x01)))
  438.     {
  439. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_PROGRAM);
  440. +       PowerPC::SetException(EXCEPTION_PROGRAM, true);
  441.         PowerPC::CheckExceptions();
  442.         m_EndBlock = true; // Dunno about this
  443.     }
  444. Index: Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
  445. ===================================================================
  446. --- Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp  (revision 6314)
  447. +++ Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp  (working copy)
  448. @@ -406,10 +406,10 @@
  449.  
  450.     if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000))
  451.     {
  452. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI);
  453. +       PowerPC::SetException(EXCEPTION_DSI, true);
  454.     }
  455.     if (EA & 3)
  456. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ALIGNMENT);
  457. +       PowerPC::SetException(EXCEPTION_ALIGNMENT, true);
  458.  
  459.  //     _assert_msg_(POWERPC,0,"eciwx - fill r%i with word @ %08x from device %02x",
  460.  //         _inst.RS, EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f);
  461. @@ -428,10 +428,10 @@
  462.  
  463.     if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000))
  464.     {
  465. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI);
  466. +       PowerPC::SetException(EXCEPTION_DSI, true);
  467.     }
  468.     if (EA & 3)
  469. -       Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ALIGNMENT);
  470. +       PowerPC::SetException(EXCEPTION_ALIGNMENT, true);
  471.    
  472.  //     _assert_msg_(POWERPC,0,"ecowx - send stw request (%08x@%08x) to device %02x",
  473.  //         m_GPR[_inst.RS], EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f);
  474. Index: Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp
  475. ===================================================================
  476. --- Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp    (revision 6314)
  477. +++ Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp    (working copy)
  478. @@ -425,7 +425,7 @@
  479.         if (!(oldValue >> 31) && (m_GPR[_inst.RD]>>31))   //top bit from 0 to 1
  480.         {
  481.             PanicAlert("Interesting - Software triggered Decrementer exception");
  482. -           Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER);
  483. +           PowerPC::SetException(EXCEPTION_DECREMENTER, true);
  484.         }
  485.         SystemTimers::DecrementerSet();
  486.         break;
  487. Index: Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp
  488. ===================================================================
  489. --- Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp  (revision 6314)
  490. +++ Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp  (working copy)
  491. @@ -23,6 +23,7 @@
  492.  #endif
  493.  
  494.  #include "Common.h"
  495. +#include "Atomic.h"
  496.  #include "x64Emitter.h"
  497.  #include "ABI.h"
  498.  #include "Thunk.h"
  499. @@ -207,8 +208,25 @@
  500.  
  501.     blocks.Init();
  502.     asm_routines.Init();
  503. +
  504. +   pNextDispatcher = asm_routines.dispatcherDefault;
  505.  }
  506.  
  507. +void Jit64::Synchronize()
  508. +{
  509. +   // Set the next dispatcher so that it will call CoreTiming::Advance()
  510. +   // This is useful when a new CoreTiming event has been scheduled before the end of the current time slice.
  511. +   pNextDispatcher = asm_routines.doTiming;
  512. +}
  513. +
  514. +void Jit64::OnExceptionUpdated()
  515. +{
  516. +   // Set the next dispatcher so that it will check for exception.
  517. +   // It won't be replaced if the previous value is not set to the default dispatcher.
  518. +   // This will prevent Synchronize requests from being discarded
  519. +   Common::AtomicCompareExchange((void *&)pNextDispatcher, (void *)asm_routines.dispatcherException, (void *)asm_routines.dispatcherDefault);
  520. +}
  521. +
  522.  void Jit64::ClearCache()
  523.  {
  524.     blocks.Clear();
  525. @@ -299,7 +317,7 @@
  526.  void Jit64::WriteExit(u32 destination, int exit_num)
  527.  {
  528.     Cleanup();
  529. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  530. +   SUB(32, M((void *)&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  531.  
  532.     //If nobody has taken care of this yet (this can be removed when all branches are done)
  533.     JitBlock *b = js.curBlock;
  534. @@ -317,7 +335,17 @@
  535.     else
  536.     {
  537.         MOV(32, M(&PC), Imm32(destination));
  538. -       JMP(asm_routines.dispatcher, true);
  539. +#ifdef _M_X64
  540. +       LEA(64, RAX, M((void *)asm_routines.dispatcherDefault));
  541. +       LOCK();
  542. +       XCHG(64, M((void *)&pNextDispatcher), R(RAX));
  543. +       JMPptr(R(RAX));
  544. +#else
  545. +       LEA(32, EAX, M((void *)asm_routines.dispatcherDefault));
  546. +       LOCK();
  547. +       XCHG(32, M((void *)&pNextDispatcher), R(EAX));
  548. +       JMPptr(R(EAX));
  549. +#endif
  550.     }
  551.  }
  552.  
  553. @@ -325,23 +353,31 @@
  554.  {
  555.     MOV(32, M(&PC), R(EAX));
  556.     Cleanup();
  557. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  558. -   JMP(asm_routines.dispatcher, true);
  559. +   SUB(32, M((void *)&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  560. +#ifdef _M_X64
  561. +   LEA(64, RAX, M((void *)asm_routines.dispatcherDefault));
  562. +   LOCK();
  563. +   XCHG(64, M((void *)&pNextDispatcher), R(RAX));
  564. +   JMPptr(R(RAX));
  565. +#else
  566. +   LEA(32, EAX, M((void *)asm_routines.dispatcherDefault));
  567. +   LOCK();
  568. +   XCHG(32, M((void *)&pNextDispatcher), R(EAX));
  569. +   JMPptr(R(EAX));
  570. +#endif
  571.  }
  572.  
  573.  void Jit64::WriteRfiExitDestInEAX()
  574.  {
  575.     MOV(32, M(&PC), R(EAX));
  576. -   Cleanup();
  577. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  578. -   JMP(asm_routines.testExceptions, true);
  579. +   WriteExceptionExit();
  580.  }
  581.  
  582.  void Jit64::WriteExceptionExit()
  583.  {
  584.     Cleanup();
  585. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  586. -   JMP(asm_routines.testExceptions, true);
  587. +   SUB(32, M((void *)&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  588. +   JMP(asm_routines.dispatcherException, true);
  589.  }
  590.  
  591.  void STACKALIGN Jit64::Run()
  592. @@ -433,6 +469,7 @@
  593.     js.curBlock = b;
  594.     js.block_flags = 0;
  595.     js.cancel = false;
  596. +   js.downcountAmount = 0;
  597.  
  598.     // Analyze the block, collect all instructions it is made of (including inlining,
  599.     // if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
  600. @@ -469,8 +506,15 @@
  601.         // This block uses FPU - needs to add FP exception bailout
  602.         TEST(32, M(&PowerPC::ppcState.msr), Imm32(1 << 13)); //Test FP enabled bit
  603.         FixupBranch b1 = J_CC(CC_NZ);
  604. +
  605. +       // Raise FPU Unavailable exception
  606. +       LOCK();
  607. +       OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
  608. +
  609. +       // If a FPU exception occurs, the exception handler will read
  610. +       // from PC.  Update PC with the latest value in case that happens.
  611.         MOV(32, M(&PC), Imm32(js.blockStart));
  612. -       JMP(asm_routines.fpException, true);
  613. +       WriteExceptionExit();
  614.         SetJumpTarget(b1);
  615.     }
  616.  
  617. @@ -497,7 +541,6 @@
  618.     gpr.Start(js.gpa);
  619.     fpr.Start(js.fpa);
  620.  
  621. -   js.downcountAmount = 0;
  622.     if (!Core::g_CoreStartupParameter.bEnableDebugging)
  623.     {
  624.         for (int i = 0; i < size_of_merged_addresses; ++i)
  625. @@ -555,11 +598,14 @@
  626.                 TEST(32, M(&PowerPC::ppcState.msr), Imm32(1 << 13)); // Test FP enabled bit
  627.                 FixupBranch b1 = J_CC(CC_NZ);
  628.  
  629. +               // Raise FPU Unavailable exception
  630. +               LOCK();
  631. +               OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
  632. +
  633.                 // If a FPU exception occurs, the exception handler will read
  634.                 // from PC.  Update PC with the latest value in case that happens.
  635.                 MOV(32, M(&PC), Imm32(ops[i].address));
  636. -               SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  637. -               JMP(asm_routines.fpException, true);
  638. +               WriteExceptionExit();
  639.                 SetJumpTarget(b1);
  640.             }
  641.  
  642. @@ -604,6 +650,7 @@
  643.     {
  644.         // Address of instruction could not be translated
  645.         MOV(32, M(&NPC), Imm32(js.compilerPC));
  646. +       LOCK();
  647.         OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI));
  648.  
  649.         // Remove the invalid instruction from the icache, forcing a recompile
  650. Index: Source/Core/Core/Src/PowerPC/Jit64/Jit.h
  651. ===================================================================
  652. --- Source/Core/Core/Src/PowerPC/Jit64/Jit.h    (revision 6314)
  653. +++ Source/Core/Core/Src/PowerPC/Jit64/Jit.h    (working copy)
  654. @@ -99,6 +99,9 @@
  655.     PPCAnalyst::CodeBuffer code_buffer;
  656.     Jit64AsmRoutineManager asm_routines;
  657.  
  658. +   // Address of the next dispatcher to call at the end of the current JIT block
  659. +   const u8 * volatile pNextDispatcher;
  660. +
  661.  public:
  662.     Jit64() : code_buffer(32000) {}
  663.     ~Jit64() {}
  664. @@ -119,9 +122,10 @@
  665.  
  666.     void ClearCache();
  667.  
  668. -   const u8 *GetDispatcher() {
  669. -       return asm_routines.dispatcher;
  670. -   }
  671. +   void Synchronize();
  672. +
  673. +   void OnExceptionUpdated();
  674. +
  675.     const CommonAsmRoutines *GetAsmRoutines() {
  676.         return &asm_routines;
  677.     }
  678. Index: Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
  679. ===================================================================
  680. --- Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp    (revision 6314)
  681. +++ Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp    (working copy)
  682. @@ -119,44 +119,57 @@
  683.     // IMHO those Idles should always be skipped and replaced by a more controllable "native" Idle methode
  684.     // ... maybe the throttle one already do that :p
  685.     // if (CommandProcessor::AllowIdleSkipping() && PixelEngine::AllowIdleSkipping())
  686. -   if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle &&
  687. -       inst.OPCD == 32 &&
  688. -       (inst.hex & 0xFFFF0000) == 0x800D0000 &&
  689. -       (Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x28000000 ||
  690. -       (SConfig::GetInstance().m_LocalCoreStartupParameter.bWii && Memory::ReadUnchecked_U32(js.compilerPC + 4) == 0x2C000000)) &&
  691. -       Memory::ReadUnchecked_U32(js.compilerPC + 8) == 0x4182fff8)
  692. +   if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSkipIdle && (inst.OPCD == 32 /* lwz */))
  693.     {
  694. -       // TODO(LinesPrower):          
  695. -       // - Rewrite this!
  696. -       // It seems to be ugly and inefficient, but I don't know JIT stuff enough to make it right
  697. -       // It only demonstrates the idea
  698. +       u32 compareInst = Memory::ReadUnchecked_U32(js.compilerPC + 4);
  699. +       if ((((compareInst & 0xFC600000) == 0x2C000000) /* cmpi */ ||
  700. +            ((compareInst & 0xFC600000) == 0x28000000) /* cmpli */) &&
  701. +           (((compareInst & 0x001F0000) >> 16) == d))
  702. +       {
  703. +           int CRField = (compareInst & 0x03800000) >> 23;
  704. +           u32 branchInst = Memory::ReadUnchecked_U32(js.compilerPC + 8);
  705. +           if ((branchInst & 0xFE80FFFF) == 0x4080FFF8) /* bcx */
  706. +           {
  707. +               int CRBit = (branchInst & 0x001F0000) >> 16;
  708. +               if (((CRBit / 4) == CRField) && ((CRBit % 4) != 3))
  709. +               {
  710. +                   s32 offset = (s32)(s16)inst.SIMM_16;
  711. +                   gpr.Lock(d);
  712. +                   SafeLoadToEAX(gpr.R(a), accessSize, offset, signExtend);
  713. +                   gpr.KillImmediate(d, false, true);
  714. +                   MOV(32, gpr.R(d), R(EAX));
  715. +                   gpr.UnlockAll();
  716. +                  
  717. +                   gpr.Flush(FLUSH_ALL);
  718. +                   fpr.Flush(FLUSH_ALL);
  719.  
  720. -       // do our job at first
  721. -       s32 offset = (s32)(s16)inst.SIMM_16;
  722. -       gpr.Lock(d);
  723. -       SafeLoadToEAX(gpr.R(a), accessSize, offset, signExtend);
  724. -       gpr.KillImmediate(d, false, true);
  725. -       MOV(32, gpr.R(d), R(EAX));
  726. -       gpr.UnlockAll();
  727. -      
  728. -       gpr.Flush(FLUSH_ALL);
  729. +                   CRBit %= 4;
  730. +                   FixupBranch noIdle;
  731. +                   if ((compareInst & 0xFC600000) == 0x2C000000) /* cmpi */
  732. +                   {
  733. +                       CMP(32, R(EAX), Imm32((u32)(s32)(s16)(compareInst & 0x0000FFFF)));
  734. +                       if (CRBit == 0) noIdle = J_CC(((branchInst & 0x01000000) != 0) ? CC_NL : CC_L);
  735. +                       else if (CRBit == 1) noIdle = J_CC(((branchInst & 0x01000000) != 0) ? CC_NG : CC_G);
  736. +                       else if (CRBit == 2) noIdle = J_CC(((branchInst & 0x01000000) != 0) ? CC_NE : CC_E);
  737. +                   }
  738. +                   else if((compareInst & 0xFC600000) == 0x28000000) /* cmpli */
  739. +                   {
  740. +                       CMP(32, R(EAX), Imm32((u32)(compareInst & 0x0000FFFF)));
  741. +                       if (CRBit == 0) noIdle = J_CC(((branchInst & 0x01000000) != 0) ? CC_NB : CC_B);
  742. +                       else if (CRBit == 1) noIdle = J_CC(((branchInst & 0x01000000) != 0) ? CC_NA : CC_A);
  743. +                       else if (CRBit == 2) noIdle = J_CC(((branchInst & 0x01000000) != 0) ? CC_NE : CC_E);
  744. +                   }
  745. +                  
  746. +                   ABI_CallFunctionC((void *)&PowerPC::OnIdle, PowerPC::ppcState.gpr[a] + (s32)(s16)inst.SIMM_16);
  747.  
  748. -       // if it's still 0, we can wait until the next event
  749. -       TEST(32, R(EAX), R(EAX));
  750. -       FixupBranch noIdle = J_CC(CC_NZ);
  751. -
  752. -       gpr.Flush(FLUSH_ALL);
  753. -       fpr.Flush(FLUSH_ALL);
  754. -       ABI_CallFunctionC((void *)&PowerPC::OnIdle, PowerPC::ppcState.gpr[a] + (s32)(s16)inst.SIMM_16);
  755. -
  756. -       // ! we must continue executing of the loop after exception handling, maybe there is still 0 in r0
  757. -       //MOV(32, M(&PowerPC::ppcState.pc), Imm32(js.compilerPC));
  758. -       JMP(asm_routines.testExceptions, true);        
  759. -
  760. -       SetJumpTarget(noIdle);
  761. -
  762. -       //js.compilerPC += 8;
  763. -       return;
  764. +                   MOV(32, M(&PowerPC::ppcState.pc), Imm32(js.compilerPC));
  765. +                   WriteExceptionExit();
  766. +                  
  767. +                   SetJumpTarget(noIdle);
  768. +                   return;
  769. +               }
  770. +           }
  771. +       }
  772.     }
  773.    
  774.     // Determine whether this instruction updates inst.RA
  775. Index: Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp
  776. ===================================================================
  777. --- Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp   (revision 6314)
  778. +++ Source/Core/Core/Src/PowerPC/Jit64/JitAsm.cpp   (working copy)
  779. @@ -70,11 +70,10 @@
  780.     MOV(64, R(R15), Imm64((u64)jit->GetBlockCache()->GetCodePointers())); //It's below 2GB so 32 bits are good enough
  781.  #endif
  782.  
  783. -   const u8 *outerLoop = GetCodePtr();
  784.         ABI_CallFunction(reinterpret_cast<void *>(&CoreTiming::Advance));
  785.         FixupBranch skipToRealDispatch = J(); //skip the sync and compare first time
  786.      
  787. -       dispatcher = GetCodePtr();
  788. +       dispatcherDefault = GetCodePtr();
  789.             // The result of slice decrementation should be in flags if somebody jumped here
  790.             // IMPORTANT - We jump on negative, not carry!!!
  791.             FixupBranch bail = J_CC(CC_BE, true);
  792. @@ -191,24 +190,19 @@
  793.  #endif
  794.             JMP(dispatcherNoCheck); // no point in special casing this
  795.  
  796. -           //FP blocks test for FPU available, jump here if false
  797. -           fpException = AlignCode4();
  798. -           LOCK();
  799. -           OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
  800. -           ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
  801. -           MOV(32, R(EAX), M(&NPC));
  802. -           MOV(32, M(&PC), R(EAX));
  803. -           JMP(dispatcher, true);
  804. +       dispatcherException = GetCodePtr();
  805. +       FixupBranch skipTiming = J_CC(CC_NBE);
  806.  
  807.         SetJumpTarget(bail);
  808.         doTiming = GetCodePtr();
  809.  
  810.         ABI_CallFunction(reinterpret_cast<void *>(&CoreTiming::Advance));
  811. -      
  812. +
  813. +       SetJumpTarget(skipTiming);
  814.         testExceptions = GetCodePtr();
  815. +       MOV(32, R(EAX), M(&PC));
  816.         TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF));
  817.         FixupBranch skipExceptions = J_CC(CC_Z);
  818. -           MOV(32, R(EAX), M(&PC));
  819.             MOV(32, M(&NPC), R(EAX));
  820.             ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
  821.             MOV(32, R(EAX), M(&NPC));
  822. @@ -216,17 +210,12 @@
  823.         SetJumpTarget(skipExceptions);
  824.        
  825.         TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
  826. -       J_CC(CC_Z, outerLoop, true);
  827. +       J_CC(CC_Z, dispatcherPcInEAX, true);
  828.  
  829.     //Landing pad for drec space
  830.     ABI_PopAllCalleeSavedRegsAndAdjustStack();
  831.     RET();
  832.  
  833. -   breakpointBailout = GetCodePtr();
  834. -   //Landing pad for drec space
  835. -   ABI_PopAllCalleeSavedRegsAndAdjustStack();
  836. -   RET();
  837. -
  838.     GenerateCommon();
  839.  }
  840.  
  841. Index: Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp
  842. ===================================================================
  843. --- Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp (revision 6314)
  844. +++ Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp (working copy)
  845. @@ -705,7 +705,7 @@
  846.             RI.Jit->MOV(32, M(&PC), R(EAX));
  847.         }
  848.         RI.Jit->Cleanup();
  849. -       RI.Jit->SUB(32, M(&CoreTiming::downcount), Imm32(RI.Jit->js.downcountAmount));
  850. +       RI.Jit->SUB(32, M((void *)&CoreTiming::downcount), Imm32(RI.Jit->js.downcountAmount));
  851.         RI.Jit->JMP(((JitIL *)jit)->asm_routines.doReJit, true);
  852.         return;
  853.     }
  854. @@ -1864,11 +1864,14 @@
  855.             Jit->TEST(32, M(&PowerPC::ppcState.msr), Imm32(1 << 13)); // Test FP enabled bit
  856.             FixupBranch b1 = Jit->J_CC(CC_NZ);
  857.  
  858. +           // Raise FPU Unavailable exception
  859. +           Jit->LOCK();
  860. +           Jit->OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
  861. +
  862.             // If a FPU exception occurs, the exception handler will read
  863.             // from PC.  Update PC with the latest value in case that happens.
  864.             Jit->MOV(32, M(&PC), Imm32(InstLoc));
  865. -           Jit->SUB(32, M(&CoreTiming::downcount), Jit->js.downcountAmount > 127 ? Imm32(Jit->js.downcountAmount) : Imm8(Jit->js.downcountAmount));
  866. -           Jit->JMP(Jit->asm_routines.fpException, true);
  867. +           Jit->WriteExceptionExit();
  868.             Jit->SetJumpTarget(b1);
  869.             break;
  870.         }
  871. @@ -1889,6 +1892,7 @@
  872.  
  873.             // Address of instruction could not be translated
  874.             Jit->MOV(32, M(&NPC), Imm32(InstLoc));
  875. +           Jit->LOCK();
  876.             Jit->OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_ISI));
  877.  
  878.             // Remove the invalid instruction from the icache, forcing a recompile
  879. Index: Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp
  880. ===================================================================
  881. --- Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp  (revision 6314)
  882. +++ Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp  (working copy)
  883. @@ -18,6 +18,7 @@
  884.  #include <map>
  885.  
  886.  #include "Common.h"
  887. +#include "Atomic.h"
  888.  #include "x64Emitter.h"
  889.  #include "ABI.h"
  890.  #include "Thunk.h"
  891. @@ -194,8 +195,25 @@
  892.  
  893.     blocks.Init();
  894.     asm_routines.Init();
  895. +
  896. +   pNextDispatcher = asm_routines.dispatcherDefault;
  897.  }
  898.  
  899. +void JitIL::Synchronize()
  900. +{
  901. +   // Set the next dispatcher so that it will call CoreTiming::Advance()
  902. +   // This is useful when a new CoreTiming event has been scheduled before the end of the current time slice.
  903. +   pNextDispatcher = asm_routines.doTiming;
  904. +}
  905. +
  906. +void JitIL::OnExceptionUpdated()
  907. +{
  908. +   // Set the next dispatcher so that it will check for exception.
  909. +   // It won't be replaced if the previous value is not set to the default dispatcher.
  910. +   // This will prevent Synchronize requests from being discarded
  911. +   Common::AtomicCompareExchange((void *&)pNextDispatcher, (void *)asm_routines.dispatcherException, (void *)asm_routines.dispatcherDefault);
  912. +}
  913. +
  914.  void JitIL::ClearCache()
  915.  {
  916.     blocks.Clear();
  917. @@ -292,7 +310,7 @@
  918.  void JitIL::WriteExit(u32 destination, int exit_num)
  919.  {
  920.     Cleanup();
  921. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  922. +   SUB(32, M((void *)&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  923.  
  924.     //If nobody has taken care of this yet (this can be removed when all branches are done)
  925.     JitBlock *b = js.curBlock;
  926. @@ -310,7 +328,17 @@
  927.     else
  928.     {
  929.         MOV(32, M(&PC), Imm32(destination));
  930. -       JMP(asm_routines.dispatcher, true);
  931. +#ifdef _M_X64
  932. +       LEA(64, RAX, M((void *)asm_routines.dispatcherDefault));
  933. +       LOCK();
  934. +       XCHG(64, M((void *)&pNextDispatcher), R(RAX));
  935. +       JMPptr(R(RAX));
  936. +#else
  937. +       LEA(32, EAX, M((void *)asm_routines.dispatcherDefault));
  938. +       LOCK();
  939. +       XCHG(32, M((void *)&pNextDispatcher), R(EAX));
  940. +       JMPptr(R(EAX));
  941. +#endif
  942.     }
  943.  }
  944.  
  945. @@ -318,23 +346,31 @@
  946.  {
  947.     MOV(32, M(&PC), arg);
  948.     Cleanup();
  949. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  950. -   JMP(asm_routines.dispatcher, true);
  951. +   SUB(32, M((void *)&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  952. +#ifdef _M_X64
  953. +   LEA(64, RAX, M((void *)asm_routines.dispatcherDefault));
  954. +   LOCK();
  955. +   XCHG(64, M((void *)&pNextDispatcher), R(RAX));
  956. +   JMPptr(R(RAX));
  957. +#else
  958. +   LEA(32, EAX, M((void *)asm_routines.dispatcherDefault));
  959. +   LOCK();
  960. +   XCHG(32, M((void *)&pNextDispatcher), R(EAX));
  961. +   JMPptr(R(EAX));
  962. +#endif
  963.  }
  964.  
  965.  void JitIL::WriteRfiExitDestInOpArg(const Gen::OpArg& arg)
  966.  {
  967.     MOV(32, M(&PC), arg);
  968. -   Cleanup();
  969. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  970. -   JMP(asm_routines.testExceptions, true);
  971. +   WriteExceptionExit();
  972.  }
  973.  
  974.  void JitIL::WriteExceptionExit()
  975.  {
  976.     Cleanup();
  977. -   SUB(32, M(&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  978. -   JMP(asm_routines.testExceptions, true);
  979. +   SUB(32, M((void *)&CoreTiming::downcount), js.downcountAmount > 127 ? Imm32(js.downcountAmount) : Imm8(js.downcountAmount));
  980. +   JMP(asm_routines.dispatcherException, true);
  981.  }
  982.  
  983.  void STACKALIGN JitIL::Run()
  984. @@ -425,6 +461,7 @@
  985.     js.fifoBytesThisBlock = 0;
  986.     js.curBlock = b;
  987.     js.cancel = false;
  988. +   js.downcountAmount = 0;
  989.  
  990.     // Analyze the block, collect all instructions it is made of (including inlining,
  991.     // if that is enabled), reorder instructions for optimal performance, and join joinable instructions.
  992. @@ -460,8 +497,13 @@
  993.         // This block uses FPU - needs to add FP exception bailout
  994.         TEST(32, M(&PowerPC::ppcState.msr), Imm32(1 << 13)); //Test FP enabled bit
  995.         FixupBranch b1 = J_CC(CC_NZ);
  996. +
  997. +       // Raise FPU Unavailable exception
  998. +       LOCK();
  999. +       OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
  1000. +
  1001.         MOV(32, M(&PC), Imm32(js.blockStart));
  1002. -       JMP(asm_routines.fpException, true);
  1003. +       WriteExceptionExit();
  1004.         SetJumpTarget(b1);
  1005.     }
  1006.  
  1007. @@ -471,7 +513,6 @@
  1008.     // instruction processed by the JIT routines)
  1009.     ibuild.Reset();
  1010.  
  1011. -   js.downcountAmount = 0;
  1012.     if (!Core::g_CoreStartupParameter.bEnableDebugging)
  1013.     {
  1014.         for (int i = 0; i < size_of_merged_addresses; ++i)
  1015. Index: Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h
  1016. ===================================================================
  1017. --- Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h    (revision 6314)
  1018. +++ Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.h    (working copy)
  1019. @@ -69,6 +69,9 @@
  1020.  public:
  1021.     JitILAsmRoutineManager asm_routines;
  1022.  
  1023. +   // Address of the next dispatcher to call at the end of the current JIT block
  1024. +   const u8 * volatile pNextDispatcher;
  1025. +
  1026.     JitIL() : code_buffer(32000) {}
  1027.     ~JitIL() {}
  1028.  
  1029. @@ -87,9 +90,11 @@
  1030.     void Trace();
  1031.  
  1032.     void ClearCache();
  1033. -   const u8 *GetDispatcher() {
  1034. -       return asm_routines.dispatcher;  // asm_routines.dispatcher
  1035. -   }
  1036. +
  1037. +   void Synchronize();
  1038. +
  1039. +   void OnExceptionUpdated();
  1040. +
  1041.     const CommonAsmRoutines *GetAsmRoutines() {
  1042.         return &asm_routines;
  1043.     }
  1044. Index: Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp
  1045. ===================================================================
  1046. --- Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp   (revision 6314)
  1047. +++ Source/Core/Core/Src/PowerPC/Jit64IL/JitILAsm.cpp   (working copy)
  1048. @@ -71,11 +71,10 @@
  1049.  #endif
  1050.  // INT3();
  1051.  
  1052. -   const u8 *outerLoop = GetCodePtr();
  1053.         ABI_CallFunction(reinterpret_cast<void *>(&CoreTiming::Advance));
  1054.         FixupBranch skipToRealDispatch = J(); //skip the sync and compare first time
  1055.    
  1056. -       dispatcher = GetCodePtr();
  1057. +       dispatcherDefault = GetCodePtr();
  1058.             //This is the place for CPUCompare!
  1059.  
  1060.             //The result of slice decrement should be in flags if somebody jumped here
  1061. @@ -193,26 +192,20 @@
  1062.  #endif
  1063.             JMP(dispatcherNoCheck); // no point in special casing this
  1064.  
  1065. -           //FP blocks test for FPU available, jump here if false
  1066. -           fpException = AlignCode4();
  1067. -           MOV(32, R(EAX), M(&PC));
  1068. -           MOV(32, M(&NPC), R(EAX));
  1069. -           LOCK();
  1070. -           OR(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(EXCEPTION_FPU_UNAVAILABLE));
  1071. -           ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
  1072. -           MOV(32, R(EAX), M(&NPC));
  1073. -           MOV(32, M(&PC), R(EAX));
  1074. -           JMP(dispatcher, true);
  1075.  
  1076. +       dispatcherException = GetCodePtr();
  1077. +       FixupBranch skipTiming = J_CC(CC_NBE);
  1078. +
  1079.         SetJumpTarget(bail);
  1080.         doTiming = GetCodePtr();
  1081.  
  1082.         ABI_CallFunction(reinterpret_cast<void *>(&CoreTiming::Advance));
  1083.        
  1084. +       SetJumpTarget(skipTiming);
  1085.         testExceptions = GetCodePtr();
  1086. +       MOV(32, R(EAX), M(&PC));
  1087.         TEST(32, M((void *)&PowerPC::ppcState.Exceptions), Imm32(0xFFFFFFFF));
  1088.         FixupBranch skipExceptions = J_CC(CC_Z);
  1089. -           MOV(32, R(EAX), M(&PC));
  1090.             MOV(32, M(&NPC), R(EAX));
  1091.             ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExceptions));
  1092.             MOV(32, R(EAX), M(&NPC));
  1093. @@ -220,16 +213,11 @@
  1094.         SetJumpTarget(skipExceptions);
  1095.        
  1096.         TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
  1097. -       J_CC(CC_Z, outerLoop, true);
  1098. +       J_CC(CC_Z, dispatcherPcInEAX, true);
  1099.     //Landing pad for drec space
  1100.     ABI_PopAllCalleeSavedRegsAndAdjustStack();
  1101.     RET();
  1102.  
  1103. -   breakpointBailout = GetCodePtr();
  1104. -   //Landing pad for drec space
  1105. -   ABI_PopAllCalleeSavedRegsAndAdjustStack();
  1106. -   RET();
  1107. -
  1108.     GenerateCommon();
  1109.  }
  1110.  
  1111. @@ -250,8 +238,8 @@
  1112.     ABI_AlignStack(0);
  1113.     CALL(reinterpret_cast<void *>(&ProfiledReJit));
  1114.     ABI_RestoreStack(0);
  1115. -   SUB(32, M(&CoreTiming::downcount), Imm8(0));
  1116. -   JMP(dispatcher, true);
  1117. +   SUB(32, M((void *)&CoreTiming::downcount), Imm8(0));
  1118. +   JMP(dispatcherDefault, true);
  1119.  
  1120.     GenQuantizedLoads();
  1121.     GenQuantizedStores();
  1122. Index: Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h
  1123. ===================================================================
  1124. --- Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h   (revision 6314)
  1125. +++ Source/Core/Core/Src/PowerPC/JitCommon/JitAsmCommon.h   (working copy)
  1126. @@ -40,17 +40,14 @@
  1127.  
  1128.     const u8 *enterCode;
  1129.  
  1130. -   const u8 *dispatcher;
  1131. +   const u8 *dispatcherDefault;
  1132.     const u8 *dispatcherNoCheck;
  1133.     const u8 *dispatcherPcInEAX;
  1134. +   const u8 *dispatcherException;
  1135.  
  1136. -   const u8 *fpException;
  1137.     const u8 *testExceptions;
  1138. -   const u8 *dispatchPcInEAX;
  1139.     const u8 *doTiming;
  1140.  
  1141. -   const u8 *breakpointBailout;
  1142. -
  1143.     // In: array index: GQR to use.
  1144.     // In: ECX: Address to read from.
  1145.     // Out: XMM0: Bottom two 32-bit slots hold the read value,
  1146. Index: Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h
  1147. ===================================================================
  1148. --- Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h    (revision 6314)
  1149. +++ Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h    (working copy)
  1150. @@ -89,6 +89,9 @@
  1151.     const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx);
  1152.  
  1153.     virtual const CommonAsmRoutines *GetAsmRoutines() = 0;
  1154. +
  1155. +   virtual void Synchronize() = 0;
  1156. +   virtual void OnExceptionUpdated() = 0;
  1157.  };
  1158.  
  1159.  extern JitBase *jit;
  1160. Index: Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp
  1161. ===================================================================
  1162. --- Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp (revision 6314)
  1163. +++ Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp (working copy)
  1164. @@ -380,7 +380,7 @@
  1165.         // Spurious entrances from previously linked blocks can only come through checkedEntry
  1166.         XEmitter emit((u8 *)b.checkedEntry);
  1167.         emit.MOV(32, M(&PC), Imm32(b.originalAddress));
  1168. -       emit.JMP(jit->GetAsmRoutines()->dispatcher, true);
  1169. +       emit.JMP(jit->GetAsmRoutines()->dispatcherNoCheck, true);
  1170.         // this is not needed really
  1171.         /*
  1172.         emit.SetCodePtr((u8 *)blockCodePointers[blocknum]);
  1173. Index: Source/Core/Core/Src/PowerPC/PowerPC.cpp
  1174. ===================================================================
  1175. --- Source/Core/Core/Src/PowerPC/PowerPC.cpp    (revision 6314)
  1176. +++ Source/Core/Core/Src/PowerPC/PowerPC.cpp    (working copy)
  1177. @@ -270,6 +270,25 @@
  1178.     Host_UpdateDisasmDialog();
  1179.  }
  1180.  
  1181. +void Synchronize()
  1182. +{
  1183. +   if (jit)
  1184. +       jit->Synchronize();
  1185. +}
  1186. +
  1187. +void SetException(u32 exception, bool active)
  1188. +{
  1189. +   if (active)
  1190. +   {
  1191. +       if ((Common::AtomicOr(ppcState.Exceptions, exception) & exception) == 0)
  1192. +           if (jit) jit->OnExceptionUpdated(); // Notify JIT compiler when a new exception is raised
  1193. +   }
  1194. +   else
  1195. +   {
  1196. +       Common::AtomicAnd(ppcState.Exceptions, ~exception);
  1197. +   }
  1198. +}
  1199. +
  1200.  void CheckExceptions()
  1201.  {
  1202.     // Read volatile data once
  1203. @@ -400,6 +419,10 @@
  1204.             ERROR_LOG(POWERPC, "Unknown EXTERNAL INTERRUPT exception: Exceptions == %08x", exceptions);
  1205.         }
  1206.     }
  1207. +
  1208. +   // Force the JIT to check for the remaining exception at the end of the next block
  1209. +   if (jit && ppcState.Exceptions)
  1210. +       jit->OnExceptionUpdated();
  1211.  }
  1212.  
  1213.  void CheckBreakPoints()
  1214. @@ -414,9 +437,9 @@
  1215.  
  1216.  void OnIdle(u32 _uThreadAddr)
  1217.  {
  1218. -   u32 nextThread = Memory::Read_U32(_uThreadAddr);
  1219. +   //u32 nextThread = Memory::Read_U32(_uThreadAddr);
  1220.     //do idle skipping
  1221. -   if (nextThread == 0)
  1222. +   //if (nextThread == 0)
  1223.         CoreTiming::Idle();
  1224.  }
  1225.  
  1226. Index: Source/Core/Core/Src/PowerPC/PowerPC.h
  1227. ===================================================================
  1228. --- Source/Core/Core/Src/PowerPC/PowerPC.h  (revision 6314)
  1229. +++ Source/Core/Core/Src/PowerPC/PowerPC.h  (working copy)
  1230. @@ -115,6 +115,11 @@
  1231.  void OnIdle(u32 _uThreadAddr);
  1232.  void OnIdleIL();
  1233.  
  1234. +// Force the CPU emulation to synchronize with CoreTiming events (only required for JIT cores)
  1235. +void Synchronize();
  1236. +
  1237. +void SetException(u32 exception, bool active);
  1238. +
  1239.     // Easy register access macros.
  1240.  #define HID0 ((UReg_HID0&)PowerPC::ppcState.spr[SPR_HID0])
  1241.  #define HID2 ((UReg_HID2&)PowerPC::ppcState.spr[SPR_HID2])
  1242. Index: Source/Core/DolphinWX/Src/ISOProperties.cpp
  1243. ===================================================================
  1244. --- Source/Core/DolphinWX/Src/ISOProperties.cpp (revision 6314)
  1245. +++ Source/Core/DolphinWX/Src/ISOProperties.cpp (working copy)
  1246. @@ -342,10 +342,6 @@
  1247.     arrayStringFor_Hack.Add(_("Skies of Arcadia"));
  1248.     Hack = new wxChoice(m_GameConfig, ID_HACK, wxDefaultPosition, wxDefaultSize, arrayStringFor_Hack, 0, wxDefaultValidator);
  1249.  
  1250. -   WMTightnessText = new wxStaticText(m_GameConfig, ID_WMTIGHTNESS_TEXT, wxT("Watermark tightness: "), wxDefaultPosition, wxDefaultSize);
  1251. -   WMTightness = new wxTextCtrl(m_GameConfig, ID_WMTIGHTNESS, wxT(""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_NUMERIC));
  1252. -   WMTightness->SetToolTip(wxT("Change this if you get lots of FIFO overflow errors. Reasonable values range from 0 to 1000."));
  1253. -
  1254.     // Emulation State
  1255.     sEmuState = new wxBoxSizer(wxHORIZONTAL);
  1256.     EmuStateText = new wxStaticText(m_GameConfig, ID_EMUSTATE_TEXT, _("Emulation State: "), wxDefaultPosition, wxDefaultSize);
  1257. @@ -383,8 +379,6 @@
  1258.     wxFlexGridSizer* fifosizer = new wxFlexGridSizer(2, 2, 0, 0);
  1259.     fifosizer->Add(Hacktext, 0, wxLEFT, 5);
  1260.     fifosizer->Add(Hack, 0, wxEXPAND|wxLEFT, 5);
  1261. -   fifosizer->Add(WMTightnessText, 0, wxLEFT, 5);
  1262. -   fifosizer->Add(WMTightness, 0, wxEXPAND|wxLEFT, 5);
  1263.     sbVideoOverrides->Add(fifosizer);
  1264.  
  1265.     sbGameConfig->Add(sbCoreOverrides, 0, wxEXPAND);
  1266. @@ -913,11 +907,6 @@
  1267.     else
  1268.         DListCache->Set3StateValue(wxCHK_UNDETERMINED);
  1269.  
  1270. -   if (GameIni.Get("Video", "FIFOWatermarkTightness", &sTemp))
  1271. -       WMTightness->SetValue(wxString(sTemp.c_str(), *wxConvCurrent));
  1272. -   else
  1273. -       WMTightness->SetValue(wxT("50"));
  1274. -
  1275.     GameIni.Get("Video", "ProjectionHack", &iTemp, -1);
  1276.     Hack->SetSelection(iTemp);
  1277.  
  1278. @@ -1034,15 +1023,6 @@
  1279.     else
  1280.         GameIni.Set("Video", "ProjectionHack", Hack->GetSelection());
  1281.  
  1282. -   if (WMTightness->GetValue().size() == 0)
  1283. -       GameIni.DeleteKey("Video", "FIFOWatermarkTightness");
  1284. -   else
  1285. -   {
  1286. -       long val;
  1287. -       WMTightness->GetValue().ToLong(&val);
  1288. -       GameIni.Set("Video", "FIFOWatermarkTightness", (int)val);
  1289. -   }
  1290. -
  1291.     if (EmuState->GetSelection() == -1)
  1292.         GameIni.DeleteKey("EmuState", "EmulationStateId");
  1293.     else
  1294. Index: Source/Core/DolphinWX/Src/ISOProperties.h
  1295. ===================================================================
  1296. --- Source/Core/DolphinWX/Src/ISOProperties.h   (revision 6314)
  1297. +++ Source/Core/DolphinWX/Src/ISOProperties.h   (working copy)
  1298. @@ -96,8 +96,6 @@
  1299.         wxStaticText *Hacktext;
  1300.         wxArrayString arrayStringFor_Hack;
  1301.         wxChoice *Hack;
  1302. -       wxStaticText *WMTightnessText;
  1303. -       wxTextCtrl *WMTightness;
  1304.  
  1305.         wxButton *EditConfig;
  1306.         wxStaticText *EmuStateText;
  1307. @@ -182,8 +180,6 @@
  1308.             ID_DLISTCACHE,
  1309.             ID_HACK_TEXT,
  1310.             ID_HACK,
  1311. -           ID_WMTIGHTNESS_TEXT,
  1312. -           ID_WMTIGHTNESS,
  1313.             ID_ENABLEPROGRESSIVESCAN,
  1314.             ID_ENABLEWIDESCREEN,
  1315.             ID_EDITCONFIG,
  1316. Index: Source/Core/VideoCommon/Src/CommandProcessor.cpp
  1317. ===================================================================
  1318. --- Source/Core/VideoCommon/Src/CommandProcessor.cpp    (revision 6314)
  1319. +++ Source/Core/VideoCommon/Src/CommandProcessor.cpp    (working copy)
  1320. @@ -98,8 +98,6 @@
  1321.  UCPCtrlReg m_CPCtrlReg;
  1322.  UCPClearReg    m_CPClearReg;
  1323.  
  1324. -u32 HiWatermark_Tighter;
  1325. -
  1326.  int m_bboxleft;
  1327.  int m_bboxtop;
  1328.  int m_bboxright;
  1329. @@ -133,7 +131,6 @@
  1330.     p.Do(m_bboxbottom);
  1331.     p.Do(m_tokenReg);
  1332.     p.Do(fifo);
  1333. -   p.Do(HiWatermark_Tighter);
  1334.  }
  1335.  
  1336.  //inline void WriteLow (u32& _reg, u16 lowbits)  {_reg = (_reg & 0xFFFF0000) | lowbits;}
  1337. @@ -404,12 +401,6 @@
  1338.  
  1339.             Common::AtomicStore(fifo.bFF_Breakpoint, false);
  1340.  
  1341. -           if (tmpCtrl.FifoUnderflowIntEnable)
  1342. -               Common::AtomicStore(fifo.CPReadIdle, false);
  1343. -
  1344. -           if (tmpCtrl.FifoOverflowIntEnable)
  1345. -               m_CPStatusReg.OverflowHiWatermark = false;
  1346. -
  1347.             UpdateInterrupts();
  1348.            
  1349.             // If the new fifo is being attached We make sure there wont be SetFinish event pending.
  1350. @@ -502,8 +493,6 @@
  1351.         break;
  1352.     case FIFO_HI_WATERMARK_HI:
  1353.         WriteHigh((u32 &)fifo.CPHiWatermark, _Value);
  1354. -       // Tune this when you see lots of FIFO overflown by GatherPipe
  1355. -       HiWatermark_Tighter = fifo.CPHiWatermark - 32 * g_ActiveConfig.iFIFOWatermarkTightness;
  1356.         DEBUG_LOG(COMMANDPROCESSOR,"\t write to FIFO_HI_WATERMARK_HI : %04x", _Value);
  1357.         break;
  1358.  
  1359. @@ -615,8 +604,7 @@
  1360.         CatchUpGPU();
  1361.     }
  1362.  
  1363. -   // The interrupt latency in Dolphin is much longer than Hardware, so we must be more vigilant on Watermark
  1364. -   if (!m_CPStatusReg.OverflowHiWatermark && fifo.CPReadWriteDistance >= HiWatermark_Tighter)
  1365. +   if (!m_CPStatusReg.OverflowHiWatermark && fifo.CPReadWriteDistance >= fifo.CPHiWatermark)
  1366.     {
  1367.         m_CPStatusReg.OverflowHiWatermark = true;
  1368.         if (m_CPCtrlReg.FifoOverflowIntEnable)
  1369. @@ -693,7 +681,7 @@
  1370.  
  1371.  void UpdateInterruptsFromVideoPlugin()
  1372.  {
  1373. -   g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0, true);
  1374. +   g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0);
  1375.  }
  1376.  
  1377.  void SetFifoIdleFromVideoPlugin()
  1378. Index: Source/Core/VideoCommon/Src/PixelEngine.cpp
  1379. ===================================================================
  1380. --- Source/Core/VideoCommon/Src/PixelEngine.cpp (revision 6314)
  1381. +++ Source/Core/VideoCommon/Src/PixelEngine.cpp (working copy)
  1382. @@ -343,7 +343,7 @@
  1383.         // This seems smelly...
  1384.         CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack since PEToken seems to be a frame-finish too
  1385.         g_VideoInitialize.pScheduleEvent_Threadsafe(
  1386. -           0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16), true);
  1387. +           0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
  1388.     }
  1389.     else // set token value
  1390.     {
  1391. @@ -362,7 +362,7 @@
  1392.  {
  1393.     CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack
  1394.     g_VideoInitialize.pScheduleEvent_Threadsafe(
  1395. -       0, et_SetFinishOnMainThread, 0, true);
  1396. +       0, et_SetFinishOnMainThread, 0);
  1397.     INFO_LOG(PIXELENGINE, "VIDEO Set Finish");
  1398.  }
  1399.  
  1400. Index: Source/Core/VideoCommon/Src/VideoConfig.cpp
  1401. ===================================================================
  1402. --- Source/Core/VideoCommon/Src/VideoConfig.cpp (revision 6314)
  1403. +++ Source/Core/VideoCommon/Src/VideoConfig.cpp (working copy)
  1404. @@ -97,7 +97,6 @@
  1405.     iniFile.Get("Hacks", "EFBCopyDisableHotKey", &bOSDHotKey, 0);
  1406.     iniFile.Get("Hacks", "EFBToTextureEnable", &bCopyEFBToTexture, false);
  1407.     iniFile.Get("Hacks", "EFBScaledCopy", &bCopyEFBScaled, true);
  1408. -   iniFile.Get("Hacks", "FIFOWatermarkTightness", &iFIFOWatermarkTightness, 50);
  1409.     iniFile.Get("Hacks", "ProjectionHack", &iPhackvalue, 0);
  1410.  
  1411.     iniFile.Get("Hardware", "Adapter", &iAdapter, 0);
  1412. @@ -145,8 +144,6 @@
  1413.         iniFile.Get("Video", "UseXFB", &bUseXFB);
  1414.     if (iniFile.Exists("Video", "UseRealXFB"))
  1415.         iniFile.Get("Video", "UseRealXFB", &bUseRealXFB);
  1416. -   if (iniFile.Exists("Video", "FIFOWatermarkTightness"))
  1417. -       iniFile.Get("Video", "FIFOWatermarkTightness", &iFIFOWatermarkTightness);
  1418.     if (iniFile.Exists("Video", "ProjectionHack"))
  1419.         iniFile.Get("Video", "ProjectionHack", &iPhackvalue);
  1420.     if (iniFile.Exists("Video", "UseNativeMips"))
  1421. Index: Source/Core/VideoCommon/Src/VideoConfig.h
  1422. ===================================================================
  1423. --- Source/Core/VideoCommon/Src/VideoConfig.h   (revision 6314)
  1424. +++ Source/Core/VideoCommon/Src/VideoConfig.h   (working copy)
  1425. @@ -122,7 +122,6 @@
  1426.     bool bCopyEFBScaled;
  1427.     bool bSafeTextureCache;
  1428.     int iSafeTextureCache_ColorSamples;
  1429. -   int iFIFOWatermarkTightness;
  1430.     int iPhackvalue;
  1431.     bool bPhackvalue1, bPhackvalue2;
  1432.     float fhackvalue1, fhackvalue2;
  1433. Index: Source/Plugins/Plugin_VideoSoftware/Src/CommandProcessor.cpp
  1434. ===================================================================
  1435. --- Source/Plugins/Plugin_VideoSoftware/Src/CommandProcessor.cpp    (revision 6314)
  1436. +++ Source/Plugins/Plugin_VideoSoftware/Src/CommandProcessor.cpp    (working copy)
  1437. @@ -322,7 +322,7 @@
  1438.  
  1439.  void UpdateInterruptsFromVideoPlugin(u64 userdata)
  1440.  {
  1441. -    g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata, true);
  1442. +    g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata);
  1443.  }
  1444.  
  1445.  void ReadFifo()
  1446. Index: Source/Plugins/Plugin_VideoSoftware/Src/PixelEngine.cpp
  1447. ===================================================================
  1448. --- Source/Plugins/Plugin_VideoSoftware/Src/PixelEngine.cpp (revision 6314)
  1449. +++ Source/Plugins/Plugin_VideoSoftware/Src/PixelEngine.cpp (working copy)
  1450. @@ -155,7 +155,7 @@
  1451.      if (_bSetTokenAcknowledge) // set token INT
  1452.     {
  1453.          g_VideoInitialize.pScheduleEvent_Threadsafe(
  1454. -           0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16), true);
  1455. +           0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
  1456.     }
  1457.  }
  1458.  
  1459. @@ -164,7 +164,7 @@
  1460.  void SetFinish()
  1461.  {
  1462.     g_VideoInitialize.pScheduleEvent_Threadsafe(
  1463. -       0, et_SetFinishOnMainThread, 0, true);
  1464. +       0, et_SetFinishOnMainThread, 0);
  1465.     INFO_LOG(PIXELENGINE, "VIDEO Set Finish");
  1466.  }
  1467.  
  1468. Index: Source/PluginSpecs/pluginspecs_video.h
  1469. ===================================================================
  1470. --- Source/PluginSpecs/pluginspecs_video.h  (revision 6314)
  1471. +++ Source/PluginSpecs/pluginspecs_video.h  (working copy)
  1472. @@ -13,7 +13,7 @@
  1473.  
  1474.  typedef void            (*TSetInterrupt)(u32 _causemask, bool _bSet);
  1475.  typedef int             (*TRegisterEvent)(const char *name, TimedCallback callback);
  1476. -typedef void            (*TScheduleEvent_Threadsafe)(int cyclesIntoFuture, int event_type, u64 userdata, bool fifoWait);
  1477. +typedef void            (*TScheduleEvent_Threadsafe)(s64 cyclesIntoFuture, int event_type, u64 userdata);
  1478.  typedef void            (*TRemoveEvent)(int event_type);
  1479.  typedef unsigned char* (*TGetMemoryPointer)(const unsigned int  _iAddress);
  1480.  typedef void           (*TVideoLog)(const char* _pMessage, int _bBreak);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement