From 98d72d55b5336fc790f52271bf7b6271f47e13ad Mon Sep 17 00:00:00 2001 From: Sour Date: Sat, 9 Mar 2019 16:03:48 -0500 Subject: [PATCH] Debugger: Added some values to the expression evaluator --- Core/Cpu.Instructions.cpp | 4 +-- Core/Cpu.cpp | 47 ++++++++++++++++++++---------------- Core/Cpu.h | 13 +++------- Core/CpuTypes.h | 20 ++++++++++----- Core/DummyCpu.h | 5 ++++ Core/ExpressionEvaluator.cpp | 13 +++++----- UI/Interop/DebugApi.cs | 13 ++++++++++ 7 files changed, 69 insertions(+), 46 deletions(-) diff --git a/Core/Cpu.Instructions.cpp b/Core/Cpu.Instructions.cpp index 44cd03f..d0f52a2 100644 --- a/Core/Cpu.Instructions.cpp +++ b/Core/Cpu.Instructions.cpp @@ -1079,13 +1079,13 @@ Misc. operations void Cpu::STP() { //Stop the CPU - _stopState = CpuStopState::Stopped; + _state.StopState = CpuStopState::Stopped; } void Cpu::WAI() { //Wait for interrupt - _stopState = CpuStopState::WaitingForIrq; + _state.StopState = CpuStopState::WaitingForIrq; } /**************** diff --git a/Core/Cpu.cpp b/Core/Cpu.cpp index 64c65f3..40530b8 100644 --- a/Core/Cpu.cpp +++ b/Core/Cpu.cpp @@ -14,11 +14,11 @@ Cpu::Cpu(Console *console) _state.SP = 0x1FF; _state.PS = ProcFlags::IrqDisable; _state.EmulationMode = true; - _nmiFlag = false; - _prevNmiFlag = false; - _stopState = CpuStopState::Running; - _irqSource = (uint8_t)IrqSource::None; - _prevIrqSource = (uint8_t)IrqSource::None; + _state.NmiFlag = false; + _state.PrevNmiFlag = false; + _state.StopState = CpuStopState::Running; + _state.IrqSource = (uint8_t)IrqSource::None; + _state.PrevIrqSource = (uint8_t)IrqSource::None; SetFlags(ProcFlags::MemoryMode8); SetFlags(ProcFlags::IndexMode8); } @@ -35,7 +35,7 @@ void Cpu::Exec() { _immediateMode = false; - switch(_stopState) { + switch(_state.StopState) { case CpuStopState::Running: RunOp(); break; case CpuStopState::Stopped: //STP was executed, CPU no longer executes any code @@ -46,7 +46,7 @@ void Cpu::Exec() case CpuStopState::WaitingForIrq: //WAI - if(!_irqSource && !_nmiFlag) { + if(!_state.IrqSource && !_state.NmiFlag) { #ifndef DUMMYCPU _memoryManager->IncrementMasterClockValue<4>(); #endif @@ -54,17 +54,17 @@ void Cpu::Exec() } else { Idle(); Idle(); - _stopState = CpuStopState::Running; + _state.StopState = CpuStopState::Running; } break; } //Use the state of the IRQ/NMI flags on the previous cycle to determine if an IRQ is processed or not - if(_prevNmiFlag) { + if(_state.PrevNmiFlag) { ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyNmiVector : Cpu::NmiVector); _console->ProcessEvent(EventType::Nmi); - _nmiFlag = false; - } else if(_prevIrqSource && !CheckFlag(ProcFlags::IrqDisable)) { + _state.NmiFlag = false; + } else if(_state.PrevIrqSource && !CheckFlag(ProcFlags::IrqDisable)) { ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyIrqVector : Cpu::IrqVector); _console->ProcessEvent(EventType::Irq); } @@ -332,19 +332,24 @@ void Cpu::RunOp() } } +CpuState Cpu::GetState() +{ + return _state; +} + void Cpu::SetNmiFlag() { - _nmiFlag = true; + _state.NmiFlag = true; } void Cpu::SetIrqSource(IrqSource source) { - _irqSource |= (uint8_t)source; + _state.IrqSource |= (uint8_t)source; } bool Cpu::CheckIrqSource(IrqSource source) { - if(_irqSource & (uint8_t)source) { + if(_state.IrqSource & (uint8_t)source) { return true; } else { return false; @@ -353,7 +358,7 @@ bool Cpu::CheckIrqSource(IrqSource source) void Cpu::ClearIrqSource(IrqSource source) { - _irqSource &= ~(uint8_t)source; + _state.IrqSource &= ~(uint8_t)source; } uint32_t Cpu::GetProgramAddress(uint16_t addr) @@ -377,8 +382,8 @@ void Cpu::Idle() { _state.CycleCount++; #ifndef DUMMYCPU - _prevNmiFlag = _nmiFlag; - _prevIrqSource = _irqSource; + _state.PrevNmiFlag = _state.NmiFlag; + _state.PrevIrqSource = _state.IrqSource; _memoryManager->IncrementMasterClockValue<6>(); #endif } @@ -412,8 +417,8 @@ uint8_t Cpu::Read(uint32_t addr, MemoryOperationType type) LogRead(addr, value); return value; #else - _prevNmiFlag = _nmiFlag; - _prevIrqSource = _irqSource; + _state.PrevNmiFlag = _state.NmiFlag; + _state.PrevIrqSource = _state.IrqSource; return _memoryManager->Read(addr, type); #endif } @@ -457,8 +462,8 @@ void Cpu::Write(uint32_t addr, uint8_t value, MemoryOperationType type) #ifdef DUMMYCPU LogWrite(addr, value); #else - _prevNmiFlag = _nmiFlag; - _prevIrqSource = _irqSource; + _state.PrevNmiFlag = _state.NmiFlag; + _state.PrevIrqSource = _state.IrqSource; _memoryManager->Write(addr, value, type); #endif } diff --git a/Core/Cpu.h b/Core/Cpu.h index d8dea7c..fbc95dd 100644 --- a/Core/Cpu.h +++ b/Core/Cpu.h @@ -13,11 +13,6 @@ class Console; class Cpu { -public: - uint16_t GetPc() { return _state.PC; } - CpuState GetState() { return _state; } - int32_t GetLastOperand() { return (int32_t)_operand; } - private: static constexpr uint32_t NmiVector = 0x00FFEA; static constexpr uint32_t ResetVector = 0x00FFFC; @@ -39,11 +34,6 @@ private: CpuState _state; uint32_t _operand; - bool _nmiFlag; - bool _prevNmiFlag; - uint8_t _irqSource; - uint8_t _prevIrqSource; - CpuStopState _stopState; uint32_t GetProgramAddress(uint16_t addr); uint32_t GetDataAddress(uint16_t addr); @@ -303,6 +293,8 @@ public: void Reset(); void Exec(); + CpuState GetState(); + void SetNmiFlag(); void SetIrqSource(IrqSource source); bool CheckIrqSource(IrqSource source); @@ -325,6 +317,7 @@ private: public: void SetDummyState(CpuState &state); + int32_t GetLastOperand(); uint32_t GetWriteCount(); uint32_t GetReadCount(); diff --git a/Core/CpuTypes.h b/Core/CpuTypes.h index fe6f3bc..1e87969 100644 --- a/Core/CpuTypes.h +++ b/Core/CpuTypes.h @@ -1,6 +1,13 @@ #pragma once #include "stdafx.h" +enum class CpuStopState : uint8_t +{ + Running = 0, + Stopped = 1, + WaitingForIrq = 2 +}; + struct CpuState { uint64_t CycleCount; @@ -30,6 +37,13 @@ struct CpuState /* 6502 emulation mode */ bool EmulationMode; + + /* Misc internal state */ + bool NmiFlag; + bool PrevNmiFlag; + uint8_t IrqSource; + uint8_t PrevIrqSource; + CpuStopState StopState; }; namespace ProcFlags @@ -68,9 +82,3 @@ enum class IrqSource Ppu = 1, }; -enum class CpuStopState -{ - Running = 0, - Stopped = 1, - WaitingForIrq = 2 -}; \ No newline at end of file diff --git a/Core/DummyCpu.h b/Core/DummyCpu.h index 26705f1..b61d9f7 100644 --- a/Core/DummyCpu.h +++ b/Core/DummyCpu.h @@ -52,4 +52,9 @@ void DummyCpu::GetReadInfo(uint32_t index, uint32_t &addr, uint8_t &value) { addr = _readAddresses[index]; value = _readValue[index]; +} + +int32_t DummyCpu::GetLastOperand() +{ + return _operand; } \ No newline at end of file diff --git a/Core/ExpressionEvaluator.cpp b/Core/ExpressionEvaluator.cpp index 5f8d9f4..a882f03 100644 --- a/Core/ExpressionEvaluator.cpp +++ b/Core/ExpressionEvaluator.cpp @@ -392,15 +392,14 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E case EvalValues::PpuFrameCount: token = state.Ppu.FrameCount; break; case EvalValues::PpuCycle: token = state.Ppu.Cycle; break; case EvalValues::PpuScanline: token = state.Ppu.Scanline; break; - //TODO - /*case EvalValues::Nmi: token = state.CPU.NMIFlag; resultType = EvalResultType::Boolean; break; - case EvalValues::Irq: token = state.CPU.IRQFlag; resultType = EvalResultType::Boolean; break; + case EvalValues::Nmi: token = state.Cpu.NmiFlag; resultType = EvalResultType::Boolean; break; + case EvalValues::Irq: token = state.Cpu.IrqSource != 0; resultType = EvalResultType::Boolean; break; case EvalValues::Value: token = operationInfo.Value; break; case EvalValues::Address: token = operationInfo.Address; break; - case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(operationInfo.Address); break; - case EvalValues::IsWrite: token = operationInfo.OperationType == MemoryOperationType::Write || operationInfo.OperationType == MemoryOperationType::DummyWrite; break; - case EvalValues::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read || operationInfo.OperationType == MemoryOperationType::DummyRead; break; - case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; break; + //case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(operationInfo.Address); break; + case EvalValues::IsWrite: token = operationInfo.Type == MemoryOperationType::Write || operationInfo.Type == MemoryOperationType::DmaWrite; break; + case EvalValues::IsRead: token = operationInfo.Type != MemoryOperationType::Write && operationInfo.Type != MemoryOperationType::DmaWrite; break; + /*case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; break; case EvalValues::Sprite0Hit: token = state.PPU.StatusFlags.Sprite0Hit; resultType = EvalResultType::Boolean; break; case EvalValues::SpriteOverflow: token = state.PPU.StatusFlags.SpriteOverflow; resultType = EvalResultType::Boolean; break; case EvalValues::VerticalBlank: token = state.PPU.StatusFlags.VerticalBlank; resultType = EvalResultType::Boolean; break; diff --git a/UI/Interop/DebugApi.cs b/UI/Interop/DebugApi.cs index e111323..1df7dea 100644 --- a/UI/Interop/DebugApi.cs +++ b/UI/Interop/DebugApi.cs @@ -126,6 +126,13 @@ namespace Mesen.GUI public SnesMemoryType Type; } + public enum CpuStopState : byte + { + Running = 0, + Stopped = 1, + WaitingForIrq = 2 + } + public struct CpuState { public UInt64 CycleCount; @@ -142,6 +149,12 @@ namespace Mesen.GUI public byte DBR; public byte PS; [MarshalAs(UnmanagedType.I1)] public bool EmulationMode; + + [MarshalAs(UnmanagedType.I1)] bool NmiFlag; + [MarshalAs(UnmanagedType.I1)] bool PrevNmiFlag; + public byte IrqSource; + public byte PrevIrqSource; + CpuStopState StopState; }; public struct PpuState