From 11faf6ccfbfd0db2057e42449cdea06c614ed894 Mon Sep 17 00:00:00 2001
From: Connor McLaughlin <stenzek@gmail.com>
Date: Sun, 18 Oct 2020 14:43:48 +1000
Subject: [PATCH] CPU/Recompiler: Skip calling event update on interrupts

---
 src/core/cpu_recompiler_code_generator_aarch64.cpp |  6 ++++++
 src/core/cpu_recompiler_code_generator_x64.cpp     |  5 +++++
 src/core/save_state_version.h                      |  2 +-
 src/core/timing_event.cpp                          | 13 ++++++-------
 4 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/core/cpu_recompiler_code_generator_aarch64.cpp b/src/core/cpu_recompiler_code_generator_aarch64.cpp
index e9fb87263..5e0d12f23 100644
--- a/src/core/cpu_recompiler_code_generator_aarch64.cpp
+++ b/src/core/cpu_recompiler_code_generator_aarch64.cpp
@@ -1976,6 +1976,12 @@ CodeCache::DispatcherFunction CodeGenerator::CompileDispatcher()
   m_emit->Bind(&downcount_hit);
 
   // check events then for frame done
+  m_emit->ldr(a64::w8, a64::MemOperand(GetHostReg64(RCPUPTR), offsetof(State, pending_ticks)));
+  EmitLoadGlobalAddress(9, TimingEvents::GetHeadEventPtr());
+  m_emit->ldr(a64::x9, a64::MemOperand(a64::x9));
+  m_emit->ldr(a64::w9, a64::MemOperand(a64::x9, offsetof(TimingEvent, m_downcount)));
+  m_emit->cmp(a64::w8, a64::w9);
+  m_emit->b(&frame_done_loop, a64::lt);
   EmitCall(reinterpret_cast<const void*>(&TimingEvents::RunEvents));
   m_emit->b(&frame_done_loop);
 
diff --git a/src/core/cpu_recompiler_code_generator_x64.cpp b/src/core/cpu_recompiler_code_generator_x64.cpp
index 04d9a8134..5ad82d345 100644
--- a/src/core/cpu_recompiler_code_generator_x64.cpp
+++ b/src/core/cpu_recompiler_code_generator_x64.cpp
@@ -2606,6 +2606,11 @@ CodeCache::DispatcherFunction CodeGenerator::CompileDispatcher()
   m_emit->L(downcount_hit);
 
   // check events then for frame done
+  EmitLoadGlobalAddress(Xbyak::Operand::RAX, TimingEvents::GetHeadEventPtr());
+  m_emit->mov(m_emit->rax, m_emit->qword[m_emit->rax]);
+  m_emit->mov(m_emit->eax, m_emit->dword[m_emit->rax + offsetof(TimingEvent, m_downcount)]);
+  m_emit->cmp(m_emit->eax, m_emit->dword[m_emit->rbp + offsetof(State, pending_ticks)]);
+  m_emit->jg(frame_done_loop);
   EmitCall(reinterpret_cast<const void*>(&TimingEvents::RunEvents));
   m_emit->jmp(frame_done_loop);
 
diff --git a/src/core/save_state_version.h b/src/core/save_state_version.h
index 215b4ea00..5e17ec4a0 100644
--- a/src/core/save_state_version.h
+++ b/src/core/save_state_version.h
@@ -2,7 +2,7 @@
 #include "types.h"
 
 static constexpr u32 SAVE_STATE_MAGIC = 0x43435544;
-static constexpr u32 SAVE_STATE_VERSION = 42;
+static constexpr u32 SAVE_STATE_VERSION = 43;
 static constexpr u32 SAVE_STATE_MINIMUM_VERSION = 42;
 
 #pragma pack(push, 4)
diff --git a/src/core/timing_event.cpp b/src/core/timing_event.cpp
index 37451e926..d7fd02f1d 100644
--- a/src/core/timing_event.cpp
+++ b/src/core/timing_event.cpp
@@ -14,7 +14,6 @@ static TimingEvent* s_active_events_tail;
 static TimingEvent* s_current_event = nullptr;
 static u32 s_active_event_count = 0;
 static u32 s_global_tick_counter = 0;
-static u32 s_last_event_run_time = 0;
 
 u32 GetGlobalTickCounter()
 {
@@ -29,7 +28,6 @@ void Initialize()
 void Reset()
 {
   s_global_tick_counter = 0;
-  s_last_event_run_time = 0;
 }
 
 void Shutdown()
@@ -264,7 +262,7 @@ void RunEvents()
 {
   DebugAssert(!s_current_event);
 
-  TickCount pending_ticks = (s_global_tick_counter + CPU::GetPendingTicks()) - s_last_event_run_time;
+  TickCount pending_ticks = CPU::GetPendingTicks();
   CPU::ResetPendingTicks();
   while (pending_ticks > 0)
   {
@@ -300,7 +298,6 @@ void RunEvents()
     }
   }
 
-  s_last_event_run_time = s_global_tick_counter;
   s_current_event = nullptr;
   UpdateCPUDowncount();
 }
@@ -342,7 +339,11 @@ bool DoState(StateWrapper& sw)
       event->m_interval = interval;
     }
 
-    sw.Do(&s_last_event_run_time);
+    if (sw.GetVersion() < 43)
+    {
+      u32 last_event_run_time = 0;
+      sw.Do(&last_event_run_time);
+    }
 
     Log_DevPrintf("Loaded %u events from save state.", event_count);
     SortEvents();
@@ -361,8 +362,6 @@ bool DoState(StateWrapper& sw)
       sw.Do(&event->m_interval);
     }
 
-    sw.Do(&s_last_event_run_time);
-
     Log_DevPrintf("Wrote %u events to save state.", s_active_event_count);
   }