Debugger breakpoint improvements (Conditional breaks, vram breaks, absolute address breaks, etc.)

This commit is contained in:
Souryo 2016-01-09 13:15:43 -05:00
parent 056c71abd5
commit a0d6e2d547
28 changed files with 1282 additions and 415 deletions

View file

@ -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));
}

View file

@ -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];
};

View file

@ -271,6 +271,7 @@
<ClInclude Include="BF909x.h" />
<ClInclude Include="BnRom.h" />
<ClInclude Include="DefaultVideoFilter.h" />
<ClInclude Include="ExpressionEvaluator.h" />
<ClInclude Include="HdVideoFilter.h" />
<ClInclude Include="Namco108.h" />
<ClInclude Include="Namco108_154.h" />
@ -379,6 +380,7 @@
<ClCompile Include="Disassembler.cpp" />
<ClCompile Include="DisassemblyInfo.cpp" />
<ClCompile Include="EmulationSettings.cpp" />
<ClCompile Include="ExpressionEvaluator.cpp" />
<ClCompile Include="GameClient.cpp" />
<ClCompile Include="GameClientConnection.cpp" />
<ClCompile Include="GameConnection.cpp" />

View file

@ -332,6 +332,9 @@
<ClInclude Include="HdVideoFilter.h">
<Filter>VideoDecoder\HD</Filter>
</ClInclude>
<ClInclude Include="ExpressionEvaluator.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -436,5 +439,8 @@
<ClCompile Include="HdVideoFilter.cpp">
<Filter>VideoDecoder\HD</Filter>
</ClCompile>
<ClCompile Include="ExpressionEvaluator.cpp">
<Filter>Debugger</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -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();
ExpressionEvaluator expEval;
for(uint32_t i = 0; i < length; i++) {
Breakpoint& bp = breakpoints[i];
if(!expEval.Validate(bp.GetCondition())) {
//Remove any invalid condition (syntax-wise)
bp.ClearCondition();
}
shared_ptr<Breakpoint> 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;
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();
}
void Debugger::RemoveBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr)
{
_bpLock.Acquire();
vector<shared_ptr<Breakpoint>> *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> breakpoint = GetMatchingBreakpoint(type, address);
for(size_t i = 0, len = breakpoints->size(); i < len; i++) {
shared_ptr<Breakpoint> breakpoint = (*breakpoints)[i];
if(breakpoint->GetAddr() == address && breakpoint->IsAbsoluteAddr() == isAbsoluteAddr) {
breakpoints->erase(breakpoints->begin() + i);
break;
}
}
_bpLock.Release();
}
shared_ptr<Breakpoint> 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<shared_ptr<Breakpoint>> *breakpoints = nullptr;
vector<Breakpoint> *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;
}
_bpLock.Acquire();
DebugState state;
GetState(&state);
_bpLock.AcquireSafe();
for(size_t i = 0, len = breakpoints->size(); i < len; i++) {
shared_ptr<Breakpoint> 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<Breakpoint>();
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;
_breakLock.AcquireSafe();
default:
case MemoryOperationType::ExecOpCode:
case MemoryOperationType::ExecOperand: breakpointType = BreakpointType::Execute; break;
}
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)
{
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);
}
}

View file

@ -45,9 +45,14 @@ private:
shared_ptr<PPU> _ppu;
shared_ptr<MemoryManager> _memoryManager;
shared_ptr<BaseMapper> _mapper;
vector<shared_ptr<Breakpoint>> _readBreakpoints;
vector<shared_ptr<Breakpoint>> _writeBreakpoints;
vector<shared_ptr<Breakpoint>> _execBreakpoints;
vector<Breakpoint> _readBreakpoints;
vector<Breakpoint> _writeBreakpoints;
vector<Breakpoint> _execBreakpoints;
vector<Breakpoint> _globalBreakpoints;
vector<Breakpoint> _readVramBreakpoints;
vector<Breakpoint> _writeVramBreakpoints;
deque<uint32_t> _callstackAbsolute;
deque<uint32_t> _callstackRelative;
@ -65,22 +70,20 @@ private:
atomic<int32_t> _stepOverAddr;
private:
void PrivateProcessRamOperation(MemoryOperationType type, uint16_t &addr);
void PrivateProcessVramOperation(MemoryOperationType type, uint16_t addr);
shared_ptr<Breakpoint> 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> console, shared_ptr<CPU> cpu, shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper);
~Debugger();
void AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr, bool enabled);
void RemoveBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr);
vector<shared_ptr<Breakpoint>> GetBreakpoints();
vector<uint32_t> 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();
};

View file

@ -0,0 +1,325 @@
#include "stdafx.h"
#include "ExpressionEvaluator.h"
#include "Console.h"
#include "Debugger.h"
std::unordered_map<string, std::vector<int>, 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<int> &outputQueue)
{
std::stack<EvalOperators> opStack = std::stack<EvalOperators>();
std::stack<int> 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<int> *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<int> *outputQueue = nullptr;
{
LockHandler lock = _cacheLock.AcquireSafe();
auto cacheOutputQueue = _outputCache.find(expression);
if(cacheOutputQueue != _outputCache.end()) {
outputQueue = &(cacheOutputQueue->second);
}
}
if(outputQueue == nullptr) {
vector<int> 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;
}
}

View file

@ -0,0 +1,91 @@
#pragma once
#include "stdafx.h"
#include <stack>
#include <deque>
#include <unordered_map>
#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<string> _binaryOperators = { { "*", "/", "%", "+", "-", "<<", ">>", "<", "<=", ">", ">=", "==", "!=", "&", "^", "|", "&&", "||" } };
const vector<int> _binaryPrecedence = { { 10, 10, 10, 9, 9, 8, 8, 7, 7, 7, 7, 6, 6, 5, 4, 3, 2, 1 } };
const vector<string> _unaryOperators = { { "+", "-", "!", "~" } };
const vector<int> _unaryPrecedence = { { 11, 11, 11, 11 } };
static std::unordered_map<string, std::vector<int>, 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<int> &outputQueue);
bool EvaluateExpression(vector<int> *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);
};

View file

@ -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);
}

View file

@ -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) {

View file

@ -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;
}
}
}

View file

@ -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;
}
}

View file

@ -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) {
if(toggleEnabled) {
breakpoint.Enabled = !breakpoint.Enabled;
} else {
_breakpoints.Remove(breakpoint);
breakpoint.Remove();
}
} 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<InteropBreakpoint> breakpoints = new List<InteropBreakpoint>();
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 : "<any>");
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();

View file

@ -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);

View file

@ -27,22 +27,44 @@
/// </summary>
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;
}
}

View file

@ -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;
}
base.OnFormClosed(e);
if(DialogResult == System.Windows.Forms.DialogResult.OK) {
((Breakpoint)Entity).Add();
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;
}
}
private void radPpu_CheckedChanged(object sender, EventArgs e)
{
if(radPpu.Checked) {
chkRead.Checked = false;
chkWrite.Checked = false;
chkExec.Checked = false;
}
}
}

View file

@ -117,4 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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<RadioButton>().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<RadioButton>().FirstOrDefault(r => r.Checked).Tag);
} else if(kvp.Value is ctrlTrackbar) {

View file

@ -415,6 +415,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Icon.ico" />
<None Include="Resources\help.png" />
<None Include="Resources\Close.png" />
<None Include="Resources\PreviousArrow.png" />
<None Include="Resources\NextArrow.png" />

View file

@ -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();
@ -425,11 +424,27 @@ 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

View file

@ -70,6 +70,16 @@ namespace Mesen.GUI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap help {
get {
object obj = ResourceManager.GetObject("help", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
/// </summary>

View file

@ -121,6 +121,9 @@
<data name="Close" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\resources\close.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="help" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\help.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="MesenIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>

BIN
GUI.NET/Resources/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

View file

@ -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); }

View file

@ -25,6 +25,11 @@ uint32_t SimpleLock::GetThreadId()
#endif
}
LockHandler SimpleLock::AcquireSafe()
{
return LockHandler(this);
}
void SimpleLock::Acquire()
{
if(_lockCount == 0 || _holderThreadID != GetThreadId()) {
@ -65,3 +70,15 @@ void SimpleLock::Release()
assert(false);
}
}
LockHandler::LockHandler(SimpleLock *lock)
{
_lock = lock;
_lock->Acquire();
}
LockHandler::~LockHandler()
{
_lock->Release();
}

View file

@ -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();