From 31fa31dc3dec3cb500144305f34c5928c55a19e4 Mon Sep 17 00:00:00 2001 From: Sour Date: Mon, 8 Jul 2019 22:06:12 -0400 Subject: [PATCH] SPC: Implemented SLEEP/STOP behavior to avoid lock up when a crashed SPC program calls them --- Core/Spc.Instructions.cpp | 4 ++++ Core/Spc.cpp | 8 ++++++++ Core/SpcTypes.h | 2 ++ UI/Interop/DebugApi.cs | 1 + 4 files changed, 15 insertions(+) diff --git a/Core/Spc.Instructions.cpp b/Core/Spc.Instructions.cpp index 470ab67..3e3e2b9 100644 --- a/Core/Spc.Instructions.cpp +++ b/Core/Spc.Instructions.cpp @@ -2105,9 +2105,13 @@ void Spc::NOP() void Spc::SLEEP() { //WAI + _state.StopState = CpuStopState::WaitingForIrq; + EndOp(); } void Spc::STOP() { //STP + _state.StopState = CpuStopState::Stopped; + EndOp(); } diff --git a/Core/Spc.cpp b/Core/Spc.cpp index 82be87f..2e33154 100644 --- a/Core/Spc.cpp +++ b/Core/Spc.cpp @@ -26,6 +26,7 @@ Spc::Spc(shared_ptr console) _state.RomEnabled = true; _state.SP = 0xFF; _state.PC = ReadWord(Spc::ResetVector); + _state.StopState = CpuStopState::Running; _opCode = 0; _opStep = SpcOpStep::ReadOpCode; @@ -49,6 +50,8 @@ Spc::~Spc() void Spc::Reset() { + _state.StopState = CpuStopState::Running; + _state.Timer0.Reset(); _state.Timer1.Reset(); _state.Timer2.Reset(); @@ -279,6 +282,11 @@ void Spc::CpuWriteRegister(uint32_t addr, uint8_t value) void Spc::Run() { + if(_state.StopState != CpuStopState::Running) { + //STOP or SLEEP were executed - execution is stopped forever. + return; + } + uint64_t targetCycle = (uint64_t)(_memoryManager->GetMasterClock() * _clockRatio); while(_state.Cycle < targetCycle) { if(_opStep == SpcOpStep::ReadOpCode) { diff --git a/Core/SpcTypes.h b/Core/SpcTypes.h index 23892f4..5114e4c 100644 --- a/Core/SpcTypes.h +++ b/Core/SpcTypes.h @@ -1,6 +1,7 @@ #pragma once #include "stdafx.h" #include "SpcTimer.h" +#include "CpuTypes.h" struct SpcState { @@ -17,6 +18,7 @@ struct SpcState uint8_t InternalSpeed; uint8_t ExternalSpeed; bool TimersEnabled; + CpuStopState StopState; uint8_t DspReg; uint8_t OutputReg[4]; diff --git a/UI/Interop/DebugApi.cs b/UI/Interop/DebugApi.cs index 0b4038d..96b7afa 100644 --- a/UI/Interop/DebugApi.cs +++ b/UI/Interop/DebugApi.cs @@ -363,6 +363,7 @@ namespace Mesen.GUI public byte InternalSpeed; public byte ExternalSpeed; [MarshalAs(UnmanagedType.I1)] public bool TimersEnabled; + public CpuStopState StopState; public byte DspReg;