System: Improve reset determinism

This commit is contained in:
Stenzek 2024-04-22 00:19:44 +10:00
parent 35f0d7f623
commit b26a9556f7
No known key found for this signature in database
5 changed files with 19 additions and 14 deletions

View file

@ -183,8 +183,6 @@ void CPU::Shutdown()
void CPU::Reset() void CPU::Reset()
{ {
g_state.pending_ticks = 0;
g_state.downcount = 0;
g_state.exception_raised = false; g_state.exception_raised = false;
g_state.bus_error = false; g_state.bus_error = false;
@ -208,8 +206,11 @@ void CPU::Reset()
if (g_settings.gpu_pgxp_enable) if (g_settings.gpu_pgxp_enable)
PGXP::Reset(); PGXP::Reset();
// TODO: This consumes cycles... // This consumes cycles, so do it first.
SetPC(RESET_VECTOR); SetPC(RESET_VECTOR);
g_state.pending_ticks = 0;
g_state.downcount = 0;
} }
bool CPU::DoState(StateWrapper& sw) bool CPU::DoState(StateWrapper& sw)

View file

@ -164,6 +164,10 @@ void GPU::Reset(bool clear_vram)
if (clear_vram) if (clear_vram)
std::memset(g_vram, 0, sizeof(g_vram)); std::memset(g_vram, 0, sizeof(g_vram));
// Force event to reschedule itself.
m_crtc_tick_event->Deactivate();
m_command_tick_event->Deactivate();
SoftReset(); SoftReset();
UpdateDisplay(); UpdateDisplay();
} }
@ -211,7 +215,6 @@ void GPU::SoftReset()
SetTextureWindow(0); SetTextureWindow(0);
UpdateDMARequest(); UpdateDMARequest();
UpdateCRTCConfig(); UpdateCRTCConfig();
UpdateCRTCTickEvent();
UpdateCommandTickEvent(); UpdateCommandTickEvent();
UpdateGPUIdle(); UpdateGPUIdle();
} }
@ -342,7 +345,6 @@ bool GPU::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_displ
if (update_display) if (update_display)
UpdateDisplay(); UpdateDisplay();
UpdateCRTCTickEvent();
UpdateCommandTickEvent(); UpdateCommandTickEvent();
} }

View file

@ -529,8 +529,9 @@ void SPU::Reset()
v.ignore_loop_address = false; v.ignore_loop_address = false;
} }
s_transfer_fifo.Clear(); s_tick_event->Deactivate();
s_transfer_event->Deactivate(); s_transfer_event->Deactivate();
s_transfer_fifo.Clear();
s_ram.fill(0); s_ram.fill(0);
UpdateEventInterval(); UpdateEventInterval();
} }

View file

@ -2266,6 +2266,7 @@ void System::InternalReset()
if (IsShutdown()) if (IsShutdown())
return; return;
TimingEvents::Reset();
CPU::Reset(); CPU::Reset();
CPU::CodeCache::Reset(); CPU::CodeCache::Reset();
if (g_settings.gpu_pgxp_enable) if (g_settings.gpu_pgxp_enable)
@ -2284,7 +2285,6 @@ void System::InternalReset()
PCDrv::Reset(); PCDrv::Reset();
s_frame_number = 1; s_frame_number = 1;
s_internal_frame_number = 0; s_internal_frame_number = 0;
TimingEvents::Reset();
InterruptExecution(); InterruptExecution();
ResetPerformanceCounters(); ResetPerformanceCounters();

View file

@ -75,9 +75,9 @@ static void UpdateSysClkEvent();
static std::unique_ptr<TimingEvent> s_sysclk_event; static std::unique_ptr<TimingEvent> s_sysclk_event;
static std::array<CounterState, NUM_TIMERS> s_states{}; static std::array<CounterState, NUM_TIMERS> s_states{};
static TickCount s_syclk_ticks_carry = 0; // 0 unless overclocking is enabled static TickCount s_sysclk_ticks_carry = 0; // 0 unless overclocking is enabled
static u32 s_sysclk_div_8_carry = 0; // partial ticks for timer 3 with sysclk/8 static u32 s_sysclk_div_8_carry = 0; // partial ticks for timer 3 with sysclk/8
}; // namespace Timers }; // namespace Timers
void Timers::Initialize() void Timers::Initialize()
{ {
@ -105,7 +105,8 @@ void Timers::Reset()
cs.irq_done = false; cs.irq_done = false;
} }
s_syclk_ticks_carry = 0; s_sysclk_event->Deactivate();
s_sysclk_ticks_carry = 0;
s_sysclk_div_8_carry = 0; s_sysclk_div_8_carry = 0;
UpdateSysClkEvent(); UpdateSysClkEvent();
} }
@ -124,7 +125,7 @@ bool Timers::DoState(StateWrapper& sw)
sw.Do(&cs.irq_done); sw.Do(&cs.irq_done);
} }
sw.Do(&s_syclk_ticks_carry); sw.Do(&s_sysclk_ticks_carry);
sw.Do(&s_sysclk_div_8_carry); sw.Do(&s_sysclk_div_8_carry);
if (sw.IsReading()) if (sw.IsReading())
@ -135,7 +136,7 @@ bool Timers::DoState(StateWrapper& sw)
void Timers::CPUClocksChanged() void Timers::CPUClocksChanged()
{ {
s_syclk_ticks_carry = 0; s_sysclk_ticks_carry = 0;
} }
bool Timers::IsUsingExternalClock(u32 timer) bool Timers::IsUsingExternalClock(u32 timer)
@ -264,7 +265,7 @@ void Timers::CheckForIRQ(u32 timer, u32 old_counter)
void Timers::AddSysClkTicks(void*, TickCount sysclk_ticks, TickCount ticks_late) void Timers::AddSysClkTicks(void*, TickCount sysclk_ticks, TickCount ticks_late)
{ {
sysclk_ticks = System::UnscaleTicksToOverclock(sysclk_ticks, &s_syclk_ticks_carry); sysclk_ticks = System::UnscaleTicksToOverclock(sysclk_ticks, &s_sysclk_ticks_carry);
if (!s_states[0].external_counting_enabled && s_states[0].counting_enabled) if (!s_states[0].external_counting_enabled && s_states[0].counting_enabled)
AddTicks(0, sysclk_ticks); AddTicks(0, sysclk_ticks);