Debugger: Improved expression evaluator when dealing with memory addresses + added "address" and "romaddress" special values
This commit is contained in:
parent
8112f906b7
commit
956834d4a5
6 changed files with 103 additions and 60 deletions
|
@ -205,7 +205,7 @@ bool Debugger::HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t
|
||||||
GetState(&_debugState);
|
GetState(&_debugState);
|
||||||
needState = false;
|
needState = false;
|
||||||
}
|
}
|
||||||
if(expEval.Evaluate(condition, _debugState, value) != 0) {
|
if(expEval.Evaluate(condition, _debugState, value, absoluteAddr) != 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,10 @@ bool ExpressionEvaluator::CheckSpecialTokens(string expression, size_t &pos, str
|
||||||
output += std::to_string(EvalValues::Nmi);
|
output += std::to_string(EvalValues::Nmi);
|
||||||
} else if(!token.compare("value")) {
|
} else if(!token.compare("value")) {
|
||||||
output += std::to_string(EvalValues::Value);
|
output += std::to_string(EvalValues::Value);
|
||||||
|
} else if(!token.compare("address")) {
|
||||||
|
output += std::to_string(EvalValues::Address);
|
||||||
|
} else if(!token.compare("romaddress")) {
|
||||||
|
output += std::to_string(EvalValues::AbsoluteAddress);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -98,15 +102,8 @@ string ExpressionEvaluator::GetNextToken(string expression, size_t &pos)
|
||||||
for(size_t len = expression.size(); pos < len; pos++) {
|
for(size_t len = expression.size(); pos < len; pos++) {
|
||||||
char c = std::tolower(expression[pos]);
|
char c = std::tolower(expression[pos]);
|
||||||
|
|
||||||
if((c == '$' || c == '[') && pos == initialPos) {
|
if(c == '$' && pos == initialPos) {
|
||||||
if(c == '$') {
|
isHex = true;
|
||||||
isHex = true;
|
|
||||||
} else if(c == '[') {
|
|
||||||
isMemoryAddress = true;
|
|
||||||
|
|
||||||
//Pretend the token starts after this
|
|
||||||
initialPos++;
|
|
||||||
}
|
|
||||||
} else if((c >= '0' && c <= '9') || (isHex && c >= 'a' && c <= 'f')) {
|
} else if((c >= '0' && c <= '9') || (isHex && c >= 'a' && c <= 'f')) {
|
||||||
if(isNumber || output.empty()) {
|
if(isNumber || output.empty()) {
|
||||||
output += c;
|
output += c;
|
||||||
|
@ -117,14 +114,8 @@ string ExpressionEvaluator::GetNextToken(string expression, size_t &pos)
|
||||||
}
|
}
|
||||||
} else if(isNumber) {
|
} else if(isNumber) {
|
||||||
//First non-numeric character, done
|
//First non-numeric character, done
|
||||||
if(c == ']') {
|
|
||||||
if(isMemoryAddress) {
|
|
||||||
validMemoryAddress = true;
|
|
||||||
}
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
} else if(c == '(' || c == ')' || c == '-' || c == '+' || c == '~') {
|
} else if(c == '(' || c == ')' || c == '[' || c == ']' || c == '-' || c == '+' || c == '~') {
|
||||||
if(output.empty()) {
|
if(output.empty()) {
|
||||||
output += c;
|
output += c;
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -172,12 +163,6 @@ string ExpressionEvaluator::GetNextToken(string expression, size_t &pos)
|
||||||
output = std::to_string(x);
|
output = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isMemoryAddress && validMemoryAddress) {
|
|
||||||
uint32_t address = std::stoi(output) % 0xFFFF;
|
|
||||||
address += EvalValues::MemoryAddress;
|
|
||||||
output = std::to_string(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +206,16 @@ void ExpressionEvaluator::ToRpn(string expression, vector<int> &outputQueue)
|
||||||
opStack.pop();
|
opStack.pop();
|
||||||
}
|
}
|
||||||
opStack.pop();
|
opStack.pop();
|
||||||
|
} else if(token[0] == '[') {
|
||||||
|
opStack.push(EvalOperators::Bracket);
|
||||||
|
precedenceStack.push(0);
|
||||||
|
} else if(token[0] == ']') {
|
||||||
|
while(opStack.top() != EvalOperators::Bracket) {
|
||||||
|
outputQueue.push_back(opStack.top());
|
||||||
|
opStack.pop();
|
||||||
|
}
|
||||||
|
outputQueue.push_back(opStack.top());
|
||||||
|
opStack.pop();
|
||||||
} else {
|
} else {
|
||||||
outputQueue.push_back(std::stoi(token));
|
outputQueue.push_back(std::stoi(token));
|
||||||
}
|
}
|
||||||
|
@ -232,7 +227,7 @@ void ExpressionEvaluator::ToRpn(string expression, vector<int> &outputQueue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ExpressionEvaluator::EvaluateExpression(vector<int> *outputQueue, DebugState &state, EvalResultType &resultType, int16_t memoryValue)
|
int32_t ExpressionEvaluator::EvaluateExpression(vector<int> *outputQueue, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr)
|
||||||
{
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
int right = 0;
|
int right = 0;
|
||||||
|
@ -257,11 +252,8 @@ int32_t ExpressionEvaluator::EvaluateExpression(vector<int> *outputQueue, DebugS
|
||||||
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;
|
||||||
case EvalValues::Value: token = memoryValue; break;
|
case EvalValues::Value: token = memoryValue; break;
|
||||||
}
|
case EvalValues::Address: token = debugger->GetRelativeAddress(memoryAddr); break;
|
||||||
|
case EvalValues::AbsoluteAddress: token = memoryAddr; break;
|
||||||
if(token >= EvalValues::MemoryAddress) {
|
|
||||||
uint16_t memoryAddress = token - EvalValues::MemoryAddress;
|
|
||||||
token = debugger->GetMemoryValue(memoryAddress);
|
|
||||||
}
|
}
|
||||||
} else if(token >= EvalOperators::Multiplication) {
|
} else if(token >= EvalOperators::Multiplication) {
|
||||||
right = operandStack[--pos];
|
right = operandStack[--pos];
|
||||||
|
@ -291,6 +283,7 @@ int32_t ExpressionEvaluator::EvaluateExpression(vector<int> *outputQueue, DebugS
|
||||||
case EvalOperators::LogicalOr: token = left || right; resultType = EvalResultType::Boolean; break;
|
case EvalOperators::LogicalOr: token = left || right; resultType = EvalResultType::Boolean; break;
|
||||||
|
|
||||||
//Unary operators
|
//Unary operators
|
||||||
|
case EvalOperators::Bracket: token = debugger->GetMemoryValue(right); break;
|
||||||
case EvalOperators::Plus: token = right; break;
|
case EvalOperators::Plus: token = right; break;
|
||||||
case EvalOperators::Minus: token = -right; break;
|
case EvalOperators::Minus: token = -right; break;
|
||||||
case EvalOperators::BinaryNot: token = ~right; break;
|
case EvalOperators::BinaryNot: token = ~right; break;
|
||||||
|
@ -307,7 +300,7 @@ ExpressionEvaluator::ExpressionEvaluator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue)
|
int32_t ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr)
|
||||||
{
|
{
|
||||||
vector<int> *outputQueue = nullptr;
|
vector<int> *outputQueue = nullptr;
|
||||||
|
|
||||||
|
@ -332,19 +325,19 @@ int32_t ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &stat
|
||||||
outputQueue = &_outputCache[expression];
|
outputQueue = &_outputCache[expression];
|
||||||
}
|
}
|
||||||
|
|
||||||
return EvaluateExpression(outputQueue, state, resultType, memoryValue);
|
return EvaluateExpression(outputQueue, state, resultType, memoryValue, memoryAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ExpressionEvaluator::Evaluate(string expression, DebugState &state, int16_t memoryValue)
|
int32_t ExpressionEvaluator::Evaluate(string expression, DebugState &state, int16_t memoryValue, uint32_t memoryAddr)
|
||||||
{
|
{
|
||||||
EvalResultType resultType;
|
EvalResultType resultType;
|
||||||
return Evaluate(expression, state, resultType, memoryValue);
|
return Evaluate(expression, state, resultType, memoryValue, memoryAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ExpressionEvaluator::Evaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue)
|
int32_t ExpressionEvaluator::Evaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
return PrivateEvaluate(expression, state, resultType, memoryValue);
|
return PrivateEvaluate(expression, state, resultType, memoryValue, memoryAddr);
|
||||||
} catch(std::exception) {
|
} catch(std::exception) {
|
||||||
resultType = EvalResultType::Invalid;
|
resultType = EvalResultType::Invalid;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -356,7 +349,7 @@ bool ExpressionEvaluator::Validate(string expression)
|
||||||
try {
|
try {
|
||||||
DebugState state;
|
DebugState state;
|
||||||
EvalResultType type;
|
EvalResultType type;
|
||||||
PrivateEvaluate(expression, state, type, 0);
|
PrivateEvaluate(expression, state, type, 0, 0);
|
||||||
return true;
|
return true;
|
||||||
} catch(std::exception e) {
|
} catch(std::exception e) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -35,8 +35,11 @@ enum EvalOperators
|
||||||
BinaryNot = 2000000052,
|
BinaryNot = 2000000052,
|
||||||
LogicalNot = 2000000053,
|
LogicalNot = 2000000053,
|
||||||
|
|
||||||
|
//Used to read ram address
|
||||||
|
Bracket = 2000000054,
|
||||||
|
|
||||||
//Special value, not used as an operator
|
//Special value, not used as an operator
|
||||||
Parenthesis = 2000000100
|
Parenthesis = 2000000100,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EvalValues
|
enum EvalValues
|
||||||
|
@ -51,8 +54,8 @@ enum EvalValues
|
||||||
Nmi = 2000000107,
|
Nmi = 2000000107,
|
||||||
Irq = 2000000108,
|
Irq = 2000000108,
|
||||||
Value = 2000000109,
|
Value = 2000000109,
|
||||||
|
Address = 2000000110,
|
||||||
MemoryAddress = 2000100000
|
AbsoluteAddress = 2000000111,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EvalResultType
|
enum EvalResultType
|
||||||
|
@ -89,13 +92,13 @@ private:
|
||||||
bool CheckSpecialTokens(string expression, size_t &pos, string &output);
|
bool CheckSpecialTokens(string expression, size_t &pos, string &output);
|
||||||
string GetNextToken(string expression, size_t &pos);
|
string GetNextToken(string expression, size_t &pos);
|
||||||
void ToRpn(string expression, vector<int> &outputQueue);
|
void ToRpn(string expression, vector<int> &outputQueue);
|
||||||
int32_t EvaluateExpression(vector<int> *outputQueue, DebugState &state, EvalResultType &resultType, int16_t memoryValue);
|
int32_t EvaluateExpression(vector<int> *outputQueue, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr);
|
||||||
int32_t PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue);
|
int32_t PrivateEvaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue, uint32_t memoryAddr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionEvaluator();
|
ExpressionEvaluator();
|
||||||
|
|
||||||
int32_t Evaluate(string expression, DebugState &state, int16_t memoryValue = 0);
|
int32_t Evaluate(string expression, DebugState &state, int16_t memoryValue = 0, uint32_t memoryAddr = 0);
|
||||||
int32_t Evaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue = 0);
|
int32_t Evaluate(string expression, DebugState &state, EvalResultType &resultType, int16_t memoryValue = 0, uint32_t memoryAddr = 0);
|
||||||
bool Validate(string expression);
|
bool Validate(string expression);
|
||||||
};
|
};
|
|
@ -37,7 +37,23 @@ namespace Mesen.GUI.Debugger
|
||||||
AddBinding("Condition", txtCondition);
|
AddBinding("Condition", txtCondition);
|
||||||
|
|
||||||
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.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, "Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine + "Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine + Environment.NewLine + "A/X/Y/PS/SP: Value of registers" + 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 + "Value: Current value being read/written from/to memory" + Environment.NewLine + "[<address>]: 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]");
|
this.toolTip.SetToolTip(this.picHelp,
|
||||||
|
"Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine +
|
||||||
|
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine + Environment.NewLine +
|
||||||
|
"A/X/Y/PS/SP: Value of registers" + 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 +
|
||||||
|
"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 +
|
||||||
|
"[<address>]: 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."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool ValidateInput()
|
protected override bool ValidateInput()
|
||||||
|
|
47
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
47
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
|
@ -61,8 +61,9 @@
|
||||||
this.mnuToggleBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuToggleBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuDisableEnableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuDisableEnableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
this.mnuRunOneFrame = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.mnuRunPpuCycle = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuRunPpuCycle = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuRunScanline = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
this.mnuRunOneFrame = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuFind = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuFind = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
|
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
@ -99,7 +100,7 @@
|
||||||
this.lblChrAnalysis = new System.Windows.Forms.ToolStripStatusLabel();
|
this.lblChrAnalysis = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
this.lblChrAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel();
|
this.lblChrAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel();
|
||||||
this.tmrCdlRatios = new System.Windows.Forms.Timer(this.components);
|
this.tmrCdlRatios = new System.Windows.Forms.Timer(this.components);
|
||||||
this.mnuRunScanline = new System.Windows.Forms.ToolStripMenuItem();
|
this.picWatchHelp = new System.Windows.Forms.PictureBox();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||||
this.splitContainer.Panel1.SuspendLayout();
|
this.splitContainer.Panel1.SuspendLayout();
|
||||||
this.splitContainer.Panel2.SuspendLayout();
|
this.splitContainer.Panel2.SuspendLayout();
|
||||||
|
@ -112,6 +113,7 @@
|
||||||
this.grpCallstack.SuspendLayout();
|
this.grpCallstack.SuspendLayout();
|
||||||
this.menuStrip.SuspendLayout();
|
this.menuStrip.SuspendLayout();
|
||||||
this.statusStrip.SuspendLayout();
|
this.statusStrip.SuspendLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).BeginInit();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// splitContainer
|
// splitContainer
|
||||||
|
@ -230,6 +232,7 @@
|
||||||
//
|
//
|
||||||
// grpWatch
|
// grpWatch
|
||||||
//
|
//
|
||||||
|
this.grpWatch.Controls.Add(this.picWatchHelp);
|
||||||
this.grpWatch.Controls.Add(this.ctrlWatch);
|
this.grpWatch.Controls.Add(this.ctrlWatch);
|
||||||
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
this.grpWatch.Location = new System.Drawing.Point(3, 3);
|
this.grpWatch.Location = new System.Drawing.Point(3, 3);
|
||||||
|
@ -409,14 +412,6 @@
|
||||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(255, 6);
|
this.toolStripMenuItem2.Size = new System.Drawing.Size(255, 6);
|
||||||
//
|
//
|
||||||
// mnuRunOneFrame
|
|
||||||
//
|
|
||||||
this.mnuRunOneFrame.Name = "mnuRunOneFrame";
|
|
||||||
this.mnuRunOneFrame.ShortcutKeys = System.Windows.Forms.Keys.F8;
|
|
||||||
this.mnuRunOneFrame.Size = new System.Drawing.Size(258, 22);
|
|
||||||
this.mnuRunOneFrame.Text = "Run one frame";
|
|
||||||
this.mnuRunOneFrame.Click += new System.EventHandler(this.mnuRunOneFrame_Click);
|
|
||||||
//
|
|
||||||
// mnuRunPpuCycle
|
// mnuRunPpuCycle
|
||||||
//
|
//
|
||||||
this.mnuRunPpuCycle.Name = "mnuRunPpuCycle";
|
this.mnuRunPpuCycle.Name = "mnuRunPpuCycle";
|
||||||
|
@ -425,6 +420,22 @@
|
||||||
this.mnuRunPpuCycle.Text = "Run one PPU cycle";
|
this.mnuRunPpuCycle.Text = "Run one PPU cycle";
|
||||||
this.mnuRunPpuCycle.Click += new System.EventHandler(this.mnuRunPpuCycle_Click);
|
this.mnuRunPpuCycle.Click += new System.EventHandler(this.mnuRunPpuCycle_Click);
|
||||||
//
|
//
|
||||||
|
// mnuRunScanline
|
||||||
|
//
|
||||||
|
this.mnuRunScanline.Name = "mnuRunScanline";
|
||||||
|
this.mnuRunScanline.ShortcutKeys = System.Windows.Forms.Keys.F7;
|
||||||
|
this.mnuRunScanline.Size = new System.Drawing.Size(258, 22);
|
||||||
|
this.mnuRunScanline.Text = "Run one scanline";
|
||||||
|
this.mnuRunScanline.Click += new System.EventHandler(this.mnuRunScanline_Click);
|
||||||
|
//
|
||||||
|
// mnuRunOneFrame
|
||||||
|
//
|
||||||
|
this.mnuRunOneFrame.Name = "mnuRunOneFrame";
|
||||||
|
this.mnuRunOneFrame.ShortcutKeys = System.Windows.Forms.Keys.F8;
|
||||||
|
this.mnuRunOneFrame.Size = new System.Drawing.Size(258, 22);
|
||||||
|
this.mnuRunOneFrame.Text = "Run one frame";
|
||||||
|
this.mnuRunOneFrame.Click += new System.EventHandler(this.mnuRunOneFrame_Click);
|
||||||
|
//
|
||||||
// searchToolStripMenuItem
|
// searchToolStripMenuItem
|
||||||
//
|
//
|
||||||
this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||||
|
@ -716,13 +727,15 @@
|
||||||
this.tmrCdlRatios.Interval = 300;
|
this.tmrCdlRatios.Interval = 300;
|
||||||
this.tmrCdlRatios.Tick += new System.EventHandler(this.tmrCdlRatios_Tick);
|
this.tmrCdlRatios.Tick += new System.EventHandler(this.tmrCdlRatios_Tick);
|
||||||
//
|
//
|
||||||
// mnuRunScanline
|
// picWatchHelp
|
||||||
//
|
//
|
||||||
this.mnuRunScanline.Name = "mnuRunScanline";
|
this.picWatchHelp.Image = global::Mesen.GUI.Properties.Resources.Help;
|
||||||
this.mnuRunScanline.ShortcutKeys = System.Windows.Forms.Keys.F7;
|
this.picWatchHelp.Location = new System.Drawing.Point(43, 0);
|
||||||
this.mnuRunScanline.Size = new System.Drawing.Size(258, 22);
|
this.picWatchHelp.Name = "picWatchHelp";
|
||||||
this.mnuRunScanline.Text = "Run one scanline";
|
this.picWatchHelp.Size = new System.Drawing.Size(14, 14);
|
||||||
this.mnuRunScanline.Click += new System.EventHandler(this.mnuRunScanline_Click);
|
this.picWatchHelp.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||||
|
this.picWatchHelp.TabIndex = 1;
|
||||||
|
this.picWatchHelp.TabStop = false;
|
||||||
//
|
//
|
||||||
// frmDebugger
|
// frmDebugger
|
||||||
//
|
//
|
||||||
|
@ -751,6 +764,7 @@
|
||||||
this.menuStrip.PerformLayout();
|
this.menuStrip.PerformLayout();
|
||||||
this.statusStrip.ResumeLayout(false);
|
this.statusStrip.ResumeLayout(false);
|
||||||
this.statusStrip.PerformLayout();
|
this.statusStrip.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).EndInit();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
this.PerformLayout();
|
this.PerformLayout();
|
||||||
|
|
||||||
|
@ -826,5 +840,6 @@
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
|
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuPpuPartialDraw;
|
private System.Windows.Forms.ToolStripMenuItem mnuPpuPartialDraw;
|
||||||
private System.Windows.Forms.ToolStripMenuItem mnuRunScanline;
|
private System.Windows.Forms.ToolStripMenuItem mnuRunScanline;
|
||||||
|
private System.Windows.Forms.PictureBox picWatchHelp;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -38,6 +38,22 @@ namespace Mesen.GUI.Debugger
|
||||||
BreakpointManager.BreakpointsChanged += BreakpointManager_BreakpointsChanged;
|
BreakpointManager.BreakpointsChanged += BreakpointManager_BreakpointsChanged;
|
||||||
this.ctrlBreakpoints.RefreshList();
|
this.ctrlBreakpoints.RefreshList();
|
||||||
RefreshBreakpoints();
|
RefreshBreakpoints();
|
||||||
|
|
||||||
|
this.toolTip.SetToolTip(this.picWatchHelp,
|
||||||
|
"Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine +
|
||||||
|
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine + Environment.NewLine +
|
||||||
|
"A/X/Y/PS/SP: Value of registers" + 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 +
|
||||||
|
"Value: Current value being read/written from/to memory" + Environment.NewLine +
|
||||||
|
"[<address>]: 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."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue