Debugger: Added "memaddress" token in expressions

This commit is contained in:
Sour 2022-09-28 18:20:45 -04:00
parent 7fb0a1c177
commit 3fe77d271a
14 changed files with 53 additions and 46 deletions

View file

@ -414,7 +414,7 @@ public:
memset(_rowIds, 0, sizeof(uint64_t) * BaseTraceLogger::ExecutionLogSize);
}
void LogNonExec(MemoryOperationInfo& operation)
void LogNonExec(MemoryOperationInfo& operation, AddressInfo& addressInfo)
{
if(_pendingLog) {
int pos = _currentPos - 1;
@ -422,18 +422,18 @@ public:
pos = BaseTraceLogger::ExecutionLogSize - 1;
}
if(ConditionMatches(_lastDisassemblyInfo, operation)) {
if(ConditionMatches(_lastDisassemblyInfo, operation, addressInfo)) {
AddRow(_lastState, _lastDisassemblyInfo);
_pendingLog = false;
}
}
}
void Log(CpuStateType& cpuState, DisassemblyInfo& disassemblyInfo, MemoryOperationInfo& operation)
void Log(CpuStateType& cpuState, DisassemblyInfo& disassemblyInfo, MemoryOperationInfo& operation, AddressInfo& addressInfo)
{
if(_enabled) {
//For the sake of performance, only log data for the CPUs we're actively displaying/logging
if(ConditionMatches(disassemblyInfo, operation)) {
if(ConditionMatches(disassemblyInfo, operation, addressInfo)) {
AddRow(cpuState, disassemblyInfo);
} else {
_pendingLog = true;
@ -477,11 +477,11 @@ public:
return _rowIds[i];
}
bool ConditionMatches(DisassemblyInfo &disassemblyInfo, MemoryOperationInfo &operationInfo)
bool ConditionMatches(DisassemblyInfo &disassemblyInfo, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo)
{
if(!_conditionData.RpnQueue.empty()) {
EvalResultType type;
if(!_expEvaluator->Evaluate(_conditionData, type, operationInfo)) {
if(!_expEvaluator->Evaluate(_conditionData, type, operationInfo, addressInfo)) {
return false;
}
}

View file

@ -85,7 +85,7 @@ int BreakpointManager::InternalCheckBreakpoint(MemoryOperationInfo operationInfo
vector<Breakpoint> &breakpoints = _breakpoints[(int)operationInfo.Type];
for(size_t i = 0, len = breakpoints.size(); i < len; i++) {
if(breakpoints[i].Matches(operationInfo, address)) {
if(breakpoints[i].HasCondition() && !_bpExpEval->Evaluate(_rpnList[(int)operationInfo.Type][i], resultType, operationInfo)) {
if(breakpoints[i].HasCondition() && !_bpExpEval->Evaluate(_rpnList[(int)operationInfo.Type][i], resultType, operationInfo, address)) {
continue;
}

View file

@ -526,11 +526,12 @@ void Debugger::GetTokenList(CpuType cpuType, char* tokenList)
int32_t Debugger::EvaluateExpression(string expression, CpuType cpuType, EvalResultType &resultType, bool useCache)
{
MemoryOperationInfo operationInfo { 0, 0, MemoryOperationType::Read, MemoryType::None };
AddressInfo addressInfo = { 0, MemoryType::None };
if(useCache && _debuggers[(int)cpuType].Evaluator) {
return _debuggers[(int)cpuType].Evaluator->Evaluate(expression, resultType, operationInfo);
return _debuggers[(int)cpuType].Evaluator->Evaluate(expression, resultType, operationInfo, addressInfo);
} else if(_debuggers[(int)cpuType].Debugger) {
ExpressionEvaluator expEval(this, _debuggers[(int)cpuType].Debugger.get(), cpuType);
return expEval.Evaluate(expression, resultType, operationInfo);
return expEval.Evaluate(expression, resultType, operationInfo, addressInfo);
}
resultType = EvalResultType::Invalid;

View file

@ -133,6 +133,8 @@ int64_t ExpressionEvaluator::ProcessSharedTokens(string token)
return EvalValues::Value;
} else if(token == "address") {
return EvalValues::Address;
} else if(token == "memaddress") {
return EvalValues::MemoryAddress;
} else if(token == "iswrite") {
return EvalValues::IsWrite;
} else if(token == "isread") {
@ -352,7 +354,7 @@ bool ExpressionEvaluator::ToRpn(string expression, ExpressionData &data)
return true;
}
int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resultType, MemoryOperationInfo &operationInfo)
int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resultType, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo)
{
if(data.RpnQueue.empty()) {
resultType = EvalResultType::Invalid;
@ -391,6 +393,7 @@ int32_t ExpressionEvaluator::Evaluate(ExpressionData &data, EvalResultType &resu
switch(token) {
case EvalValues::Value: token = operationInfo.Value; break;
case EvalValues::Address: token = operationInfo.Address; break;
case EvalValues::MemoryAddress: token = addressInfo.Address; break;
case EvalValues::IsWrite: token = operationInfo.Type == MemoryOperationType::Write || operationInfo.Type == MemoryOperationType::DmaWrite || operationInfo.Type == MemoryOperationType::DummyWrite; break;
case EvalValues::IsRead: token = operationInfo.Type != MemoryOperationType::Write && operationInfo.Type != MemoryOperationType::DmaWrite && operationInfo.Type != MemoryOperationType::DummyWrite; break;
case EvalValues::IsDma: token = operationInfo.Type == MemoryOperationType::DmaRead || operationInfo.Type == MemoryOperationType::DmaWrite; break;
@ -565,7 +568,7 @@ ExpressionData* ExpressionEvaluator::PrivateGetRpnList(string expression, bool&
return cachedData;
}
int32_t ExpressionEvaluator::PrivateEvaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo, bool& success)
int32_t ExpressionEvaluator::PrivateEvaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo, bool& success)
{
success = true;
ExpressionData *cachedData = PrivateGetRpnList(expression, success);
@ -575,14 +578,14 @@ int32_t ExpressionEvaluator::PrivateEvaluate(string expression, EvalResultType &
return 0;
}
return Evaluate(*cachedData, resultType, operationInfo);
return Evaluate(*cachedData, resultType, operationInfo, addressInfo);
}
int32_t ExpressionEvaluator::Evaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo)
int32_t ExpressionEvaluator::Evaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo)
{
try {
bool success;
int32_t result = PrivateEvaluate(expression, resultType, operationInfo, success);
int32_t result = PrivateEvaluate(expression, resultType, operationInfo, addressInfo, success);
if(success) {
return result;
}
@ -596,9 +599,10 @@ bool ExpressionEvaluator::Validate(string expression)
{
try {
EvalResultType type;
MemoryOperationInfo operationInfo;
MemoryOperationInfo operationInfo = {};
AddressInfo addressInfo = {};
bool success;
PrivateEvaluate(expression, type, operationInfo, success);
PrivateEvaluate(expression, type, operationInfo, addressInfo, success);
return success;
} catch(std::exception&) {
return false;

View file

@ -75,6 +75,7 @@ enum EvalValues : int64_t
Irq,
Value,
Address,
MemoryAddress,
IsWrite,
IsRead,
IsDma,
@ -220,7 +221,7 @@ private:
string GetNextToken(string expression, size_t &pos, ExpressionData &data, bool &success, bool previousTokenIsOp);
bool ProcessSpecialOperator(EvalOperators evalOp, std::stack<EvalOperators> &opStack, std::stack<int> &precedenceStack, vector<int64_t> &outputQueue);
bool ToRpn(string expression, ExpressionData &data);
int32_t PrivateEvaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo, bool &success);
int32_t PrivateEvaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo, bool &success);
ExpressionData* PrivateGetRpnList(string expression, bool& success);
protected:
@ -228,8 +229,8 @@ protected:
public:
ExpressionEvaluator(Debugger* debugger, IDebugger* cpuDebugger, CpuType cpuType);
int32_t Evaluate(ExpressionData &data, EvalResultType &resultType, MemoryOperationInfo &operationInfo);
int32_t Evaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo);
int32_t Evaluate(ExpressionData &data, EvalResultType &resultType, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo);
int32_t Evaluate(string expression, EvalResultType &resultType, MemoryOperationInfo &operationInfo, AddressInfo& addressInfo);
ExpressionData GetRpnList(string expression, bool &success);
void GetTokenList(char* tokenList);

View file

@ -145,7 +145,7 @@ void GbDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType t
if(type == MemoryOperationType::ExecOpCode) {
if(_traceLogger->IsEnabled()) {
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, 0, CpuType::Gameboy);
_traceLogger->Log(_cpu->GetState(), disInfo, operation);
_traceLogger->Log(_cpu->GetState(), disInfo, operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _gameboy->GetMasterClock());
} else if(type == MemoryOperationType::ExecOperand) {
@ -154,7 +154,7 @@ void GbDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType t
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _gameboy->GetMasterClock());
@ -165,7 +165,7 @@ void GbDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType t
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
if(addr < 0xFE00 || addr >= 0xFF80) {
@ -200,7 +200,7 @@ void GbDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
if(addr == 0xFFFF || (addr >= 0xFE00 && addr < 0xFF80) || (addr >= 0x8000 && addr <= 0x9FFF)) {

View file

@ -173,7 +173,7 @@ void NesDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
if(_traceLogger->IsEnabled()) {
NesCpuState& state = _cpu->GetState();
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, state.PS, CpuType::Nes);
_traceLogger->Log(state, disInfo, operation);
_traceLogger->Log(state, disInfo, operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _cpu->GetCycleCount());
@ -186,7 +186,7 @@ void NesDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _cpu->GetCycleCount());
_step->ProcessCpuCycle();
@ -205,7 +205,7 @@ void NesDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
ReadResult result = _memoryAccessCounter->ProcessMemoryRead(addressInfo, _cpu->GetCycleCount());
@ -239,7 +239,7 @@ void NesDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _cpu->GetCycleCount());

View file

@ -159,7 +159,7 @@ void PceDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
if(_traceLogger->IsEnabled()) {
PceCpuState& state = _cpu->GetState();
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, state.PS, CpuType::Pce);
_traceLogger->Log(state, disInfo, operation);
_traceLogger->Log(state, disInfo, operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetState().CycleCount);
@ -172,7 +172,7 @@ void PceDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetState().CycleCount);
@ -184,7 +184,7 @@ void PceDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
ReadResult result = _memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetState().CycleCount);
@ -218,7 +218,7 @@ void PceDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetState().CycleCount);

View file

@ -89,7 +89,7 @@ void Cx4Debugger::ProcessInstruction()
if(_traceLogger->IsEnabled()) {
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, pc, 0, CpuType::Cx4);
_traceLogger->Log(state, disInfo, operation);
_traceLogger->Log(state, disInfo, operation, addressInfo);
}
AddressInfo opCodeHighAddr = _cx4->GetMemoryMappings()->GetAbsoluteAddress(pc + 1);
@ -109,7 +109,7 @@ void Cx4Debugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
_codeDataLogger->SetData<SnesCdlFlags::Cx4>(addressInfo.Address);
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
@ -123,7 +123,7 @@ void Cx4Debugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
_debugger->ProcessBreakConditions(CpuType::Cx4, *_step.get(), _breakpointManager.get(), operation, addressInfo);
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
}

View file

@ -74,7 +74,7 @@ void GsuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
if(type == MemoryOperationType::ExecOpCode) {
if(_traceLogger->IsEnabled()) {
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, 0, CpuType::Gsu);
_traceLogger->Log(_gsu->GetState(), disInfo, operation);
_traceLogger->Log(_gsu->GetState(), disInfo, operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
} else if(type == MemoryOperationType::ExecOperand) {
@ -87,7 +87,7 @@ void GsuDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
_codeDataLogger->SetData<SnesCdlFlags::Gsu>(addressInfo.Address);
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
_debugger->ProcessBreakConditions(CpuType::Gsu, *_step.get(), _breakpointManager.get(), operation, addressInfo);
@ -101,7 +101,7 @@ void GsuDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
_debugger->ProcessBreakConditions(CpuType::Gsu, *_step.get(), _breakpointManager.get(), operation, addressInfo);
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_disassembler->InvalidateCache(addressInfo, CpuType::Gsu);

View file

@ -77,7 +77,7 @@ void NecDspDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationTy
if(_traceLogger->IsEnabled()) {
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, 0, CpuType::NecDsp);
_traceLogger->Log(_dsp->GetState(), disInfo, operation);
_traceLogger->Log(_dsp->GetState(), disInfo, operation, addressInfo);
}
}

View file

@ -208,7 +208,7 @@ void SnesDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
if(type == MemoryOperationType::ExecOpCode) {
if(_traceLogger->IsEnabled()) {
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, state.PS, _cpuType);
_traceLogger->Log(state, disInfo, operation);
_traceLogger->Log(state, disInfo, operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
@ -220,7 +220,7 @@ void SnesDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
_cdl->SetCode(addressInfo.Address, (state.PS & (SnesCdlFlags::IndexMode8 | SnesCdlFlags::MemoryMode8)));
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
@ -231,7 +231,7 @@ void SnesDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
_cdl->SetData(addressInfo.Address);
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
ReadResult result = _memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
@ -267,7 +267,7 @@ void SnesDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationTyp
}
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());

View file

@ -114,19 +114,19 @@ void SpcDebugger::ProcessRead(uint32_t addr, uint8_t value, MemoryOperationType
if(_traceLogger->IsEnabled()) {
SpcState& state = _spc->GetState();
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo, addr, 0, CpuType::Spc);
_traceLogger->Log(state, disInfo, operation);
_traceLogger->Log(state, disInfo, operation, addressInfo);
}
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
} else if(type == MemoryOperationType::ExecOperand) {
_memoryAccessCounter->ProcessMemoryExec(addressInfo, _memoryManager->GetMasterClock());
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_debugger->ProcessBreakConditions(CpuType::Spc, *_step.get(), _breakpointManager.get(), operation, addressInfo);
} else {
_memoryAccessCounter->ProcessMemoryRead(addressInfo, _memoryManager->GetMasterClock());
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
_debugger->ProcessBreakConditions(CpuType::Spc, *_step.get(), _breakpointManager.get(), operation, addressInfo);
}
@ -143,7 +143,7 @@ void SpcDebugger::ProcessWrite(uint32_t addr, uint8_t value, MemoryOperationType
_memoryAccessCounter->ProcessMemoryWrite(addressInfo, _memoryManager->GetMasterClock());
if(_traceLogger->IsEnabled()) {
_traceLogger->LogNonExec(operation);
_traceLogger->LogNonExec(operation, addressInfo);
}
}

View file

@ -54,6 +54,7 @@ namespace Mesen.Debugger.Utilities
addBoldRow("Other values");
addRow(" OpPc: Program counter of the first byte of the current instruction");
addRow(" Address: CPU memory address being read/written");
addRow(" MemAddress: RAM or ROM address (byte offset) being read/written (-1 if not mapped to RAM/ROM)");
addRow(" Value: Value being read/written");
addRow(" IsRead: True if the CPU is reading data");
addRow(" IsWrite: True if the CPU is writing data");