diff --git a/Core/Breakpoint.cpp b/Core/Breakpoint.cpp
index 9b2b9597..3f83a4c9 100644
--- a/Core/Breakpoint.cpp
+++ b/Core/Breakpoint.cpp
@@ -2,11 +2,30 @@
#include "Breakpoint.h"
-Breakpoint::Breakpoint(BreakpointType type, uint32_t addr, bool isAbsoluteAddr)
+Breakpoint::Breakpoint()
{
- UpdateBreakpoint(type, addr, isAbsoluteAddr, true);
}
Breakpoint::~Breakpoint()
{
}
+
+bool Breakpoint::Matches(uint32_t memoryAddr, uint32_t absoluteAddr)
+{
+ return _addr == -1 || (memoryAddr == _addr && !_isAbsoluteAddr) || (absoluteAddr == _addr && _isAbsoluteAddr);
+}
+
+BreakpointType Breakpoint::GetType()
+{
+ return _type;
+}
+
+string Breakpoint::GetCondition()
+{
+ return _condition;
+}
+
+void Breakpoint::ClearCondition()
+{
+ memset(_condition, 0, sizeof(_condition));
+}
\ No newline at end of file
diff --git a/Core/Breakpoint.h b/Core/Breakpoint.h
index 04746f0d..29a1dd9a 100644
--- a/Core/Breakpoint.h
+++ b/Core/Breakpoint.h
@@ -1,70 +1,31 @@
#pragma once
#include "stdafx.h"
+#include "ExpressionEvaluator.h"
-enum class BreakpointType
+enum BreakpointType
{
- Execute = 0,
- Read = 1,
- Write = 2
+ Global = 0,
+ Execute = 1,
+ ReadRam = 2,
+ WriteRam = 4,
+ ReadVram = 8,
+ WriteVram = 16,
};
class Breakpoint
{
public:
- Breakpoint(BreakpointType type, uint32_t addr, bool isAbsoluteAddr);
+ Breakpoint();
~Breakpoint();
- bool Matches(uint32_t memoryAddr, uint32_t absoluteAddr)
- {
- return _enabled && ((memoryAddr == _addr && !_isAbsoluteAddr) || (absoluteAddr == _addr && _isAbsoluteAddr));
- }
-
- uint32_t GetAddr()
- {
- return _addr;
- }
-
- bool IsAbsoluteAddr()
- {
- return _isAbsoluteAddr;
- }
-
- BreakpointType GetType()
- {
- return _type;
- }
-
- string GetTypeText()
- {
- switch(_type) {
- case BreakpointType::Execute: return "Exec";
- case BreakpointType::Read: return "Read";
- case BreakpointType::Write: return "Write";
- }
- return "";
- }
-
- bool IsEnabled()
- {
- return _enabled;
- }
-
- void SetEnabled(bool enabled)
- {
- _enabled = enabled;
- }
-
- void UpdateBreakpoint(BreakpointType type, uint32_t addr, bool isAbsoluteAddr, bool enabled)
- {
- _type = type;
- _addr = addr;
- _isAbsoluteAddr = isAbsoluteAddr;
- _enabled = enabled;
- }
+ bool Matches(uint32_t memoryAddr, uint32_t absoluteAddr);
+ BreakpointType GetType();
+ string GetCondition();
+ void ClearCondition();
private:
BreakpointType _type;
- uint32_t _addr;
+ int32_t _addr;
bool _isAbsoluteAddr;
- bool _enabled;
+ char _condition[1000];
};
\ No newline at end of file
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 6fdfa9c7..a13cd79d 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -271,6 +271,7 @@
+
@@ -379,6 +380,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index b764fedf..2e47f733 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -332,6 +332,9 @@
VideoDecoder\HD
+
+ Debugger
+
@@ -436,5 +439,8 @@
VideoDecoder\HD
+
+ Debugger
+
\ No newline at end of file
diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp
index 4f550bd3..a785b188 100644
--- a/Core/Debugger.cpp
+++ b/Core/Debugger.cpp
@@ -8,6 +8,7 @@
#include "VideoDecoder.h"
#include "APU.h"
#include "CodeDataLogger.h"
+#include "ExpressionEvaluator.h"
Debugger* Debugger::Instance = nullptr;
@@ -84,69 +85,82 @@ CdlRatios Debugger::GetCdlRatios()
return _codeDataLogger->GetRatios();
}
-void Debugger::AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr, bool enabled)
+void Debugger::SetBreakpoints(Breakpoint breakpoints[], uint32_t length)
{
- _bpLock.Acquire();
+ _bpLock.AcquireSafe();
- if(isAbsoluteAddr) {
- address = _mapper->ToAbsoluteAddress(address);
- }
+ _globalBreakpoints.clear();
+ _execBreakpoints.clear();
+ _readBreakpoints.clear();
+ _writeBreakpoints.clear();
+ _readVramBreakpoints.clear();
+ _writeVramBreakpoints.clear();
- shared_ptr breakpoint(new Breakpoint(type, address, isAbsoluteAddr));
- breakpoint->SetEnabled(enabled);
- switch(type) {
- case BreakpointType::Execute: _execBreakpoints.push_back(breakpoint); break;
- case BreakpointType::Read: _readBreakpoints.push_back(breakpoint); break;
- case BreakpointType::Write: _writeBreakpoints.push_back(breakpoint); break;
- }
+ ExpressionEvaluator expEval;
+ for(uint32_t i = 0; i < length; i++) {
+ Breakpoint& bp = breakpoints[i];
- _bpLock.Release();
-}
+ if(!expEval.Validate(bp.GetCondition())) {
+ //Remove any invalid condition (syntax-wise)
+ bp.ClearCondition();
+ }
-void Debugger::RemoveBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr)
-{
- _bpLock.Acquire();
-
- vector> *breakpoints = nullptr;
- switch(type) {
- case BreakpointType::Execute: breakpoints = &_execBreakpoints; break;
- case BreakpointType::Read: breakpoints = &_readBreakpoints; break;
- case BreakpointType::Write: breakpoints = &_writeBreakpoints; break;
- }
-
- shared_ptr breakpoint = GetMatchingBreakpoint(type, address);
- for(size_t i = 0, len = breakpoints->size(); i < len; i++) {
- shared_ptr breakpoint = (*breakpoints)[i];
- if(breakpoint->GetAddr() == address && breakpoint->IsAbsoluteAddr() == isAbsoluteAddr) {
- breakpoints->erase(breakpoints->begin() + i);
- break;
+ BreakpointType type = bp.GetType();
+ if(type & BreakpointType::Execute) {
+ _execBreakpoints.push_back(bp);
+ }
+ if(type & BreakpointType::ReadRam) {
+ _readBreakpoints.push_back(bp);
+ }
+ if(type & BreakpointType::ReadVram) {
+ _readVramBreakpoints.push_back(bp);
+ }
+ if(type & BreakpointType::WriteRam) {
+ _writeBreakpoints.push_back(bp);
+ }
+ if(type & BreakpointType::WriteVram) {
+ _writeVramBreakpoints.push_back(bp);
+ }
+ if(type == BreakpointType::Global) {
+ _globalBreakpoints.push_back(bp);
}
}
- _bpLock.Release();
}
-shared_ptr Debugger::GetMatchingBreakpoint(BreakpointType type, uint32_t addr)
+bool Debugger::HasMatchingBreakpoint(BreakpointType type, uint32_t addr, int16_t value)
{
uint32_t absoluteAddr = _mapper->ToAbsoluteAddress(addr);
- vector> *breakpoints = nullptr;
+ vector *breakpoints = nullptr;
switch(type) {
+ case BreakpointType::Global: breakpoints = &_globalBreakpoints; break;
case BreakpointType::Execute: breakpoints = &_execBreakpoints; break;
- case BreakpointType::Read: breakpoints = &_readBreakpoints; break;
- case BreakpointType::Write: breakpoints = &_writeBreakpoints; break;
+ case BreakpointType::ReadRam: breakpoints = &_readBreakpoints; break;
+ case BreakpointType::WriteRam: breakpoints = &_writeBreakpoints; break;
+ case BreakpointType::ReadVram: breakpoints = &_readVramBreakpoints; break;
+ case BreakpointType::WriteVram: breakpoints = &_writeVramBreakpoints; break;
}
+
+ DebugState state;
+ GetState(&state);
- _bpLock.Acquire();
+ _bpLock.AcquireSafe();
for(size_t i = 0, len = breakpoints->size(); i < len; i++) {
- shared_ptr breakpoint = (*breakpoints)[i];
- if(breakpoint->Matches(addr, absoluteAddr)) {
- _bpLock.Release();
- return breakpoint;
+ Breakpoint &breakpoint = (*breakpoints)[i];
+ if(type == BreakpointType::Global || breakpoint.Matches(addr, absoluteAddr)) {
+ string condition = breakpoint.GetCondition();
+ if(condition.empty()) {
+ return true;
+ } else {
+ ExpressionEvaluator expEval;
+ if(expEval.Evaluate(condition, state, value)) {
+ return true;
+ }
+ }
}
}
- _bpLock.Release();
- return shared_ptr();
+ return false;
}
void Debugger::UpdateCallstack(uint32_t addr)
@@ -180,28 +194,20 @@ void Debugger::ProcessStepConditions(uint32_t addr)
}
}
-void Debugger::BreakOnBreakpoint(MemoryOperationType type, uint32_t addr)
+void Debugger::PrivateProcessPpuCycle()
{
- BreakpointType breakpointType;
- switch(type) {
- case MemoryOperationType::Read: breakpointType = BreakpointType::Read; break;
- case MemoryOperationType::Write: breakpointType = BreakpointType::Write; break;
-
- default:
- case MemoryOperationType::ExecOpCode:
- case MemoryOperationType::ExecOperand: breakpointType = BreakpointType::Execute; break;
- }
+ _breakLock.AcquireSafe();
- if(GetMatchingBreakpoint(breakpointType, addr)) {
+ if(HasMatchingBreakpoint(BreakpointType::Global, 0, -1)) {
//Found a matching breakpoint, stop execution
Step(1);
SleepUntilResume();
}
}
-void Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr)
+void Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t value)
{
- _breakLock.Acquire();
+ _breakLock.AcquireSafe();
_currentReadAddr = &addr;
@@ -226,12 +232,29 @@ void Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
}
if(!breakDone) {
- BreakOnBreakpoint(type, addr);
+ BreakOnBreakpoint(type, addr, value);
}
_currentReadAddr = nullptr;
+}
- _breakLock.Release();
+void Debugger::BreakOnBreakpoint(MemoryOperationType type, uint32_t addr, uint8_t value)
+{
+ BreakpointType breakpointType;
+ switch(type) {
+ case MemoryOperationType::Read: breakpointType = BreakpointType::ReadRam; break;
+ case MemoryOperationType::Write: breakpointType = BreakpointType::WriteRam; break;
+
+ default:
+ case MemoryOperationType::ExecOpCode:
+ case MemoryOperationType::ExecOperand: breakpointType = BreakpointType::Execute; break;
+ }
+
+ if(HasMatchingBreakpoint(breakpointType, addr, (type == MemoryOperationType::ExecOperand) ? -1 : value)) {
+ //Found a matching breakpoint, stop execution
+ Step(1);
+ SleepUntilResume();
+ }
}
bool Debugger::SleepUntilResume()
@@ -256,10 +279,18 @@ bool Debugger::SleepUntilResume()
return false;
}
-void Debugger::PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr)
+void Debugger::PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value)
{
- int32_t absoluteAddr = _mapper->ToAbsoluteChrAddress(addr);
- _codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn);
+ if(type != MemoryOperationType::Write) {
+ int32_t absoluteAddr = _mapper->ToAbsoluteChrAddress(addr);
+ _codeDataLogger->SetFlag(absoluteAddr, type == MemoryOperationType::Read ? CdlChrFlags::Read : CdlChrFlags::Drawn);
+ }
+
+ if(HasMatchingBreakpoint(type == MemoryOperationType::Write ? BreakpointType::WriteVram : BreakpointType::ReadVram, addr, value)) {
+ //Found a matching breakpoint, stop execution
+ Step(1);
+ SleepUntilResume();
+ }
}
void Debugger::GetState(DebugState *state)
@@ -373,17 +404,24 @@ void Debugger::SetNextStatement(uint16_t addr)
}
}
-void Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr)
+void Debugger::ProcessPpuCycle()
{
if(Debugger::Instance) {
- Debugger::Instance->PrivateProcessRamOperation(type, addr);
+ Debugger::Instance->PrivateProcessPpuCycle();
}
}
-void Debugger::ProcessVramOperation(MemoryOperationType type, uint16_t addr)
+void Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t value)
{
if(Debugger::Instance) {
- Debugger::Instance->PrivateProcessVramOperation(type, addr);
+ Debugger::Instance->PrivateProcessRamOperation(type, addr, value);
+ }
+}
+
+void Debugger::ProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value)
+{
+ if(Debugger::Instance) {
+ Debugger::Instance->PrivateProcessVramOperation(type, addr, value);
}
}
diff --git a/Core/Debugger.h b/Core/Debugger.h
index 34cf10d0..fee482c1 100644
--- a/Core/Debugger.h
+++ b/Core/Debugger.h
@@ -45,9 +45,14 @@ private:
shared_ptr _ppu;
shared_ptr _memoryManager;
shared_ptr _mapper;
- vector> _readBreakpoints;
- vector> _writeBreakpoints;
- vector> _execBreakpoints;
+
+ vector _readBreakpoints;
+ vector _writeBreakpoints;
+ vector _execBreakpoints;
+ vector _globalBreakpoints;
+ vector _readVramBreakpoints;
+ vector _writeVramBreakpoints;
+
deque _callstackAbsolute;
deque _callstackRelative;
@@ -65,22 +70,20 @@ private:
atomic _stepOverAddr;
private:
- void PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr);
- void PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr);
- shared_ptr GetMatchingBreakpoint(BreakpointType type, uint32_t addr);
+ void PrivateProcessPpuCycle();
+ void 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);
void UpdateCallstack(uint32_t addr);
void ProcessStepConditions(uint32_t addr);
- void BreakOnBreakpoint(MemoryOperationType type, uint32_t addr);
+ void BreakOnBreakpoint(MemoryOperationType type, uint32_t addr, uint8_t value);
bool SleepUntilResume();
public:
Debugger(shared_ptr console, shared_ptr cpu, shared_ptr ppu, shared_ptr memoryManager, shared_ptr mapper);
~Debugger();
- void AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr, bool enabled);
- void RemoveBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr);
- vector> GetBreakpoints();
- vector GetExecBreakpointAddresses();
+ void SetBreakpoints(Breakpoint breakpoints[], uint32_t length);
uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer);
void GetNametable(int nametableIndex, uint32_t* frameBuffer, uint8_t* tileData, uint8_t* paletteData);
@@ -112,8 +115,9 @@ public:
uint8_t GetMemoryValue(uint32_t addr);
uint32_t GetRelativeAddress(uint32_t addr);
- static void ProcessRamOperation(MemoryOperationType type, uint16_t &addr);
- static void ProcessVramOperation(MemoryOperationType type, uint16_t addr);
+ static void ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uint8_t value);
+ static void ProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value);
+ static void ProcessPpuCycle();
static void BreakIfDebugging();
};
\ No newline at end of file
diff --git a/Core/ExpressionEvaluator.cpp b/Core/ExpressionEvaluator.cpp
new file mode 100644
index 00000000..2bc1c38b
--- /dev/null
+++ b/Core/ExpressionEvaluator.cpp
@@ -0,0 +1,325 @@
+#include "stdafx.h"
+#include "ExpressionEvaluator.h"
+#include "Console.h"
+#include "Debugger.h"
+
+std::unordered_map, StringHasher> ExpressionEvaluator::_outputCache;
+SimpleLock ExpressionEvaluator::_cacheLock;
+
+bool ExpressionEvaluator::IsOperator(string token, int &precedence, bool unaryOperator)
+{
+ if(unaryOperator) {
+ for(size_t i = 0, len = _unaryOperators.size(); i < len; i++) {
+ if(token.compare(_unaryOperators[i]) == 0) {
+ precedence = _unaryPrecedence[i];
+ return true;
+ }
+ }
+ } else {
+ for(size_t i = 0, len = _binaryOperators.size(); i < len; i++) {
+ if(token.compare(_binaryOperators[i]) == 0) {
+ precedence = _binaryPrecedence[i];
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+EvalOperators ExpressionEvaluator::GetOperator(string token, bool unaryOperator)
+{
+ if(unaryOperator) {
+ for(size_t i = 0, len = _unaryOperators.size(); i < len; i++) {
+ if(token.compare(_unaryOperators[i]) == 0) {
+ return (EvalOperators)(2000000050 + i);
+ }
+ }
+ } else {
+ for(size_t i = 0, len = _binaryOperators.size(); i < len; i++) {
+ if(token.compare(_binaryOperators[i]) == 0) {
+ return (EvalOperators)(2000000000 + i);
+ }
+ }
+ }
+ return EvalOperators::Addition;
+}
+
+bool ExpressionEvaluator::CheckSpecialTokens(string expression, size_t &pos, string &output)
+{
+ string token;
+ size_t len = expression.size();
+ do {
+ char c = std::tolower(expression[pos]);
+ if(c >= 'a' && c <= 'z') {
+ token += expression[pos];
+ pos++;
+ } else {
+ break;
+ }
+ } while(pos < len);
+
+ if(!token.compare("a")) {
+ output += std::to_string(EvalValues::RegA);
+ } else if(!token.compare("x")) {
+ output += std::to_string(EvalValues::RegX);
+ } else if(!token.compare("y")) {
+ output += std::to_string(EvalValues::RegY);
+ } else if(!token.compare("ps")) {
+ output += std::to_string(EvalValues::RegPS);
+ } else if(!token.compare("sp")) {
+ output += std::to_string(EvalValues::RegSP);
+ } else if(!token.compare("cycle")) {
+ output += std::to_string(EvalValues::PpuCycle);
+ } else if(!token.compare("scanline")) {
+ output += std::to_string(EvalValues::PpuScanline);
+ } else if(!token.compare("irq")) {
+ output += std::to_string(EvalValues::Irq);
+ } else if(!token.compare("nmi")) {
+ output += std::to_string(EvalValues::Nmi);
+ } else if(!token.compare("value")) {
+ output += std::to_string(EvalValues::Value);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+string ExpressionEvaluator::GetNextToken(string expression, size_t &pos)
+{
+ string output;
+ bool isOperator = false;
+ bool isNumber = false;
+ bool isHex = false;
+ size_t initialPos = pos;
+ for(size_t len = expression.size(); pos < len; pos++) {
+ char c = std::tolower(expression[pos]);
+
+ if(c == '$' && pos == initialPos) {
+ isHex = true;
+ } else if((c >= '0' && c <= '9') || (isHex && c >= 'a' && c <= 'f')) {
+ if(isNumber || output.empty()) {
+ output += c;
+ isNumber = true;
+ } else {
+ //Done reading number
+ break;
+ }
+ } else if(isNumber) {
+ //First non-numeric character, done
+ break;
+ } else if(c == '(' || c == ')' || c == '-' || c == '+' || c == '~') {
+ if(output.empty()) {
+ output += c;
+ pos++;
+ }
+ break;
+ } else if(c == '!') {
+ //Figure out if it's ! or !=
+ if(pos < len - 1) {
+ if(expression[pos + 1] == '=') {
+ pos++;
+ output += "!=";
+ } else {
+ output += "!";
+ }
+ }
+ break;
+ } else {
+ if(c == '$') {
+ break;
+ } else if(c < 'a' || c > 'z') {
+ //Not a number, not a letter, this is an operator
+ isOperator = true;
+ output += c;
+ } else {
+ if(isOperator) {
+ break;
+ } else {
+ if(output.empty()) {
+ if(CheckSpecialTokens(expression, pos, output)) {
+ break;
+ }
+ }
+ output += c;
+ }
+ }
+ }
+ }
+
+ if(isHex) {
+ unsigned int x;
+ std::stringstream ss;
+ ss << std::hex << output;
+ ss >> x;
+ output = std::to_string(x);
+ }
+
+ return output;
+}
+
+void ExpressionEvaluator::ToRpn(string expression, vector &outputQueue)
+{
+ std::stack opStack = std::stack();
+ std::stack precedenceStack;
+
+ size_t position = 0;
+ bool previousTokenIsOp = true;
+ while(true) {
+ string token = GetNextToken(expression, position);
+ if(token.empty()) {
+ break;
+ }
+
+ bool unaryOperator = previousTokenIsOp;
+ previousTokenIsOp = false;
+
+ int precedence = 0;
+ if(IsOperator(token, precedence, unaryOperator)) {
+ EvalOperators op = GetOperator(token, unaryOperator);
+ if(!opStack.empty()) {
+ EvalOperators topOp = opStack.top();
+ if((unaryOperator && precedence < precedenceStack.top()) || (!unaryOperator && precedence <= precedenceStack.top())) {
+ opStack.pop();
+ precedenceStack.pop();
+ outputQueue.push_back(topOp);
+ }
+ }
+ opStack.push(op);
+ precedenceStack.push(precedence);
+
+ previousTokenIsOp = true;
+ } else if(token[0] == '(') {
+ opStack.push(EvalOperators::Parenthesis);
+ precedenceStack.push(0);
+ } else if(token[0] == ')') {
+ while(opStack.top() != EvalOperators::Parenthesis) {
+ outputQueue.push_back(opStack.top());
+ opStack.pop();
+ }
+ opStack.pop();
+ } else {
+ outputQueue.push_back(std::stoi(token));
+ }
+ }
+
+ while(!opStack.empty()) {
+ outputQueue.push_back(opStack.top());
+ opStack.pop();
+ }
+}
+
+bool ExpressionEvaluator::EvaluateExpression(vector *outputQueue, DebugState &state, int16_t memoryValue)
+{
+ int pos = 0;
+ int right = 0;
+ int left = 0;
+ int operandStack[1000];
+
+ for(size_t i = 0, len = outputQueue->size(); i < len; i++) {
+ int token = (*outputQueue)[i];
+
+ if(token >= EvalValues::RegA) {
+ //Replace value with a special value
+ switch(token) {
+ case EvalValues::RegA: token = state.CPU.A; break;
+ case EvalValues::RegX: token = state.CPU.X; break;
+ case EvalValues::RegY: token = state.CPU.Y; break;
+ case EvalValues::RegPS: token = state.CPU.PS; break;
+ case EvalValues::RegSP: token = state.CPU.SP; break;
+ case EvalValues::Irq: token = state.CPU.IRQFlag; break;
+ case EvalValues::Nmi: token = state.CPU.NMIFlag; break;
+ case EvalValues::PpuCycle: token = state.PPU.Cycle; break;
+ case EvalValues::PpuScanline: token = state.PPU.Scanline; break;
+ case EvalValues::Value: token = memoryValue; break;
+ }
+ } else if(token >= EvalOperators::Multiplication) {
+ right = operandStack[--pos];
+ if(pos > 0) {
+ left = operandStack[--pos];
+ }
+
+ switch(token) {
+ case EvalOperators::Multiplication: token = left * right; break;
+ case EvalOperators::Division: token = left / right; break;
+ case EvalOperators::Modulo: token = left % right; break;
+ case EvalOperators::Addition: token = left + right; break;
+ case EvalOperators::Substration: token = left - right; break;
+ case EvalOperators::ShiftLeft: token = left << right; break;
+ case EvalOperators::ShiftRight: token = left >> right; break;
+ case EvalOperators::SmallerThan: token = left < right; break;
+ case EvalOperators::SmallerOrEqual: token = left <= right; break;
+ case EvalOperators::GreaterThan: token = left > right; break;
+ case EvalOperators::GreaterOrEqual: token = left >= right; break;
+ case EvalOperators::Equal: token = left == right; break;
+ case EvalOperators::NotEqual: token = left != right; break;
+ case EvalOperators::BinaryAnd: token = left & right; break;
+ case EvalOperators::BinaryXor: token = left | right; break;
+ case EvalOperators::BinaryOr: token = left ^ right; break;
+ case EvalOperators::LogicalAnd: token = left && right; break;
+ case EvalOperators::LogicalOr: token = left || right; break;
+
+ //Unary operators
+ case EvalOperators::Plus: token = right; break;
+ case EvalOperators::Minus: token = -right; break;
+ case EvalOperators::BinaryNot: token = ~right; break;
+ case EvalOperators::LogicalNot: token = !right; break;
+ default: throw std::runtime_error("Invalid operator");
+ }
+ }
+ operandStack[pos++] = token;
+ }
+ return operandStack[0] != 0;
+}
+
+ExpressionEvaluator::ExpressionEvaluator()
+{
+}
+
+bool ExpressionEvaluator::PrivateEvaluate(string expression, DebugState &state, int16_t memoryValue)
+{
+ vector *outputQueue = nullptr;
+
+ {
+ LockHandler lock = _cacheLock.AcquireSafe();
+
+ auto cacheOutputQueue = _outputCache.find(expression);
+ if(cacheOutputQueue != _outputCache.end()) {
+ outputQueue = &(cacheOutputQueue->second);
+ }
+ }
+
+ if(outputQueue == nullptr) {
+ vector output;
+
+ string fixedExp = expression;
+ fixedExp.erase(std::remove(fixedExp.begin(), fixedExp.end(), ' '), fixedExp.end());
+ ToRpn(fixedExp, output);
+
+ LockHandler lock = _cacheLock.AcquireSafe();
+ _outputCache[expression] = output;
+ outputQueue = &_outputCache[expression];
+ }
+
+ return EvaluateExpression(outputQueue, state, memoryValue);
+}
+
+bool ExpressionEvaluator::Evaluate(string expression, DebugState &state, int16_t memoryValue)
+{
+ try {
+ return PrivateEvaluate(expression, state, memoryValue);
+ } catch(std::exception) {
+ return false;
+ }
+}
+
+bool ExpressionEvaluator::Validate(string expression)
+{
+ try {
+ DebugState state;
+ PrivateEvaluate(expression, state, 0);
+ return true;
+ } catch(std::exception e) {
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/Core/ExpressionEvaluator.h b/Core/ExpressionEvaluator.h
new file mode 100644
index 00000000..03dafc0c
--- /dev/null
+++ b/Core/ExpressionEvaluator.h
@@ -0,0 +1,91 @@
+#pragma once
+#include "stdafx.h"
+#include
+#include
+#include
+#include "../Utilities/SimpleLock.h"
+
+struct DebugState;
+
+enum EvalOperators
+{
+ //Binary operators
+ Multiplication = 2000000000,
+ Division = 2000000001,
+ Modulo = 2000000002,
+ Addition = 2000000003,
+ Substration = 2000000004,
+ ShiftLeft = 2000000005,
+ ShiftRight = 2000000006,
+ SmallerThan = 2000000007,
+ SmallerOrEqual = 2000000008,
+ GreaterThan = 2000000009,
+ GreaterOrEqual = 2000000010,
+ Equal = 2000000011,
+ NotEqual = 2000000012,
+ BinaryAnd = 2000000013,
+ BinaryXor = 2000000014,
+ BinaryOr = 2000000015,
+ LogicalAnd = 2000000016,
+ LogicalOr = 2000000017,
+
+ //Unary operators
+ Plus = 2000000050,
+ Minus = 2000000051,
+ BinaryNot = 2000000052,
+ LogicalNot = 2000000053,
+
+ //Special value, not used as an operator
+ Parenthesis = 2000000100
+};
+
+enum EvalValues
+{
+ RegA = 2000000100,
+ RegX = 2000000101,
+ RegY = 2000000102,
+ RegSP = 2000000103,
+ RegPS = 2000000104,
+ PpuCycle = 2000000105,
+ PpuScanline = 2000000106,
+ Nmi = 2000000107,
+ Irq = 2000000108,
+ Value = 2000000109,
+};
+
+class StringHasher
+{
+public:
+ size_t operator()(const std::string& t) const
+ {
+ //Quick hash for expressions - most are likely to have different lengths, and not expecting dozens of breakpoints, either, so this should be fine.
+ return t.size();
+ }
+};
+
+class ExpressionEvaluator
+{
+private:
+ const vector _binaryOperators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||" } };
+ const vector _binaryPrecedence = { { 10, 10, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 1 } };
+ const vector _unaryOperators = { { "+", "-", "!", "~" } };
+ const vector _unaryPrecedence = { { 11, 11, 11, 11 } };
+
+ static std::unordered_map, StringHasher> _outputCache;
+ static SimpleLock _cacheLock;
+
+ bool IsOperator(string token, int &precedence, bool unaryOperator);
+ EvalOperators GetOperator(string token, bool unaryOperator);
+ int GetOperatorPrecendence(string token);
+ bool CheckSpecialTokens(string expression, size_t &pos, string &output);
+ string GetNextToken(string expression, size_t &pos);
+ void ToRpn(string expression, vector &outputQueue);
+ bool EvaluateExpression(vector *outputQueue, DebugState &state, int16_t memoryValue);
+ bool PrivateEvaluate(string expression, DebugState &state, int16_t memoryValue);
+
+public:
+ ExpressionEvaluator();
+
+ bool Evaluate(string expression, DebugState &state, int16_t memoryValue = 0);
+ bool Validate(string expression);
+};
\ No newline at end of file
diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp
index f919fb9d..1059339d 100644
--- a/Core/MemoryManager.cpp
+++ b/Core/MemoryManager.cpp
@@ -97,8 +97,6 @@ uint8_t MemoryManager::DebugRead(uint16_t addr)
uint8_t MemoryManager::Read(uint16_t addr, MemoryOperationType operationType)
{
- Debugger::ProcessRamOperation(operationType, addr);
-
uint8_t value;
if(addr <= 0x1FFF) {
value = _internalRAM[addr & 0x07FF];
@@ -109,12 +107,15 @@ uint8_t MemoryManager::Read(uint16_t addr, MemoryOperationType operationType)
_mapper->ProcessCpuClock();
CheatManager::ApplyRamCodes(addr, value);
+
+ Debugger::ProcessRamOperation(operationType, addr, value);
+
return value;
}
void MemoryManager::Write(uint16_t addr, uint8_t value)
{
- Debugger::ProcessRamOperation(MemoryOperationType::Write, addr);
+ Debugger::ProcessRamOperation(MemoryOperationType::Write, addr, value);
if(addr <= 0x1FFF) {
_internalRAM[addr & 0x07FF] = value;
@@ -147,14 +148,15 @@ uint8_t MemoryManager::DebugReadVRAM(uint16_t addr)
uint8_t MemoryManager::ReadVRAM(uint16_t addr, MemoryOperationType operationType)
{
- Debugger::ProcessVramOperation(operationType, addr);
ProcessVramAccess(addr);
- return _mapper->ReadVRAM(addr);
+ uint8_t value = _mapper->ReadVRAM(addr);
+ Debugger::ProcessVramOperation(operationType, addr, value);
+ return value;
}
void MemoryManager::WriteVRAM(uint16_t addr, uint8_t value)
{
- Debugger::ProcessVramOperation(MemoryOperationType::Write, addr);
+ Debugger::ProcessVramOperation(MemoryOperationType::Write, addr, value);
ProcessVramAccess(addr);
_mapper->WriteVRAM(addr, value);
}
diff --git a/Core/PPU.cpp b/Core/PPU.cpp
index 8761bb4f..9814f935 100644
--- a/Core/PPU.cpp
+++ b/Core/PPU.cpp
@@ -3,6 +3,7 @@
#include "CPU.h"
#include "EmulationSettings.h"
#include "VideoDecoder.h"
+#include "Debugger.h"
PPU* PPU::Instance = nullptr;
@@ -778,6 +779,8 @@ void PPU::Exec()
}
_cycle++;
+ Debugger::ProcessPpuCycle();
+
if(_scanline != -1 && _scanline < 240) {
ProcessVisibleScanline();
} else if(_scanline == -1) {
diff --git a/GUI.NET/Debugger/Breakpoint.cs b/GUI.NET/Debugger/Breakpoint.cs
index 68e19d36..f2ad6534 100644
--- a/GUI.NET/Debugger/Breakpoint.cs
+++ b/GUI.NET/Debugger/Breakpoint.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
@@ -8,31 +9,54 @@ namespace Mesen.GUI.Debugger
{
public class Breakpoint
{
- private bool _added = false;
+ public bool BreakOnRead = false;
+ public bool BreakOnWrite = false;
+ public bool BreakOnReadVram = false;
+ public bool BreakOnWriteVram = false;
+ public bool BreakOnExec = true;
- public BreakpointType Type;
public bool Enabled = true;
public UInt32 Address;
- public bool IsAbsoluteAddress;
-
- public void Remove()
- {
- if(_added) {
- InteropEmu.DebugRemoveBreakpoint(Type, Address, false);
- }
- }
-
- public void Add()
- {
- InteropEmu.DebugAddBreakpoint(Type, Address, false, Enabled);
- _added = true;
- }
+ public bool SpecificAddress = true;
+ public bool IsAbsoluteAddress = false;
+ public string Condition = "";
public void SetEnabled(bool enabled)
{
Enabled = enabled;
- Remove();
- Add();
+ }
+
+ public BreakpointType Type
+ {
+ get
+ {
+ BreakpointType type = BreakpointType.Global;
+ if(BreakOnRead) {
+ type |= BreakpointType.Read;
+ }
+ if(BreakOnWrite) {
+ type |= BreakpointType.Write;
+ }
+ if(BreakOnExec) {
+ type |= BreakpointType.Execute;
+ }
+ if(BreakOnReadVram) {
+ type |= BreakpointType.ReadVram;
+ }
+ if(BreakOnWriteVram) {
+ type |= BreakpointType.WriteVram;
+ }
+ return type;
+ }
+ }
+
+ public InteropBreakpoint ToInteropBreakpoint()
+ {
+ InteropBreakpoint bp = new InteropBreakpoint() { Address = SpecificAddress ? (Int32)Address : -1, Type = Type, IsAbsoluteAddress = IsAbsoluteAddress };
+ bp.Condition = new byte[1000];
+ byte[] condition = Encoding.UTF8.GetBytes(Condition);
+ Array.Copy(condition, bp.Condition, condition.Length);
+ return bp;
}
}
-}
+}
\ No newline at end of file
diff --git a/GUI.NET/Debugger/Controls/ctrlBreakpoints.Designer.cs b/GUI.NET/Debugger/Controls/ctrlBreakpoints.Designer.cs
index e5ac736a..69ab264a 100644
--- a/GUI.NET/Debugger/Controls/ctrlBreakpoints.Designer.cs
+++ b/GUI.NET/Debugger/Controls/ctrlBreakpoints.Designer.cs
@@ -32,10 +32,11 @@
this.mnuAddBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRemoveBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.lstBreakpoints = new Mesen.GUI.Controls.MyListView();
+ this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colLastColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
- this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.contextMenuBreakpoints.SuspendLayout();
this.SuspendLayout();
//
@@ -70,6 +71,7 @@
this.columnHeader3,
this.columnHeader1,
this.columnHeader2,
+ this.columnHeader4,
this.colLastColumn});
this.lstBreakpoints.ContextMenuStrip = this.contextMenuBreakpoints;
this.lstBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -86,6 +88,11 @@
this.lstBreakpoints.ColumnWidthChanging += new System.Windows.Forms.ColumnWidthChangingEventHandler(this.lstBreakpoints_ColumnWidthChanging);
this.lstBreakpoints.DoubleClick += new System.EventHandler(this.lstBreakpoints_DoubleClick);
//
+ // columnHeader3
+ //
+ this.columnHeader3.Text = "";
+ this.columnHeader3.Width = 21;
+ //
// columnHeader1
//
this.columnHeader1.Text = "Type";
@@ -94,16 +101,17 @@
// columnHeader2
//
this.columnHeader2.Text = "Address";
- this.columnHeader2.Width = 100;
+ this.columnHeader2.Width = 70;
+ //
+ // columnHeader4
+ //
+ this.columnHeader4.Text = "Condition";
+ this.columnHeader4.Width = 100;
//
// colLastColumn
//
this.colLastColumn.Text = "";
//
- // columnHeader3
- //
- this.columnHeader3.Text = "Enabled";
- //
// ctrlBreakpoints
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -126,5 +134,6 @@
private System.Windows.Forms.ToolStripMenuItem mnuAddBreakpoint;
private System.Windows.Forms.ToolStripMenuItem mnuRemoveBreakpoint;
private System.Windows.Forms.ColumnHeader columnHeader3;
+ private System.Windows.Forms.ColumnHeader columnHeader4;
}
}
diff --git a/GUI.NET/Debugger/Controls/ctrlBreakpoints.cs b/GUI.NET/Debugger/Controls/ctrlBreakpoints.cs
index 737404b9..8cce599f 100644
--- a/GUI.NET/Debugger/Controls/ctrlBreakpoints.cs
+++ b/GUI.NET/Debugger/Controls/ctrlBreakpoints.cs
@@ -26,22 +26,24 @@ namespace Mesen.GUI.Debugger.Controls
AdjustColumnWidth();
}
- public void ToggleBreakpoint(int address)
+ public void ToggleBreakpoint(int address, bool toggleEnabled)
{
if(address >= 0) {
Breakpoint breakpoint = GetMatchingBreakpoint(address);
if(breakpoint != null) {
- _breakpoints.Remove(breakpoint);
- breakpoint.Remove();
+ if(toggleEnabled) {
+ breakpoint.Enabled = !breakpoint.Enabled;
+ } else {
+ _breakpoints.Remove(breakpoint);
+ }
} else {
breakpoint = new Breakpoint() {
- Type = BreakpointType.Execute,
+ BreakOnExec = true,
Address = (UInt32)address,
IsAbsoluteAddress = false,
Enabled = true
};
_breakpoints.Add(breakpoint);
- breakpoint.Add();
}
RefreshList();
OnBreakpointChanged();
@@ -63,19 +65,38 @@ namespace Mesen.GUI.Debugger.Controls
return _breakpoints;
}
+ public void SetBreakpoints()
+ {
+ List breakpoints = new List();
+ foreach(Breakpoint bp in GetBreakpoints()) {
+ if(bp.Enabled) {
+ breakpoints.Add(bp.ToInteropBreakpoint());
+ }
+ }
+ InteropEmu.DebugSetBreakpoints(breakpoints.ToArray(), (UInt32)breakpoints.Count);
+ }
+
private void RefreshList()
{
lstBreakpoints.ItemChecked -= new System.Windows.Forms.ItemCheckedEventHandler(lstBreakpoints_ItemChecked);
lstBreakpoints.Items.Clear();
foreach(Breakpoint breakpoint in _breakpoints) {
+ string address = "$" + breakpoint.Address.ToString("X");
+ if(breakpoint.IsAbsoluteAddress) {
+ address = "[" + address + "]";
+ }
+
ListViewItem item = new ListViewItem();
item.Tag = breakpoint;
item.Checked = breakpoint.Enabled;
item.SubItems.Add(breakpoint.Type.ToString());
- item.SubItems.Add("$" + breakpoint.Address.ToString("X"));
+ item.SubItems.Add(breakpoint.SpecificAddress ? address : "");
+ item.SubItems.Add(breakpoint.Condition);
lstBreakpoints.Items.Add(item);
}
lstBreakpoints.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(lstBreakpoints_ItemChecked);
+
+ SetBreakpoints();
}
private void lstBreakpoints_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
@@ -97,7 +118,7 @@ namespace Mesen.GUI.Debugger.Controls
lstBreakpoints.ColumnWidthChanged -= lstBreakpoints_ColumnWidthChanged;
//Force watch values to take the full width of the list
- int totalWidth = lstBreakpoints.Columns[0].Width + lstBreakpoints.Columns[1].Width + lstBreakpoints.Columns[2].Width;
+ int totalWidth = lstBreakpoints.Columns[0].Width + lstBreakpoints.Columns[1].Width + lstBreakpoints.Columns[2].Width + lstBreakpoints.Columns[3].Width;
colLastColumn.Width = lstBreakpoints.ClientSize.Width - totalWidth;
lstBreakpoints.ColumnWidthChanging += lstBreakpoints_ColumnWidthChanging;
@@ -106,6 +127,7 @@ namespace Mesen.GUI.Debugger.Controls
private void OnBreakpointChanged()
{
+ SetBreakpoints();
if(BreakpointChanged != null) {
BreakpointChanged(this, null);
}
@@ -131,7 +153,6 @@ namespace Mesen.GUI.Debugger.Controls
private void mnuRemoveBreakpoint_Click(object sender, EventArgs e)
{
foreach(ListViewItem item in lstBreakpoints.SelectedItems) {
- ((Breakpoint)item.Tag).Remove();
_breakpoints.Remove((Breakpoint)item.Tag);
}
RefreshList();
diff --git a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs
index b3e721db..60a6f56c 100644
--- a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs
+++ b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs
@@ -34,12 +34,12 @@
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuShowOnlyDisassembledCode = new System.Windows.Forms.ToolStripMenuItem();
this.mnuShowLineNotes = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuShowCodeNotes = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuGoToLocation = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAddToWatch = new System.Windows.Forms.ToolStripMenuItem();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.ctrlCodeViewer = new Mesen.GUI.Debugger.ctrlScrollableTextbox();
- this.mnuShowCodeNotes = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenuCode.SuspendLayout();
this.SuspendLayout();
//
@@ -56,7 +56,7 @@
this.mnuGoToLocation,
this.mnuAddToWatch});
this.contextMenuCode.Name = "contextMenuWatch";
- this.contextMenuCode.Size = new System.Drawing.Size(259, 192);
+ this.contextMenuCode.Size = new System.Drawing.Size(259, 170);
this.contextMenuCode.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuCode_Opening);
//
// mnuShowNextStatement
@@ -100,6 +100,14 @@
this.mnuShowLineNotes.Text = "Show PRG Addresses";
this.mnuShowLineNotes.Click += new System.EventHandler(this.mnuShowLineNotes_Click);
//
+ // mnuShowCodeNotes
+ //
+ this.mnuShowCodeNotes.CheckOnClick = true;
+ this.mnuShowCodeNotes.Name = "mnuShowCodeNotes";
+ this.mnuShowCodeNotes.Size = new System.Drawing.Size(258, 22);
+ this.mnuShowCodeNotes.Text = "Show Byte Code";
+ this.mnuShowCodeNotes.Click += new System.EventHandler(this.mnuShowCodeNotes_Click);
+ //
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
@@ -127,19 +135,13 @@
this.ctrlCodeViewer.FontSize = 13F;
this.ctrlCodeViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlCodeViewer.Name = "ctrlCodeViewer";
+ this.ctrlCodeViewer.ShowContentNotes = false;
+ this.ctrlCodeViewer.ShowLineNumberNotes = false;
this.ctrlCodeViewer.Size = new System.Drawing.Size(379, 218);
this.ctrlCodeViewer.TabIndex = 1;
this.ctrlCodeViewer.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseUp);
this.ctrlCodeViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseMove);
//
- // mnuShowCodeNotes
- //
- this.mnuShowCodeNotes.CheckOnClick = true;
- this.mnuShowCodeNotes.Name = "mnuShowCodeNotes";
- this.mnuShowCodeNotes.Size = new System.Drawing.Size(258, 22);
- this.mnuShowCodeNotes.Text = "Show Byte Code";
- this.mnuShowCodeNotes.Click += new System.EventHandler(this.mnuShowCodeNotes_Click);
- //
// ctrlDebuggerCode
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
diff --git a/GUI.NET/Debugger/frmBreakpoint.Designer.cs b/GUI.NET/Debugger/frmBreakpoint.Designer.cs
index 2064de07..edf642f8 100644
--- a/GUI.NET/Debugger/frmBreakpoint.Designer.cs
+++ b/GUI.NET/Debugger/frmBreakpoint.Designer.cs
@@ -27,22 +27,44 @@
///
private void InitializeComponent()
{
+ this.components = new System.ComponentModel.Container();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblBreakOn = new System.Windows.Forms.Label();
this.lblAddress = new System.Windows.Forms.Label();
- this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
- this.radTypeExecute = new System.Windows.Forms.RadioButton();
- this.radTypeRead = new System.Windows.Forms.RadioButton();
- this.radTypeWrite = new System.Windows.Forms.RadioButton();
- this.txtAddress = new System.Windows.Forms.TextBox();
this.chkEnabled = new System.Windows.Forms.CheckBox();
+ this.lblCondition = new System.Windows.Forms.Label();
+ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.picHelp = new System.Windows.Forms.PictureBox();
+ this.txtCondition = new System.Windows.Forms.TextBox();
+ this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
+ this.txtAddress = new System.Windows.Forms.TextBox();
+ this.chkAbsolute = new System.Windows.Forms.CheckBox();
+ this.radSpecificAddress = new System.Windows.Forms.RadioButton();
+ this.radAnyAddress = new System.Windows.Forms.RadioButton();
+ this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
+ this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
+ this.chkReadVram = new System.Windows.Forms.CheckBox();
+ this.chkWriteVram = new System.Windows.Forms.CheckBox();
+ this.radCpu = new System.Windows.Forms.RadioButton();
+ this.radPpu = new System.Windows.Forms.RadioButton();
+ this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
+ this.chkRead = new System.Windows.Forms.CheckBox();
+ this.chkWrite = new System.Windows.Forms.CheckBox();
+ this.chkExec = new System.Windows.Forms.CheckBox();
+ this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.tableLayoutPanel1.SuspendLayout();
+ this.tableLayoutPanel2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picHelp)).BeginInit();
+ this.tableLayoutPanel3.SuspendLayout();
+ this.tableLayoutPanel4.SuspendLayout();
+ this.flowLayoutPanel3.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
- this.baseConfigPanel.Location = new System.Drawing.Point(0, 142);
+ this.baseConfigPanel.Location = new System.Drawing.Point(0, 151);
+ this.baseConfigPanel.Size = new System.Drawing.Size(378, 29);
//
// tableLayoutPanel1
//
@@ -51,18 +73,22 @@
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lblBreakOn, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 1);
- this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 0);
- this.tableLayoutPanel1.Controls.Add(this.txtAddress, 1, 1);
- this.tableLayoutPanel1.Controls.Add(this.chkEnabled, 0, 2);
+ this.tableLayoutPanel1.Controls.Add(this.chkEnabled, 0, 3);
+ this.tableLayoutPanel1.Controls.Add(this.lblCondition, 0, 2);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 2);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 1, 1);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel4, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
- this.tableLayoutPanel1.RowCount = 4;
+ this.tableLayoutPanel1.RowCount = 5;
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());
- this.tableLayoutPanel1.Size = new System.Drawing.Size(327, 142);
+ 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(378, 180);
this.tableLayoutPanel1.TabIndex = 2;
//
// lblBreakOn
@@ -77,94 +103,286 @@
//
// lblAddress
//
- this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
- this.lblAddress.Location = new System.Drawing.Point(3, 76);
+ this.lblAddress.Location = new System.Drawing.Point(3, 51);
+ this.lblAddress.Margin = new System.Windows.Forms.Padding(3, 5, 3, 0);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(48, 13);
this.lblAddress.TabIndex = 3;
this.lblAddress.Text = "Address:";
//
- // flowLayoutPanel2
- //
- this.flowLayoutPanel2.Controls.Add(this.radTypeExecute);
- this.flowLayoutPanel2.Controls.Add(this.radTypeRead);
- this.flowLayoutPanel2.Controls.Add(this.radTypeWrite);
- this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
- this.flowLayoutPanel2.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
- this.flowLayoutPanel2.Location = new System.Drawing.Point(59, 0);
- this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
- this.flowLayoutPanel2.Name = "flowLayoutPanel2";
- this.flowLayoutPanel2.Size = new System.Drawing.Size(268, 70);
- this.flowLayoutPanel2.TabIndex = 4;
- //
- // radTypeExecute
- //
- this.radTypeExecute.AutoSize = true;
- this.radTypeExecute.Location = new System.Drawing.Point(3, 3);
- this.radTypeExecute.Name = "radTypeExecute";
- this.radTypeExecute.Size = new System.Drawing.Size(72, 17);
- this.radTypeExecute.TabIndex = 0;
- this.radTypeExecute.TabStop = true;
- this.radTypeExecute.Text = "Execution";
- this.radTypeExecute.UseVisualStyleBackColor = true;
- //
- // radTypeRead
- //
- this.radTypeRead.AutoSize = true;
- this.radTypeRead.Location = new System.Drawing.Point(3, 26);
- this.radTypeRead.Name = "radTypeRead";
- this.radTypeRead.Size = new System.Drawing.Size(51, 17);
- this.radTypeRead.TabIndex = 1;
- this.radTypeRead.TabStop = true;
- this.radTypeRead.Text = "Read";
- this.radTypeRead.UseVisualStyleBackColor = true;
- //
- // radTypeWrite
- //
- this.radTypeWrite.AutoSize = true;
- this.radTypeWrite.Location = new System.Drawing.Point(3, 49);
- this.radTypeWrite.Name = "radTypeWrite";
- this.radTypeWrite.Size = new System.Drawing.Size(50, 17);
- this.radTypeWrite.TabIndex = 2;
- this.radTypeWrite.TabStop = true;
- this.radTypeWrite.Text = "Write";
- this.radTypeWrite.UseVisualStyleBackColor = true;
- //
- // txtAddress
- //
- this.txtAddress.Dock = System.Windows.Forms.DockStyle.Fill;
- this.txtAddress.Location = new System.Drawing.Point(62, 73);
- this.txtAddress.Name = "txtAddress";
- this.txtAddress.Size = new System.Drawing.Size(262, 20);
- this.txtAddress.TabIndex = 5;
- //
// chkEnabled
//
this.chkEnabled.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.chkEnabled, 2);
- this.chkEnabled.Location = new System.Drawing.Point(3, 99);
+ this.chkEnabled.Location = new System.Drawing.Point(3, 123);
this.chkEnabled.Name = "chkEnabled";
this.chkEnabled.Size = new System.Drawing.Size(65, 17);
this.chkEnabled.TabIndex = 2;
this.chkEnabled.Text = "Enabled";
this.chkEnabled.UseVisualStyleBackColor = true;
//
+ // lblCondition
+ //
+ this.lblCondition.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblCondition.AutoSize = true;
+ this.lblCondition.Location = new System.Drawing.Point(3, 100);
+ this.lblCondition.Name = "lblCondition";
+ this.lblCondition.Size = new System.Drawing.Size(54, 13);
+ this.lblCondition.TabIndex = 7;
+ this.lblCondition.Text = "Condition:";
+ //
+ // tableLayoutPanel2
+ //
+ this.tableLayoutPanel2.ColumnCount = 2;
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel2.Controls.Add(this.picHelp, 1, 0);
+ this.tableLayoutPanel2.Controls.Add(this.txtCondition, 0, 0);
+ this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel2.Location = new System.Drawing.Point(60, 94);
+ this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
+ this.tableLayoutPanel2.Name = "tableLayoutPanel2";
+ this.tableLayoutPanel2.RowCount = 1;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(318, 26);
+ this.tableLayoutPanel2.TabIndex = 10;
+ //
+ // picHelp
+ //
+ this.picHelp.Image = global::Mesen.GUI.Properties.Resources.help;
+ this.picHelp.Location = new System.Drawing.Point(297, 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, 18);
+ this.picHelp.TabIndex = 8;
+ this.picHelp.TabStop = false;
+ //
+ // txtCondition
+ //
+ this.txtCondition.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtCondition.Location = new System.Drawing.Point(3, 3);
+ this.txtCondition.MaxLength = 900;
+ this.txtCondition.Name = "txtCondition";
+ this.txtCondition.Size = new System.Drawing.Size(288, 20);
+ this.txtCondition.TabIndex = 6;
+ //
+ // tableLayoutPanel3
+ //
+ this.tableLayoutPanel3.ColumnCount = 3;
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel3.Controls.Add(this.txtAddress, 1, 0);
+ this.tableLayoutPanel3.Controls.Add(this.chkAbsolute, 2, 0);
+ this.tableLayoutPanel3.Controls.Add(this.radSpecificAddress, 0, 0);
+ this.tableLayoutPanel3.Controls.Add(this.radAnyAddress, 0, 1);
+ this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel3.Location = new System.Drawing.Point(60, 46);
+ this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
+ this.tableLayoutPanel3.Name = "tableLayoutPanel3";
+ this.tableLayoutPanel3.RowCount = 2;
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel3.Size = new System.Drawing.Size(318, 48);
+ this.tableLayoutPanel3.TabIndex = 11;
+ //
+ // txtAddress
+ //
+ this.txtAddress.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtAddress.Location = new System.Drawing.Point(75, 3);
+ this.txtAddress.Name = "txtAddress";
+ this.txtAddress.Size = new System.Drawing.Size(167, 20);
+ this.txtAddress.TabIndex = 5;
+ this.txtAddress.Enter += new System.EventHandler(this.txtAddress_Enter);
+ //
+ // chkAbsolute
+ //
+ this.chkAbsolute.AutoSize = true;
+ this.chkAbsolute.Location = new System.Drawing.Point(248, 5);
+ this.chkAbsolute.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
+ this.chkAbsolute.Name = "chkAbsolute";
+ this.chkAbsolute.Size = new System.Drawing.Size(67, 17);
+ this.chkAbsolute.TabIndex = 6;
+ this.chkAbsolute.Text = "Absolute";
+ this.chkAbsolute.UseVisualStyleBackColor = true;
+ this.chkAbsolute.Enter += new System.EventHandler(this.txtAddress_Enter);
+ //
+ // radSpecificAddress
+ //
+ this.radSpecificAddress.AutoSize = true;
+ this.radSpecificAddress.Location = new System.Drawing.Point(3, 3);
+ this.radSpecificAddress.Name = "radSpecificAddress";
+ this.radSpecificAddress.Size = new System.Drawing.Size(66, 17);
+ this.radSpecificAddress.TabIndex = 7;
+ this.radSpecificAddress.TabStop = true;
+ this.radSpecificAddress.Text = "Specific:";
+ this.radSpecificAddress.UseVisualStyleBackColor = true;
+ //
+ // radAnyAddress
+ //
+ this.radAnyAddress.AutoSize = true;
+ this.radAnyAddress.Location = new System.Drawing.Point(3, 29);
+ this.radAnyAddress.Name = "radAnyAddress";
+ this.radAnyAddress.Size = new System.Drawing.Size(43, 17);
+ this.radAnyAddress.TabIndex = 8;
+ this.radAnyAddress.TabStop = true;
+ this.radAnyAddress.Text = "Any";
+ this.radAnyAddress.UseVisualStyleBackColor = true;
+ //
+ // tableLayoutPanel4
+ //
+ this.tableLayoutPanel4.ColumnCount = 2;
+ 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.Controls.Add(this.flowLayoutPanel3, 1, 1);
+ this.tableLayoutPanel4.Controls.Add(this.radCpu, 0, 0);
+ this.tableLayoutPanel4.Controls.Add(this.radPpu, 0, 1);
+ this.tableLayoutPanel4.Controls.Add(this.flowLayoutPanel2, 1, 0);
+ this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel4.Location = new System.Drawing.Point(60, 0);
+ this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
+ this.tableLayoutPanel4.Name = "tableLayoutPanel4";
+ this.tableLayoutPanel4.RowCount = 2;
+ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel4.Size = new System.Drawing.Size(318, 46);
+ this.tableLayoutPanel4.TabIndex = 12;
+ //
+ // flowLayoutPanel3
+ //
+ this.flowLayoutPanel3.Controls.Add(this.chkReadVram);
+ this.flowLayoutPanel3.Controls.Add(this.chkWriteVram);
+ this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel3.Location = new System.Drawing.Point(56, 23);
+ this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel3.Name = "flowLayoutPanel3";
+ this.flowLayoutPanel3.Size = new System.Drawing.Size(262, 23);
+ this.flowLayoutPanel3.TabIndex = 5;
+ //
+ // chkReadVram
+ //
+ this.chkReadVram.AutoSize = true;
+ this.chkReadVram.Location = new System.Drawing.Point(3, 3);
+ this.chkReadVram.Name = "chkReadVram";
+ this.chkReadVram.Size = new System.Drawing.Size(52, 17);
+ this.chkReadVram.TabIndex = 4;
+ this.chkReadVram.Text = "Read";
+ this.chkReadVram.UseVisualStyleBackColor = true;
+ this.chkReadVram.Enter += new System.EventHandler(this.chkWriteVram_Enter);
+ //
+ // chkWriteVram
+ //
+ this.chkWriteVram.AutoSize = true;
+ this.chkWriteVram.Location = new System.Drawing.Point(61, 3);
+ this.chkWriteVram.Name = "chkWriteVram";
+ this.chkWriteVram.Size = new System.Drawing.Size(51, 17);
+ this.chkWriteVram.TabIndex = 5;
+ this.chkWriteVram.Text = "Write";
+ this.chkWriteVram.UseVisualStyleBackColor = true;
+ this.chkWriteVram.Enter += new System.EventHandler(this.chkWriteVram_Enter);
+ //
+ // radCpu
+ //
+ this.radCpu.AutoSize = true;
+ this.radCpu.Location = new System.Drawing.Point(3, 3);
+ this.radCpu.Name = "radCpu";
+ this.radCpu.Size = new System.Drawing.Size(50, 17);
+ this.radCpu.TabIndex = 0;
+ this.radCpu.TabStop = true;
+ this.radCpu.Text = "CPU:";
+ this.radCpu.UseVisualStyleBackColor = true;
+ this.radCpu.CheckedChanged += new System.EventHandler(this.radCpu_CheckedChanged);
+ //
+ // radPpu
+ //
+ this.radPpu.AutoSize = true;
+ this.radPpu.Location = new System.Drawing.Point(3, 26);
+ this.radPpu.Name = "radPpu";
+ this.radPpu.Size = new System.Drawing.Size(50, 17);
+ this.radPpu.TabIndex = 1;
+ this.radPpu.TabStop = true;
+ this.radPpu.Text = "PPU:";
+ this.radPpu.UseVisualStyleBackColor = true;
+ this.radPpu.CheckedChanged += new System.EventHandler(this.radPpu_CheckedChanged);
+ //
+ // flowLayoutPanel2
+ //
+ this.flowLayoutPanel2.Controls.Add(this.chkRead);
+ this.flowLayoutPanel2.Controls.Add(this.chkWrite);
+ this.flowLayoutPanel2.Controls.Add(this.chkExec);
+ this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel2.Location = new System.Drawing.Point(56, 0);
+ this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel2.Name = "flowLayoutPanel2";
+ this.flowLayoutPanel2.Size = new System.Drawing.Size(262, 23);
+ this.flowLayoutPanel2.TabIndex = 4;
+ //
+ // chkRead
+ //
+ this.chkRead.AutoSize = true;
+ this.chkRead.Location = new System.Drawing.Point(3, 3);
+ this.chkRead.Name = "chkRead";
+ this.chkRead.Size = new System.Drawing.Size(52, 17);
+ this.chkRead.TabIndex = 4;
+ this.chkRead.Text = "Read";
+ this.chkRead.UseVisualStyleBackColor = true;
+ this.chkRead.Enter += new System.EventHandler(this.chkRead_Enter);
+ //
+ // chkWrite
+ //
+ this.chkWrite.AutoSize = true;
+ this.chkWrite.Location = new System.Drawing.Point(61, 3);
+ this.chkWrite.Name = "chkWrite";
+ this.chkWrite.Size = new System.Drawing.Size(51, 17);
+ this.chkWrite.TabIndex = 5;
+ this.chkWrite.Text = "Write";
+ this.chkWrite.UseVisualStyleBackColor = true;
+ this.chkWrite.Enter += new System.EventHandler(this.chkRead_Enter);
+ //
+ // chkExec
+ //
+ this.chkExec.AutoSize = true;
+ this.chkExec.Location = new System.Drawing.Point(118, 3);
+ this.chkExec.Name = "chkExec";
+ this.chkExec.Size = new System.Drawing.Size(73, 17);
+ this.chkExec.TabIndex = 3;
+ this.chkExec.Text = "Execution";
+ this.chkExec.UseVisualStyleBackColor = true;
+ this.chkExec.Enter += new System.EventHandler(this.chkRead_Enter);
+ //
+ // toolTip
+ //
+ this.toolTip.AutomaticDelay = 0;
+ this.toolTip.AutoPopDelay = 32700;
+ this.toolTip.InitialDelay = 10;
+ this.toolTip.ReshowDelay = 10;
+ this.toolTip.UseFading = false;
+ //
// frmBreakpoint
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(327, 171);
+ this.ClientSize = new System.Drawing.Size(378, 180);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmBreakpoint";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Breakpoint";
- this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
+ this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
+ this.tableLayoutPanel2.ResumeLayout(false);
+ this.tableLayoutPanel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picHelp)).EndInit();
+ this.tableLayoutPanel3.ResumeLayout(false);
+ this.tableLayoutPanel3.PerformLayout();
+ this.tableLayoutPanel4.ResumeLayout(false);
+ this.tableLayoutPanel4.PerformLayout();
+ this.flowLayoutPanel3.ResumeLayout(false);
+ this.flowLayoutPanel3.PerformLayout();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
@@ -177,10 +395,25 @@
private System.Windows.Forms.Label lblBreakOn;
private System.Windows.Forms.Label lblAddress;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
- private System.Windows.Forms.RadioButton radTypeExecute;
- private System.Windows.Forms.RadioButton radTypeRead;
- private System.Windows.Forms.RadioButton radTypeWrite;
private System.Windows.Forms.TextBox txtAddress;
private System.Windows.Forms.CheckBox chkEnabled;
+ private System.Windows.Forms.TextBox txtCondition;
+ private System.Windows.Forms.Label lblCondition;
+ private System.Windows.Forms.PictureBox picHelp;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
+ private System.Windows.Forms.ToolTip toolTip;
+ private System.Windows.Forms.CheckBox chkExec;
+ private System.Windows.Forms.CheckBox chkRead;
+ private System.Windows.Forms.CheckBox chkWrite;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
+ private System.Windows.Forms.CheckBox chkAbsolute;
+ private System.Windows.Forms.RadioButton radSpecificAddress;
+ private System.Windows.Forms.RadioButton radAnyAddress;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
+ private System.Windows.Forms.CheckBox chkReadVram;
+ private System.Windows.Forms.CheckBox chkWriteVram;
+ private System.Windows.Forms.RadioButton radCpu;
+ private System.Windows.Forms.RadioButton radPpu;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Debugger/frmBreakpoint.cs b/GUI.NET/Debugger/frmBreakpoint.cs
index a6ca1389..9c453f19 100644
--- a/GUI.NET/Debugger/frmBreakpoint.cs
+++ b/GUI.NET/Debugger/frmBreakpoint.cs
@@ -19,23 +19,61 @@ namespace Mesen.GUI.Debugger
Entity = breakpoint;
- radTypeExecute.Tag = BreakpointType.Execute;
- radTypeRead.Tag = BreakpointType.Read;
- radTypeWrite.Tag = BreakpointType.Write;
+ if(breakpoint.Type >= BreakpointType.ReadVram) {
+ radPpu.Checked = true;
+ } else {
+ radCpu.Checked = true;
+ }
+ AddBinding("SpecificAddress", radSpecificAddress, radAnyAddress);
AddBinding("Enabled", chkEnabled);
+ AddBinding("IsAbsoluteAddress", chkAbsolute);
AddBinding("Address", txtAddress);
- AddBinding("Type", radTypeExecute.Parent);
+ AddBinding("BreakOnRead", chkRead);
+ AddBinding("BreakOnWrite", chkWrite);
+ AddBinding("BreakOnExec", chkExec);
+ AddBinding("BreakOnReadVram", chkReadVram);
+ AddBinding("BreakOnWriteVram", chkWriteVram);
+ 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.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 240) of the PPU" + Environment.NewLine + "Value: Current value being read/written from/to memory" + Environment.NewLine + Environment.NewLine + "Examples:" + Environment.NewLine + "a == 10 || x == $23" + Environment.NewLine + "scanline == 10 && (cycle >= 55 && cycle <= 100)");
}
- protected override void OnFormClosed(FormClosedEventArgs e)
+ protected override bool ValidateInput()
{
- if(DialogResult == System.Windows.Forms.DialogResult.OK) {
- ((Breakpoint)Entity).Remove();
+ return chkRead.Checked || chkWrite.Checked || chkExec.Checked || chkReadVram.Checked || chkWriteVram.Checked || txtCondition.Text.Length > 0;
+ }
+
+ private void txtAddress_Enter(object sender, EventArgs e)
+ {
+ radSpecificAddress.Checked = true;
+ }
+
+ private void chkWriteVram_Enter(object sender, EventArgs e)
+ {
+ radPpu.Checked = true;
+ }
+
+ private void chkRead_Enter(object sender, EventArgs e)
+ {
+ radCpu.Checked = true;
+ }
+
+ private void radCpu_CheckedChanged(object sender, EventArgs e)
+ {
+ if(radCpu.Checked) {
+ chkReadVram.Checked = false;
+ chkWriteVram.Checked = false;
}
- base.OnFormClosed(e);
- if(DialogResult == System.Windows.Forms.DialogResult.OK) {
- ((Breakpoint)Entity).Add();
+ }
+
+ private void radPpu_CheckedChanged(object sender, EventArgs e)
+ {
+ if(radPpu.Checked) {
+ chkRead.Checked = false;
+ chkWrite.Checked = false;
+ chkExec.Checked = false;
}
}
}
diff --git a/GUI.NET/Debugger/frmBreakpoint.resx b/GUI.NET/Debugger/frmBreakpoint.resx
index 1af7de15..8766f298 100644
--- a/GUI.NET/Debugger/frmBreakpoint.resx
+++ b/GUI.NET/Debugger/frmBreakpoint.resx
@@ -117,4 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 17, 17
+
\ No newline at end of file
diff --git a/GUI.NET/Debugger/frmDebugger.Designer.cs b/GUI.NET/Debugger/frmDebugger.Designer.cs
index 3ec71dd6..06a8ba13 100644
--- a/GUI.NET/Debugger/frmDebugger.Designer.cs
+++ b/GUI.NET/Debugger/frmDebugger.Designer.cs
@@ -34,13 +34,19 @@
this.components = new System.ComponentModel.Container();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.tlpTop = new System.Windows.Forms.TableLayoutPanel();
+ this.ctrlDebuggerCode = new Mesen.GUI.Debugger.ctrlDebuggerCode();
this.contextMenuCode = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuShowNextStatement = new System.Windows.Forms.ToolStripMenuItem();
this.mnuSetNextStatement = new System.Windows.Forms.ToolStripMenuItem();
+ this.ctrlConsoleStatus = new Mesen.GUI.Debugger.ctrlConsoleStatus();
+ this.ctrlDebuggerCodeSplit = new Mesen.GUI.Debugger.ctrlDebuggerCode();
this.tableLayoutPanel10 = new System.Windows.Forms.TableLayoutPanel();
this.grpWatch = new System.Windows.Forms.GroupBox();
+ this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
this.grpBreakpoints = new System.Windows.Forms.GroupBox();
+ this.ctrlBreakpoints = new Mesen.GUI.Debugger.Controls.ctrlBreakpoints();
this.grpCallstack = new System.Windows.Forms.GroupBox();
+ this.ctrlCallstack = new Mesen.GUI.Debugger.Controls.ctrlCallstack();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
@@ -70,26 +76,21 @@
this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuCodeDataLogger = new System.Windows.Forms.ToolStripMenuItem();
+ this.autoLoadsaveCDLFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
+ this.mnuLoadCdlFile = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuSaveAsCdlFile = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuResetCdlLog = new System.Windows.Forms.ToolStripMenuItem();
+ this.generateROMToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.saveStrippedDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.saveUnusedDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.lblPrgAnalysis = new System.Windows.Forms.ToolStripStatusLabel();
this.lblPrgAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel();
this.lblChrAnalysis = new System.Windows.Forms.ToolStripStatusLabel();
this.lblChrAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel();
this.tmrCdlRatios = new System.Windows.Forms.Timer(this.components);
- this.mnuResetCdlLog = new System.Windows.Forms.ToolStripMenuItem();
- this.autoLoadsaveCDLFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.generateROMToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.saveStrippedDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.saveUnusedDataToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
- this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
- this.mnuSaveAsCdlFile = new System.Windows.Forms.ToolStripMenuItem();
- this.mnuLoadCdlFile = new System.Windows.Forms.ToolStripMenuItem();
- this.ctrlDebuggerCode = new Mesen.GUI.Debugger.ctrlDebuggerCode();
- this.ctrlConsoleStatus = new Mesen.GUI.Debugger.ctrlConsoleStatus();
- this.ctrlDebuggerCodeSplit = new Mesen.GUI.Debugger.ctrlDebuggerCode();
- this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
- this.ctrlBreakpoints = new Mesen.GUI.Debugger.Controls.ctrlBreakpoints();
- this.ctrlCallstack = new Mesen.GUI.Debugger.Controls.ctrlCallstack();
+ this.mnuDisableEnableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
@@ -142,6 +143,19 @@
this.tlpTop.Size = new System.Drawing.Size(984, 412);
this.tlpTop.TabIndex = 2;
//
+ // ctrlDebuggerCode
+ //
+ this.ctrlDebuggerCode.Code = null;
+ this.ctrlDebuggerCode.ContextMenuStrip = this.contextMenuCode;
+ this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ctrlDebuggerCode.Location = new System.Drawing.Point(3, 3);
+ this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
+ this.ctrlDebuggerCode.Size = new System.Drawing.Size(546, 406);
+ this.ctrlDebuggerCode.TabIndex = 2;
+ this.ctrlDebuggerCode.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
+ this.ctrlDebuggerCode.OnSetNextStatement += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnSetNextStatement);
+ this.ctrlDebuggerCode.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
+ //
// contextMenuCode
//
this.contextMenuCode.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -166,6 +180,28 @@
this.mnuSetNextStatement.Size = new System.Drawing.Size(258, 22);
this.mnuSetNextStatement.Text = "Set Next Statement";
//
+ // ctrlConsoleStatus
+ //
+ this.ctrlConsoleStatus.Dock = System.Windows.Forms.DockStyle.Top;
+ this.ctrlConsoleStatus.Location = new System.Drawing.Point(552, 0);
+ this.ctrlConsoleStatus.Margin = new System.Windows.Forms.Padding(0);
+ this.ctrlConsoleStatus.Name = "ctrlConsoleStatus";
+ this.ctrlConsoleStatus.Size = new System.Drawing.Size(432, 362);
+ this.ctrlConsoleStatus.TabIndex = 3;
+ //
+ // ctrlDebuggerCodeSplit
+ //
+ this.ctrlDebuggerCodeSplit.Code = null;
+ this.ctrlDebuggerCodeSplit.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(555, 3);
+ this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
+ this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 406);
+ this.ctrlDebuggerCodeSplit.TabIndex = 4;
+ this.ctrlDebuggerCodeSplit.Visible = false;
+ this.ctrlDebuggerCodeSplit.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
+ this.ctrlDebuggerCodeSplit.OnSetNextStatement += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnSetNextStatement);
+ this.ctrlDebuggerCodeSplit.Enter += new System.EventHandler(this.ctrlDebuggerCodeSplit_Enter);
+ //
// tableLayoutPanel10
//
this.tableLayoutPanel10.ColumnCount = 3;
@@ -194,6 +230,14 @@
this.grpWatch.TabStop = false;
this.grpWatch.Text = "Watch";
//
+ // ctrlWatch
+ //
+ this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
+ this.ctrlWatch.Name = "ctrlWatch";
+ this.ctrlWatch.Size = new System.Drawing.Size(316, 123);
+ this.ctrlWatch.TabIndex = 0;
+ //
// grpBreakpoints
//
this.grpBreakpoints.Controls.Add(this.ctrlBreakpoints);
@@ -205,6 +249,15 @@
this.grpBreakpoints.TabStop = false;
this.grpBreakpoints.Text = "Breakpoints";
//
+ // ctrlBreakpoints
+ //
+ this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
+ this.ctrlBreakpoints.Name = "ctrlBreakpoints";
+ this.ctrlBreakpoints.Size = new System.Drawing.Size(316, 123);
+ this.ctrlBreakpoints.TabIndex = 0;
+ this.ctrlBreakpoints.BreakpointChanged += new System.EventHandler(this.ctrlBreakpoints_BreakpointChanged);
+ //
// grpCallstack
//
this.grpCallstack.Controls.Add(this.ctrlCallstack);
@@ -216,6 +269,15 @@
this.grpCallstack.TabStop = false;
this.grpCallstack.Text = "Callstack";
//
+ // ctrlCallstack
+ //
+ this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ctrlCallstack.Location = new System.Drawing.Point(3, 16);
+ this.ctrlCallstack.Name = "ctrlCallstack";
+ this.ctrlCallstack.Size = new System.Drawing.Size(316, 123);
+ this.ctrlCallstack.TabIndex = 0;
+ this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected);
+ //
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -315,6 +377,7 @@
this.mnuStepOut,
this.toolStripMenuItem1,
this.mnuToggleBreakpoint,
+ this.mnuDisableEnableBreakpoint,
this.toolStripMenuItem2,
this.mnuRunOneFrame});
this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
@@ -325,7 +388,7 @@
//
this.mnuContinue.Name = "mnuContinue";
this.mnuContinue.ShortcutKeys = System.Windows.Forms.Keys.F5;
- this.mnuContinue.Size = new System.Drawing.Size(190, 22);
+ this.mnuContinue.Size = new System.Drawing.Size(258, 22);
this.mnuContinue.Text = "Continue";
this.mnuContinue.Click += new System.EventHandler(this.mnuContinue_Click);
//
@@ -335,7 +398,7 @@
this.mnuBreak.ShortcutKeyDisplayString = "Ctrl+Alt+Break";
this.mnuBreak.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Alt)
| System.Windows.Forms.Keys.Cancel)));
- this.mnuBreak.Size = new System.Drawing.Size(190, 22);
+ this.mnuBreak.Size = new System.Drawing.Size(258, 22);
this.mnuBreak.Text = "Break";
this.mnuBreak.Click += new System.EventHandler(this.mnuBreak_Click);
//
@@ -343,7 +406,7 @@
//
this.mnuStepInto.Name = "mnuStepInto";
this.mnuStepInto.ShortcutKeys = System.Windows.Forms.Keys.F11;
- this.mnuStepInto.Size = new System.Drawing.Size(190, 22);
+ this.mnuStepInto.Size = new System.Drawing.Size(258, 22);
this.mnuStepInto.Text = "Step Into";
this.mnuStepInto.Click += new System.EventHandler(this.mnuStepInto_Click);
//
@@ -351,7 +414,7 @@
//
this.mnuStepOver.Name = "mnuStepOver";
this.mnuStepOver.ShortcutKeys = System.Windows.Forms.Keys.F10;
- this.mnuStepOver.Size = new System.Drawing.Size(190, 22);
+ this.mnuStepOver.Size = new System.Drawing.Size(258, 22);
this.mnuStepOver.Text = "Step Over";
this.mnuStepOver.Click += new System.EventHandler(this.mnuStepOver_Click);
//
@@ -359,33 +422,33 @@
//
this.mnuStepOut.Name = "mnuStepOut";
this.mnuStepOut.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.F11)));
- this.mnuStepOut.Size = new System.Drawing.Size(190, 22);
+ this.mnuStepOut.Size = new System.Drawing.Size(258, 22);
this.mnuStepOut.Text = "Step Out";
this.mnuStepOut.Click += new System.EventHandler(this.mnuStepOut_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
- this.toolStripMenuItem1.Size = new System.Drawing.Size(187, 6);
+ this.toolStripMenuItem1.Size = new System.Drawing.Size(255, 6);
//
// mnuToggleBreakpoint
//
this.mnuToggleBreakpoint.Name = "mnuToggleBreakpoint";
this.mnuToggleBreakpoint.ShortcutKeys = System.Windows.Forms.Keys.F9;
- this.mnuToggleBreakpoint.Size = new System.Drawing.Size(190, 22);
+ this.mnuToggleBreakpoint.Size = new System.Drawing.Size(258, 22);
this.mnuToggleBreakpoint.Text = "Toggle Breakpoint";
this.mnuToggleBreakpoint.Click += new System.EventHandler(this.mnuToggleBreakpoint_Click);
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
- this.toolStripMenuItem2.Size = new System.Drawing.Size(187, 6);
+ this.toolStripMenuItem2.Size = new System.Drawing.Size(255, 6);
//
// mnuRunOneFrame
//
this.mnuRunOneFrame.Name = "mnuRunOneFrame";
this.mnuRunOneFrame.ShortcutKeys = System.Windows.Forms.Keys.F12;
- this.mnuRunOneFrame.Size = new System.Drawing.Size(190, 22);
+ this.mnuRunOneFrame.Size = new System.Drawing.Size(258, 22);
this.mnuRunOneFrame.Text = "Run one frame";
this.mnuRunOneFrame.Click += new System.EventHandler(this.mnuRunOneFrame_Click);
//
@@ -469,6 +532,63 @@
this.mnuCodeDataLogger.Size = new System.Drawing.Size(171, 22);
this.mnuCodeDataLogger.Text = "Code/Data Logger";
//
+ // autoLoadsaveCDLFileToolStripMenuItem
+ //
+ this.autoLoadsaveCDLFileToolStripMenuItem.Checked = true;
+ this.autoLoadsaveCDLFileToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.autoLoadsaveCDLFileToolStripMenuItem.Enabled = false;
+ this.autoLoadsaveCDLFileToolStripMenuItem.Name = "autoLoadsaveCDLFileToolStripMenuItem";
+ this.autoLoadsaveCDLFileToolStripMenuItem.Size = new System.Drawing.Size(193, 22);
+ this.autoLoadsaveCDLFileToolStripMenuItem.Text = "Auto load/save log file";
+ //
+ // toolStripMenuItem4
+ //
+ this.toolStripMenuItem4.Name = "toolStripMenuItem4";
+ this.toolStripMenuItem4.Size = new System.Drawing.Size(190, 6);
+ //
+ // mnuLoadCdlFile
+ //
+ this.mnuLoadCdlFile.Name = "mnuLoadCdlFile";
+ this.mnuLoadCdlFile.Size = new System.Drawing.Size(193, 22);
+ this.mnuLoadCdlFile.Text = "Load CDL file...";
+ this.mnuLoadCdlFile.Click += new System.EventHandler(this.mnuLoadCdlFile_Click);
+ //
+ // mnuSaveAsCdlFile
+ //
+ this.mnuSaveAsCdlFile.Name = "mnuSaveAsCdlFile";
+ this.mnuSaveAsCdlFile.Size = new System.Drawing.Size(193, 22);
+ this.mnuSaveAsCdlFile.Text = "Save as CDL file...";
+ this.mnuSaveAsCdlFile.Click += new System.EventHandler(this.mnuSaveAsCdlFile_Click);
+ //
+ // mnuResetCdlLog
+ //
+ this.mnuResetCdlLog.Name = "mnuResetCdlLog";
+ this.mnuResetCdlLog.Size = new System.Drawing.Size(193, 22);
+ this.mnuResetCdlLog.Text = "Reset log";
+ this.mnuResetCdlLog.Click += new System.EventHandler(this.mnuResetCdlLog_Click);
+ //
+ // generateROMToolStripMenuItem
+ //
+ this.generateROMToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.saveStrippedDataToolStripMenuItem,
+ this.saveUnusedDataToolStripMenuItem});
+ this.generateROMToolStripMenuItem.Enabled = false;
+ this.generateROMToolStripMenuItem.Name = "generateROMToolStripMenuItem";
+ this.generateROMToolStripMenuItem.Size = new System.Drawing.Size(193, 22);
+ this.generateROMToolStripMenuItem.Text = "Generate ROM";
+ //
+ // saveStrippedDataToolStripMenuItem
+ //
+ this.saveStrippedDataToolStripMenuItem.Name = "saveStrippedDataToolStripMenuItem";
+ this.saveStrippedDataToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
+ this.saveStrippedDataToolStripMenuItem.Text = "Save stripped data";
+ //
+ // saveUnusedDataToolStripMenuItem
+ //
+ this.saveUnusedDataToolStripMenuItem.Name = "saveUnusedDataToolStripMenuItem";
+ this.saveUnusedDataToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
+ this.saveUnusedDataToolStripMenuItem.Text = "Save unused data";
+ //
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -514,123 +634,13 @@
this.tmrCdlRatios.Interval = 300;
this.tmrCdlRatios.Tick += new System.EventHandler(this.tmrCdlRatios_Tick);
//
- // mnuResetCdlLog
+ // mnuDisableEnableBreakpoint
//
- this.mnuResetCdlLog.Name = "mnuResetCdlLog";
- this.mnuResetCdlLog.Size = new System.Drawing.Size(193, 22);
- this.mnuResetCdlLog.Text = "Reset log";
- this.mnuResetCdlLog.Click += new System.EventHandler(this.mnuResetCdlLog_Click);
- //
- // autoLoadsaveCDLFileToolStripMenuItem
- //
- this.autoLoadsaveCDLFileToolStripMenuItem.Checked = true;
- this.autoLoadsaveCDLFileToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
- this.autoLoadsaveCDLFileToolStripMenuItem.Enabled = false;
- this.autoLoadsaveCDLFileToolStripMenuItem.Name = "autoLoadsaveCDLFileToolStripMenuItem";
- this.autoLoadsaveCDLFileToolStripMenuItem.Size = new System.Drawing.Size(193, 22);
- this.autoLoadsaveCDLFileToolStripMenuItem.Text = "Auto load/save log file";
- //
- // generateROMToolStripMenuItem
- //
- this.generateROMToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
- this.saveStrippedDataToolStripMenuItem,
- this.saveUnusedDataToolStripMenuItem});
- this.generateROMToolStripMenuItem.Enabled = false;
- this.generateROMToolStripMenuItem.Name = "generateROMToolStripMenuItem";
- this.generateROMToolStripMenuItem.Size = new System.Drawing.Size(193, 22);
- this.generateROMToolStripMenuItem.Text = "Generate ROM";
- //
- // saveStrippedDataToolStripMenuItem
- //
- this.saveStrippedDataToolStripMenuItem.Name = "saveStrippedDataToolStripMenuItem";
- this.saveStrippedDataToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
- this.saveStrippedDataToolStripMenuItem.Text = "Save stripped data";
- //
- // saveUnusedDataToolStripMenuItem
- //
- this.saveUnusedDataToolStripMenuItem.Name = "saveUnusedDataToolStripMenuItem";
- this.saveUnusedDataToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
- this.saveUnusedDataToolStripMenuItem.Text = "Save unused data";
- //
- // toolStripMenuItem4
- //
- this.toolStripMenuItem4.Name = "toolStripMenuItem4";
- this.toolStripMenuItem4.Size = new System.Drawing.Size(190, 6);
- //
- // mnuSaveAsCdlFile
- //
- this.mnuSaveAsCdlFile.Name = "mnuSaveAsCdlFile";
- this.mnuSaveAsCdlFile.Size = new System.Drawing.Size(193, 22);
- this.mnuSaveAsCdlFile.Text = "Save as CDL file...";
- this.mnuSaveAsCdlFile.Click += new System.EventHandler(this.mnuSaveAsCdlFile_Click);
- //
- // mnuLoadCdlFile
- //
- this.mnuLoadCdlFile.Name = "mnuLoadCdlFile";
- this.mnuLoadCdlFile.Size = new System.Drawing.Size(193, 22);
- this.mnuLoadCdlFile.Text = "Load CDL file...";
- this.mnuLoadCdlFile.Click += new System.EventHandler(this.mnuLoadCdlFile_Click);
- //
- // ctrlDebuggerCode
- //
- this.ctrlDebuggerCode.Code = null;
- this.ctrlDebuggerCode.ContextMenuStrip = this.contextMenuCode;
- this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ctrlDebuggerCode.Location = new System.Drawing.Point(3, 3);
- this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
- this.ctrlDebuggerCode.Size = new System.Drawing.Size(546, 406);
- this.ctrlDebuggerCode.TabIndex = 2;
- this.ctrlDebuggerCode.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
- this.ctrlDebuggerCode.OnSetNextStatement += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnSetNextStatement);
- this.ctrlDebuggerCode.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
- //
- // ctrlConsoleStatus
- //
- this.ctrlConsoleStatus.Dock = System.Windows.Forms.DockStyle.Top;
- this.ctrlConsoleStatus.Location = new System.Drawing.Point(552, 0);
- this.ctrlConsoleStatus.Margin = new System.Windows.Forms.Padding(0);
- this.ctrlConsoleStatus.Name = "ctrlConsoleStatus";
- this.ctrlConsoleStatus.Size = new System.Drawing.Size(432, 362);
- this.ctrlConsoleStatus.TabIndex = 3;
- //
- // ctrlDebuggerCodeSplit
- //
- this.ctrlDebuggerCodeSplit.Code = null;
- this.ctrlDebuggerCodeSplit.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(555, 3);
- this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
- this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 406);
- this.ctrlDebuggerCodeSplit.TabIndex = 4;
- this.ctrlDebuggerCodeSplit.Visible = false;
- this.ctrlDebuggerCodeSplit.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
- this.ctrlDebuggerCodeSplit.OnSetNextStatement += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnSetNextStatement);
- this.ctrlDebuggerCodeSplit.Enter += new System.EventHandler(this.ctrlDebuggerCodeSplit_Enter);
- //
- // ctrlWatch
- //
- this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
- this.ctrlWatch.Name = "ctrlWatch";
- this.ctrlWatch.Size = new System.Drawing.Size(316, 123);
- this.ctrlWatch.TabIndex = 0;
- //
- // ctrlBreakpoints
- //
- this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
- this.ctrlBreakpoints.Name = "ctrlBreakpoints";
- this.ctrlBreakpoints.Size = new System.Drawing.Size(316, 123);
- this.ctrlBreakpoints.TabIndex = 0;
- this.ctrlBreakpoints.BreakpointChanged += new System.EventHandler(this.ctrlBreakpoints_BreakpointChanged);
- //
- // ctrlCallstack
- //
- this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ctrlCallstack.Location = new System.Drawing.Point(3, 16);
- this.ctrlCallstack.Name = "ctrlCallstack";
- this.ctrlCallstack.Size = new System.Drawing.Size(316, 123);
- this.ctrlCallstack.TabIndex = 0;
- this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected);
+ this.mnuDisableEnableBreakpoint.Name = "mnuDisableEnableBreakpoint";
+ this.mnuDisableEnableBreakpoint.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F9)));
+ this.mnuDisableEnableBreakpoint.Size = new System.Drawing.Size(258, 22);
+ this.mnuDisableEnableBreakpoint.Text = "Disable/Enable Breakpoint";
+ this.mnuDisableEnableBreakpoint.Click += new System.EventHandler(this.mnuDisableEnableBreakpoint_Click);
//
// frmDebugger
//
@@ -724,5 +734,6 @@
private System.Windows.Forms.ToolStripMenuItem generateROMToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveStrippedDataToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveUnusedDataToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem mnuDisableEnableBreakpoint;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Debugger/frmDebugger.cs b/GUI.NET/Debugger/frmDebugger.cs
index cf91edb1..76889d02 100644
--- a/GUI.NET/Debugger/frmDebugger.cs
+++ b/GUI.NET/Debugger/frmDebugger.cs
@@ -116,9 +116,9 @@ namespace Mesen.GUI.Debugger
RefreshBreakpoints();
}
- private void ToggleBreakpoint()
+ private void ToggleBreakpoint(bool toggleEnabled)
{
- ctrlBreakpoints.ToggleBreakpoint(_lastCodeWindow.GetCurrentLine());
+ ctrlBreakpoints.ToggleBreakpoint(_lastCodeWindow.GetCurrentLine(), toggleEnabled);
}
private void RefreshBreakpoints()
@@ -149,7 +149,12 @@ namespace Mesen.GUI.Debugger
private void mnuToggleBreakpoint_Click(object sender, EventArgs e)
{
- ToggleBreakpoint();
+ ToggleBreakpoint(false);
+ }
+
+ private void mnuDisableEnableBreakpoint_Click(object sender, EventArgs e)
+ {
+ ToggleBreakpoint(true);
}
private void mnuBreak_Click(object sender, EventArgs e)
diff --git a/GUI.NET/Forms/BaseConfigForm.cs b/GUI.NET/Forms/BaseConfigForm.cs
index bd0c7cff..d8934941 100644
--- a/GUI.NET/Forms/BaseConfigForm.cs
+++ b/GUI.NET/Forms/BaseConfigForm.cs
@@ -98,6 +98,12 @@ namespace Mesen.GUI.Forms
return true;
}
+ protected void AddBinding(string fieldName, RadioButton trueRadio, RadioButton falseRadio)
+ {
+ falseRadio.Checked = true;
+ AddBinding(fieldName, trueRadio);
+ }
+
protected void AddBinding(string fieldName, Control bindedField)
{
if(BindedType == null) {
@@ -145,6 +151,8 @@ namespace Mesen.GUI.Forms
}
} else if(kvp.Value is CheckBox) {
((CheckBox)kvp.Value).Checked = (bool)value;
+ } else if(kvp.Value is RadioButton) {
+ ((RadioButton)kvp.Value).Checked = (bool)value;
} else if(kvp.Value is Panel) {
RadioButton radio = kvp.Value.Controls.OfType().FirstOrDefault(r => r.Tag.Equals(value));
if(radio != null) {
@@ -192,6 +200,7 @@ namespace Mesen.GUI.Forms
if(kvp.Value is TextBox) {
object value = kvp.Value.Text;
if(field.FieldType == typeof(UInt32)) {
+ value = ((string)value).Trim().Replace("$", "").Replace("0x", "");
value = (object)UInt32.Parse((string)value, System.Globalization.NumberStyles.HexNumber);
} else if(field.FieldType == typeof(Byte)) {
value = (object)Byte.Parse((string)value, System.Globalization.NumberStyles.HexNumber);
@@ -199,6 +208,8 @@ namespace Mesen.GUI.Forms
field.SetValue(Entity, value);
} else if(kvp.Value is CheckBox) {
field.SetValue(Entity, ((CheckBox)kvp.Value).Checked);
+ } else if(kvp.Value is RadioButton) {
+ field.SetValue(Entity, ((RadioButton)kvp.Value).Checked);
} else if(kvp.Value is Panel) {
field.SetValue(Entity, kvp.Value.Controls.OfType().FirstOrDefault(r => r.Checked).Tag);
} else if(kvp.Value is ctrlTrackbar) {
diff --git a/GUI.NET/GUI.NET.csproj b/GUI.NET/GUI.NET.csproj
index 201464ea..45296969 100644
--- a/GUI.NET/GUI.NET.csproj
+++ b/GUI.NET/GUI.NET.csproj
@@ -415,6 +415,7 @@
+
diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs
index 52843fea..aa270a47 100644
--- a/GUI.NET/InteropEmu.cs
+++ b/GUI.NET/InteropEmu.cs
@@ -83,8 +83,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void DebugInitialize();
[DllImport(DLLPath)] public static extern void DebugRelease();
[DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state);
- [DllImport(DLLPath)] public static extern void DebugAddBreakpoint(BreakpointType type, UInt32 address, [MarshalAs(UnmanagedType.I1)]bool isAbsoluteAddr, [MarshalAs(UnmanagedType.I1)]bool enabled);
- [DllImport(DLLPath)] public static extern void DebugRemoveBreakpoint(BreakpointType type, UInt32 address, [MarshalAs(UnmanagedType.I1)]bool isAbsoluteAddr);
+ [DllImport(DLLPath)] public static extern void DebugSetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]InteropBreakpoint[] breakpoints, UInt32 length);
[DllImport(DLLPath)] public static extern void DebugStep(UInt32 count);
[DllImport(DLLPath)] public static extern void DebugStepCycles(UInt32 count);
[DllImport(DLLPath)] public static extern void DebugStepOut();
@@ -424,12 +423,28 @@ namespace Mesen.GUI
Mmc3IrqAltBehavior = 0x8000,
}
+
+ public struct InteropBreakpoint
+ {
+ public BreakpointType Type;
+ public Int32 Address;
+
+ [MarshalAs(UnmanagedType.I1)]
+ public bool IsAbsoluteAddress;
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
+ public byte[] Condition;
+ }
+
+ [Flags]
public enum BreakpointType
{
- Execute = 0,
- Read = 1,
- Write = 2
+ Global = 0,
+ Execute = 1,
+ Read = 2,
+ Write = 4,
+ ReadVram = 8,
+ WriteVram = 16
};
public enum NesModel
diff --git a/GUI.NET/Properties/Resources.Designer.cs b/GUI.NET/Properties/Resources.Designer.cs
index 1d54d584..1b9930d9 100644
--- a/GUI.NET/Properties/Resources.Designer.cs
+++ b/GUI.NET/Properties/Resources.Designer.cs
@@ -70,6 +70,16 @@ namespace Mesen.GUI.Properties {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap help {
+ get {
+ object obj = ResourceManager.GetObject("help", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
///
diff --git a/GUI.NET/Properties/Resources.resx b/GUI.NET/Properties/Resources.resx
index c9368818..44b6fc04 100644
--- a/GUI.NET/Properties/Resources.resx
+++ b/GUI.NET/Properties/Resources.resx
@@ -121,6 +121,9 @@
..\resources\close.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\help.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
..\Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
diff --git a/GUI.NET/Resources/help.png b/GUI.NET/Resources/help.png
new file mode 100644
index 00000000..dd83ee06
Binary files /dev/null and b/GUI.NET/Resources/help.png differ
diff --git a/InteropDLL/DebugWrapper.cpp b/InteropDLL/DebugWrapper.cpp
index 0950c635..f06b9f17 100644
--- a/InteropDLL/DebugWrapper.cpp
+++ b/InteropDLL/DebugWrapper.cpp
@@ -28,8 +28,7 @@ extern "C"
DllExport void __stdcall DebugGetState(DebugState *state) { GetDebugger()->GetState(state); }
- DllExport void __stdcall DebugAddBreakpoint(uint32_t type, uint32_t address, bool isAbsoluteAddr, bool enabled) { GetDebugger()->AddBreakpoint((BreakpointType)type, address, isAbsoluteAddr, enabled); }
- DllExport void __stdcall DebugRemoveBreakpoint(uint32_t type, uint32_t address, bool isAbsoluteAddr) { GetDebugger()->RemoveBreakpoint((BreakpointType)type, address, isAbsoluteAddr); }
+ DllExport void __stdcall DebugSetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->SetBreakpoints(breakpoints, length); }
DllExport void __stdcall DebugRun() { GetDebugger()->Run(); }
DllExport void __stdcall DebugStep(uint32_t count) { GetDebugger()->Step(count); }
diff --git a/Utilities/SimpleLock.cpp b/Utilities/SimpleLock.cpp
index 21a0338d..e263857a 100644
--- a/Utilities/SimpleLock.cpp
+++ b/Utilities/SimpleLock.cpp
@@ -25,6 +25,11 @@ uint32_t SimpleLock::GetThreadId()
#endif
}
+LockHandler SimpleLock::AcquireSafe()
+{
+ return LockHandler(this);
+}
+
void SimpleLock::Acquire()
{
if(_lockCount == 0 || _holderThreadID != GetThreadId()) {
@@ -64,4 +69,16 @@ void SimpleLock::Release()
} else {
assert(false);
}
+}
+
+
+LockHandler::LockHandler(SimpleLock *lock)
+{
+ _lock = lock;
+ _lock->Acquire();
+}
+
+LockHandler::~LockHandler()
+{
+ _lock->Release();
}
\ No newline at end of file
diff --git a/Utilities/SimpleLock.h b/Utilities/SimpleLock.h
index 78d836d4..09d6cd1c 100644
--- a/Utilities/SimpleLock.h
+++ b/Utilities/SimpleLock.h
@@ -1,6 +1,17 @@
#pragma once
#include "stdafx.h"
+class SimpleLock;
+
+class LockHandler
+{
+private:
+ SimpleLock *_lock;
+public:
+ LockHandler(SimpleLock *lock);
+ ~LockHandler();
+};
+
class SimpleLock
{
private:
@@ -13,6 +24,9 @@ private:
public:
SimpleLock();
~SimpleLock();
+
+ LockHandler AcquireSafe();
+
void Acquire();
bool IsFree();
void WaitForRelease();