mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Debugger: Added conditional logging to trace logger
This commit is contained in:
parent
3fe9faaf57
commit
2753273206
13 changed files with 371 additions and 201 deletions
|
@ -41,7 +41,7 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
|
|||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, _mapper, _codeDataLogger, this, _disassembler));
|
||||
_memoryAccessCounter.reset(new MemoryAccessCounter(this));
|
||||
_profiler.reset(new Profiler(this));
|
||||
_traceLogger.reset(new TraceLogger(memoryManager, _labelManager));
|
||||
_traceLogger.reset(new TraceLogger(this, memoryManager, _labelManager));
|
||||
|
||||
_stepOut = false;
|
||||
_stepCount = -1;
|
||||
|
@ -227,7 +227,7 @@ void Debugger::UpdateBreakpoints()
|
|||
for(int i = 0; i < Debugger::BreakpointTypeCount; i++) {
|
||||
if(bp.HasBreakpointType((BreakpointType)i)) {
|
||||
_breakpoints[i].push_back(bp);
|
||||
_breakpointRpnList[i].push_back(expEval.GetRpnList(bp.GetCondition()));
|
||||
_breakpointRpnList[i].push_back(*expEval.GetRpnList(bp.GetCondition()));
|
||||
_hasBreakpoint[i] = true;
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ void Debugger::UpdateBreakpoints()
|
|||
}
|
||||
}
|
||||
|
||||
bool Debugger::HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t value)
|
||||
bool Debugger::HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo)
|
||||
{
|
||||
if(_runToCycle != 0) {
|
||||
//Disable all breakpoints while stepping backwards
|
||||
|
@ -246,14 +246,14 @@ bool Debugger::HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t
|
|||
|
||||
UpdateBreakpoints();
|
||||
|
||||
uint32_t absoluteAddr = _mapper->ToAbsoluteAddress(addr);
|
||||
uint32_t absoluteAddr = _mapper->ToAbsoluteAddress(operationInfo.Address);
|
||||
vector<Breakpoint> &breakpoints = _breakpoints[(int)type];
|
||||
|
||||
bool needState = true;
|
||||
EvalResultType resultType;
|
||||
for(size_t i = 0, len = breakpoints.size(); i < len; i++) {
|
||||
Breakpoint &breakpoint = breakpoints[i];
|
||||
if(type == BreakpointType::Global || breakpoint.Matches(addr, absoluteAddr)) {
|
||||
if(type == BreakpointType::Global || breakpoint.Matches(operationInfo.Address, absoluteAddr)) {
|
||||
if(!breakpoint.HasCondition()) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -261,12 +261,12 @@ bool Debugger::HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t
|
|||
GetState(&_debugState, false);
|
||||
needState = false;
|
||||
}
|
||||
if(_breakpointRpnList[(int)type][i]) {
|
||||
if(_bpExpEval.Evaluate(_breakpointRpnList[(int)type][i], _debugState, resultType, value, addr) != 0) {
|
||||
if(_breakpointRpnList[(int)type][i].size() > 0) {
|
||||
if(_bpExpEval.Evaluate(_breakpointRpnList[(int)type][i], _debugState, resultType, operationInfo) != 0) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if(_bpExpEval.Evaluate(breakpoint.GetCondition(), _debugState, resultType, value, addr) != 0) {
|
||||
if(_bpExpEval.Evaluate(breakpoint.GetCondition(), _debugState, resultType, operationInfo) != 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -280,8 +280,9 @@ bool Debugger::HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t
|
|||
int32_t Debugger::EvaluateExpression(string expression, EvalResultType &resultType)
|
||||
{
|
||||
DebugState state;
|
||||
OperationInfo operationInfo { 0, 0, MemoryOperationType::DummyRead };
|
||||
GetState(&state);
|
||||
return _watchExpEval.Evaluate(expression, state, resultType);
|
||||
return _watchExpEval.Evaluate(expression, state, resultType, operationInfo);
|
||||
}
|
||||
|
||||
void Debugger::RemoveExcessCallstackEntries()
|
||||
|
@ -361,7 +362,8 @@ void Debugger::PrivateProcessPpuCycle()
|
|||
MessageManager::SendNotification(ConsoleNotificationType::PpuViewerDisplayFrame);
|
||||
}
|
||||
|
||||
if(_hasBreakpoint[BreakpointType::Global] && HasMatchingBreakpoint(BreakpointType::Global, 0, -1)) {
|
||||
OperationInfo operationInfo { 0, 0, MemoryOperationType::DummyRead };
|
||||
if(_hasBreakpoint[BreakpointType::Global] && HasMatchingBreakpoint(BreakpointType::Global, operationInfo)) {
|
||||
//Found a matching breakpoint, stop execution
|
||||
Step(1);
|
||||
SleepUntilResume();
|
||||
|
@ -376,6 +378,8 @@ void Debugger::PrivateProcessPpuCycle()
|
|||
|
||||
bool Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value)
|
||||
{
|
||||
OperationInfo operationInfo { addr, (int16_t)value, type };
|
||||
|
||||
if(type == MemoryOperationType::ExecOpCode) {
|
||||
if(_runToCycle == 0) {
|
||||
_rewindCache.clear();
|
||||
|
@ -490,8 +494,9 @@ bool Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
|
|||
} else {
|
||||
disassemblyInfo = _disassembler->GetDisassemblyInfo(addressInfo);
|
||||
}
|
||||
_traceLogger->Log(_debugState.CPU, _debugState.PPU, disassemblyInfo);
|
||||
_traceLogger->Log(_debugState, disassemblyInfo, operationInfo);
|
||||
} else {
|
||||
_traceLogger->LogNonExec(operationInfo);
|
||||
_profiler->ProcessCycle();
|
||||
}
|
||||
|
||||
|
@ -502,7 +507,7 @@ bool Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
|
|||
case MemoryOperationType::Write: breakpointType = BreakpointType::WriteRam; break;
|
||||
}
|
||||
|
||||
if(_hasBreakpoint[breakpointType] && HasMatchingBreakpoint(breakpointType, addr, (type == MemoryOperationType::ExecOperand) ? -1 : value)) {
|
||||
if(_hasBreakpoint[breakpointType] && HasMatchingBreakpoint(breakpointType, operationInfo)) {
|
||||
//Found a matching breakpoint, stop execution
|
||||
Step(1);
|
||||
SleepUntilResume();
|
||||
|
@ -563,7 +568,8 @@ void Debugger::PrivateProcessVramOperation(MemoryOperationType type, uint16_t ad
|
|||
}
|
||||
|
||||
BreakpointType bpType = type == MemoryOperationType::Write ? BreakpointType::WriteVram : BreakpointType::ReadVram;
|
||||
if(_hasBreakpoint[bpType] && HasMatchingBreakpoint(bpType, addr, value)) {
|
||||
OperationInfo operationInfo { addr, value, type };
|
||||
if(_hasBreakpoint[bpType] && HasMatchingBreakpoint(bpType, operationInfo)) {
|
||||
//Found a matching breakpoint, stop execution
|
||||
Step(1);
|
||||
SleepUntilResume();
|
||||
|
|
|
@ -58,7 +58,7 @@ private:
|
|||
atomic<int32_t> _suspendCount;
|
||||
vector<Breakpoint> _newBreakpoints;
|
||||
vector<Breakpoint> _breakpoints[BreakpointTypeCount];
|
||||
vector<vector<int>*> _breakpointRpnList[BreakpointTypeCount];
|
||||
vector<vector<int>> _breakpointRpnList[BreakpointTypeCount];
|
||||
bool _hasBreakpoint[BreakpointTypeCount] = {};
|
||||
|
||||
vector<uint8_t> _frozenAddresses;
|
||||
|
@ -111,7 +111,7 @@ private:
|
|||
void PrivateProcessPpuCycle();
|
||||
bool PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t &value);
|
||||
void PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value);
|
||||
bool HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t value);
|
||||
bool HasMatchingBreakpoint(BreakpointType type, OperationInfo &operationInfo);
|
||||
|
||||
void UpdateCallstack(uint32_t addr);
|
||||
void PrivateProcessInterrupt(uint16_t cpuAddr, uint16_t destCpuAddr, bool forNmi);
|
||||
|
|
|
@ -65,4 +65,11 @@ struct DebugState
|
|||
State CPU;
|
||||
PPUDebugState PPU;
|
||||
CartridgeState Cartridge;
|
||||
};
|
||||
|
||||
struct OperationInfo
|
||||
{
|
||||
uint16_t Address;
|
||||
int16_t Value;
|
||||
MemoryOperationType OperationType;
|
||||
};
|
|
@ -100,6 +100,10 @@ bool ExpressionEvaluator::CheckSpecialTokens(string expression, size_t &pos, str
|
|||
output += std::to_string(EvalValues::Address);
|
||||
} else if(!token.compare("romaddress")) {
|
||||
output += std::to_string(EvalValues::AbsoluteAddress);
|
||||
} else if(!token.compare("iswrite")) {
|
||||
output += std::to_string(EvalValues::IsWrite);
|
||||
} else if(!token.compare("isread")) {
|
||||
output += std::to_string(EvalValues::IsRead);
|
||||
} else {
|
||||
string originalExpression = expression.substr(initialPos, pos - initialPos);
|
||||
int32_t address = _debugger->GetLabelManager()->GetLabelRelativeAddress(originalExpression);
|
||||
|
@ -290,15 +294,15 @@ bool ExpressionEvaluator::ToRpn(string expression, vector<int> &outputQueue)
|
|||
return true;
|
||||
}
|
||||
|
||||
int32_t ExpressionEvaluator::Evaluate(vector<int> *rpnList, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr)
|
||||
int32_t ExpressionEvaluator::Evaluate(vector<int> &rpnList, DebugState &state, EvalResultType &resultType, OperationInfo &operationInfo)
|
||||
{
|
||||
int pos = 0;
|
||||
int right = 0;
|
||||
int left = 0;
|
||||
resultType = EvalResultType::Numeric;
|
||||
|
||||
for(size_t i = 0, len = rpnList->size(); i < len; i++) {
|
||||
int token = (*rpnList)[i];
|
||||
for(size_t i = 0, len = rpnList.size(); i < len; i++) {
|
||||
int token = rpnList[i];
|
||||
|
||||
if(token >= EvalValues::RegA) {
|
||||
//Replace value with a special value
|
||||
|
@ -315,9 +319,11 @@ int32_t ExpressionEvaluator::Evaluate(vector<int> *rpnList, DebugState &state, E
|
|||
case EvalValues::PpuScanline: token = state.PPU.Scanline; break;
|
||||
case EvalValues::Nmi: token = state.CPU.NMIFlag; break;
|
||||
case EvalValues::Irq: token = state.CPU.IRQFlag; break;
|
||||
case EvalValues::Value: token = memoryValue; break;
|
||||
case EvalValues::Address: token = memoryAddr; break;
|
||||
case EvalValues::AbsoluteAddress: token = _debugger->GetAbsoluteAddress(memoryAddr); 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; break;
|
||||
case EvalValues::IsRead: token = operationInfo.OperationType == MemoryOperationType::Read; break;
|
||||
}
|
||||
} else if(token >= EvalOperators::Multiplication) {
|
||||
right = operandStack[--pos];
|
||||
|
@ -401,7 +407,7 @@ vector<int>* ExpressionEvaluator::GetRpnList(string expression, vector<int> &out
|
|||
return outputQueue;
|
||||
}
|
||||
|
||||
int32_t ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr, bool& success)
|
||||
int32_t ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, OperationInfo &operationInfo, bool& success)
|
||||
{
|
||||
success = true;
|
||||
vector<int> output;
|
||||
|
@ -415,14 +421,14 @@ int32_t ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &stat
|
|||
rpnList = &output;
|
||||
}
|
||||
|
||||
return Evaluate(rpnList, state, resultType, memoryValue, memoryAddr);
|
||||
return Evaluate(*rpnList, state, resultType, operationInfo);
|
||||
}
|
||||
|
||||
int32_t ExpressionEvaluator::Evaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr)
|
||||
int32_t ExpressionEvaluator::Evaluate(string expression, DebugState &state, EvalResultType &resultType, OperationInfo &operationInfo)
|
||||
{
|
||||
try {
|
||||
bool success;
|
||||
int32_t result = PrivateEvaluate(expression, state, resultType, memoryValue, memoryAddr, success);
|
||||
int32_t result = PrivateEvaluate(expression, state, resultType, operationInfo, success);
|
||||
if(success) {
|
||||
return result;
|
||||
}
|
||||
|
@ -437,8 +443,9 @@ bool ExpressionEvaluator::Validate(string expression)
|
|||
try {
|
||||
DebugState state;
|
||||
EvalResultType type;
|
||||
OperationInfo operationInfo;
|
||||
bool success;
|
||||
PrivateEvaluate(expression, state, type, 0, 0, success);
|
||||
PrivateEvaluate(expression, state, type, operationInfo, success);
|
||||
return success;
|
||||
} catch(std::exception e) {
|
||||
return false;
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include <deque>
|
||||
#include <unordered_map>
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
#include "DebuggerTypes.h"
|
||||
|
||||
struct DebugState;
|
||||
class Debugger;
|
||||
|
||||
enum EvalOperators
|
||||
|
@ -61,6 +61,8 @@ enum EvalValues
|
|||
Value = 2000000112,
|
||||
Address = 2000000113,
|
||||
AbsoluteAddress = 2000000114,
|
||||
IsWrite = 2000000115,
|
||||
IsRead = 2000000116,
|
||||
};
|
||||
|
||||
enum EvalResultType
|
||||
|
@ -101,14 +103,14 @@ private:
|
|||
string GetNextToken(string expression, size_t &pos);
|
||||
bool ProcessSpecialOperator(EvalOperators evalOp, std::stack<EvalOperators> &opStack, vector<int> &outputQueue);
|
||||
bool ToRpn(string expression, vector<int> &outputQueue);
|
||||
int32_t PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr, bool &success);
|
||||
int32_t PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, OperationInfo &operationInfo, bool &success);
|
||||
vector<int>* GetRpnList(string expression, vector<int> &output, bool& success);
|
||||
|
||||
public:
|
||||
ExpressionEvaluator(Debugger* debugger);
|
||||
|
||||
int32_t Evaluate(vector<int> *outputQueue, DebugState &state, EvalResultType &resultType, int16_t memoryValue = 0, uint32_t memoryAddr = 0);
|
||||
int32_t Evaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue = 0, uint32_t memoryAddr = 0);
|
||||
int32_t Evaluate(vector<int> &outputQueue, DebugState &state, EvalResultType &resultType, OperationInfo &operationInfo);
|
||||
int32_t Evaluate(string expression, DebugState &state, EvalResultType &resultType, OperationInfo &operationInfo);
|
||||
vector<int>* GetRpnList(string expression);
|
||||
|
||||
bool Validate(string expression);
|
||||
|
|
|
@ -3,16 +3,19 @@
|
|||
#include "DisassemblyInfo.h"
|
||||
#include "DebuggerTypes.h"
|
||||
#include "Console.h"
|
||||
#include "Debugger.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "LabelManager.h"
|
||||
#include "EmulationSettings.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/FolderUtilities.h"
|
||||
|
||||
TraceLogger *TraceLogger::_instance = nullptr;
|
||||
|
||||
TraceLogger::TraceLogger(shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
TraceLogger::TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager)
|
||||
{
|
||||
_expEvaluator = shared_ptr<ExpressionEvaluator>(new ExpressionEvaluator(debugger));
|
||||
_memoryManager = memoryManager;
|
||||
_labelManager = labelManager;
|
||||
_instance = this;
|
||||
|
@ -29,6 +32,16 @@ TraceLogger::~TraceLogger()
|
|||
void TraceLogger::SetOptions(TraceLoggerOptions options)
|
||||
{
|
||||
_options = options;
|
||||
string condition = _options.Condition;
|
||||
|
||||
auto lock = _lock.AcquireSafe();
|
||||
_conditionRpnList.clear();
|
||||
if(!condition.empty()) {
|
||||
vector<int> *rpnList = _expEvaluator->GetRpnList(condition);
|
||||
if(rpnList) {
|
||||
_conditionRpnList = *rpnList;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::StartLogging(string filename)
|
||||
|
@ -146,24 +159,57 @@ void TraceLogger::GetTraceRow(string &output, State &cpuState, PPUDebugState &pp
|
|||
}
|
||||
}
|
||||
|
||||
SimpleLock _lock;
|
||||
void TraceLogger::Log(State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> disassemblyInfo)
|
||||
bool TraceLogger::ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo> &disassemblyInfo, OperationInfo &operationInfo)
|
||||
{
|
||||
if(!_conditionRpnList.empty()) {
|
||||
EvalResultType type;
|
||||
if(!_expEvaluator->Evaluate(_conditionRpnList, state, type, operationInfo)) {
|
||||
if(operationInfo.OperationType == MemoryOperationType::ExecOpCode) {
|
||||
//Condition did not match, keep state/disassembly info for instruction's subsequent cycles
|
||||
_lastState = state;
|
||||
_lastDisassemblyInfo = disassemblyInfo;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void TraceLogger::AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugState &state)
|
||||
{
|
||||
_disassemblyCache[_currentPos] = disassemblyInfo;
|
||||
_cpuStateCache[_currentPos] = state.CPU;
|
||||
_ppuStateCache[_currentPos] = state.PPU;
|
||||
_currentPos = (_currentPos + 1) % ExecutionLogSize;
|
||||
_lastDisassemblyInfo.reset();
|
||||
|
||||
if(_logToFile) {
|
||||
GetTraceRow(_outputBuffer, state.CPU, state.PPU, disassemblyInfo, _firstLine);
|
||||
if(_outputBuffer.size() > 32768) {
|
||||
_outputFile << _outputBuffer;
|
||||
_outputBuffer.clear();
|
||||
}
|
||||
|
||||
_firstLine = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::LogNonExec(OperationInfo& operationInfo)
|
||||
{
|
||||
if(_lastDisassemblyInfo) {
|
||||
auto lock = _lock.AcquireSafe();
|
||||
if(ConditionMatches(_lastState, _lastDisassemblyInfo, operationInfo)) {
|
||||
AddRow(_lastDisassemblyInfo, _lastState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TraceLogger::Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo, OperationInfo &operationInfo)
|
||||
{
|
||||
if(disassemblyInfo) {
|
||||
auto lock = _lock.AcquireSafe();
|
||||
_disassemblyCache[_currentPos] = disassemblyInfo;
|
||||
_cpuStateCache[_currentPos] = cpuState;
|
||||
_ppuStateCache[_currentPos] = ppuState;
|
||||
_currentPos = (_currentPos + 1) % ExecutionLogSize;
|
||||
|
||||
if(_logToFile) {
|
||||
GetTraceRow(_outputBuffer, cpuState, ppuState, disassemblyInfo, _firstLine);
|
||||
if(_outputBuffer.size() > 32768) {
|
||||
_outputFile << _outputBuffer;
|
||||
_outputBuffer.clear();
|
||||
}
|
||||
|
||||
_firstLine = false;
|
||||
if(ConditionMatches(state, disassemblyInfo, operationInfo)) {
|
||||
AddRow(disassemblyInfo, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "DebuggerTypes.h"
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
|
||||
class DisassemblyInfo;
|
||||
class MemoryManager;
|
||||
class LabelManager;
|
||||
class ExpressionEvaluator;
|
||||
class Debugger;
|
||||
|
||||
enum class StatusFlagFormat
|
||||
{
|
||||
|
@ -26,6 +29,8 @@ struct TraceLoggerOptions
|
|||
bool ShowEffectiveAddresses;
|
||||
bool UseLabels;
|
||||
StatusFlagFormat StatusFormat;
|
||||
|
||||
char Condition[1000];
|
||||
};
|
||||
|
||||
class TraceLogger
|
||||
|
@ -39,6 +44,11 @@ private:
|
|||
bool _firstLine;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
shared_ptr<LabelManager> _labelManager;
|
||||
|
||||
shared_ptr<ExpressionEvaluator> _expEvaluator;
|
||||
vector<int> _conditionRpnList;
|
||||
DebugState _lastState;
|
||||
shared_ptr<DisassemblyInfo> _lastDisassemblyInfo;
|
||||
|
||||
constexpr static int ExecutionLogSize = 30000;
|
||||
bool _logToFile;
|
||||
|
@ -47,15 +57,20 @@ private:
|
|||
PPUDebugState _ppuStateCache[ExecutionLogSize] = {};
|
||||
shared_ptr<DisassemblyInfo> _disassemblyCache[ExecutionLogSize] = {};
|
||||
|
||||
SimpleLock _lock;
|
||||
string _executionTrace;
|
||||
|
||||
void GetStatusFlag(string &output, uint8_t ps);
|
||||
void AddRow(shared_ptr<DisassemblyInfo> &disassemblyInfo, DebugState &state);
|
||||
bool ConditionMatches(DebugState &state, shared_ptr<DisassemblyInfo> &disassemblyInfo, OperationInfo &operationInfo);
|
||||
|
||||
public:
|
||||
TraceLogger(shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager, shared_ptr<LabelManager> labelManager);
|
||||
~TraceLogger();
|
||||
|
||||
void Log(State &cpuState, PPUDebugState &ppuState, shared_ptr<DisassemblyInfo> disassemblyInfo);
|
||||
|
||||
void Log(DebugState &state, shared_ptr<DisassemblyInfo> disassemblyInfo, OperationInfo &operationInfo);
|
||||
void LogNonExec(OperationInfo& operationInfo);
|
||||
void SetOptions(TraceLoggerOptions options);
|
||||
void StartLogging(string filename);
|
||||
void StopLogging();
|
||||
|
|
|
@ -31,7 +31,6 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
_regions = regions;
|
||||
this.Invalidate();
|
||||
} else {
|
||||
bool needUpdate = false;
|
||||
for(int i = 0; i < regions.Count; i++) {
|
||||
if(_regions[i].Color != regions[i].Color || _regions[i].Name != regions[i].Name || _regions[i].Size != regions[i].Size) {
|
||||
_regions = regions;
|
||||
|
|
|
@ -46,9 +46,14 @@ namespace Mesen.GUI.Debugger
|
|||
this.toolTip.SetToolTip(this.picExpressionWarning, "Condition contains invalid syntax or symbols.");
|
||||
|
||||
this.toolTip.SetToolTip(this.chkAbsolute, "Check to set an absolute address based on the exact address in PRG/CHR ROM (not CPU/PPU memory)");
|
||||
this.toolTip.SetToolTip(this.picHelp,
|
||||
this.toolTip.SetToolTip(this.picHelp, frmBreakpoint.GetConditionTooltip(false));
|
||||
}
|
||||
|
||||
public static string GetConditionTooltip(bool forWatch)
|
||||
{
|
||||
string tooltip =
|
||||
"Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine +
|
||||
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine +
|
||||
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine +
|
||||
"Note 2: Labels assigned to the code can be used (their value will match the label's address in CPU memory)." + Environment.NewLine + Environment.NewLine +
|
||||
"A/X/Y/PS/SP: Value of registers" + Environment.NewLine +
|
||||
"PC: Program Counter" + Environment.NewLine +
|
||||
|
@ -57,8 +62,16 @@ namespace Mesen.GUI.Debugger
|
|||
"Cycle/Scanline: Current cycle (0-340)/scanline(-1 to 260) of the PPU" + Environment.NewLine +
|
||||
"Frame: PPU frame number (since power on/reset)" + Environment.NewLine +
|
||||
"Value: Current value being read/written from/to memory" + Environment.NewLine +
|
||||
"Address: Current CPU memory address being read/written" + Environment.NewLine +
|
||||
"RomAddress: Current ROM address being read/written" + Environment.NewLine +
|
||||
"IsRead: True if the CPU is reading from a memory address" + Environment.NewLine +
|
||||
"IsWrite: True if the CPU is writing to a memory address" + Environment.NewLine;
|
||||
|
||||
if(!forWatch) {
|
||||
tooltip +=
|
||||
"Address: Current CPU memory address being read/written" + Environment.NewLine +
|
||||
"RomAddress: Current ROM address being read/written" + Environment.NewLine;
|
||||
}
|
||||
|
||||
tooltip +=
|
||||
"[<address>]: (Byte) Memory value at <address> (CPU)" + Environment.NewLine +
|
||||
"{<address>}: (Word) Memory value at <address> (CPU)" + Environment.NewLine + Environment.NewLine +
|
||||
|
||||
|
@ -67,8 +80,9 @@ namespace Mesen.GUI.Debugger
|
|||
"scanline == 10 && (cycle >= 55 && cycle <= 100)" + Environment.NewLine +
|
||||
"x == [$150] || y == [10]" + Environment.NewLine +
|
||||
"[[$15] + y] -> Reads the value at address $15, adds Y to it and reads the value at the resulting address." + Environment.NewLine +
|
||||
"{$FFFA} -> Returns the NMI handler's address."
|
||||
);
|
||||
"{$FFFA} -> Returns the NMI handler's address.";
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
protected override void UpdateConfig()
|
||||
|
|
|
@ -99,27 +99,7 @@ namespace Mesen.GUI.Debugger
|
|||
this.ctrlDebuggerCode.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
this.ctrlDebuggerCodeSplit.SetConfig(ConfigManager.Config.DebugInfo.RightView);
|
||||
|
||||
this.toolTip.SetToolTip(this.picWatchHelp,
|
||||
"Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine +
|
||||
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine +
|
||||
"Note 2: Labels assigned to the code can be used (their value will match the label's address in CPU memory)." + Environment.NewLine + Environment.NewLine +
|
||||
"A/X/Y/PS/SP: Value of registers" + Environment.NewLine +
|
||||
"PC: Program Counter" + Environment.NewLine +
|
||||
"OpPC: Address of the current instruction's first byte" + Environment.NewLine +
|
||||
"Irq/Nmi: True if the Irq/Nmi flags are set" + Environment.NewLine +
|
||||
"Cycle/Scanline: Current cycle (0-340)/scanline(-1 to 260) of the PPU" + Environment.NewLine +
|
||||
"Frame: PPU frame number (since power on/reset)" + Environment.NewLine +
|
||||
"Value: Current value being read/written from/to memory" + Environment.NewLine +
|
||||
"[<address>]: (Byte) Memory value at <address> (CPU)" + Environment.NewLine +
|
||||
"{<address>}: (Word) Memory value at <address> (CPU)" + Environment.NewLine + Environment.NewLine +
|
||||
|
||||
"Examples:" + Environment.NewLine +
|
||||
"a == 10 || x == $23" + Environment.NewLine +
|
||||
"scanline == 10 && (cycle >= 55 && cycle <= 100)" + Environment.NewLine +
|
||||
"x == [$150] || y == [10]" + Environment.NewLine +
|
||||
"[[$15] + y] -> Reads the value at address $15, adds Y to it and reads the value at the resulting address." + Environment.NewLine +
|
||||
"{$FFFA} -> Returns the NMI handler's address."
|
||||
);
|
||||
this.toolTip.SetToolTip(this.picWatchHelp, frmBreakpoint.GetConditionTooltip(true));
|
||||
|
||||
_notifListener = new InteropEmu.NotificationListener();
|
||||
_notifListener.OnNotification += _notifListener_OnNotification;
|
||||
|
|
324
GUI.NET/Debugger/frmTraceLogger.Designer.cs
generated
324
GUI.NET/Debugger/frmTraceLogger.Designer.cs
generated
|
@ -34,16 +34,20 @@
|
|||
this.btnStopLogging = new System.Windows.Forms.Button();
|
||||
this.grpLogOptions = new System.Windows.Forms.GroupBox();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.chkShowEffectiveAddresses = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowRegisters = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowExtraInfo = new System.Windows.Forms.CheckBox();
|
||||
this.chkIndentCode = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowByteCode = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowFrameCount = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuScanline = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowCpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkUseLabels = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowByteCode = new System.Windows.Forms.CheckBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.chkShowCpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuCycles = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuScanline = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowFrameCount = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowEffectiveAddresses = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowExtraInfo = new System.Windows.Forms.CheckBox();
|
||||
this.cboStatusFlagFormat = new System.Windows.Forms.ComboBox();
|
||||
this.lblCondition = new System.Windows.Forms.Label();
|
||||
this.txtCondition = new System.Windows.Forms.TextBox();
|
||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.grpExecutionLog = new System.Windows.Forms.GroupBox();
|
||||
this.txtTraceLog = new System.Windows.Forms.TextBox();
|
||||
|
@ -58,14 +62,18 @@
|
|||
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.cboStatusFlagFormat = new System.Windows.Forms.ComboBox();
|
||||
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.picExpressionWarning = new System.Windows.Forms.PictureBox();
|
||||
this.picHelp = new System.Windows.Forms.PictureBox();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.grpLogOptions.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
this.grpExecutionLog.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picHelp)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
|
@ -78,21 +86,22 @@
|
|||
this.tableLayoutPanel1.Controls.Add(this.btnStartLogging, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.btnStopLogging, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpLogOptions, 0, 1);
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 314);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 274);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 3;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(442, 206);
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(781, 181);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// btnOpenTrace
|
||||
//
|
||||
this.btnOpenTrace.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnOpenTrace.Enabled = false;
|
||||
this.btnOpenTrace.Location = new System.Drawing.Point(344, 3);
|
||||
this.btnOpenTrace.Location = new System.Drawing.Point(683, 3);
|
||||
this.btnOpenTrace.Name = "btnOpenTrace";
|
||||
this.btnOpenTrace.Size = new System.Drawing.Size(95, 23);
|
||||
this.btnOpenTrace.TabIndex = 2;
|
||||
|
@ -126,71 +135,47 @@
|
|||
//
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.grpLogOptions, 3);
|
||||
this.grpLogOptions.Controls.Add(this.tableLayoutPanel2);
|
||||
this.grpLogOptions.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpLogOptions.Location = new System.Drawing.Point(3, 32);
|
||||
this.grpLogOptions.Name = "grpLogOptions";
|
||||
this.grpLogOptions.Size = new System.Drawing.Size(436, 168);
|
||||
this.grpLogOptions.Size = new System.Drawing.Size(775, 146);
|
||||
this.grpLogOptions.TabIndex = 3;
|
||||
this.grpLogOptions.TabStop = false;
|
||||
this.grpLogOptions.Text = "Log Options";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 3;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 24.18605F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 42.32558F));
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
|
||||
this.tableLayoutPanel2.ColumnCount = 4;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowRegisters, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkIndentCode, 0, 7);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowCpuCycles, 2, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkUseLabels, 2, 7);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowFrameCount, 2, 3);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuScanline, 2, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuCycles, 2, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowEffectiveAddresses, 0, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkIndentCode, 0, 5);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkUseLabels, 3, 5);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowByteCode, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowExtraInfo, 0, 3);
|
||||
this.tableLayoutPanel2.Controls.Add(this.label1, 0, 5);
|
||||
this.tableLayoutPanel2.Controls.Add(this.cboStatusFlagFormat, 1, 5);
|
||||
this.tableLayoutPanel2.Controls.Add(this.label1, 0, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowCpuCycles, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuCycles, 2, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowPpuScanline, 2, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowFrameCount, 1, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowEffectiveAddresses, 3, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowExtraInfo, 3, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.cboStatusFlagFormat, 1, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel4, 0, 3);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 8;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowCount = 6;
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(430, 149);
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(769, 127);
|
||||
this.tableLayoutPanel2.TabIndex = 0;
|
||||
//
|
||||
// chkShowEffectiveAddresses
|
||||
//
|
||||
this.chkShowEffectiveAddresses.AutoSize = true;
|
||||
this.chkShowEffectiveAddresses.Checked = true;
|
||||
this.chkShowEffectiveAddresses.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkShowEffectiveAddresses, 2);
|
||||
this.chkShowEffectiveAddresses.Location = new System.Drawing.Point(3, 49);
|
||||
this.chkShowEffectiveAddresses.Name = "chkShowEffectiveAddresses";
|
||||
this.chkShowEffectiveAddresses.Size = new System.Drawing.Size(150, 17);
|
||||
this.chkShowEffectiveAddresses.TabIndex = 10;
|
||||
this.chkShowEffectiveAddresses.Text = "Show Effective Addresses";
|
||||
this.chkShowEffectiveAddresses.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowPpuCycles
|
||||
//
|
||||
this.chkShowPpuCycles.AutoSize = true;
|
||||
this.chkShowPpuCycles.Checked = true;
|
||||
this.chkShowPpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowPpuCycles.Location = new System.Drawing.Point(289, 26);
|
||||
this.chkShowPpuCycles.Name = "chkShowPpuCycles";
|
||||
this.chkShowPpuCycles.Size = new System.Drawing.Size(77, 17);
|
||||
this.chkShowPpuCycles.TabIndex = 5;
|
||||
this.chkShowPpuCycles.Text = "PPU Cycle";
|
||||
this.chkShowPpuCycles.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowRegisters
|
||||
//
|
||||
this.chkShowRegisters.AutoSize = true;
|
||||
|
@ -203,30 +188,27 @@
|
|||
this.chkShowRegisters.Text = "Registers";
|
||||
this.chkShowRegisters.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowExtraInfo
|
||||
//
|
||||
this.chkShowExtraInfo.AutoSize = true;
|
||||
this.chkShowExtraInfo.Checked = true;
|
||||
this.chkShowExtraInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkShowExtraInfo, 2);
|
||||
this.chkShowExtraInfo.Location = new System.Drawing.Point(3, 72);
|
||||
this.chkShowExtraInfo.Name = "chkShowExtraInfo";
|
||||
this.chkShowExtraInfo.Size = new System.Drawing.Size(204, 17);
|
||||
this.chkShowExtraInfo.TabIndex = 9;
|
||||
this.chkShowExtraInfo.Text = "Additional information (IRQ, NMI, etc.)";
|
||||
this.chkShowExtraInfo.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkIndentCode
|
||||
//
|
||||
this.chkIndentCode.AutoSize = true;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkIndentCode, 2);
|
||||
this.chkIndentCode.Location = new System.Drawing.Point(3, 129);
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkIndentCode, 3);
|
||||
this.chkIndentCode.Location = new System.Drawing.Point(3, 107);
|
||||
this.chkIndentCode.Name = "chkIndentCode";
|
||||
this.chkIndentCode.Size = new System.Drawing.Size(194, 17);
|
||||
this.chkIndentCode.TabIndex = 8;
|
||||
this.chkIndentCode.Text = "Indent code based on stack pointer";
|
||||
this.chkIndentCode.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkUseLabels
|
||||
//
|
||||
this.chkUseLabels.AutoSize = true;
|
||||
this.chkUseLabels.Location = new System.Drawing.Point(332, 107);
|
||||
this.chkUseLabels.Name = "chkUseLabels";
|
||||
this.chkUseLabels.Size = new System.Drawing.Size(79, 17);
|
||||
this.chkUseLabels.TabIndex = 11;
|
||||
this.chkUseLabels.Text = "Use Labels";
|
||||
this.chkUseLabels.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowByteCode
|
||||
//
|
||||
this.chkShowByteCode.AutoSize = true;
|
||||
|
@ -239,55 +221,118 @@
|
|||
this.chkShowByteCode.Text = "Byte Code";
|
||||
this.chkShowByteCode.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowFrameCount
|
||||
// label1
|
||||
//
|
||||
this.chkShowFrameCount.AutoSize = true;
|
||||
this.chkShowFrameCount.Location = new System.Drawing.Point(289, 72);
|
||||
this.chkShowFrameCount.Name = "chkShowFrameCount";
|
||||
this.chkShowFrameCount.Size = new System.Drawing.Size(86, 17);
|
||||
this.chkShowFrameCount.TabIndex = 7;
|
||||
this.chkShowFrameCount.Text = "Frame Count";
|
||||
this.chkShowFrameCount.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowPpuScanline
|
||||
//
|
||||
this.chkShowPpuScanline.AutoSize = true;
|
||||
this.chkShowPpuScanline.Checked = true;
|
||||
this.chkShowPpuScanline.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowPpuScanline.Location = new System.Drawing.Point(289, 49);
|
||||
this.chkShowPpuScanline.Name = "chkShowPpuScanline";
|
||||
this.chkShowPpuScanline.Size = new System.Drawing.Size(92, 17);
|
||||
this.chkShowPpuScanline.TabIndex = 6;
|
||||
this.chkShowPpuScanline.Text = "PPU Scanline";
|
||||
this.chkShowPpuScanline.UseVisualStyleBackColor = true;
|
||||
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(3, 53);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(98, 13);
|
||||
this.label1.TabIndex = 12;
|
||||
this.label1.Text = "Status Flag Format:";
|
||||
//
|
||||
// chkShowCpuCycles
|
||||
//
|
||||
this.chkShowCpuCycles.AutoSize = true;
|
||||
this.chkShowCpuCycles.Checked = true;
|
||||
this.chkShowCpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowCpuCycles.Location = new System.Drawing.Point(289, 3);
|
||||
this.chkShowCpuCycles.Location = new System.Drawing.Point(107, 3);
|
||||
this.chkShowCpuCycles.Name = "chkShowCpuCycles";
|
||||
this.chkShowCpuCycles.Size = new System.Drawing.Size(82, 17);
|
||||
this.chkShowCpuCycles.TabIndex = 3;
|
||||
this.chkShowCpuCycles.Text = "CPU Cycles";
|
||||
this.chkShowCpuCycles.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkUseLabels
|
||||
// chkShowPpuCycles
|
||||
//
|
||||
this.chkUseLabels.AutoSize = true;
|
||||
this.chkUseLabels.Location = new System.Drawing.Point(289, 129);
|
||||
this.chkUseLabels.Name = "chkUseLabels";
|
||||
this.chkUseLabels.Size = new System.Drawing.Size(79, 17);
|
||||
this.chkUseLabels.TabIndex = 11;
|
||||
this.chkUseLabels.Text = "Use Labels";
|
||||
this.chkUseLabels.UseVisualStyleBackColor = true;
|
||||
this.chkShowPpuCycles.AutoSize = true;
|
||||
this.chkShowPpuCycles.Checked = true;
|
||||
this.chkShowPpuCycles.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowPpuCycles.Location = new System.Drawing.Point(234, 3);
|
||||
this.chkShowPpuCycles.Name = "chkShowPpuCycles";
|
||||
this.chkShowPpuCycles.Size = new System.Drawing.Size(77, 17);
|
||||
this.chkShowPpuCycles.TabIndex = 5;
|
||||
this.chkShowPpuCycles.Text = "PPU Cycle";
|
||||
this.chkShowPpuCycles.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowPpuScanline
|
||||
//
|
||||
this.chkShowPpuScanline.AutoSize = true;
|
||||
this.chkShowPpuScanline.Checked = true;
|
||||
this.chkShowPpuScanline.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowPpuScanline.Location = new System.Drawing.Point(234, 26);
|
||||
this.chkShowPpuScanline.Name = "chkShowPpuScanline";
|
||||
this.chkShowPpuScanline.Size = new System.Drawing.Size(92, 17);
|
||||
this.chkShowPpuScanline.TabIndex = 6;
|
||||
this.chkShowPpuScanline.Text = "PPU Scanline";
|
||||
this.chkShowPpuScanline.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowFrameCount
|
||||
//
|
||||
this.chkShowFrameCount.AutoSize = true;
|
||||
this.chkShowFrameCount.Location = new System.Drawing.Point(107, 26);
|
||||
this.chkShowFrameCount.Name = "chkShowFrameCount";
|
||||
this.chkShowFrameCount.Size = new System.Drawing.Size(86, 17);
|
||||
this.chkShowFrameCount.TabIndex = 7;
|
||||
this.chkShowFrameCount.Text = "Frame Count";
|
||||
this.chkShowFrameCount.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowEffectiveAddresses
|
||||
//
|
||||
this.chkShowEffectiveAddresses.AutoSize = true;
|
||||
this.chkShowEffectiveAddresses.Checked = true;
|
||||
this.chkShowEffectiveAddresses.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowEffectiveAddresses.Location = new System.Drawing.Point(332, 3);
|
||||
this.chkShowEffectiveAddresses.Name = "chkShowEffectiveAddresses";
|
||||
this.chkShowEffectiveAddresses.Size = new System.Drawing.Size(150, 17);
|
||||
this.chkShowEffectiveAddresses.TabIndex = 10;
|
||||
this.chkShowEffectiveAddresses.Text = "Show Effective Addresses";
|
||||
this.chkShowEffectiveAddresses.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkShowExtraInfo
|
||||
//
|
||||
this.chkShowExtraInfo.AutoSize = true;
|
||||
this.chkShowExtraInfo.Checked = true;
|
||||
this.chkShowExtraInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.chkShowExtraInfo.Location = new System.Drawing.Point(332, 26);
|
||||
this.chkShowExtraInfo.Name = "chkShowExtraInfo";
|
||||
this.chkShowExtraInfo.Size = new System.Drawing.Size(204, 17);
|
||||
this.chkShowExtraInfo.TabIndex = 9;
|
||||
this.chkShowExtraInfo.Text = "Additional information (IRQ, NMI, etc.)";
|
||||
this.chkShowExtraInfo.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// cboStatusFlagFormat
|
||||
//
|
||||
this.cboStatusFlagFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboStatusFlagFormat.FormattingEnabled = true;
|
||||
this.cboStatusFlagFormat.Location = new System.Drawing.Point(107, 49);
|
||||
this.cboStatusFlagFormat.Name = "cboStatusFlagFormat";
|
||||
this.cboStatusFlagFormat.Size = new System.Drawing.Size(121, 21);
|
||||
this.cboStatusFlagFormat.TabIndex = 13;
|
||||
//
|
||||
// lblCondition
|
||||
//
|
||||
this.lblCondition.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblCondition.AutoSize = true;
|
||||
this.lblCondition.Location = new System.Drawing.Point(3, 6);
|
||||
this.lblCondition.Name = "lblCondition";
|
||||
this.lblCondition.Size = new System.Drawing.Size(54, 13);
|
||||
this.lblCondition.TabIndex = 14;
|
||||
this.lblCondition.Text = "Condition:";
|
||||
//
|
||||
// txtCondition
|
||||
//
|
||||
this.txtCondition.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtCondition.Location = new System.Drawing.Point(63, 3);
|
||||
this.txtCondition.Name = "txtCondition";
|
||||
this.txtCondition.Size = new System.Drawing.Size(655, 20);
|
||||
this.txtCondition.TabIndex = 15;
|
||||
//
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
this.tableLayoutPanel3.ColumnCount = 2;
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel3.ColumnCount = 1;
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel1, 0, 1);
|
||||
this.tableLayoutPanel3.Controls.Add(this.grpExecutionLog, 0, 0);
|
||||
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
|
@ -296,18 +341,16 @@
|
|||
this.tableLayoutPanel3.RowCount = 2;
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(808, 523);
|
||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(787, 458);
|
||||
this.tableLayoutPanel3.TabIndex = 1;
|
||||
//
|
||||
// grpExecutionLog
|
||||
//
|
||||
this.tableLayoutPanel3.SetColumnSpan(this.grpExecutionLog, 2);
|
||||
this.grpExecutionLog.Controls.Add(this.txtTraceLog);
|
||||
this.grpExecutionLog.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpExecutionLog.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpExecutionLog.Name = "grpExecutionLog";
|
||||
this.grpExecutionLog.Size = new System.Drawing.Size(802, 305);
|
||||
this.grpExecutionLog.Size = new System.Drawing.Size(781, 265);
|
||||
this.grpExecutionLog.TabIndex = 2;
|
||||
this.grpExecutionLog.TabStop = false;
|
||||
this.grpExecutionLog.Text = "Execution Log";
|
||||
|
@ -321,7 +364,7 @@
|
|||
this.txtTraceLog.Name = "txtTraceLog";
|
||||
this.txtTraceLog.ReadOnly = true;
|
||||
this.txtTraceLog.ScrollBars = System.Windows.Forms.ScrollBars.Both;
|
||||
this.txtTraceLog.Size = new System.Drawing.Size(796, 286);
|
||||
this.txtTraceLog.Size = new System.Drawing.Size(775, 246);
|
||||
this.txtTraceLog.TabIndex = 1;
|
||||
//
|
||||
// tmrUpdateLog
|
||||
|
@ -335,7 +378,7 @@
|
|||
this.showToolStripMenuItem});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = new System.Drawing.Size(808, 24);
|
||||
this.menuStrip1.Size = new System.Drawing.Size(787, 24);
|
||||
this.menuStrip1.TabIndex = 2;
|
||||
this.menuStrip1.Text = "menuStrip1";
|
||||
//
|
||||
|
@ -414,32 +457,56 @@
|
|||
this.mnuRefresh.Text = "Refresh";
|
||||
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
|
||||
//
|
||||
// label1
|
||||
// tableLayoutPanel4
|
||||
//
|
||||
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(3, 99);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(98, 13);
|
||||
this.label1.TabIndex = 12;
|
||||
this.label1.Text = "Status Flag Format:";
|
||||
this.tableLayoutPanel4.ColumnCount = 4;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel4, 4);
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel4.Controls.Add(this.picHelp, 3, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.picExpressionWarning, 2, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.lblCondition, 0, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.txtCondition, 1, 0);
|
||||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel4.Location = new System.Drawing.Point(0, 73);
|
||||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
|
||||
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
|
||||
this.tableLayoutPanel4.RowCount = 1;
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(769, 25);
|
||||
this.tableLayoutPanel4.TabIndex = 16;
|
||||
//
|
||||
// cboStatusFlagFormat
|
||||
// picExpressionWarning
|
||||
//
|
||||
this.cboStatusFlagFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboStatusFlagFormat.FormattingEnabled = true;
|
||||
this.cboStatusFlagFormat.Location = new System.Drawing.Point(107, 95);
|
||||
this.cboStatusFlagFormat.Name = "cboStatusFlagFormat";
|
||||
this.cboStatusFlagFormat.Size = new System.Drawing.Size(121, 21);
|
||||
this.cboStatusFlagFormat.TabIndex = 13;
|
||||
this.picExpressionWarning.Image = global::Mesen.GUI.Properties.Resources.Warning;
|
||||
this.picExpressionWarning.Location = new System.Drawing.Point(724, 5);
|
||||
this.picExpressionWarning.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.picExpressionWarning.Name = "picExpressionWarning";
|
||||
this.picExpressionWarning.Size = new System.Drawing.Size(18, 17);
|
||||
this.picExpressionWarning.TabIndex = 16;
|
||||
this.picExpressionWarning.TabStop = false;
|
||||
this.picExpressionWarning.Visible = false;
|
||||
//
|
||||
// picHelp
|
||||
//
|
||||
this.picHelp.Image = global::Mesen.GUI.Properties.Resources.Help;
|
||||
this.picHelp.Location = new System.Drawing.Point(748, 5);
|
||||
this.picHelp.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.picHelp.Name = "picHelp";
|
||||
this.picHelp.Size = new System.Drawing.Size(18, 17);
|
||||
this.picHelp.TabIndex = 17;
|
||||
this.picHelp.TabStop = false;
|
||||
//
|
||||
// frmTraceLogger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(808, 547);
|
||||
this.ClientSize = new System.Drawing.Size(787, 482);
|
||||
this.Controls.Add(this.tableLayoutPanel3);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
this.MinimumSize = new System.Drawing.Size(669, 448);
|
||||
this.Name = "frmTraceLogger";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Trace Logger";
|
||||
|
@ -452,6 +519,10 @@
|
|||
this.grpExecutionLog.PerformLayout();
|
||||
this.menuStrip1.ResumeLayout(false);
|
||||
this.menuStrip1.PerformLayout();
|
||||
this.tableLayoutPanel4.ResumeLayout(false);
|
||||
this.tableLayoutPanel4.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picHelp)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -491,5 +562,10 @@
|
|||
private System.Windows.Forms.CheckBox chkUseLabels;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.ComboBox cboStatusFlagFormat;
|
||||
private System.Windows.Forms.Label lblCondition;
|
||||
private System.Windows.Forms.TextBox txtCondition;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
|
||||
private System.Windows.Forms.PictureBox picExpressionWarning;
|
||||
private System.Windows.Forms.PictureBox picHelp;
|
||||
}
|
||||
}
|
|
@ -46,6 +46,9 @@ namespace Mesen.GUI.Debugger
|
|||
UpdateMenu();
|
||||
txtTraceLog.Font = new Font(BaseControl.MonospaceFontFamily, 10);
|
||||
tmrUpdateLog.Start();
|
||||
|
||||
this.toolTip.SetToolTip(this.picExpressionWarning, "Condition contains invalid syntax or symbols.");
|
||||
this.toolTip.SetToolTip(this.picHelp, "When a condition is given, instructions will only be logged by the trace logger if the condition returns a value not equal to 0 or false." + Environment.NewLine + Environment.NewLine + frmBreakpoint.GetConditionTooltip(false));
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
|
@ -71,7 +74,10 @@ namespace Mesen.GUI.Debugger
|
|||
{
|
||||
_entityBinder.Entity = ConfigManager.Config.DebugInfo.TraceLoggerOptions;
|
||||
_entityBinder.UpdateObject();
|
||||
InteropEmu.DebugSetTraceOptions((TraceLoggerOptions)_entityBinder.Entity);
|
||||
TraceLoggerOptions options = (TraceLoggerOptions)_entityBinder.Entity;
|
||||
options.Condition = Encoding.UTF8.GetBytes(txtCondition.Text);
|
||||
Array.Resize(ref options.Condition, 1000);
|
||||
InteropEmu.DebugSetTraceOptions(options);
|
||||
}
|
||||
|
||||
private void btnStartLogging_Click(object sender, EventArgs e)
|
||||
|
@ -141,6 +147,14 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
private void tmrUpdateLog_Tick(object sender, EventArgs e)
|
||||
{
|
||||
if(txtCondition.Text.Length > 0) {
|
||||
EvalResultType resultType;
|
||||
InteropEmu.DebugEvaluateExpression(txtCondition.Text, out resultType);
|
||||
picExpressionWarning.Visible = (resultType == EvalResultType.Invalid);
|
||||
} else {
|
||||
picExpressionWarning.Visible = false;
|
||||
}
|
||||
|
||||
if(mnuAutoRefresh.Checked) {
|
||||
RefreshLog();
|
||||
}
|
||||
|
|
|
@ -959,6 +959,10 @@ namespace Mesen.GUI
|
|||
[MarshalAs(UnmanagedType.I1)] public bool ShowEffectiveAddresses;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool UseLabels;
|
||||
public StatusFlagFormat StatusFormat;
|
||||
|
||||
[NonSerialized]
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
|
||||
public byte[] Condition;
|
||||
}
|
||||
|
||||
public enum ProfilerDataType
|
||||
|
|
Loading…
Add table
Reference in a new issue