Debugger: Breakpoint support
This commit is contained in:
parent
72c17966b9
commit
8502581a1d
30 changed files with 2271 additions and 43 deletions
88
Core/Breakpoint.cpp
Normal file
88
Core/Breakpoint.cpp
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include "stdafx.h"
|
||||
#include "Breakpoint.h"
|
||||
#include "DebugTypes.h"
|
||||
|
||||
bool Breakpoint::Matches(uint32_t memoryAddr, AddressInfo &info)
|
||||
{
|
||||
if(_memoryType == SnesMemoryType::CpuMemory) {
|
||||
if(_startAddr == -1) {
|
||||
return true;
|
||||
} else if(_endAddr == -1) {
|
||||
return (int32_t)memoryAddr == _startAddr;
|
||||
} else {
|
||||
return (int32_t)memoryAddr >= _startAddr && (int32_t)memoryAddr <= _endAddr;
|
||||
}
|
||||
} else if(_memoryType == info.Type) {
|
||||
if(_startAddr == -1) {
|
||||
return true;
|
||||
} else if(_endAddr == -1) {
|
||||
return info.Address == _startAddr;
|
||||
} else {
|
||||
return info.Address >= _startAddr && info.Address <= _endAddr;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Breakpoint::HasBreakpointType(BreakpointType type)
|
||||
{
|
||||
switch(type) {
|
||||
default:
|
||||
case BreakpointType::Execute: return ((uint8_t)_type & (uint8_t)BreakpointTypeFlags::Execute) != 0;
|
||||
case BreakpointType::Read: return ((uint8_t)_type & (uint8_t)BreakpointTypeFlags::Read) != 0;
|
||||
case BreakpointType::Write: return ((uint8_t)_type & (uint8_t)BreakpointTypeFlags::Write) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
string Breakpoint::GetCondition()
|
||||
{
|
||||
return _condition;
|
||||
}
|
||||
|
||||
bool Breakpoint::HasCondition()
|
||||
{
|
||||
return _condition[0] != 0;
|
||||
}
|
||||
|
||||
uint32_t Breakpoint::GetId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
BreakpointCategory Breakpoint::GetBreakpointCategory()
|
||||
{
|
||||
return GetBreakpointCategory(_memoryType);
|
||||
}
|
||||
|
||||
BreakpointCategory Breakpoint::GetBreakpointCategory(SnesMemoryType memoryType)
|
||||
{
|
||||
switch(memoryType) {
|
||||
case SnesMemoryType::CpuMemory:
|
||||
case SnesMemoryType::PrgRom:
|
||||
case SnesMemoryType::WorkRam:
|
||||
case SnesMemoryType::SaveRam:
|
||||
return BreakpointCategory::Cpu;
|
||||
|
||||
case SnesMemoryType::VideoRam:
|
||||
return BreakpointCategory::VideoRam;
|
||||
|
||||
case SnesMemoryType::SpriteRam:
|
||||
return BreakpointCategory::Oam;
|
||||
|
||||
case SnesMemoryType::CGRam:
|
||||
return BreakpointCategory::CgRam;
|
||||
|
||||
default: throw std::runtime_error("invalid memory type");
|
||||
}
|
||||
}
|
||||
|
||||
bool Breakpoint::IsEnabled()
|
||||
{
|
||||
return _enabled;
|
||||
}
|
||||
|
||||
bool Breakpoint::IsMarked()
|
||||
{
|
||||
return _markEvent;
|
||||
}
|
34
Core/Breakpoint.h
Normal file
34
Core/Breakpoint.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
|
||||
enum class SnesMemoryType;
|
||||
struct AddressInfo;
|
||||
enum class BreakpointType;
|
||||
enum class BreakpointTypeFlags;
|
||||
enum class BreakpointCategory;
|
||||
|
||||
class Breakpoint
|
||||
{
|
||||
public:
|
||||
bool Matches(uint32_t memoryAddr, AddressInfo &info);
|
||||
bool HasBreakpointType(BreakpointType type);
|
||||
string GetCondition();
|
||||
bool HasCondition();
|
||||
|
||||
uint32_t GetId();
|
||||
bool IsEnabled();
|
||||
bool IsMarked();
|
||||
|
||||
BreakpointCategory GetBreakpointCategory();
|
||||
static BreakpointCategory GetBreakpointCategory(SnesMemoryType memoryType);
|
||||
|
||||
private:
|
||||
uint32_t _id;
|
||||
SnesMemoryType _memoryType;
|
||||
BreakpointTypeFlags _type;
|
||||
int32_t _startAddr;
|
||||
int32_t _endAddr;
|
||||
bool _enabled;
|
||||
bool _markEvent;
|
||||
char _condition[1000];
|
||||
};
|
86
Core/BreakpointManager.cpp
Normal file
86
Core/BreakpointManager.cpp
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include "stdafx.h"
|
||||
#include "BreakpointManager.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "Debugger.h"
|
||||
#include "Breakpoint.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
|
||||
BreakpointManager::BreakpointManager(Debugger *debugger)
|
||||
{
|
||||
_debugger = debugger;
|
||||
}
|
||||
|
||||
void BreakpointManager::SetBreakpoints(Breakpoint breakpoints[], uint32_t count)
|
||||
{
|
||||
for(int j = 0; j < BreakpointManager::CategoryCount; j++) {
|
||||
for(int i = 0; i < BreakpointManager::BreakpointTypeCount; i++) {
|
||||
_breakpoints[j][i].clear();
|
||||
_rpnList[j][i].clear();
|
||||
_hasBreakpoint[j][i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
_bpExpEval.reset(new ExpressionEvaluator(_debugger));
|
||||
for(uint32_t j = 0; j < count; j++) {
|
||||
Breakpoint &bp = breakpoints[j];
|
||||
for(int i = 0; i < BreakpointManager::BreakpointTypeCount; i++) {
|
||||
BreakpointType bpType = (BreakpointType)i;
|
||||
bool isEnabled = bp.IsEnabled(); //TODO && _console->GetSettings()->CheckFlag(EmulationFlags::DebuggerWindowEnabled);
|
||||
if((bp.IsMarked() || isEnabled) && bp.HasBreakpointType(bpType)) {
|
||||
BreakpointCategory category = bp.GetBreakpointCategory();
|
||||
_breakpoints[(int)category][i].push_back(bp);
|
||||
|
||||
if(bp.HasCondition()) {
|
||||
bool success = true;
|
||||
ExpressionData data = _bpExpEval->GetRpnList(bp.GetCondition(), success);
|
||||
_rpnList[(int)category][i].push_back(success ? data : ExpressionData());
|
||||
} else {
|
||||
_rpnList[(int)category][i].push_back(ExpressionData());
|
||||
}
|
||||
|
||||
_hasBreakpoint[(int)category][i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BreakpointType BreakpointManager::GetBreakpointType(MemoryOperationType type)
|
||||
{
|
||||
switch(type) {
|
||||
default:
|
||||
case MemoryOperationType::ExecOperand:
|
||||
case MemoryOperationType::ExecOpCode:
|
||||
return BreakpointType::Execute;
|
||||
|
||||
case MemoryOperationType::DmaRead:
|
||||
case MemoryOperationType::Read: return BreakpointType::Read;
|
||||
|
||||
case MemoryOperationType::DmaWrite:
|
||||
case MemoryOperationType::Write: return BreakpointType::Write;
|
||||
}
|
||||
}
|
||||
|
||||
bool BreakpointManager::CheckBreakpoint(MemoryOperationInfo operationInfo, AddressInfo &address)
|
||||
{
|
||||
BreakpointCategory category = Breakpoint::GetBreakpointCategory(address.Type);
|
||||
BreakpointType type = GetBreakpointType(operationInfo.Type);
|
||||
|
||||
if(!_hasBreakpoint[(int)category][(int)type]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DebugState state;
|
||||
_debugger->GetState(state);
|
||||
EvalResultType resultType;
|
||||
vector<Breakpoint> &breakpoints = _breakpoints[(int)category][(int)type];
|
||||
for(size_t i = 0; i < breakpoints.size(); i++) {
|
||||
Breakpoint bp = breakpoints[i];
|
||||
if(bp.Matches(operationInfo.Address, address)) {
|
||||
if(!bp.HasCondition() || _bpExpEval->Evaluate(_rpnList[(int)category][(int)type][i], state, resultType, operationInfo)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
33
Core/BreakpointManager.h
Normal file
33
Core/BreakpointManager.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Breakpoint.h"
|
||||
|
||||
class ExpressionEvaluator;
|
||||
class Debugger;
|
||||
struct MemoryOperationInfo;
|
||||
struct ExpressionData;
|
||||
struct AddressInfo;
|
||||
enum class MemoryOperationType;
|
||||
|
||||
class BreakpointManager
|
||||
{
|
||||
private:
|
||||
static constexpr int BreakpointTypeCount = 3; //Read, Write, Exec
|
||||
static constexpr int CategoryCount = 4; //CPU, VRAM, OAM, CGRAM
|
||||
|
||||
Debugger *_debugger;
|
||||
|
||||
vector<Breakpoint> _breakpoints[CategoryCount][BreakpointTypeCount];
|
||||
vector<ExpressionData> _rpnList[CategoryCount][BreakpointTypeCount];
|
||||
bool _hasBreakpoint[CategoryCount][BreakpointTypeCount] = {};
|
||||
|
||||
unique_ptr<ExpressionEvaluator> _bpExpEval;
|
||||
|
||||
BreakpointType GetBreakpointType(MemoryOperationType type);
|
||||
|
||||
public:
|
||||
BreakpointManager(Debugger *debugger);
|
||||
|
||||
void SetBreakpoints(Breakpoint breakpoints[], uint32_t count);
|
||||
bool CheckBreakpoint(MemoryOperationInfo operationInfo, AddressInfo &address);
|
||||
};
|
|
@ -10,6 +10,7 @@
|
|||
#include "BaseCartridge.h"
|
||||
#include "RamHandler.h"
|
||||
#include "Debugger.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "NotificationManager.h"
|
||||
#include "SoundMixer.h"
|
||||
#include "VideoDecoder.h"
|
||||
|
@ -247,3 +248,30 @@ void Console::ProcessCpuWrite(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_debugger->ProcessCpuWrite(addr, value, type);
|
||||
}
|
||||
}
|
||||
|
||||
void Console::ProcessPpuRead(uint32_t addr, uint8_t value, SnesMemoryType memoryType)
|
||||
{
|
||||
if(_debugger) {
|
||||
_debugger->ProcessPpuRead(addr, value, memoryType);
|
||||
}
|
||||
}
|
||||
|
||||
void Console::ProcessPpuWrite(uint32_t addr, uint8_t value, SnesMemoryType memoryType)
|
||||
{
|
||||
if(_debugger) {
|
||||
_debugger->ProcessPpuWrite(addr, value, memoryType);
|
||||
}
|
||||
}
|
||||
|
||||
void Console::ProcessWorkRamRead(uint32_t addr, uint8_t value)
|
||||
{
|
||||
if(_debugger) {
|
||||
_debugger->ProcessWorkRamRead(addr, value);
|
||||
}
|
||||
}
|
||||
void Console::ProcessWorkRamWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
if(_debugger) {
|
||||
_debugger->ProcessWorkRamWrite(addr, value);
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ class VideoRenderer;
|
|||
class VideoDecoder;
|
||||
class NotificationManager;
|
||||
enum class MemoryOperationType;
|
||||
enum class SnesMemoryType;
|
||||
|
||||
class Console : public std::enable_shared_from_this<Console>
|
||||
{
|
||||
|
@ -75,4 +76,8 @@ public:
|
|||
|
||||
void ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
void ProcessCpuWrite(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
void ProcessPpuRead(uint32_t addr, uint8_t value, SnesMemoryType memoryType);
|
||||
void ProcessPpuWrite(uint32_t addr, uint8_t value, SnesMemoryType memoryType);
|
||||
void ProcessWorkRamRead(uint32_t addr, uint8_t value);
|
||||
void ProcessWorkRamWrite(uint32_t addr, uint8_t value);
|
||||
};
|
|
@ -52,6 +52,8 @@
|
|||
<ClInclude Include="blargg_config.h" />
|
||||
<ClInclude Include="blargg_endian.h" />
|
||||
<ClInclude Include="blargg_source.h" />
|
||||
<ClInclude Include="Breakpoint.h" />
|
||||
<ClInclude Include="BreakpointManager.h" />
|
||||
<ClInclude Include="CodeDataLogger.h" />
|
||||
<ClInclude Include="Console.h" />
|
||||
<ClInclude Include="ControlDeviceState.h" />
|
||||
|
@ -114,6 +116,8 @@
|
|||
<ClCompile Include="BaseRenderer.cpp" />
|
||||
<ClCompile Include="BaseSoundManager.cpp" />
|
||||
<ClCompile Include="BaseVideoFilter.cpp" />
|
||||
<ClCompile Include="Breakpoint.cpp" />
|
||||
<ClCompile Include="BreakpointManager.cpp" />
|
||||
<ClCompile Include="CodeDataLogger.cpp" />
|
||||
<ClCompile Include="Console.cpp" />
|
||||
<ClCompile Include="ControlManager.cpp" />
|
||||
|
|
|
@ -191,6 +191,12 @@
|
|||
<ClInclude Include="DummyCpu.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="BreakpointManager.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Breakpoint.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
|
@ -296,6 +302,10 @@
|
|||
<ClCompile Include="ExpressionEvaluator.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Breakpoint.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BreakpointManager.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="SNES">
|
||||
|
|
|
@ -92,10 +92,8 @@ enum class MemoryOperationType
|
|||
Write = 1,
|
||||
ExecOpCode = 2,
|
||||
ExecOperand = 3,
|
||||
DummyRead = 5,
|
||||
DummyWrite = 6,
|
||||
DmaRead = 7,
|
||||
DmaWrite = 8
|
||||
DmaRead = 4,
|
||||
DmaWrite = 5
|
||||
};
|
||||
|
||||
enum class IrqSource
|
||||
|
|
|
@ -24,13 +24,53 @@ struct AddressInfo
|
|||
{
|
||||
int32_t Address;
|
||||
SnesMemoryType Type;
|
||||
|
||||
AddressInfo() { }
|
||||
|
||||
AddressInfo(int32_t address, SnesMemoryType type)
|
||||
{
|
||||
Address = address;
|
||||
Type = type;
|
||||
}
|
||||
};
|
||||
|
||||
struct MemoryOperationInfo
|
||||
{
|
||||
uint32_t Address;
|
||||
int32_t Value;
|
||||
MemoryOperationType OperationType;
|
||||
MemoryOperationType Type;
|
||||
|
||||
MemoryOperationInfo() { }
|
||||
|
||||
MemoryOperationInfo(uint32_t address, int32_t value, MemoryOperationType type)
|
||||
{
|
||||
Address = address;
|
||||
Value = value;
|
||||
Type = type;
|
||||
}
|
||||
};
|
||||
|
||||
enum class BreakpointTypeFlags
|
||||
{
|
||||
None = 0,
|
||||
Execute = 1,
|
||||
Read = 2,
|
||||
Write = 4,
|
||||
};
|
||||
|
||||
enum class BreakpointType
|
||||
{
|
||||
Execute = 0,
|
||||
Read = 1,
|
||||
Write = 2,
|
||||
};
|
||||
|
||||
enum class BreakpointCategory
|
||||
{
|
||||
Cpu = 0,
|
||||
VideoRam = 1,
|
||||
Oam = 2,
|
||||
CgRam = 3
|
||||
};
|
||||
|
||||
namespace CdlFlags
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "MemoryDumper.h"
|
||||
#include "CodeDataLogger.h"
|
||||
#include "Disassembler.h"
|
||||
#include "BreakpointManager.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/FolderUtilities.h"
|
||||
|
@ -29,6 +30,7 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_disassembler.reset(new Disassembler(console, _codeDataLogger));
|
||||
_traceLogger.reset(new TraceLogger(this, _memoryManager));
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, console->GetCartridge()));
|
||||
_breakpointManager.reset(new BreakpointManager(this));
|
||||
_cpuStepCount = 0;
|
||||
|
||||
string cdlFile = FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), FolderUtilities::GetFilename(_console->GetCartridge()->GetRomInfo().RomPath, false) + ".cdl");
|
||||
|
@ -55,6 +57,7 @@ Debugger::~Debugger()
|
|||
void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType type)
|
||||
{
|
||||
AddressInfo addressInfo = _memoryManager->GetAbsoluteAddress(addr);
|
||||
MemoryOperationInfo operation = { addr, value, type };
|
||||
CpuState state = _cpu->GetState();
|
||||
|
||||
if(type == MemoryOperationType::ExecOpCode) {
|
||||
|
@ -70,27 +73,20 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
}
|
||||
|
||||
DebugState debugState;
|
||||
GetState(&debugState);
|
||||
GetState(debugState);
|
||||
|
||||
DisassemblyInfo disInfo = _disassembler->GetDisassemblyInfo(addressInfo);
|
||||
_traceLogger->Log(debugState, disInfo);
|
||||
|
||||
_prevOpCode = value;
|
||||
|
||||
if(value == 0x00 || value == 0xCB) {
|
||||
//break on BRK/WAI
|
||||
_cpuStepCount = 1;
|
||||
}
|
||||
|
||||
if(_cpuStepCount > 0) {
|
||||
_cpuStepCount--;
|
||||
if(_cpuStepCount == 0) {
|
||||
_disassembler->Disassemble();
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::CodeBreak);
|
||||
while(_cpuStepCount == 0) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(value == 0x00 || value == 0xCB) {
|
||||
//Break on BRK/WAI
|
||||
_cpuStepCount = 0;
|
||||
}
|
||||
} else if(type == MemoryOperationType::ExecOperand) {
|
||||
if(addressInfo.Type == SnesMemoryType::PrgRom && addressInfo.Address >= 0) {
|
||||
|
@ -101,21 +97,71 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_codeDataLogger->SetFlags(addressInfo.Address, CdlFlags::Data | (state.PS & (CdlFlags::IndexMode8 | CdlFlags::MemoryMode8)));
|
||||
}
|
||||
}
|
||||
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
void Debugger::ProcessCpuWrite(uint32_t addr, uint8_t value, MemoryOperationType type)
|
||||
{
|
||||
AddressInfo addressInfo = _memoryManager->GetAbsoluteAddress(addr);
|
||||
MemoryOperationInfo operation = { addr, value, type };
|
||||
if(addressInfo.Address >= 0 && (addressInfo.Type == SnesMemoryType::WorkRam || addressInfo.Type == SnesMemoryType::SaveRam)) {
|
||||
_disassembler->InvalidateCache(addressInfo);
|
||||
}
|
||||
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
void Debugger::ProcessWorkRamRead(uint32_t addr, uint8_t value)
|
||||
{
|
||||
AddressInfo addressInfo(addr, SnesMemoryType::WorkRam);
|
||||
//TODO Make this more flexible/accurate
|
||||
MemoryOperationInfo operation(0x7E0000 | addr, value, MemoryOperationType::Read);
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
void Debugger::ProcessWorkRamWrite(uint32_t addr, uint8_t value)
|
||||
{
|
||||
AddressInfo addressInfo(addr, SnesMemoryType::WorkRam);
|
||||
//TODO Make this more flexible/accurate
|
||||
MemoryOperationInfo operation(0x7E0000 | addr, value, MemoryOperationType::Write);
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
void Debugger::ProcessPpuRead(uint16_t addr, uint8_t value, SnesMemoryType memoryType)
|
||||
{
|
||||
AddressInfo addressInfo(addr, memoryType);
|
||||
MemoryOperationInfo operation(addr, value, MemoryOperationType::Read);
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
void Debugger::ProcessPpuWrite(uint16_t addr, uint8_t value, SnesMemoryType memoryType)
|
||||
{
|
||||
AddressInfo addressInfo(addr, memoryType);
|
||||
MemoryOperationInfo operation(addr, value, MemoryOperationType::Write);
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
void Debugger::ProcessBreakConditions(MemoryOperationInfo &operation, AddressInfo &addressInfo)
|
||||
{
|
||||
if(_breakpointManager->CheckBreakpoint(operation, addressInfo)) {
|
||||
_cpuStepCount = 0;
|
||||
}
|
||||
|
||||
if(_cpuStepCount == 0) {
|
||||
_disassembler->Disassemble();
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::CodeBreak);
|
||||
while(_cpuStepCount == 0) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Debugger::EvaluateExpression(string expression, EvalResultType &resultType, bool useCache)
|
||||
{
|
||||
MemoryOperationInfo operationInfo { 0, 0, MemoryOperationType::Read };
|
||||
DebugState state;
|
||||
MemoryOperationInfo operationInfo { 0, 0, MemoryOperationType::DummyRead };
|
||||
GetState(&state);
|
||||
GetState(state);
|
||||
if(useCache) {
|
||||
return _watchExpEval->Evaluate(expression, state, resultType, operationInfo);
|
||||
} else {
|
||||
|
@ -140,10 +186,10 @@ bool Debugger::IsExecutionStopped()
|
|||
return false;
|
||||
}
|
||||
|
||||
void Debugger::GetState(DebugState *state)
|
||||
void Debugger::GetState(DebugState &state)
|
||||
{
|
||||
state->Cpu = _cpu->GetState();
|
||||
state->Ppu = _ppu->GetState();
|
||||
state.Cpu = _cpu->GetState();
|
||||
state.Ppu = _ppu->GetState();
|
||||
}
|
||||
|
||||
shared_ptr<TraceLogger> Debugger::GetTraceLogger()
|
||||
|
@ -160,3 +206,8 @@ shared_ptr<Disassembler> Debugger::GetDisassembler()
|
|||
{
|
||||
return _disassembler;
|
||||
}
|
||||
|
||||
shared_ptr<BreakpointManager> Debugger::GetBreakpointManager()
|
||||
{
|
||||
return _breakpointManager;
|
||||
}
|
||||
|
|
|
@ -10,13 +10,18 @@ class BaseCartridge;
|
|||
class MemoryManager;
|
||||
class CodeDataLogger;
|
||||
|
||||
enum class SnesMemoryType;
|
||||
enum class MemoryOperationType;
|
||||
enum class BreakpointCategory;
|
||||
enum class EvalResultType : int32_t;
|
||||
class TraceLogger;
|
||||
class ExpressionEvaluator;
|
||||
class MemoryDumper;
|
||||
class Disassembler;
|
||||
class BreakpointManager;
|
||||
struct DebugState;
|
||||
struct MemoryOperationInfo;
|
||||
struct AddressInfo;
|
||||
|
||||
class Debugger
|
||||
{
|
||||
|
@ -31,6 +36,7 @@ private:
|
|||
shared_ptr<MemoryDumper> _memoryDumper;
|
||||
shared_ptr<CodeDataLogger> _codeDataLogger;
|
||||
shared_ptr<Disassembler> _disassembler;
|
||||
shared_ptr<BreakpointManager> _breakpointManager;
|
||||
|
||||
unique_ptr<ExpressionEvaluator> _watchExpEval;
|
||||
|
||||
|
@ -44,15 +50,24 @@ public:
|
|||
void ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
void ProcessCpuWrite(uint32_t addr, uint8_t value, MemoryOperationType type);
|
||||
|
||||
void ProcessWorkRamRead(uint32_t addr, uint8_t value);
|
||||
void ProcessWorkRamWrite(uint32_t addr, uint8_t value);
|
||||
|
||||
void ProcessPpuRead(uint16_t addr, uint8_t value, SnesMemoryType memoryType);
|
||||
void ProcessPpuWrite(uint16_t addr, uint8_t value, SnesMemoryType memoryType);
|
||||
|
||||
void ProcessBreakConditions(MemoryOperationInfo &operation, AddressInfo &addressInfo);
|
||||
|
||||
int32_t EvaluateExpression(string expression, EvalResultType &resultType, bool useCache);
|
||||
|
||||
void Run();
|
||||
void Step(int32_t stepCount);
|
||||
bool IsExecutionStopped();
|
||||
|
||||
void GetState(DebugState *state);
|
||||
void GetState(DebugState &state);
|
||||
|
||||
shared_ptr<TraceLogger> GetTraceLogger();
|
||||
shared_ptr<MemoryDumper> GetMemoryDumper();
|
||||
shared_ptr<Disassembler> GetDisassembler();
|
||||
shared_ptr<BreakpointManager> GetBreakpointManager();
|
||||
};
|
|
@ -553,7 +553,7 @@ void ExpressionEvaluator::RunTests()
|
|||
//Some basic unit tests to run in debug mode
|
||||
auto test = [=](string expr, EvalResultType expectedType, int expectedResult) {
|
||||
DebugState state = { 0 };
|
||||
OperationInfo opInfo = { 0 };
|
||||
MemoryOperationInfo opInfo(0, 0, MemoryOperationType::Read);
|
||||
EvalResultType type;
|
||||
int32_t result = Evaluate(expr, state, type, opInfo);
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ void MemoryManager::Initialize(shared_ptr<Console> console)
|
|||
));
|
||||
|
||||
_registerHandlerB.reset(new RegisterHandlerB(
|
||||
_console.get(),
|
||||
_ppu.get(),
|
||||
console->GetSpc().get(),
|
||||
_workRam
|
||||
|
|
15
Core/Ppu.cpp
15
Core/Ppu.cpp
|
@ -1065,8 +1065,10 @@ uint8_t Ppu::Read(uint16_t addr)
|
|||
uint8_t value;
|
||||
if(_internalOamAddress < 512) {
|
||||
value = _oamRam[_internalOamAddress];
|
||||
_console->ProcessPpuRead(_internalOamAddress, value, SnesMemoryType::SpriteRam);
|
||||
} else {
|
||||
value = _oamRam[0x200 | (_internalOamAddress & 0x1F)];
|
||||
_console->ProcessPpuRead(0x200 | (_internalOamAddress & 0x1F), value, SnesMemoryType::SpriteRam);
|
||||
}
|
||||
_internalOamAddress = (_internalOamAddress + 1) & 0x3FF;
|
||||
return value;
|
||||
|
@ -1075,6 +1077,7 @@ uint8_t Ppu::Read(uint16_t addr)
|
|||
case 0x2139: {
|
||||
//VMDATALREAD - VRAM Data Read low byte
|
||||
uint8_t returnValue = (uint8_t)_vramReadBuffer;
|
||||
_console->ProcessPpuRead(_vramAddress, returnValue, SnesMemoryType::VideoRam);
|
||||
if(!_vramAddrIncrementOnSecondReg) {
|
||||
UpdateVramReadBuffer();
|
||||
_vramAddress = (_vramAddress + _vramIncrementValue) & 0x7FFF;
|
||||
|
@ -1085,6 +1088,7 @@ uint8_t Ppu::Read(uint16_t addr)
|
|||
case 0x213A: {
|
||||
//VMDATAHREAD - VRAM Data Read high byte
|
||||
uint8_t returnValue = (uint8_t)(_vramReadBuffer >> 8);
|
||||
_console->ProcessPpuRead(_vramAddress + 1, returnValue, SnesMemoryType::VideoRam);
|
||||
if(_vramAddrIncrementOnSecondReg) {
|
||||
UpdateVramReadBuffer();
|
||||
_vramAddress = (_vramAddress + _vramIncrementValue) & 0x7FFF;
|
||||
|
@ -1095,6 +1099,7 @@ uint8_t Ppu::Read(uint16_t addr)
|
|||
case 0x213B: {
|
||||
//CGDATAREAD - CGRAM Data read
|
||||
uint8_t value = _cgram[_cgramAddress];
|
||||
_console->ProcessPpuRead(_cgramAddress, value, SnesMemoryType::CGRam);
|
||||
_cgramAddress = (_cgramAddress + 1) & (Ppu::CgRamSize - 1);
|
||||
return value;
|
||||
}
|
||||
|
@ -1195,7 +1200,10 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
case 0x2104:
|
||||
if(_internalOamAddress < 512) {
|
||||
if(_internalOamAddress & 0x01) {
|
||||
_console->ProcessPpuWrite(_internalOamAddress - 1, _oamWriteBuffer, SnesMemoryType::SpriteRam);
|
||||
_oamRam[_internalOamAddress - 1] = _oamWriteBuffer;
|
||||
|
||||
_console->ProcessPpuWrite(_internalOamAddress, value, SnesMemoryType::SpriteRam);
|
||||
_oamRam[_internalOamAddress] = value;
|
||||
} else {
|
||||
_oamWriteBuffer = value;
|
||||
|
@ -1205,6 +1213,7 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
if((_internalOamAddress & 0x01) == 0) {
|
||||
_oamWriteBuffer = value;
|
||||
}
|
||||
_console->ProcessPpuWrite(address, value, SnesMemoryType::SpriteRam);
|
||||
_oamRam[address] = value;
|
||||
}
|
||||
_internalOamAddress = (_internalOamAddress + 1) & 0x3FF;
|
||||
|
@ -1303,6 +1312,8 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
|
||||
case 0x2118:
|
||||
//VMDATAL - VRAM Data Write low byte
|
||||
_console->ProcessPpuWrite(_vramAddress << 1, value, SnesMemoryType::VideoRam);
|
||||
|
||||
_vram[_vramAddress << 1] = value;
|
||||
if(!_vramAddrIncrementOnSecondReg) {
|
||||
_vramAddress = (_vramAddress + _vramIncrementValue) & 0x7FFF;
|
||||
|
@ -1311,6 +1322,8 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
|
||||
case 0x2119:
|
||||
//VMDATAH - VRAM Data Write high byte
|
||||
_console->ProcessPpuWrite((_vramAddress << 1) + 1, value, SnesMemoryType::VideoRam);
|
||||
|
||||
_vram[(_vramAddress << 1) + 1] = value;
|
||||
if(_vramAddrIncrementOnSecondReg) {
|
||||
_vramAddress = (_vramAddress + _vramIncrementValue) & 0x7FFF;
|
||||
|
@ -1350,6 +1363,8 @@ void Ppu::Write(uint32_t addr, uint8_t value)
|
|||
|
||||
case 0x2122:
|
||||
//CGRAM Data write (CGDATA)
|
||||
_console->ProcessPpuWrite(_cgramAddress, value, SnesMemoryType::CGRam);
|
||||
|
||||
_cgram[_cgramAddress] = value;
|
||||
_cgramAddress = (_cgramAddress + 1) & (Ppu::CgRamSize - 1);
|
||||
break;
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "IMemoryHandler.h"
|
||||
#include "Console.h"
|
||||
#include "Ppu.h"
|
||||
#include "Spc.h"
|
||||
|
||||
class RegisterHandlerB : public IMemoryHandler
|
||||
{
|
||||
private:
|
||||
Ppu * _ppu;
|
||||
Console *_console;
|
||||
Ppu *_ppu;
|
||||
Spc *_spc;
|
||||
uint8_t *_workRam;
|
||||
uint32_t _wramPosition;
|
||||
|
||||
public:
|
||||
RegisterHandlerB(Ppu *ppu, Spc *spc, uint8_t *workRam)
|
||||
RegisterHandlerB(Console *console, Ppu *ppu, Spc *spc, uint8_t *workRam)
|
||||
{
|
||||
_console = console;
|
||||
_ppu = ppu;
|
||||
_spc = spc;
|
||||
_workRam = workRam;
|
||||
|
@ -28,6 +31,7 @@ public:
|
|||
return _spc->Read(addr & 0x03);
|
||||
} else if(addr == 0x2180) {
|
||||
uint8_t value = _workRam[_wramPosition];
|
||||
_console->ProcessWorkRamRead(_wramPosition, value);
|
||||
_wramPosition = (_wramPosition + 1) & 0x1FFFF;
|
||||
return value;
|
||||
} else {
|
||||
|
@ -49,8 +53,9 @@ public:
|
|||
} if(addr >= 0x2180 && addr <= 0x2183) {
|
||||
switch(addr & 0xFFFF) {
|
||||
case 0x2180:
|
||||
_console->ProcessWorkRamWrite(_wramPosition, value);
|
||||
_workRam[_wramPosition] = value;
|
||||
_wramPosition = (_wramPosition + 1) & (0x1FFFF);
|
||||
_wramPosition = (_wramPosition + 1) & 0x1FFFF;
|
||||
break;
|
||||
|
||||
case 0x2181: _wramPosition = (_wramPosition & 0x1FF00) | value; break;
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "../Core/MemoryDumper.h"
|
||||
#include "../Core/Disassembler.h"
|
||||
#include "../Core/DebugTypes.h"
|
||||
#include "../Core/Breakpoint.h"
|
||||
#include "../Core/BreakpointManager.h"
|
||||
|
||||
extern shared_ptr<Console> _console;
|
||||
|
||||
|
@ -33,7 +35,7 @@ extern "C"
|
|||
}
|
||||
|
||||
DllExport bool __stdcall IsExecutionStopped() { return GetDebugger()->IsExecutionStopped(); }
|
||||
DllExport void __stdcall ResumeExecution() { GetDebugger()->Run(); }
|
||||
DllExport void __stdcall ResumeExecution() { if(IsDebuggerRunning()) GetDebugger()->Run(); }
|
||||
DllExport void __stdcall Step(uint32_t count) { GetDebugger()->Step(count); }
|
||||
|
||||
DllExport void __stdcall GetDisassemblyLineData(uint32_t lineIndex, CodeLineData &data) { GetDebugger()->GetDisassembler()->GetLineData(lineIndex, data); }
|
||||
|
@ -46,9 +48,10 @@ extern "C"
|
|||
DllExport void __stdcall StopTraceLogger() { GetDebugger()->GetTraceLogger()->StopLogging(); }
|
||||
DllExport const char* GetExecutionTrace(uint32_t lineCount) { return GetDebugger()->GetTraceLogger()->GetExecutionTrace(lineCount); }
|
||||
|
||||
DllExport void __stdcall SetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->GetBreakpointManager()->SetBreakpoints(breakpoints, length); }
|
||||
DllExport int32_t __stdcall EvaluateExpression(char* expression, EvalResultType *resultType, bool useCache) { return GetDebugger()->EvaluateExpression(expression, *resultType, useCache); }
|
||||
|
||||
DllExport void __stdcall GetState(DebugState *state) { GetDebugger()->GetState(state); }
|
||||
DllExport void __stdcall GetState(DebugState &state) { GetDebugger()->GetState(state); }
|
||||
|
||||
DllExport void __stdcall SetMemoryState(SnesMemoryType type, uint8_t *buffer, int32_t length) { GetDebugger()->GetMemoryDumper()->SetMemoryState(type, buffer, length); }
|
||||
DllExport uint32_t __stdcall GetMemorySize(SnesMemoryType type) { return GetDebugger()->GetMemoryDumper()->GetMemorySize(type); }
|
||||
|
|
221
UI/Debugger/Breakpoints/Breakpoint.cs
Normal file
221
UI/Debugger/Breakpoints/Breakpoint.cs
Normal file
|
@ -0,0 +1,221 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public class Breakpoint
|
||||
{
|
||||
private SnesMemoryType _memoryType = SnesMemoryType.CpuMemory;
|
||||
private bool _isCpuBreakpoint = true;
|
||||
|
||||
public bool BreakOnRead = false;
|
||||
public bool BreakOnWrite = false;
|
||||
public bool BreakOnExec = true;
|
||||
|
||||
public bool Enabled = true;
|
||||
public bool MarkEvent = false;
|
||||
public UInt32 Address = UInt32.MaxValue;
|
||||
public UInt32 StartAddress;
|
||||
public UInt32 EndAddress;
|
||||
public BreakpointAddressType AddressType = BreakpointAddressType.SingleAddress;
|
||||
public string Condition = "";
|
||||
|
||||
public SnesMemoryType MemoryType
|
||||
{
|
||||
get { return _memoryType; }
|
||||
set
|
||||
{
|
||||
_memoryType = value;
|
||||
_isCpuBreakpoint = IsTypeCpuBreakpoint(value);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetAddressString(bool showLabel)
|
||||
{
|
||||
string addr = "";
|
||||
switch(AddressType) {
|
||||
case BreakpointAddressType.AnyAddress:
|
||||
return "<any>";
|
||||
case BreakpointAddressType.SingleAddress:
|
||||
if(IsAbsoluteAddress) {
|
||||
addr += $"[${Address.ToString("X6")}]";
|
||||
} else {
|
||||
addr = $"${Address.ToString("X6")}";
|
||||
}
|
||||
break;
|
||||
|
||||
case BreakpointAddressType.AddressRange:
|
||||
if(IsAbsoluteAddress) {
|
||||
addr = $"[${StartAddress.ToString("X6")}] - [${EndAddress.ToString("X6")}]";
|
||||
} else {
|
||||
addr = $"${StartAddress.ToString("X6")} - ${EndAddress.ToString("X6")}";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO LABELS
|
||||
/*string label = GetAddressLabel();
|
||||
if(showLabel && !string.IsNullOrWhiteSpace(label)) {
|
||||
addr = label + $", {addr}";
|
||||
}*/
|
||||
return addr;
|
||||
}
|
||||
|
||||
public static bool IsTypeCpuBreakpoint(SnesMemoryType type)
|
||||
{
|
||||
return (
|
||||
type == SnesMemoryType.CpuMemory ||
|
||||
type == SnesMemoryType.WorkRam ||
|
||||
type == SnesMemoryType.SaveRam ||
|
||||
type == SnesMemoryType.PrgRom
|
||||
);
|
||||
}
|
||||
|
||||
public void SetEnabled(bool enabled)
|
||||
{
|
||||
Enabled = enabled;
|
||||
BreakpointManager.RefreshBreakpoints(this);
|
||||
}
|
||||
|
||||
public void SetMarked(bool marked)
|
||||
{
|
||||
MarkEvent = marked;
|
||||
BreakpointManager.RefreshBreakpoints(this);
|
||||
}
|
||||
|
||||
public bool IsAbsoluteAddress { get { return MemoryType != SnesMemoryType.CpuMemory; } }
|
||||
public bool IsCpuBreakpoint { get { return this._isCpuBreakpoint; } }
|
||||
|
||||
private BreakpointTypeFlags Type
|
||||
{
|
||||
get
|
||||
{
|
||||
BreakpointTypeFlags type = BreakpointTypeFlags.None;
|
||||
if(BreakOnRead) {
|
||||
type |= BreakpointTypeFlags.Read;
|
||||
}
|
||||
if(BreakOnWrite) {
|
||||
type |= BreakpointTypeFlags.Write;
|
||||
}
|
||||
if(BreakOnExec && IsCpuBreakpoint) {
|
||||
type |= BreakpointTypeFlags.Execute;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToReadableType()
|
||||
{
|
||||
string type;
|
||||
|
||||
switch(MemoryType) {
|
||||
default: throw new Exception("invalid type");
|
||||
case SnesMemoryType.CpuMemory: type = "CPU"; break;
|
||||
case SnesMemoryType.PrgRom: type = "PRG"; break;
|
||||
case SnesMemoryType.WorkRam: type = "WRAM"; break;
|
||||
case SnesMemoryType.SaveRam: type = "SRAM"; break;
|
||||
case SnesMemoryType.VideoRam: type = "VRAM"; break;
|
||||
case SnesMemoryType.SpriteRam: type = "OAM"; break;
|
||||
case SnesMemoryType.CGRam: type = "CG"; break;
|
||||
}
|
||||
|
||||
type += ":";
|
||||
type += BreakOnRead ? "R" : "‒";
|
||||
type += BreakOnWrite ? "W" : "‒";
|
||||
if(IsCpuBreakpoint) {
|
||||
type += BreakOnExec ? "X" : "‒";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public int GetRelativeAddress()
|
||||
{
|
||||
UInt32 address = AddressType == BreakpointAddressType.SingleAddress ? this.Address : this.StartAddress;
|
||||
if(IsCpuBreakpoint && this.IsAbsoluteAddress) {
|
||||
//TODO
|
||||
//return InteropEmu.DebugGetRelativeAddress(address, this.MemoryType.ToAddressType());
|
||||
return -1;
|
||||
} else {
|
||||
return (int)address;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetRelativeAddressEnd()
|
||||
{
|
||||
if(this.AddressType == BreakpointAddressType.AddressRange){
|
||||
if(IsCpuBreakpoint && this.IsAbsoluteAddress) {
|
||||
//TODO
|
||||
//return InteropEmu.DebugGetRelativeAddress(this.EndAddress, this.MemoryType.ToAddressType());
|
||||
} else {
|
||||
return (int)this.EndAddress;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public bool Matches(UInt32 address, SnesMemoryType type)
|
||||
{
|
||||
if(IsTypeCpuBreakpoint(type) != this.IsCpuBreakpoint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isRelativeMemory = type == SnesMemoryType.CpuMemory;
|
||||
|
||||
if(this.AddressType == BreakpointAddressType.SingleAddress) {
|
||||
return address == this.Address && type == this.MemoryType;
|
||||
} else if(this.AddressType == BreakpointAddressType.AddressRange) {
|
||||
return address >= this.StartAddress && address <= this.EndAddress && type == this.MemoryType;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public InteropBreakpoint ToInteropBreakpoint(int breakpointId)
|
||||
{
|
||||
InteropBreakpoint bp = new InteropBreakpoint() {
|
||||
Id = breakpointId,
|
||||
MemoryType = MemoryType,
|
||||
Type = Type,
|
||||
MarkEvent = MarkEvent,
|
||||
Enabled = Enabled
|
||||
};
|
||||
switch(AddressType) {
|
||||
case BreakpointAddressType.AnyAddress:
|
||||
bp.StartAddress = -1;
|
||||
bp.EndAddress = -1;
|
||||
break;
|
||||
|
||||
case BreakpointAddressType.SingleAddress:
|
||||
bp.StartAddress = (Int32)Address;
|
||||
bp.EndAddress = -1;
|
||||
break;
|
||||
|
||||
case BreakpointAddressType.AddressRange:
|
||||
bp.StartAddress = (Int32)StartAddress;
|
||||
bp.EndAddress = (Int32)EndAddress;
|
||||
break;
|
||||
}
|
||||
|
||||
bp.Condition = new byte[1000];
|
||||
byte[] condition = Encoding.UTF8.GetBytes(Condition.Replace(Environment.NewLine, " "));
|
||||
Array.Copy(condition, bp.Condition, condition.Length);
|
||||
return bp;
|
||||
}
|
||||
}
|
||||
|
||||
public enum BreakpointAddressType
|
||||
{
|
||||
AnyAddress,
|
||||
SingleAddress,
|
||||
AddressRange,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum BreakpointTypeFlags
|
||||
{
|
||||
None = 0,
|
||||
Execute = 1,
|
||||
Read = 2,
|
||||
Write = 4,
|
||||
}
|
||||
}
|
114
UI/Debugger/Breakpoints/BreakpointManager.cs
Normal file
114
UI/Debugger/Breakpoints/BreakpointManager.cs
Normal file
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public class BreakpointManager
|
||||
{
|
||||
public static event EventHandler BreakpointsChanged;
|
||||
|
||||
private static List<Breakpoint> _breakpoints = new List<Breakpoint>();
|
||||
|
||||
public static ReadOnlyCollection<Breakpoint> Breakpoints
|
||||
{
|
||||
get { return _breakpoints.ToList().AsReadOnly(); }
|
||||
}
|
||||
|
||||
public static void RefreshBreakpoints(Breakpoint bp = null)
|
||||
{
|
||||
if(BreakpointsChanged != null) {
|
||||
BreakpointsChanged(bp, null);
|
||||
}
|
||||
|
||||
SetBreakpoints();
|
||||
}
|
||||
|
||||
public static void SetBreakpoints(List<Breakpoint> breakpoints)
|
||||
{
|
||||
_breakpoints = breakpoints.ToList();
|
||||
RefreshBreakpoints();
|
||||
}
|
||||
|
||||
public static void EditBreakpoint(Breakpoint bp)
|
||||
{
|
||||
if(new frmBreakpoint(bp).ShowDialog() == DialogResult.OK) {
|
||||
if(!_breakpoints.Contains(bp)) {
|
||||
_breakpoints.Add(bp);
|
||||
}
|
||||
RefreshBreakpoints(bp);
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveBreakpoint(Breakpoint bp)
|
||||
{
|
||||
_breakpoints.Remove(bp);
|
||||
RefreshBreakpoints(bp);
|
||||
}
|
||||
|
||||
public static void AddBreakpoint(Breakpoint bp)
|
||||
{
|
||||
_breakpoints.Add(bp);
|
||||
RefreshBreakpoints(bp);
|
||||
}
|
||||
|
||||
public static Breakpoint GetMatchingBreakpoint(AddressInfo info)
|
||||
{
|
||||
return Breakpoints.Where((bp) => bp.Matches((UInt32)info.Address, info.Type)).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static Breakpoint GetMatchingBreakpoint(UInt32 startAddress, UInt32 endAddress, SnesMemoryType memoryType)
|
||||
{
|
||||
bool isAddressRange = startAddress != endAddress;
|
||||
return Breakpoints.Where((bp) =>
|
||||
bp.MemoryType == memoryType &&
|
||||
((!isAddressRange && bp.Address == startAddress) || (isAddressRange && bp.StartAddress == startAddress && bp.EndAddress == endAddress))
|
||||
).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static void EnableDisableBreakpoint(AddressInfo info)
|
||||
{
|
||||
Breakpoint breakpoint = BreakpointManager.GetMatchingBreakpoint(info);
|
||||
if(breakpoint != null) {
|
||||
breakpoint.SetEnabled(!breakpoint.Enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ToggleBreakpoint(AddressInfo info)
|
||||
{
|
||||
if(info.Address < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Breakpoint breakpoint = BreakpointManager.GetMatchingBreakpoint(info);
|
||||
if(breakpoint != null) {
|
||||
BreakpointManager.RemoveBreakpoint(breakpoint);
|
||||
} else {
|
||||
breakpoint = new Breakpoint() {
|
||||
Enabled = true,
|
||||
BreakOnExec = true,
|
||||
Address = (UInt32)info.Address
|
||||
};
|
||||
|
||||
if(info.Type != SnesMemoryType.PrgRom) {
|
||||
breakpoint.BreakOnRead = true;
|
||||
breakpoint.BreakOnWrite = true;
|
||||
}
|
||||
|
||||
breakpoint.MemoryType = info.Type;
|
||||
BreakpointManager.AddBreakpoint(breakpoint);
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetBreakpoints()
|
||||
{
|
||||
List<InteropBreakpoint> breakpoints = new List<InteropBreakpoint>();
|
||||
for(int i = 0; i < Breakpoints.Count; i++) {
|
||||
breakpoints.Add(Breakpoints[i].ToInteropBreakpoint(i));
|
||||
}
|
||||
DebugApi.SetBreakpoints(breakpoints.ToArray(), (UInt32)breakpoints.Count);
|
||||
}
|
||||
}
|
||||
}
|
23
UI/Debugger/Breakpoints/InteropBreakpoint.cs
Normal file
23
UI/Debugger/Breakpoints/InteropBreakpoint.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public struct InteropBreakpoint
|
||||
{
|
||||
public Int32 Id;
|
||||
public SnesMemoryType MemoryType;
|
||||
public BreakpointTypeFlags Type;
|
||||
public Int32 StartAddress;
|
||||
public Int32 EndAddress;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool Enabled;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)]
|
||||
public bool MarkEvent;
|
||||
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
|
||||
public byte[] Condition;
|
||||
}
|
||||
}
|
176
UI/Debugger/Breakpoints/ctrlBreakpoints.cs
Normal file
176
UI/Debugger/Breakpoints/ctrlBreakpoints.cs
Normal file
|
@ -0,0 +1,176 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using System.Collections.ObjectModel;
|
||||
using Mesen.GUI.Config;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class ctrlBreakpoints : BaseControl
|
||||
{
|
||||
public event EventHandler BreakpointNavigation;
|
||||
private Font _markedColumnFont;
|
||||
|
||||
public ctrlBreakpoints()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
if(!IsDesignMode) {
|
||||
_markedColumnFont = new Font(this.Font.FontFamily, 13f);
|
||||
|
||||
//TODO Labels
|
||||
//mnuShowLabels.Checked = ConfigManager.Config.Debug.ShowBreakpointLabels;
|
||||
mnuShowLabels.CheckedChanged += mnuShowLabels_CheckedChanged;
|
||||
|
||||
BreakpointManager.BreakpointsChanged += BreakpointManager_OnBreakpointChanged;
|
||||
mnuRemoveBreakpoint.Enabled = false;
|
||||
mnuEditBreakpoint.Enabled = false;
|
||||
mnuGoToLocation.Enabled = false;
|
||||
|
||||
InitShortcuts();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitShortcuts()
|
||||
{
|
||||
mnuAddBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_Add));
|
||||
mnuEditBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_Edit));
|
||||
mnuRemoveBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_Delete));
|
||||
mnuGoToLocation.InitShortcut(this, nameof(DebuggerShortcutsConfig.BreakpointList_GoToLocation));
|
||||
}
|
||||
|
||||
private void BreakpointManager_OnBreakpointChanged(object sender, EventArgs e)
|
||||
{
|
||||
RefreshList();
|
||||
}
|
||||
|
||||
public void RefreshListAddresses()
|
||||
{
|
||||
lstBreakpoints.BeginUpdate();
|
||||
ReadOnlyCollection<Breakpoint> breakpoints = BreakpointManager.Breakpoints;
|
||||
for(int i = 0; i < breakpoints.Count; i++) {
|
||||
lstBreakpoints.Items[i].SubItems[3].Text = breakpoints[i].GetAddressString(mnuShowLabels.Checked);
|
||||
}
|
||||
lstBreakpoints.EndUpdate();
|
||||
}
|
||||
|
||||
public void RefreshList()
|
||||
{
|
||||
lstBreakpoints.ItemChecked -= new ItemCheckedEventHandler(lstBreakpoints_ItemChecked);
|
||||
|
||||
int topIndex = lstBreakpoints.TopItem != null ? lstBreakpoints.TopItem.Index : 0;
|
||||
lstBreakpoints.BeginUpdate();
|
||||
lstBreakpoints.Items.Clear();
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
ListViewItem item = new ListViewItem();
|
||||
item.Tag = breakpoint;
|
||||
item.Checked = breakpoint.Enabled;
|
||||
item.UseItemStyleForSubItems = false;
|
||||
item.SubItems.Add(breakpoint.MarkEvent ? "☑" : "☐").Font = _markedColumnFont;
|
||||
item.SubItems.Add(breakpoint.ToReadableType());
|
||||
item.SubItems.Add(breakpoint.GetAddressString(mnuShowLabels.Checked));
|
||||
item.SubItems.Add(breakpoint.Condition);
|
||||
lstBreakpoints.Items.Add(item);
|
||||
}
|
||||
lstBreakpoints.EndUpdate();
|
||||
if(lstBreakpoints.Items.Count > 0) {
|
||||
lstBreakpoints.TopItem = lstBreakpoints.Items[lstBreakpoints.Items.Count > topIndex ? topIndex : lstBreakpoints.Items.Count - 1];
|
||||
}
|
||||
|
||||
lstBreakpoints.ItemChecked += new ItemCheckedEventHandler(lstBreakpoints_ItemChecked);
|
||||
}
|
||||
|
||||
private void lstBreakpoints_ItemChecked(object sender, ItemCheckedEventArgs e)
|
||||
{
|
||||
if(((Breakpoint)e.Item.Tag).Enabled != e.Item.Checked) {
|
||||
((Breakpoint)e.Item.Tag).SetEnabled(e.Item.Checked);
|
||||
}
|
||||
}
|
||||
|
||||
private void lstBreakpoints_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(lstBreakpoints.SelectedItems.Count > 0) {
|
||||
BreakpointManager.EditBreakpoint(((Breakpoint)lstBreakpoints.SelectedItems[0].Tag));
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuRemoveBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
foreach(ListViewItem item in lstBreakpoints.SelectedItems) {
|
||||
BreakpointManager.RemoveBreakpoint((Breakpoint)item.Tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuAddBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
Breakpoint breakpoint = new Breakpoint();
|
||||
if(new frmBreakpoint(breakpoint).ShowDialog() == DialogResult.OK) {
|
||||
BreakpointManager.AddBreakpoint(breakpoint);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuGoToLocation_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(BreakpointNavigation != null) {
|
||||
Breakpoint bp = lstBreakpoints.SelectedItems[0].Tag as Breakpoint;
|
||||
if(bp.IsCpuBreakpoint && bp.GetRelativeAddress() >= 0) {
|
||||
BreakpointNavigation(bp, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuEditBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(lstBreakpoints.SelectedItems.Count > 0) {
|
||||
BreakpointManager.EditBreakpoint(((Breakpoint)lstBreakpoints.SelectedItems[0].Tag));
|
||||
}
|
||||
}
|
||||
|
||||
private void lstBreakpoints_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
mnuRemoveBreakpoint.Enabled = (lstBreakpoints.SelectedItems.Count > 0);
|
||||
mnuEditBreakpoint.Enabled = (lstBreakpoints.SelectedItems.Count == 1);
|
||||
if(lstBreakpoints.SelectedItems.Count == 1) {
|
||||
Breakpoint bp = lstBreakpoints.SelectedItems[0].Tag as Breakpoint;
|
||||
mnuGoToLocation.Enabled = bp.IsCpuBreakpoint && bp.GetRelativeAddress() >= 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void mnuShowLabels_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
//TODO
|
||||
/*ConfigManager.Config.Debug.ShowBreakpointLabels = mnuShowLabels.Checked;
|
||||
ConfigManager.ApplyChanges();
|
||||
*/
|
||||
this.RefreshListAddresses();
|
||||
}
|
||||
|
||||
private void lstBreakpoints_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
ListViewHitTestInfo info = lstBreakpoints.HitTest(e.X, e.Y);
|
||||
if(info != null && info.Item != null) {
|
||||
int row = info.Item.Index;
|
||||
int col = info.Item.SubItems.IndexOf(info.SubItem);
|
||||
|
||||
if(col == 1 && row < lstBreakpoints.Items.Count) {
|
||||
this.BeginInvoke((Action)(() => {
|
||||
Breakpoint bp = lstBreakpoints.Items[row].Tag as Breakpoint;
|
||||
bp?.SetMarked(!bp.MarkEvent);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
188
UI/Debugger/Breakpoints/ctrlBreakpoints.designer.cs
generated
Normal file
188
UI/Debugger/Breakpoints/ctrlBreakpoints.designer.cs
generated
Normal file
|
@ -0,0 +1,188 @@
|
|||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class ctrlBreakpoints
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
BreakpointManager.BreakpointsChanged -= BreakpointManager_OnBreakpointChanged;
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.mnuBreakpoints = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.mnuAddBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEditBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRemoveBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuGoToLocation = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowLabels = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.lstBreakpoints = new Mesen.GUI.Controls.MyListView();
|
||||
this.colEnabled = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colMarker = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colType = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colAddress = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.colCondition = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.mnuBreakpoints.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// mnuBreakpoints
|
||||
//
|
||||
this.mnuBreakpoints.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuAddBreakpoint,
|
||||
this.mnuEditBreakpoint,
|
||||
this.mnuRemoveBreakpoint,
|
||||
this.toolStripMenuItem1,
|
||||
this.mnuGoToLocation,
|
||||
this.toolStripMenuItem2,
|
||||
this.mnuShowLabels});
|
||||
this.mnuBreakpoints.Name = "mnuBreakpoints";
|
||||
this.mnuBreakpoints.Size = new System.Drawing.Size(150, 126);
|
||||
//
|
||||
// mnuAddBreakpoint
|
||||
//
|
||||
this.mnuAddBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Add;
|
||||
this.mnuAddBreakpoint.Name = "mnuAddBreakpoint";
|
||||
this.mnuAddBreakpoint.Size = new System.Drawing.Size(149, 22);
|
||||
this.mnuAddBreakpoint.Text = "Add...";
|
||||
this.mnuAddBreakpoint.Click += new System.EventHandler(this.mnuAddBreakpoint_Click);
|
||||
//
|
||||
// mnuEditBreakpoint
|
||||
//
|
||||
this.mnuEditBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Edit;
|
||||
this.mnuEditBreakpoint.Name = "mnuEditBreakpoint";
|
||||
this.mnuEditBreakpoint.Size = new System.Drawing.Size(149, 22);
|
||||
this.mnuEditBreakpoint.Text = "Edit";
|
||||
this.mnuEditBreakpoint.Click += new System.EventHandler(this.mnuEditBreakpoint_Click);
|
||||
//
|
||||
// mnuRemoveBreakpoint
|
||||
//
|
||||
this.mnuRemoveBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Close;
|
||||
this.mnuRemoveBreakpoint.Name = "mnuRemoveBreakpoint";
|
||||
this.mnuRemoveBreakpoint.Size = new System.Drawing.Size(149, 22);
|
||||
this.mnuRemoveBreakpoint.Text = "Remove";
|
||||
this.mnuRemoveBreakpoint.Click += new System.EventHandler(this.mnuRemoveBreakpoint_Click);
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(146, 6);
|
||||
//
|
||||
// mnuGoToLocation
|
||||
//
|
||||
this.mnuGoToLocation.Name = "mnuGoToLocation";
|
||||
this.mnuGoToLocation.Size = new System.Drawing.Size(149, 22);
|
||||
this.mnuGoToLocation.Text = "Go to location";
|
||||
this.mnuGoToLocation.Click += new System.EventHandler(this.mnuGoToLocation_Click);
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(146, 6);
|
||||
//
|
||||
// mnuShowLabels
|
||||
//
|
||||
this.mnuShowLabels.CheckOnClick = true;
|
||||
this.mnuShowLabels.Name = "mnuShowLabels";
|
||||
this.mnuShowLabels.Size = new System.Drawing.Size(149, 22);
|
||||
this.mnuShowLabels.Text = "Show Labels";
|
||||
//
|
||||
// lstBreakpoints
|
||||
//
|
||||
this.lstBreakpoints.CheckBoxes = true;
|
||||
this.lstBreakpoints.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.colEnabled,
|
||||
this.colMarker,
|
||||
this.colType,
|
||||
this.colAddress,
|
||||
this.colCondition});
|
||||
this.lstBreakpoints.ContextMenuStrip = this.mnuBreakpoints;
|
||||
this.lstBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lstBreakpoints.FullRowSelect = true;
|
||||
this.lstBreakpoints.GridLines = true;
|
||||
this.lstBreakpoints.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
this.lstBreakpoints.Location = new System.Drawing.Point(0, 0);
|
||||
this.lstBreakpoints.Name = "lstBreakpoints";
|
||||
this.lstBreakpoints.Size = new System.Drawing.Size(393, 101);
|
||||
this.lstBreakpoints.TabIndex = 7;
|
||||
this.lstBreakpoints.UseCompatibleStateImageBehavior = false;
|
||||
this.lstBreakpoints.View = System.Windows.Forms.View.Details;
|
||||
this.lstBreakpoints.SelectedIndexChanged += new System.EventHandler(this.lstBreakpoints_SelectedIndexChanged);
|
||||
this.lstBreakpoints.DoubleClick += new System.EventHandler(this.lstBreakpoints_DoubleClick);
|
||||
this.lstBreakpoints.MouseDown += new System.Windows.Forms.MouseEventHandler(this.lstBreakpoints_MouseDown);
|
||||
//
|
||||
// colEnabled
|
||||
//
|
||||
this.colEnabled.Text = "";
|
||||
this.colEnabled.Width = 21;
|
||||
//
|
||||
// colMarker
|
||||
//
|
||||
this.colMarker.Text = "M";
|
||||
this.colMarker.Width = 25;
|
||||
//
|
||||
// colType
|
||||
//
|
||||
this.colType.Text = "Type";
|
||||
this.colType.Width = 87;
|
||||
//
|
||||
// colAddress
|
||||
//
|
||||
this.colAddress.Text = "Address";
|
||||
this.colAddress.Width = 108;
|
||||
//
|
||||
// colCondition
|
||||
//
|
||||
this.colCondition.Text = "Condition";
|
||||
this.colCondition.Width = 142;
|
||||
//
|
||||
// ctrlBreakpoints
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.lstBreakpoints);
|
||||
this.Name = "ctrlBreakpoints";
|
||||
this.Size = new System.Drawing.Size(393, 101);
|
||||
this.mnuBreakpoints.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private Mesen.GUI.Controls.MyListView lstBreakpoints;
|
||||
private System.Windows.Forms.ColumnHeader colType;
|
||||
private System.Windows.Forms.ColumnHeader colAddress;
|
||||
private System.Windows.Forms.ContextMenuStrip mnuBreakpoints;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAddBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRemoveBreakpoint;
|
||||
private System.Windows.Forms.ColumnHeader colEnabled;
|
||||
private System.Windows.Forms.ColumnHeader colCondition;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGoToLocation;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditBreakpoint;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowLabels;
|
||||
private System.Windows.Forms.ColumnHeader colMarker;
|
||||
}
|
||||
}
|
123
UI/Debugger/Breakpoints/ctrlBreakpoints.resx
Normal file
123
UI/Debugger/Breakpoints/ctrlBreakpoints.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="mnuBreakpoints.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
219
UI/Debugger/Breakpoints/frmBreakpoint.cs
Normal file
219
UI/Debugger/Breakpoints/frmBreakpoint.cs
Normal file
|
@ -0,0 +1,219 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmBreakpoint : BaseConfigForm
|
||||
{
|
||||
public frmBreakpoint(Breakpoint breakpoint)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Entity = breakpoint;
|
||||
|
||||
switch(breakpoint.AddressType) {
|
||||
case BreakpointAddressType.AnyAddress: radAnyAddress.Checked = true; break;
|
||||
case BreakpointAddressType.SingleAddress: radSpecificAddress.Checked = true; break;
|
||||
case BreakpointAddressType.AddressRange: radRange.Checked = true; break;
|
||||
}
|
||||
|
||||
AddBinding("MemoryType", cboBreakpointType);
|
||||
AddBinding("Enabled", chkEnabled);
|
||||
AddBinding("MarkEvent", chkMarkOnEventViewer);
|
||||
AddBinding("Address", txtAddress);
|
||||
AddBinding("StartAddress", txtFrom);
|
||||
AddBinding("EndAddress", txtTo);
|
||||
AddBinding("BreakOnRead", chkRead);
|
||||
AddBinding("BreakOnWrite", chkWrite);
|
||||
AddBinding("BreakOnExec", chkExec);
|
||||
AddBinding("Condition", txtCondition);
|
||||
|
||||
cboBreakpointType.Items.Clear();
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CpuMemory));
|
||||
cboBreakpointType.Items.Add("-");
|
||||
|
||||
//TODO - Might not be useful on the SNES?
|
||||
/*if(DebugApi.GetMemorySize(SnesMemoryType.PrgRom) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
|
||||
}
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.WorkRam) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
|
||||
}
|
||||
if(DebugApi.GetMemorySize(SnesMemoryType.SaveRam) > 0) {
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SaveRam));
|
||||
}
|
||||
|
||||
if(cboBreakpointType.Items.Count > 2) {
|
||||
cboBreakpointType.Items.Add("-");
|
||||
}*/
|
||||
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.VideoRam));
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SpriteRam));
|
||||
cboBreakpointType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CGRam));
|
||||
|
||||
this.toolTip.SetToolTip(this.picExpressionWarning, "Condition contains invalid syntax or symbols.");
|
||||
this.toolTip.SetToolTip(this.picHelp, frmBreakpoint.GetConditionTooltip(false));
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
|
||||
Breakpoint bp = (Breakpoint)this.Entity;
|
||||
if(!BreakpointManager.Breakpoints.Contains(bp)) {
|
||||
//This is a new breakpoint, make sure address fields are empty instead of 0
|
||||
if(bp.Address == UInt32.MaxValue) {
|
||||
txtAddress.Text = "";
|
||||
}
|
||||
if(txtFrom.Text == "0") {
|
||||
txtFrom.Text = "";
|
||||
}
|
||||
if(txtTo.Text == "0") {
|
||||
txtTo.Text = "";
|
||||
}
|
||||
}
|
||||
if(bp.Address == 0 && bp.AddressType != BreakpointAddressType.SingleAddress) {
|
||||
txtAddress.Text = "";
|
||||
}
|
||||
if(bp.StartAddress == 0 && bp.EndAddress == 0 && bp.AddressType != BreakpointAddressType.AddressRange) {
|
||||
txtFrom.Text = "";
|
||||
txtTo.Text = "";
|
||||
}
|
||||
|
||||
if(bp.AddressType == BreakpointAddressType.AddressRange) {
|
||||
txtFrom.Focus();
|
||||
txtFrom.SelectionStart = 0;
|
||||
txtFrom.SelectionLength = 0;
|
||||
} else if(bp.AddressType == BreakpointAddressType.SingleAddress) {
|
||||
txtAddress.Focus();
|
||||
txtAddress.SelectionStart = 0;
|
||||
txtAddress.SelectionLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetConditionTooltip(bool forWatch)
|
||||
{
|
||||
string tooltip =
|
||||
"Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine +
|
||||
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine +
|
||||
"Note 2: Labels assigned to the code can be used (their value will match the label's address in CPU memory)." + Environment.NewLine + Environment.NewLine +
|
||||
"A/X/Y/PS/SP: Value of registers" + Environment.NewLine +
|
||||
"PC: Program Counter" + Environment.NewLine +
|
||||
"OpPC: Address of the current instruction's first byte" + Environment.NewLine +
|
||||
"PreviousOpPC: Address of the previous instruction's first byte" + Environment.NewLine +
|
||||
"Irq/Nmi/Sprite0Hit/SpriteOverflow/VerticalBlank: True if the corresponding flags are set" + Environment.NewLine +
|
||||
"Branched: True if the current instruction was reached by jumping or branching" + Environment.NewLine +
|
||||
"Cycle/Scanline: Current cycle (0-340)/scanline(-1 to 260) of the PPU" + Environment.NewLine +
|
||||
"Frame: PPU frame number (since power on/reset)" + Environment.NewLine +
|
||||
"Value: Current value being read/written from/to memory" + Environment.NewLine +
|
||||
"IsRead: True if the CPU is reading from a memory address" + Environment.NewLine +
|
||||
"IsWrite: True if the CPU is writing to a memory address" + Environment.NewLine;
|
||||
|
||||
if(!forWatch) {
|
||||
tooltip +=
|
||||
"Address: Current CPU memory address being read/written" + Environment.NewLine +
|
||||
"RomAddress: Current ROM address being read/written" + Environment.NewLine;
|
||||
}
|
||||
|
||||
tooltip +=
|
||||
"[<address>]: (Byte) Memory value at <address> (CPU)" + Environment.NewLine +
|
||||
"{<address>}: (Word) Memory value at <address> (CPU)" + Environment.NewLine + Environment.NewLine +
|
||||
|
||||
"Examples:" + Environment.NewLine +
|
||||
"a == 10 || x == $23" + Environment.NewLine +
|
||||
"scanline == 10 && (cycle >= 55 && cycle <= 100)" + Environment.NewLine +
|
||||
"x == [$150] || y == [10]" + Environment.NewLine +
|
||||
"[[$15] + y] -> Reads the value at address $15, adds Y to it and reads the value at the resulting address." + Environment.NewLine +
|
||||
"{$FFFA} -> Returns the NMI handler's address.";
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
protected override void UpdateConfig()
|
||||
{
|
||||
base.UpdateConfig();
|
||||
|
||||
if(radAnyAddress.Checked) {
|
||||
((Breakpoint)Entity).AddressType = BreakpointAddressType.AnyAddress;
|
||||
} else if(radSpecificAddress.Checked) {
|
||||
((Breakpoint)Entity).AddressType = BreakpointAddressType.SingleAddress;
|
||||
} else if(radRange.Checked) {
|
||||
((Breakpoint)Entity).AddressType = BreakpointAddressType.AddressRange;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool ValidateInput()
|
||||
{
|
||||
if(txtCondition.Text.Trim().Length > 0) {
|
||||
EvalResultType resultType;
|
||||
DebugApi.EvaluateExpression(txtCondition.Text.Replace(Environment.NewLine, " "), out resultType, false);
|
||||
if(resultType == EvalResultType.Invalid) {
|
||||
picExpressionWarning.Visible = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
picExpressionWarning.Visible = false;
|
||||
|
||||
SnesMemoryType type = cboBreakpointType.GetEnumValue<SnesMemoryType>();
|
||||
int maxValue = DebugApi.GetMemorySize(type) - 1;
|
||||
|
||||
if(radSpecificAddress.Checked) {
|
||||
if(ValidateAddress(txtAddress, maxValue) < 0) {
|
||||
return false;
|
||||
}
|
||||
} else if(radRange.Checked) {
|
||||
int start = ValidateAddress(txtFrom, maxValue);
|
||||
int end = ValidateAddress(txtTo, maxValue);
|
||||
|
||||
if(start < 0 || end < 0 || end < start) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return chkRead.Checked || chkWrite.Checked || (chkExec.Checked && Breakpoint.IsTypeCpuBreakpoint(type)) || txtCondition.Text.Length > 0;
|
||||
}
|
||||
|
||||
private int ValidateAddress(TextBox field, int maxValue)
|
||||
{
|
||||
int value = -1;
|
||||
if(!int.TryParse(field.Text, NumberStyles.HexNumber, null, out value) || value > maxValue) {
|
||||
field.ForeColor = Color.Red;
|
||||
value = -1;
|
||||
} else {
|
||||
field.ForeColor = SystemColors.ControlText;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private void txtAddress_Enter(object sender, EventArgs e)
|
||||
{
|
||||
radSpecificAddress.Checked = true;
|
||||
}
|
||||
|
||||
private void txtFrom_Enter(object sender, EventArgs e)
|
||||
{
|
||||
radRange.Checked = true;
|
||||
}
|
||||
|
||||
private void txtTo_Enter(object sender, EventArgs e)
|
||||
{
|
||||
radRange.Checked = true;
|
||||
}
|
||||
|
||||
private void cboBreakpointType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
SnesMemoryType type = cboBreakpointType.GetEnumValue<SnesMemoryType>();
|
||||
|
||||
chkExec.Visible = Breakpoint.IsTypeCpuBreakpoint(type);
|
||||
|
||||
string maxValue = (DebugApi.GetMemorySize(type) - 1).ToString("X2");
|
||||
string minValue = "".PadLeft(maxValue.Length, '0');
|
||||
|
||||
lblRange.Text = $"(range: ${minValue}-${maxValue})";
|
||||
}
|
||||
}
|
||||
}
|
562
UI/Debugger/Breakpoints/frmBreakpoint.designer.cs
generated
Normal file
562
UI/Debugger/Breakpoints/frmBreakpoint.designer.cs
generated
Normal file
|
@ -0,0 +1,562 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmBreakpoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblBreakpointType = new System.Windows.Forms.Label();
|
||||
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.lblBreakOn = new System.Windows.Forms.Label();
|
||||
this.lblAddress = 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.picExpressionWarning = new System.Windows.Forms.PictureBox();
|
||||
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.txtAddress = new System.Windows.Forms.TextBox();
|
||||
this.radSpecificAddress = new System.Windows.Forms.RadioButton();
|
||||
this.radAnyAddress = new System.Windows.Forms.RadioButton();
|
||||
this.lblAddressSign = new System.Windows.Forms.Label();
|
||||
this.radRange = new System.Windows.Forms.RadioButton();
|
||||
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.txtTo = new System.Windows.Forms.TextBox();
|
||||
this.lblTo = new System.Windows.Forms.Label();
|
||||
this.txtFrom = new System.Windows.Forms.TextBox();
|
||||
this.lblFrom = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.cboBreakpointType = new Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator();
|
||||
this.lblRange = new System.Windows.Forms.Label();
|
||||
this.tableLayoutPanel6 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.lblCondition = new System.Windows.Forms.Label();
|
||||
this.chkMarkOnEventViewer = new System.Windows.Forms.CheckBox();
|
||||
this.chkEnabled = new System.Windows.Forms.CheckBox();
|
||||
this.tableLayoutPanel7 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.flowLayoutPanel2.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picHelp)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).BeginInit();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
this.tableLayoutPanel5.SuspendLayout();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
this.tableLayoutPanel6.SuspendLayout();
|
||||
this.tableLayoutPanel7.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// baseConfigPanel
|
||||
//
|
||||
this.baseConfigPanel.Location = new System.Drawing.Point(0, 197);
|
||||
this.baseConfigPanel.Size = new System.Drawing.Size(426, 29);
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblBreakpointType, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblBreakOn, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel4, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel6, 0, 3);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 6;
|
||||
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.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(426, 226);
|
||||
this.tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// lblBreakpointType
|
||||
//
|
||||
this.lblBreakpointType.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblBreakpointType.AutoSize = true;
|
||||
this.lblBreakpointType.Location = new System.Drawing.Point(3, 8);
|
||||
this.lblBreakpointType.Margin = new System.Windows.Forms.Padding(3, 4, 3, 0);
|
||||
this.lblBreakpointType.Name = "lblBreakpointType";
|
||||
this.lblBreakpointType.Size = new System.Drawing.Size(88, 13);
|
||||
this.lblBreakpointType.TabIndex = 12;
|
||||
this.lblBreakpointType.Text = "Breakpoint Type:";
|
||||
//
|
||||
// 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(94, 25);
|
||||
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
|
||||
this.flowLayoutPanel2.Size = new System.Drawing.Size(332, 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;
|
||||
//
|
||||
// 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;
|
||||
//
|
||||
// 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;
|
||||
//
|
||||
// lblBreakOn
|
||||
//
|
||||
this.lblBreakOn.AutoSize = true;
|
||||
this.lblBreakOn.Location = new System.Drawing.Point(3, 29);
|
||||
this.lblBreakOn.Margin = new System.Windows.Forms.Padding(3, 4, 3, 0);
|
||||
this.lblBreakOn.Name = "lblBreakOn";
|
||||
this.lblBreakOn.Size = new System.Drawing.Size(53, 13);
|
||||
this.lblBreakOn.TabIndex = 0;
|
||||
this.lblBreakOn.Text = "Break on:";
|
||||
//
|
||||
// lblAddress
|
||||
//
|
||||
this.lblAddress.AutoSize = true;
|
||||
this.lblAddress.Location = new System.Drawing.Point(3, 53);
|
||||
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:";
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 3;
|
||||
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.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel2.Controls.Add(this.picHelp, 2, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.txtCondition, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.picExpressionWarning, 1, 0);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(94, 123);
|
||||
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(329, 65);
|
||||
this.tableLayoutPanel2.TabIndex = 10;
|
||||
//
|
||||
// picHelp
|
||||
//
|
||||
this.picHelp.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.picHelp.Image = global::Mesen.GUI.Properties.Resources.Help;
|
||||
this.picHelp.Location = new System.Drawing.Point(308, 24);
|
||||
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.AcceptsReturn = true;
|
||||
this.txtCondition.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtCondition.Location = new System.Drawing.Point(3, 3);
|
||||
this.txtCondition.MaxLength = 900;
|
||||
this.txtCondition.Multiline = true;
|
||||
this.txtCondition.Name = "txtCondition";
|
||||
this.txtCondition.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
|
||||
this.txtCondition.Size = new System.Drawing.Size(275, 59);
|
||||
this.txtCondition.TabIndex = 6;
|
||||
//
|
||||
// picExpressionWarning
|
||||
//
|
||||
this.picExpressionWarning.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.picExpressionWarning.Image = global::Mesen.GUI.Properties.Resources.Warning;
|
||||
this.picExpressionWarning.Location = new System.Drawing.Point(284, 24);
|
||||
this.picExpressionWarning.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
|
||||
this.picExpressionWarning.Name = "picExpressionWarning";
|
||||
this.picExpressionWarning.Size = new System.Drawing.Size(18, 18);
|
||||
this.picExpressionWarning.TabIndex = 9;
|
||||
this.picExpressionWarning.TabStop = false;
|
||||
this.picExpressionWarning.Visible = false;
|
||||
//
|
||||
// tableLayoutPanel3
|
||||
//
|
||||
this.tableLayoutPanel3.ColumnCount = 4;
|
||||
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
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, 2, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.radSpecificAddress, 0, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.radAnyAddress, 0, 2);
|
||||
this.tableLayoutPanel3.Controls.Add(this.lblAddressSign, 1, 0);
|
||||
this.tableLayoutPanel3.Controls.Add(this.radRange, 0, 1);
|
||||
this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel5, 1, 1);
|
||||
this.tableLayoutPanel3.Location = new System.Drawing.Point(94, 48);
|
||||
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
|
||||
this.tableLayoutPanel3.RowCount = 4;
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel3.Size = new System.Drawing.Size(271, 75);
|
||||
this.tableLayoutPanel3.TabIndex = 11;
|
||||
//
|
||||
// txtAddress
|
||||
//
|
||||
this.txtAddress.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.txtAddress.Location = new System.Drawing.Point(85, 3);
|
||||
this.txtAddress.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
|
||||
this.txtAddress.Name = "txtAddress";
|
||||
this.txtAddress.Size = new System.Drawing.Size(64, 20);
|
||||
this.txtAddress.TabIndex = 5;
|
||||
this.txtAddress.Enter += new System.EventHandler(this.txtAddress_Enter);
|
||||
//
|
||||
// radSpecificAddress
|
||||
//
|
||||
this.radSpecificAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.radSpecificAddress.AutoSize = true;
|
||||
this.radSpecificAddress.Location = new System.Drawing.Point(3, 4);
|
||||
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.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.radAnyAddress.AutoSize = true;
|
||||
this.radAnyAddress.Location = new System.Drawing.Point(3, 52);
|
||||
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;
|
||||
//
|
||||
// lblAddressSign
|
||||
//
|
||||
this.lblAddressSign.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblAddressSign.AutoSize = true;
|
||||
this.lblAddressSign.Location = new System.Drawing.Point(72, 6);
|
||||
this.lblAddressSign.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lblAddressSign.Name = "lblAddressSign";
|
||||
this.lblAddressSign.Size = new System.Drawing.Size(13, 13);
|
||||
this.lblAddressSign.TabIndex = 9;
|
||||
this.lblAddressSign.Text = "$";
|
||||
//
|
||||
// radRange
|
||||
//
|
||||
this.radRange.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.radRange.AutoSize = true;
|
||||
this.radRange.Location = new System.Drawing.Point(3, 29);
|
||||
this.radRange.Name = "radRange";
|
||||
this.radRange.Size = new System.Drawing.Size(60, 17);
|
||||
this.radRange.TabIndex = 10;
|
||||
this.radRange.TabStop = true;
|
||||
this.radRange.Text = "Range:";
|
||||
this.radRange.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel5
|
||||
//
|
||||
this.tableLayoutPanel5.ColumnCount = 4;
|
||||
this.tableLayoutPanel3.SetColumnSpan(this.tableLayoutPanel5, 2);
|
||||
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel5.Controls.Add(this.txtTo, 3, 0);
|
||||
this.tableLayoutPanel5.Controls.Add(this.lblTo, 2, 0);
|
||||
this.tableLayoutPanel5.Controls.Add(this.txtFrom, 1, 0);
|
||||
this.tableLayoutPanel5.Controls.Add(this.lblFrom, 0, 0);
|
||||
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel5.Location = new System.Drawing.Point(72, 26);
|
||||
this.tableLayoutPanel5.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
|
||||
this.tableLayoutPanel5.RowCount = 1;
|
||||
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel5.Size = new System.Drawing.Size(199, 23);
|
||||
this.tableLayoutPanel5.TabIndex = 12;
|
||||
//
|
||||
// txtTo
|
||||
//
|
||||
this.txtTo.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.txtTo.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtTo.Location = new System.Drawing.Point(131, 3);
|
||||
this.txtTo.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
|
||||
this.txtTo.Name = "txtTo";
|
||||
this.txtTo.Size = new System.Drawing.Size(65, 20);
|
||||
this.txtTo.TabIndex = 13;
|
||||
this.txtTo.Enter += new System.EventHandler(this.txtTo_Enter);
|
||||
//
|
||||
// lblTo
|
||||
//
|
||||
this.lblTo.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblTo.AutoSize = true;
|
||||
this.lblTo.Location = new System.Drawing.Point(106, 5);
|
||||
this.lblTo.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lblTo.Name = "lblTo";
|
||||
this.lblTo.Size = new System.Drawing.Size(25, 13);
|
||||
this.lblTo.TabIndex = 11;
|
||||
this.lblTo.Text = "to $";
|
||||
//
|
||||
// txtFrom
|
||||
//
|
||||
this.txtFrom.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.txtFrom.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.txtFrom.Location = new System.Drawing.Point(39, 3);
|
||||
this.txtFrom.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
|
||||
this.txtFrom.Name = "txtFrom";
|
||||
this.txtFrom.Size = new System.Drawing.Size(64, 20);
|
||||
this.txtFrom.TabIndex = 12;
|
||||
this.txtFrom.Enter += new System.EventHandler(this.txtFrom_Enter);
|
||||
//
|
||||
// lblFrom
|
||||
//
|
||||
this.lblFrom.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblFrom.AutoSize = true;
|
||||
this.lblFrom.Location = new System.Drawing.Point(0, 5);
|
||||
this.lblFrom.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lblFrom.Name = "lblFrom";
|
||||
this.lblFrom.Size = new System.Drawing.Size(39, 13);
|
||||
this.lblFrom.TabIndex = 10;
|
||||
this.lblFrom.Text = "From $";
|
||||
//
|
||||
// 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.cboBreakpointType, 0, 0);
|
||||
this.tableLayoutPanel4.Controls.Add(this.lblRange, 1, 0);
|
||||
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel4.Location = new System.Drawing.Point(94, 0);
|
||||
this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
|
||||
this.tableLayoutPanel4.RowCount = 1;
|
||||
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel4.Size = new System.Drawing.Size(332, 25);
|
||||
this.tableLayoutPanel4.TabIndex = 13;
|
||||
//
|
||||
// cboBreakpointType
|
||||
//
|
||||
this.cboBreakpointType.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
|
||||
this.cboBreakpointType.FormattingEnabled = true;
|
||||
this.cboBreakpointType.Location = new System.Drawing.Point(3, 3);
|
||||
this.cboBreakpointType.Name = "cboBreakpointType";
|
||||
this.cboBreakpointType.Size = new System.Drawing.Size(121, 21);
|
||||
this.cboBreakpointType.TabIndex = 13;
|
||||
this.cboBreakpointType.SelectedIndexChanged += new System.EventHandler(this.cboBreakpointType_SelectedIndexChanged);
|
||||
//
|
||||
// lblRange
|
||||
//
|
||||
this.lblRange.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblRange.AutoSize = true;
|
||||
this.lblRange.ForeColor = System.Drawing.SystemColors.ControlDarkDark;
|
||||
this.lblRange.Location = new System.Drawing.Point(130, 6);
|
||||
this.lblRange.Name = "lblRange";
|
||||
this.lblRange.Size = new System.Drawing.Size(40, 13);
|
||||
this.lblRange.TabIndex = 6;
|
||||
this.lblRange.Text = "(range)";
|
||||
//
|
||||
// tableLayoutPanel6
|
||||
//
|
||||
this.tableLayoutPanel6.ColumnCount = 1;
|
||||
this.tableLayoutPanel6.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel6.Controls.Add(this.label1, 0, 1);
|
||||
this.tableLayoutPanel6.Controls.Add(this.lblCondition, 0, 0);
|
||||
this.tableLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel6.Location = new System.Drawing.Point(0, 123);
|
||||
this.tableLayoutPanel6.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel6.Name = "tableLayoutPanel6";
|
||||
this.tableLayoutPanel6.RowCount = 2;
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel6.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel6.Size = new System.Drawing.Size(94, 65);
|
||||
this.tableLayoutPanel6.TabIndex = 14;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.ForeColor = System.Drawing.SystemColors.GrayText;
|
||||
this.label1.Location = new System.Drawing.Point(3, 32);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(50, 13);
|
||||
this.label1.TabIndex = 8;
|
||||
this.label1.Text = "(optional)";
|
||||
//
|
||||
// lblCondition
|
||||
//
|
||||
this.lblCondition.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.lblCondition.AutoSize = true;
|
||||
this.lblCondition.Location = new System.Drawing.Point(3, 19);
|
||||
this.lblCondition.Name = "lblCondition";
|
||||
this.lblCondition.Size = new System.Drawing.Size(54, 13);
|
||||
this.lblCondition.TabIndex = 7;
|
||||
this.lblCondition.Text = "Condition:";
|
||||
//
|
||||
// chkMarkOnEventViewer
|
||||
//
|
||||
this.chkMarkOnEventViewer.AutoSize = true;
|
||||
this.chkMarkOnEventViewer.Location = new System.Drawing.Point(3, 3);
|
||||
this.chkMarkOnEventViewer.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.chkMarkOnEventViewer.Name = "chkMarkOnEventViewer";
|
||||
this.chkMarkOnEventViewer.Size = new System.Drawing.Size(131, 17);
|
||||
this.chkMarkOnEventViewer.TabIndex = 15;
|
||||
this.chkMarkOnEventViewer.Text = "Mark on Event Viewer";
|
||||
this.chkMarkOnEventViewer.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// chkEnabled
|
||||
//
|
||||
this.chkEnabled.AutoSize = true;
|
||||
this.chkEnabled.Location = new System.Drawing.Point(3, 20);
|
||||
this.chkEnabled.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.chkEnabled.Name = "chkEnabled";
|
||||
this.chkEnabled.Size = new System.Drawing.Size(104, 17);
|
||||
this.chkEnabled.TabIndex = 2;
|
||||
this.chkEnabled.Text = "Break Execution";
|
||||
this.chkEnabled.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// tableLayoutPanel7
|
||||
//
|
||||
this.tableLayoutPanel7.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.tableLayoutPanel7.ColumnCount = 1;
|
||||
this.tableLayoutPanel7.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel7.Controls.Add(this.chkEnabled, 0, 3);
|
||||
this.tableLayoutPanel7.Controls.Add(this.chkMarkOnEventViewer, 0, 2);
|
||||
this.tableLayoutPanel7.Location = new System.Drawing.Point(0, 188);
|
||||
this.tableLayoutPanel7.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.tableLayoutPanel7.Name = "tableLayoutPanel7";
|
||||
this.tableLayoutPanel7.RowCount = 4;
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel7.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel7.Size = new System.Drawing.Size(243, 37);
|
||||
this.tableLayoutPanel7.TabIndex = 3;
|
||||
//
|
||||
// frmBreakpoint
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(426, 226);
|
||||
this.Controls.Add(this.tableLayoutPanel7);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "frmBreakpoint";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Breakpoint";
|
||||
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
|
||||
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
|
||||
this.Controls.SetChildIndex(this.tableLayoutPanel7, 0);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.flowLayoutPanel2.ResumeLayout(false);
|
||||
this.flowLayoutPanel2.PerformLayout();
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picHelp)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picExpressionWarning)).EndInit();
|
||||
this.tableLayoutPanel3.ResumeLayout(false);
|
||||
this.tableLayoutPanel3.PerformLayout();
|
||||
this.tableLayoutPanel5.ResumeLayout(false);
|
||||
this.tableLayoutPanel5.PerformLayout();
|
||||
this.tableLayoutPanel4.ResumeLayout(false);
|
||||
this.tableLayoutPanel4.PerformLayout();
|
||||
this.tableLayoutPanel6.ResumeLayout(false);
|
||||
this.tableLayoutPanel6.PerformLayout();
|
||||
this.tableLayoutPanel7.ResumeLayout(false);
|
||||
this.tableLayoutPanel7.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label lblBreakOn;
|
||||
private System.Windows.Forms.Label lblAddress;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
|
||||
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.CheckBox chkExec;
|
||||
private System.Windows.Forms.CheckBox chkRead;
|
||||
private System.Windows.Forms.CheckBox chkWrite;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
|
||||
private System.Windows.Forms.RadioButton radSpecificAddress;
|
||||
private System.Windows.Forms.RadioButton radAnyAddress;
|
||||
private System.Windows.Forms.Label lblAddressSign;
|
||||
private System.Windows.Forms.PictureBox picExpressionWarning;
|
||||
private System.Windows.Forms.RadioButton radRange;
|
||||
private System.Windows.Forms.Label lblFrom;
|
||||
private System.Windows.Forms.TextBox txtFrom;
|
||||
private System.Windows.Forms.Label lblTo;
|
||||
private System.Windows.Forms.TextBox txtTo;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
|
||||
private System.Windows.Forms.Label lblBreakpointType;
|
||||
private Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator cboBreakpointType;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
|
||||
private System.Windows.Forms.Label lblRange;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel6;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.CheckBox chkMarkOnEventViewer;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel7;
|
||||
}
|
||||
}
|
123
UI/Debugger/Breakpoints/frmBreakpoint.resx
Normal file
123
UI/Debugger/Breakpoints/frmBreakpoint.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<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>
|
|
@ -116,13 +116,14 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
props.Symbol |= LineSymbol.Arrow;
|
||||
}
|
||||
|
||||
public LineProperties GetLineStyle(CodeLineData lineData, int lineNumber)
|
||||
public LineProperties GetLineStyle(CodeLineData lineData, int lineIndex)
|
||||
{
|
||||
DebugInfo info = ConfigManager.Config.Debug;
|
||||
LineProperties props = new LineProperties();
|
||||
//TODO
|
||||
//AddressInfo addressInfo = _code.GetAddressInfo(lineNumber);
|
||||
//GetBreakpointLineProperties(props, cpuAddress, addressInfo);
|
||||
|
||||
if(lineData.Address >= 0) {
|
||||
GetBreakpointLineProperties(props, lineData.Address);
|
||||
}
|
||||
|
||||
bool isActiveStatement = ActiveAddress.HasValue && ActiveAddress.Value == lineData.Address;
|
||||
if(isActiveStatement) {
|
||||
|
@ -151,13 +152,11 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
return props;
|
||||
}
|
||||
|
||||
public static void GetBreakpointLineProperties(LineProperties props, int cpuAddress, AddressInfo addressInfo)
|
||||
public static void GetBreakpointLineProperties(LineProperties props, int cpuAddress)
|
||||
{
|
||||
//TODO
|
||||
|
||||
/*DebugInfo config = ConfigManager.Config.Debug;
|
||||
DebugInfo config = ConfigManager.Config.Debug;
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
if(breakpoint.Matches(cpuAddress, addressInfo)) {
|
||||
if(breakpoint.Matches((uint)cpuAddress, SnesMemoryType.CpuMemory)) {
|
||||
Color fgColor = Color.White;
|
||||
Color? bgColor = null;
|
||||
Color bpColor = breakpoint.BreakOnExec ? config.CodeExecBreakpointColor : (breakpoint.BreakOnWrite ? config.CodeWriteBreakpointColor : config.CodeReadBreakpointColor);
|
||||
|
@ -185,7 +184,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
props.Symbol = symbol;
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
47
UI/Debugger/frmDebugger.Designer.cs
generated
47
UI/Debugger/frmDebugger.Designer.cs
generated
|
@ -58,12 +58,17 @@
|
|||
this.ctrlSplitContainer = new Mesen.GUI.Controls.ctrlSplitContainer();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
|
||||
this.grpWatch = new System.Windows.Forms.GroupBox();
|
||||
this.grpBreakpoints = new System.Windows.Forms.GroupBox();
|
||||
this.ctrlBreakpoints = new Mesen.GUI.Debugger.Controls.ctrlBreakpoints();
|
||||
this.ctrlMesenMenuStrip1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainer)).BeginInit();
|
||||
this.ctrlSplitContainer.Panel1.SuspendLayout();
|
||||
this.ctrlSplitContainer.Panel2.SuspendLayout();
|
||||
this.ctrlSplitContainer.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.grpWatch.SuspendLayout();
|
||||
this.grpBreakpoints.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ctrlDisassemblyView
|
||||
|
@ -275,7 +280,8 @@
|
|||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel1.Controls.Add(this.ctrlWatch, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpWatch, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.grpBreakpoints, 1, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
|
@ -287,11 +293,41 @@
|
|||
// ctrlWatch
|
||||
//
|
||||
this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlWatch.Location = new System.Drawing.Point(3, 3);
|
||||
this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlWatch.Name = "ctrlWatch";
|
||||
this.ctrlWatch.Size = new System.Drawing.Size(420, 171);
|
||||
this.ctrlWatch.Size = new System.Drawing.Size(414, 152);
|
||||
this.ctrlWatch.TabIndex = 0;
|
||||
//
|
||||
// grpWatch
|
||||
//
|
||||
this.grpWatch.Controls.Add(this.ctrlWatch);
|
||||
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpWatch.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpWatch.Name = "grpWatch";
|
||||
this.grpWatch.Size = new System.Drawing.Size(420, 171);
|
||||
this.grpWatch.TabIndex = 1;
|
||||
this.grpWatch.TabStop = false;
|
||||
this.grpWatch.Text = "Watch";
|
||||
//
|
||||
// grpBreakpoints
|
||||
//
|
||||
this.grpBreakpoints.Controls.Add(this.ctrlBreakpoints);
|
||||
this.grpBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpBreakpoints.Location = new System.Drawing.Point(429, 3);
|
||||
this.grpBreakpoints.Name = "grpBreakpoints";
|
||||
this.grpBreakpoints.Size = new System.Drawing.Size(420, 171);
|
||||
this.grpBreakpoints.TabIndex = 2;
|
||||
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(414, 152);
|
||||
this.ctrlBreakpoints.TabIndex = 0;
|
||||
//
|
||||
// frmDebugger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -308,6 +344,8 @@
|
|||
((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainer)).EndInit();
|
||||
this.ctrlSplitContainer.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.grpWatch.ResumeLayout(false);
|
||||
this.grpBreakpoints.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
|
@ -342,5 +380,8 @@
|
|||
private GUI.Controls.ctrlSplitContainer ctrlSplitContainer;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private ctrlWatch ctrlWatch;
|
||||
private System.Windows.Forms.GroupBox grpWatch;
|
||||
private System.Windows.Forms.GroupBox grpBreakpoints;
|
||||
private Controls.ctrlBreakpoints ctrlBreakpoints;
|
||||
}
|
||||
}
|
|
@ -61,6 +61,8 @@ namespace Mesen.GUI
|
|||
[DllImport(DllPath)] public static extern void SetMemoryValues(SnesMemoryType type, UInt32 address, [In] byte[] data, Int32 length);
|
||||
[DllImport(DllPath)] public static extern void SetMemoryState(SnesMemoryType type, [In] byte[] buffer, Int32 length);
|
||||
|
||||
[DllImport(DllPath)] public static extern void SetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]InteropBreakpoint[] breakpoints, UInt32 length);
|
||||
|
||||
[DllImport(DllPath, EntryPoint = "GetMemoryState")] private static extern void GetMemoryStateWrapper(SnesMemoryType type, [In, Out] byte[] buffer);
|
||||
public static byte[] GetMemoryState(SnesMemoryType type)
|
||||
{
|
||||
|
|
21
UI/UI.csproj
21
UI/UI.csproj
|
@ -212,6 +212,21 @@
|
|||
<Compile Include="Config\ConfigAttributes.cs" />
|
||||
<Compile Include="Config\Configuration.cs" />
|
||||
<Compile Include="Config\ConfigManager.cs" />
|
||||
<Compile Include="Debugger\Breakpoints\Breakpoint.cs" />
|
||||
<Compile Include="Debugger\Breakpoints\BreakpointManager.cs" />
|
||||
<Compile Include="Debugger\Breakpoints\ctrlBreakpoints.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Breakpoints\ctrlBreakpoints.designer.cs">
|
||||
<DependentUpon>ctrlBreakpoints.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Breakpoints\frmBreakpoint.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Breakpoints\frmBreakpoint.designer.cs">
|
||||
<DependentUpon>frmBreakpoint.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Breakpoints\InteropBreakpoint.cs" />
|
||||
<Compile Include="Debugger\Config\DebuggerShortcutsConfig.cs" />
|
||||
<Compile Include="Debugger\Config\HexEditorInfo.cs" />
|
||||
<Compile Include="Debugger\Config\TraceLoggerInfo.cs" />
|
||||
|
@ -454,6 +469,12 @@
|
|||
<EmbeddedResource Include="Controls\ctrlRenderer.resx">
|
||||
<DependentUpon>ctrlRenderer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Breakpoints\ctrlBreakpoints.resx">
|
||||
<DependentUpon>ctrlBreakpoints.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Breakpoints\frmBreakpoint.resx">
|
||||
<DependentUpon>frmBreakpoint.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlDbgShortcuts.resx">
|
||||
<DependentUpon>ctrlDbgShortcuts.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Add table
Reference in a new issue