Debugger: Added more CPUs and values to exp. evaluator

This commit is contained in:
Sour 2022-02-22 18:26:24 -05:00
parent 92734d6015
commit 52127bd354
10 changed files with 262 additions and 26 deletions

View file

@ -369,8 +369,10 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="Debugger\BaseEventManager.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Cx4.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Gameboy.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Gsu.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.NecDsp.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Nes.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Snes.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Spc.cpp" />

View file

@ -1272,6 +1272,8 @@
<ClCompile Include="Debugger\ExpressionEvaluator.Spc.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Gsu.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Gameboy.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.NecDsp.cpp" />
<ClCompile Include="Debugger\ExpressionEvaluator.Cx4.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="SNES">

View file

@ -0,0 +1,84 @@
#include "stdafx.h"
#include "ExpressionEvaluator.h"
#include "SNES/Debugger/Cx4Debugger.h"
#include "SNES/Coprocessors/CX4/Cx4Types.h"
unordered_map<string, int64_t>& ExpressionEvaluator::GetCx4Tokens()
{
static unordered_map<string, int64_t> supportedTokens = {
{ "r0", EvalValues::R0 },
{ "r1", EvalValues::R1 },
{ "r2", EvalValues::R2 },
{ "r3", EvalValues::R3 },
{ "r4", EvalValues::R4 },
{ "r5", EvalValues::R5 },
{ "r6", EvalValues::R6 },
{ "r7", EvalValues::R7 },
{ "r8", EvalValues::R8 },
{ "r9", EvalValues::R9 },
{ "r10", EvalValues::R10 },
{ "r11", EvalValues::R11 },
{ "r12", EvalValues::R12 },
{ "r13", EvalValues::R13 },
{ "r14", EvalValues::R14 },
{ "r15", EvalValues::R15 },
{ "pb", EvalValues::RegPB },
{ "pc", EvalValues::RegPC },
{ "a", EvalValues::RegA },
{ "p", EvalValues::RegP },
{ "sp", EvalValues::RegSP },
{ "mult", EvalValues::RegMult },
{ "negative", EvalValues::RegPS_Negative },
{ "zero", EvalValues::RegPS_Zero },
{ "carry", EvalValues::RegPS_Carry },
{ "overflow", EvalValues::RegPS_Overflow },
{ "irq", EvalValues::RegPS_Interrupt },
{ "mdr", EvalValues::RegMDR },
{ "mar", EvalValues::RegMAR },
{ "dpr", EvalValues::RegDPR },
};
return supportedTokens;
}
int64_t ExpressionEvaluator::GetCx4TokenValue(int64_t token, EvalResultType& resultType)
{
Cx4State& s = (Cx4State&)((Cx4Debugger*)_cpuDebugger)->GetState();
switch(token) {
case EvalValues::R0: return s.Regs[0];
case EvalValues::R1: return s.Regs[1];
case EvalValues::R2: return s.Regs[2];
case EvalValues::R3: return s.Regs[3];
case EvalValues::R4: return s.Regs[4];
case EvalValues::R5: return s.Regs[5];
case EvalValues::R6: return s.Regs[6];
case EvalValues::R7: return s.Regs[7];
case EvalValues::R8: return s.Regs[8];
case EvalValues::R9: return s.Regs[9];
case EvalValues::R10: return s.Regs[10];
case EvalValues::R11: return s.Regs[11];
case EvalValues::R12: return s.Regs[12];
case EvalValues::R13: return s.Regs[13];
case EvalValues::R14: return s.Regs[14];
case EvalValues::R15: return s.Regs[15];
case EvalValues::RegPB: return s.PB;
case EvalValues::RegPC: return s.PC;
case EvalValues::RegA: return s.A;
case EvalValues::RegP: return s.P;
case EvalValues::RegSP: return s.SP;
case EvalValues::RegMult: return s.Mult;
case EvalValues::RegPS_Negative: return ReturnBool(s.Negative, resultType);
case EvalValues::RegPS_Zero: return ReturnBool(s.Zero, resultType);
case EvalValues::RegPS_Carry: return ReturnBool(s.Carry, resultType);
case EvalValues::RegPS_Overflow: return ReturnBool(s.Overflow, resultType);
case EvalValues::RegPS_Interrupt: return ReturnBool(s.IrqFlag, resultType);
case EvalValues::RegMDR: return s.MemoryDataReg;
case EvalValues::RegMAR: return s.MemoryAddressReg;
case EvalValues::RegDPR: return s.DataPointerReg;
default: return 0;
}
}

View file

@ -20,6 +20,10 @@ unordered_map<string, int64_t>& ExpressionEvaluator::GetGameboyTokens()
{ "hl", EvalValues::RegHL },
{ "sp", EvalValues::RegSP },
{ "pc", EvalValues::RegPC },
{ "frame", EvalValues::PpuFrameCount },
{ "cycle", EvalValues::PpuCycle },
{ "scanline", EvalValues::PpuScanline },
};
return supportedTokens;
@ -27,6 +31,12 @@ unordered_map<string, int64_t>& ExpressionEvaluator::GetGameboyTokens()
int64_t ExpressionEvaluator::GetGameboyTokenValue(int64_t token, EvalResultType& resultType)
{
auto ppu = [this]() -> GbPpuState {
GbPpuState ppu;
((GbDebugger*)_cpuDebugger)->GetPpuState(ppu);
return ppu;
};
GbCpuState& s = (GbCpuState&)((GbDebugger*)_cpuDebugger)->GetState();
switch(token) {
case EvalValues::RegA: return s.A;
@ -43,6 +53,11 @@ int64_t ExpressionEvaluator::GetGameboyTokenValue(int64_t token, EvalResultType&
case EvalValues::RegHL: return (s.H << 8) | s.L;
case EvalValues::RegSP: return s.SP;
case EvalValues::RegPC: return s.PC;
case EvalValues::PpuFrameCount: return ppu().FrameCount;
case EvalValues::PpuCycle: return ppu().Cycle;
case EvalValues::PpuScanline: return ppu().Scanline;
default: return 0;
}
}

View file

@ -0,0 +1,48 @@
#include "stdafx.h"
#include "ExpressionEvaluator.h"
#include "SNES/Coprocessors/DSP/NecDspTypes.h"
#include "SNES/Debugger/NecDspDebugger.h"
unordered_map<string, int64_t>& ExpressionEvaluator::GetNecDspTokens()
{
static unordered_map<string, int64_t> supportedTokens = {
{ "a", EvalValues::RegA },
{ "b", EvalValues::RegB },
{ "tr", EvalValues::RegTR },
{ "trb", EvalValues::RegTRB },
{ "rp", EvalValues::RegRP },
{ "dp", EvalValues::RegDP },
{ "dr", EvalValues::RegDR },
{ "sr", EvalValues::RegSR },
{ "k", EvalValues::RegK },
{ "l", EvalValues::RegL },
{ "m", EvalValues::RegM },
{ "n", EvalValues::RegN },
{ "sp", EvalValues::RegSP },
{ "pc", EvalValues::RegPC },
};
return supportedTokens;
}
int64_t ExpressionEvaluator::GetNecDspTokenValue(int64_t token, EvalResultType& resultType)
{
NecDspState& s = (NecDspState&)((NecDspDebugger*)_cpuDebugger)->GetState();
switch(token) {
case EvalValues::RegA: return s.A;
case EvalValues::RegB: return s.B;
case EvalValues::RegTR: return s.TR;
case EvalValues::RegTRB: return s.TRB;
case EvalValues::RegRP: return s.RP;
case EvalValues::RegDP: return s.DP;
case EvalValues::RegDR: return s.DR;
case EvalValues::RegSR: return s.SR;
case EvalValues::RegK: return s.K;
case EvalValues::RegL: return s.L;
case EvalValues::RegM: return s.M;
case EvalValues::RegN: return s.N;
case EvalValues::RegSP: return s.SP;
case EvalValues::RegPC: return s.PC;
default: return 0;
}
}

View file

@ -13,7 +13,19 @@ unordered_map<string, int64_t>& ExpressionEvaluator::GetNesTokens()
{ "sp", EvalValues::RegSP },
{ "pc", EvalValues::RegPC },
{ "irq", EvalValues::Irq },
{ "nmi", EvalValues::Nmi }
{ "nmi", EvalValues::Nmi },
{ "frame", EvalValues::PpuFrameCount },
{ "cycle", EvalValues::PpuCycle },
{ "scanline", EvalValues::PpuScanline },
{ "sprite0hit", EvalValues::Sprite0Hit },
{ "verticalblank", EvalValues::VerticalBlank },
{ "spriteoverflow", EvalValues::SpriteOverflow },
{ "pscarry", EvalValues::RegPS_Carry },
{ "pszero", EvalValues::RegPS_Zero },
{ "psinterrupt", EvalValues::RegPS_Interrupt },
{ "psdecimal", EvalValues::RegPS_Decimal },
{ "psoverflow", EvalValues::RegPS_Overflow },
{ "psnegative", EvalValues::RegPS_Negative },
};
return supportedTokens;
@ -21,6 +33,12 @@ unordered_map<string, int64_t>& ExpressionEvaluator::GetNesTokens()
int64_t ExpressionEvaluator::GetNesTokenValue(int64_t token, EvalResultType& resultType)
{
auto ppu = [this]() -> NesPpuState {
NesPpuState ppu;
((NesDebugger*)_cpuDebugger)->GetPpuState(ppu);
return ppu;
};
NesCpuState& s = (NesCpuState&)((NesDebugger*)_cpuDebugger)->GetState();
switch(token) {
case EvalValues::RegA: return s.A;
@ -29,12 +47,24 @@ int64_t ExpressionEvaluator::GetNesTokenValue(int64_t token, EvalResultType& res
case EvalValues::RegSP: return s.SP;
case EvalValues::RegPS: return s.PS;
case EvalValues::RegPC: return s.PC;
case EvalValues::Nmi:
resultType = EvalResultType::Boolean;
return s.NMIFlag;
case EvalValues::Irq:
resultType = EvalResultType::Boolean;
return s.IRQFlag != 0;
case EvalValues::Nmi: return ReturnBool(s.NMIFlag, resultType);
case EvalValues::Irq: return ReturnBool(s.IRQFlag, resultType);
case EvalValues::PpuFrameCount: return ppu().FrameCount;
case EvalValues::PpuCycle: return ppu().Cycle;
case EvalValues::PpuScanline: return ppu().Scanline;
case EvalValues::Sprite0Hit: return ReturnBool(ppu().StatusFlags.Sprite0Hit, resultType);
case EvalValues::SpriteOverflow: return ReturnBool(ppu().StatusFlags.SpriteOverflow, resultType);
case EvalValues::VerticalBlank: return ReturnBool(ppu().StatusFlags.VerticalBlank, resultType);
case EvalValues::RegPS_Carry: return ReturnBool(s.PS & PSFlags::Carry, resultType);
case EvalValues::RegPS_Zero: return ReturnBool(s.PS & PSFlags::Zero, resultType);
case EvalValues::RegPS_Interrupt: return ReturnBool(s.PS & PSFlags::Interrupt, resultType);
case EvalValues::RegPS_Decimal: return ReturnBool(s.PS & PSFlags::Decimal, resultType);
case EvalValues::RegPS_Overflow: return ReturnBool(s.PS & PSFlags::Overflow, resultType);
case EvalValues::RegPS_Negative: return ReturnBool(s.PS & PSFlags::Negative, resultType);
default: return 0;
}
}

View file

@ -19,6 +19,14 @@ unordered_map<string, int64_t>& ExpressionEvaluator::GetSnesTokens()
{ "hclock", EvalValues::PpuHClock },
{ "cycle", EvalValues::PpuCycle },
{ "scanline", EvalValues::PpuScanline },
{ "pscarry", EvalValues::RegPS_Carry },
{ "pszero", EvalValues::RegPS_Zero },
{ "psinterrupt", EvalValues::RegPS_Interrupt },
{ "psindex", EvalValues::RegPS_Memory },
{ "psmemory", EvalValues::RegPS_Index },
{ "psdecimal", EvalValues::RegPS_Decimal },
{ "psoverflow", EvalValues::RegPS_Overflow },
{ "psnegative", EvalValues::RegPS_Negative },
};
return supportedTokens;
@ -40,18 +48,22 @@ int64_t ExpressionEvaluator::GetSnesTokenValue(int64_t token, EvalResultType& re
case EvalValues::RegSP: return s.SP;
case EvalValues::RegPS: return s.PS;
case EvalValues::RegPC: return (s.K << 16) | s.PC;
case EvalValues::Nmi:
resultType = EvalResultType::Boolean;
return s.NmiFlag;
case EvalValues::Irq:
resultType = EvalResultType::Boolean;
return s.IrqSource != 0;
case EvalValues::Nmi: return ReturnBool(s.NmiFlag, resultType);
case EvalValues::Irq: return ReturnBool(s.IrqSource, resultType);
case EvalValues::PpuFrameCount: return getPpuState().FrameCount;
case EvalValues::PpuCycle: return getPpuState().Cycle;
case EvalValues::PpuHClock: return getPpuState().HClock;
case EvalValues::PpuScanline: return getPpuState().Scanline;
case EvalValues::RegPS_Carry: return ReturnBool(s.PS & ProcFlags::Carry, resultType);
case EvalValues::RegPS_Zero: return ReturnBool(s.PS & ProcFlags::Zero, resultType);
case EvalValues::RegPS_Interrupt: return ReturnBool(s.PS & ProcFlags::IrqDisable, resultType);
case EvalValues::RegPS_Memory: return ReturnBool(s.PS & ProcFlags::MemoryMode8, resultType);
case EvalValues::RegPS_Index: return ReturnBool(s.PS & ProcFlags::IndexMode8, resultType);
case EvalValues::RegPS_Decimal: return ReturnBool(s.PS & ProcFlags::Decimal, resultType);
case EvalValues::RegPS_Overflow: return ReturnBool(s.PS & ProcFlags::Overflow, resultType);
case EvalValues::RegPS_Negative: return ReturnBool(s.PS & ProcFlags::Negative, resultType);
default: return 0;
}
}

View file

@ -61,10 +61,10 @@ unordered_map<string, int64_t>* ExpressionEvaluator::GetAvailableTokens()
switch(_cpuType) {
case CpuType::Snes: return &GetSnesTokens();
case CpuType::Spc: return &GetSpcTokens();
//case CpuType::NecDsp: return &GetNecDspTokens();
case CpuType::NecDsp: return &GetNecDspTokens();
case CpuType::Sa1: return &GetSnesTokens();
case CpuType::Gsu: return &GetGsuTokens();
//case CpuType::Cx4: return &GetCx4Tokens();
case CpuType::Cx4: return &GetCx4Tokens();
case CpuType::Gameboy: return &GetGameboyTokens();
case CpuType::Nes: return &GetNesTokens();
}
@ -391,9 +391,6 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resu
//TODO
//case EvalValues::RegOpPC: token = state.Cpu.DebugPC; break;
//case EvalValues::PpuFrameCount: token = _cpuType == CpuType::Gameboy ? state.Gameboy.Ppu.FrameCount : state.Ppu.FrameCount; break;
//case EvalValues::PpuCycle: token = _cpuType == CpuType::Gameboy ? state.Gameboy.Ppu.Cycle : state.Ppu.Cycle; break;
//case EvalValues::PpuScanline: token = _cpuType == CpuType::Gameboy ? state.Gameboy.Ppu.Scanline : state.Ppu.Scanline; break;
//case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(operationInfo.Address); break;
//case EvalValues::PreviousOpPC: token = state.CPU.PreviousDebugPC; break;
@ -404,10 +401,10 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resu
switch(_cpuType) {
case CpuType::Snes: token = GetSnesTokenValue(token, resultType); break;
case CpuType::Spc: token = GetSpcTokenValue(token, resultType); break;
//case CpuType::NecDsp: token = GetNecDspTokenValue(token, resultType); break;
case CpuType::NecDsp: token = GetNecDspTokenValue(token, resultType); break;
case CpuType::Sa1: token = GetSnesTokenValue(token, resultType); break;
case CpuType::Gsu: token = GetGsuTokenValue(token, resultType); break;
//case CpuType::Cx4: token = GetCx4TokenValue(token, resultType); break;
case CpuType::Cx4: token = GetCx4TokenValue(token, resultType); break;
case CpuType::Gameboy: token = GetGameboyTokenValue(token, resultType); break;
case CpuType::Nes: token = GetNesTokenValue(token, resultType); break;
}
@ -416,6 +413,11 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resu
}
}
} else if(token >= EvalOperators::Multiplication) {
if(pos <= 0) {
resultType = EvalResultType::Invalid;
return 0;
}
right = operandStack[--pos];
if(pos > 0 && token <= EvalOperators::LogicalOr) {
//Only do this for binary operators
@ -466,7 +468,8 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resu
}
operandStack[pos++] = token;
if(pos >= 100) {
throw std::runtime_error("Out of stack space");
resultType = EvalResultType::Invalid;
return 0;
}
}
return (int32_t)operandStack[0];
@ -481,6 +484,12 @@ ExpressionEvaluator::ExpressionEvaluator(Debugger* debugger, IDebugger* cpuDebug
_cpuMemory = DebugUtilities::GetCpuMemoryType(cpuType);
}
bool ExpressionEvaluator::ReturnBool(int64_t value, EvalResultType& resultType)
{
resultType = EvalResultType::Boolean;
return value != 0;
}
ExpressionData ExpressionEvaluator::GetRpnList(string expression, bool &success)
{
ExpressionData* cachedData = PrivateGetRpnList(expression, success);

View file

@ -53,7 +53,17 @@ enum EvalValues : int64_t
RegX,
RegY,
RegSP,
RegPS,
RegPS_Carry,
RegPS_Zero,
RegPS_Interrupt,
RegPS_Memory,
RegPS_Index,
RegPS_Decimal,
RegPS_Overflow,
RegPS_Negative,
RegPC,
RegOpPC,
PpuFrameCount,
@ -104,6 +114,28 @@ enum EvalValues : int64_t
RegDE,
RegHL,
RegTR,
RegTRB,
RegRP,
RegDP,
RegDR,
RegSR,
RegK,
RegM,
RegN,
RegPB,
RegP,
RegMult,
RegMDR,
RegMAR,
RegDPR,
Sprite0Hit,
VerticalBlank,
SpriteOverflow,
FirstLabelIndex,
};
@ -164,11 +196,11 @@ private:
unordered_map<string, int64_t>& GetGsuTokens();
int64_t GetGsuTokenValue(int64_t token, EvalResultType& resultType);
/*unordered_map<string, int64_t>& GetCx4Tokens();
unordered_map<string, int64_t>& GetCx4Tokens();
int64_t GetCx4TokenValue(int64_t token, EvalResultType& resultType);
unordered_map<string, int64_t>& GetNecDspTokens();
int64_t GetNecDspTokenValue(int64_t token, EvalResultType& resultType);*/
int64_t GetNecDspTokenValue(int64_t token, EvalResultType& resultType);
unordered_map<string, int64_t>& GetGameboyTokens();
int64_t GetGameboyTokenValue(int64_t token, EvalResultType& resultType);
@ -176,6 +208,8 @@ private:
unordered_map<string, int64_t>& GetNesTokens();
int64_t GetNesTokenValue(int64_t token, EvalResultType& resultType);
bool ReturnBool(int64_t value, EvalResultType& resultType);
int64_t ProcessSharedTokens(string token);
string GetNextToken(string expression, size_t &pos, ExpressionData &data, bool &success, bool previousTokenIsOp);

View file

@ -52,7 +52,7 @@ namespace Mesen.Config
CpuConfig[CpuType.NecDsp] = new TraceLoggerCpuConfig() {
Enabled = true,
Format = "[Disassembly][Align,38] A:[A,4h] [FlagsA] B:[A,4h] [FlagsB] K:[K,4h] L:[L,4h] M:[M,4h] N:[N,4h] RP:[RP,4h] DP:[DP,4h] DR:[DR,4h] SR:[SR,4h] TR:[TR,4h] TRB:[TRB,4h] H:[Cycle,3] V:[Scanline,3]"
Format = "[Disassembly][Align,38] A:[A,4h] [FlagsA] B:[B,4h] [FlagsB] K:[K,4h] L:[L,4h] M:[M,4h] N:[N,4h] RP:[RP,4h] DP:[DP,4h] DR:[DR,4h] SR:[SR,4h] TR:[TR,4h] TRB:[TRB,4h] H:[Cycle,3] V:[Scanline,3]"
};
CpuConfig[CpuType.Nes] = new TraceLoggerCpuConfig() {