Debugger: Added some values to the expression evaluator

This commit is contained in:
Sour 2019-03-09 16:03:48 -05:00
parent bcb74aae40
commit 98d72d55b5
7 changed files with 69 additions and 46 deletions

View file

@ -1079,13 +1079,13 @@ Misc. operations
void Cpu::STP() void Cpu::STP()
{ {
//Stop the CPU //Stop the CPU
_stopState = CpuStopState::Stopped; _state.StopState = CpuStopState::Stopped;
} }
void Cpu::WAI() void Cpu::WAI()
{ {
//Wait for interrupt //Wait for interrupt
_stopState = CpuStopState::WaitingForIrq; _state.StopState = CpuStopState::WaitingForIrq;
} }
/**************** /****************

View file

@ -14,11 +14,11 @@ Cpu::Cpu(Console *console)
_state.SP = 0x1FF; _state.SP = 0x1FF;
_state.PS = ProcFlags::IrqDisable; _state.PS = ProcFlags::IrqDisable;
_state.EmulationMode = true; _state.EmulationMode = true;
_nmiFlag = false; _state.NmiFlag = false;
_prevNmiFlag = false; _state.PrevNmiFlag = false;
_stopState = CpuStopState::Running; _state.StopState = CpuStopState::Running;
_irqSource = (uint8_t)IrqSource::None; _state.IrqSource = (uint8_t)IrqSource::None;
_prevIrqSource = (uint8_t)IrqSource::None; _state.PrevIrqSource = (uint8_t)IrqSource::None;
SetFlags(ProcFlags::MemoryMode8); SetFlags(ProcFlags::MemoryMode8);
SetFlags(ProcFlags::IndexMode8); SetFlags(ProcFlags::IndexMode8);
} }
@ -35,7 +35,7 @@ void Cpu::Exec()
{ {
_immediateMode = false; _immediateMode = false;
switch(_stopState) { switch(_state.StopState) {
case CpuStopState::Running: RunOp(); break; case CpuStopState::Running: RunOp(); break;
case CpuStopState::Stopped: case CpuStopState::Stopped:
//STP was executed, CPU no longer executes any code //STP was executed, CPU no longer executes any code
@ -46,7 +46,7 @@ void Cpu::Exec()
case CpuStopState::WaitingForIrq: case CpuStopState::WaitingForIrq:
//WAI //WAI
if(!_irqSource && !_nmiFlag) { if(!_state.IrqSource && !_state.NmiFlag) {
#ifndef DUMMYCPU #ifndef DUMMYCPU
_memoryManager->IncrementMasterClockValue<4>(); _memoryManager->IncrementMasterClockValue<4>();
#endif #endif
@ -54,17 +54,17 @@ void Cpu::Exec()
} else { } else {
Idle(); Idle();
Idle(); Idle();
_stopState = CpuStopState::Running; _state.StopState = CpuStopState::Running;
} }
break; break;
} }
//Use the state of the IRQ/NMI flags on the previous cycle to determine if an IRQ is processed or not //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); ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyNmiVector : Cpu::NmiVector);
_console->ProcessEvent(EventType::Nmi); _console->ProcessEvent(EventType::Nmi);
_nmiFlag = false; _state.NmiFlag = false;
} else if(_prevIrqSource && !CheckFlag(ProcFlags::IrqDisable)) { } else if(_state.PrevIrqSource && !CheckFlag(ProcFlags::IrqDisable)) {
ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyIrqVector : Cpu::IrqVector); ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyIrqVector : Cpu::IrqVector);
_console->ProcessEvent(EventType::Irq); _console->ProcessEvent(EventType::Irq);
} }
@ -332,19 +332,24 @@ void Cpu::RunOp()
} }
} }
CpuState Cpu::GetState()
{
return _state;
}
void Cpu::SetNmiFlag() void Cpu::SetNmiFlag()
{ {
_nmiFlag = true; _state.NmiFlag = true;
} }
void Cpu::SetIrqSource(IrqSource source) void Cpu::SetIrqSource(IrqSource source)
{ {
_irqSource |= (uint8_t)source; _state.IrqSource |= (uint8_t)source;
} }
bool Cpu::CheckIrqSource(IrqSource source) bool Cpu::CheckIrqSource(IrqSource source)
{ {
if(_irqSource & (uint8_t)source) { if(_state.IrqSource & (uint8_t)source) {
return true; return true;
} else { } else {
return false; return false;
@ -353,7 +358,7 @@ bool Cpu::CheckIrqSource(IrqSource source)
void Cpu::ClearIrqSource(IrqSource source) void Cpu::ClearIrqSource(IrqSource source)
{ {
_irqSource &= ~(uint8_t)source; _state.IrqSource &= ~(uint8_t)source;
} }
uint32_t Cpu::GetProgramAddress(uint16_t addr) uint32_t Cpu::GetProgramAddress(uint16_t addr)
@ -377,8 +382,8 @@ void Cpu::Idle()
{ {
_state.CycleCount++; _state.CycleCount++;
#ifndef DUMMYCPU #ifndef DUMMYCPU
_prevNmiFlag = _nmiFlag; _state.PrevNmiFlag = _state.NmiFlag;
_prevIrqSource = _irqSource; _state.PrevIrqSource = _state.IrqSource;
_memoryManager->IncrementMasterClockValue<6>(); _memoryManager->IncrementMasterClockValue<6>();
#endif #endif
} }
@ -412,8 +417,8 @@ uint8_t Cpu::Read(uint32_t addr, MemoryOperationType type)
LogRead(addr, value); LogRead(addr, value);
return value; return value;
#else #else
_prevNmiFlag = _nmiFlag; _state.PrevNmiFlag = _state.NmiFlag;
_prevIrqSource = _irqSource; _state.PrevIrqSource = _state.IrqSource;
return _memoryManager->Read(addr, type); return _memoryManager->Read(addr, type);
#endif #endif
} }
@ -457,8 +462,8 @@ void Cpu::Write(uint32_t addr, uint8_t value, MemoryOperationType type)
#ifdef DUMMYCPU #ifdef DUMMYCPU
LogWrite(addr, value); LogWrite(addr, value);
#else #else
_prevNmiFlag = _nmiFlag; _state.PrevNmiFlag = _state.NmiFlag;
_prevIrqSource = _irqSource; _state.PrevIrqSource = _state.IrqSource;
_memoryManager->Write(addr, value, type); _memoryManager->Write(addr, value, type);
#endif #endif
} }

View file

@ -13,11 +13,6 @@ class Console;
class Cpu class Cpu
{ {
public:
uint16_t GetPc() { return _state.PC; }
CpuState GetState() { return _state; }
int32_t GetLastOperand() { return (int32_t)_operand; }
private: private:
static constexpr uint32_t NmiVector = 0x00FFEA; static constexpr uint32_t NmiVector = 0x00FFEA;
static constexpr uint32_t ResetVector = 0x00FFFC; static constexpr uint32_t ResetVector = 0x00FFFC;
@ -39,11 +34,6 @@ private:
CpuState _state; CpuState _state;
uint32_t _operand; uint32_t _operand;
bool _nmiFlag;
bool _prevNmiFlag;
uint8_t _irqSource;
uint8_t _prevIrqSource;
CpuStopState _stopState;
uint32_t GetProgramAddress(uint16_t addr); uint32_t GetProgramAddress(uint16_t addr);
uint32_t GetDataAddress(uint16_t addr); uint32_t GetDataAddress(uint16_t addr);
@ -303,6 +293,8 @@ public:
void Reset(); void Reset();
void Exec(); void Exec();
CpuState GetState();
void SetNmiFlag(); void SetNmiFlag();
void SetIrqSource(IrqSource source); void SetIrqSource(IrqSource source);
bool CheckIrqSource(IrqSource source); bool CheckIrqSource(IrqSource source);
@ -325,6 +317,7 @@ private:
public: public:
void SetDummyState(CpuState &state); void SetDummyState(CpuState &state);
int32_t GetLastOperand();
uint32_t GetWriteCount(); uint32_t GetWriteCount();
uint32_t GetReadCount(); uint32_t GetReadCount();

View file

@ -1,6 +1,13 @@
#pragma once #pragma once
#include "stdafx.h" #include "stdafx.h"
enum class CpuStopState : uint8_t
{
Running = 0,
Stopped = 1,
WaitingForIrq = 2
};
struct CpuState struct CpuState
{ {
uint64_t CycleCount; uint64_t CycleCount;
@ -30,6 +37,13 @@ struct CpuState
/* 6502 emulation mode */ /* 6502 emulation mode */
bool EmulationMode; bool EmulationMode;
/* Misc internal state */
bool NmiFlag;
bool PrevNmiFlag;
uint8_t IrqSource;
uint8_t PrevIrqSource;
CpuStopState StopState;
}; };
namespace ProcFlags namespace ProcFlags
@ -68,9 +82,3 @@ enum class IrqSource
Ppu = 1, Ppu = 1,
}; };
enum class CpuStopState
{
Running = 0,
Stopped = 1,
WaitingForIrq = 2
};

View file

@ -53,3 +53,8 @@ void DummyCpu::GetReadInfo(uint32_t index, uint32_t &addr, uint8_t &value)
addr = _readAddresses[index]; addr = _readAddresses[index];
value = _readValue[index]; value = _readValue[index];
} }
int32_t DummyCpu::GetLastOperand()
{
return _operand;
}

View file

@ -392,15 +392,14 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, DebugState &state, E
case EvalValues::PpuFrameCount: token = state.Ppu.FrameCount; break; case EvalValues::PpuFrameCount: token = state.Ppu.FrameCount; break;
case EvalValues::PpuCycle: token = state.Ppu.Cycle; break; case EvalValues::PpuCycle: token = state.Ppu.Cycle; break;
case EvalValues::PpuScanline: token = state.Ppu.Scanline; break; case EvalValues::PpuScanline: token = state.Ppu.Scanline; break;
//TODO case EvalValues::Nmi: token = state.Cpu.NmiFlag; 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::Irq: token = state.CPU.IRQFlag; resultType = EvalResultType::Boolean; break;
case EvalValues::Value: token = operationInfo.Value; break; case EvalValues::Value: token = operationInfo.Value; break;
case EvalValues::Address: token = operationInfo.Address; break; case EvalValues::Address: token = operationInfo.Address; break;
case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(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::IsWrite: token = operationInfo.Type == MemoryOperationType::Write || operationInfo.Type == MemoryOperationType::DmaWrite; break;
case EvalValues::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read || operationInfo.OperationType == MemoryOperationType::DummyRead; break; case EvalValues::IsRead: token = operationInfo.Type != MemoryOperationType::Write && operationInfo.Type != MemoryOperationType::DmaWrite; break;
case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; break; /*case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; break;
case EvalValues::Sprite0Hit: token = state.PPU.StatusFlags.Sprite0Hit; resultType = EvalResultType::Boolean; 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::SpriteOverflow: token = state.PPU.StatusFlags.SpriteOverflow; resultType = EvalResultType::Boolean; break;
case EvalValues::VerticalBlank: token = state.PPU.StatusFlags.VerticalBlank; resultType = EvalResultType::Boolean; break; case EvalValues::VerticalBlank: token = state.PPU.StatusFlags.VerticalBlank; resultType = EvalResultType::Boolean; break;

View file

@ -126,6 +126,13 @@ namespace Mesen.GUI
public SnesMemoryType Type; public SnesMemoryType Type;
} }
public enum CpuStopState : byte
{
Running = 0,
Stopped = 1,
WaitingForIrq = 2
}
public struct CpuState public struct CpuState
{ {
public UInt64 CycleCount; public UInt64 CycleCount;
@ -142,6 +149,12 @@ namespace Mesen.GUI
public byte DBR; public byte DBR;
public byte PS; public byte PS;
[MarshalAs(UnmanagedType.I1)] public bool EmulationMode; [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 public struct PpuState