SPC: Implemented SLEEP/STOP behavior to avoid lock up when a crashed SPC program calls them

This commit is contained in:
Sour 2019-07-08 22:06:12 -04:00
parent 3f4a72a338
commit 31fa31dc3d
4 changed files with 15 additions and 0 deletions

View file

@ -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();
}

View file

@ -26,6 +26,7 @@ Spc::Spc(shared_ptr<Console> 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) {

View file

@ -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];

View file

@ -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;