SPC: Implemented SLEEP/STOP behavior to avoid lock up when a crashed SPC program calls them
This commit is contained in:
parent
3f4a72a338
commit
31fa31dc3d
4 changed files with 15 additions and 0 deletions
|
@ -2105,9 +2105,13 @@ void Spc::NOP()
|
||||||
void Spc::SLEEP()
|
void Spc::SLEEP()
|
||||||
{
|
{
|
||||||
//WAI
|
//WAI
|
||||||
|
_state.StopState = CpuStopState::WaitingForIrq;
|
||||||
|
EndOp();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spc::STOP()
|
void Spc::STOP()
|
||||||
{
|
{
|
||||||
//STP
|
//STP
|
||||||
|
_state.StopState = CpuStopState::Stopped;
|
||||||
|
EndOp();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ Spc::Spc(shared_ptr<Console> console)
|
||||||
_state.RomEnabled = true;
|
_state.RomEnabled = true;
|
||||||
_state.SP = 0xFF;
|
_state.SP = 0xFF;
|
||||||
_state.PC = ReadWord(Spc::ResetVector);
|
_state.PC = ReadWord(Spc::ResetVector);
|
||||||
|
_state.StopState = CpuStopState::Running;
|
||||||
|
|
||||||
_opCode = 0;
|
_opCode = 0;
|
||||||
_opStep = SpcOpStep::ReadOpCode;
|
_opStep = SpcOpStep::ReadOpCode;
|
||||||
|
@ -49,6 +50,8 @@ Spc::~Spc()
|
||||||
|
|
||||||
void Spc::Reset()
|
void Spc::Reset()
|
||||||
{
|
{
|
||||||
|
_state.StopState = CpuStopState::Running;
|
||||||
|
|
||||||
_state.Timer0.Reset();
|
_state.Timer0.Reset();
|
||||||
_state.Timer1.Reset();
|
_state.Timer1.Reset();
|
||||||
_state.Timer2.Reset();
|
_state.Timer2.Reset();
|
||||||
|
@ -279,6 +282,11 @@ void Spc::CpuWriteRegister(uint32_t addr, uint8_t value)
|
||||||
|
|
||||||
void Spc::Run()
|
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);
|
uint64_t targetCycle = (uint64_t)(_memoryManager->GetMasterClock() * _clockRatio);
|
||||||
while(_state.Cycle < targetCycle) {
|
while(_state.Cycle < targetCycle) {
|
||||||
if(_opStep == SpcOpStep::ReadOpCode) {
|
if(_opStep == SpcOpStep::ReadOpCode) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "SpcTimer.h"
|
#include "SpcTimer.h"
|
||||||
|
#include "CpuTypes.h"
|
||||||
|
|
||||||
struct SpcState
|
struct SpcState
|
||||||
{
|
{
|
||||||
|
@ -17,6 +18,7 @@ struct SpcState
|
||||||
uint8_t InternalSpeed;
|
uint8_t InternalSpeed;
|
||||||
uint8_t ExternalSpeed;
|
uint8_t ExternalSpeed;
|
||||||
bool TimersEnabled;
|
bool TimersEnabled;
|
||||||
|
CpuStopState StopState;
|
||||||
|
|
||||||
uint8_t DspReg;
|
uint8_t DspReg;
|
||||||
uint8_t OutputReg[4];
|
uint8_t OutputReg[4];
|
||||||
|
|
|
@ -363,6 +363,7 @@ namespace Mesen.GUI
|
||||||
public byte InternalSpeed;
|
public byte InternalSpeed;
|
||||||
public byte ExternalSpeed;
|
public byte ExternalSpeed;
|
||||||
[MarshalAs(UnmanagedType.I1)] public bool TimersEnabled;
|
[MarshalAs(UnmanagedType.I1)] public bool TimersEnabled;
|
||||||
|
public CpuStopState StopState;
|
||||||
|
|
||||||
public byte DspReg;
|
public byte DspReg;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue