Debugger: Added assembler tool

This commit is contained in:
Sour 2020-02-11 22:01:06 -05:00
parent c385155955
commit b62a0a3960
32 changed files with 2480 additions and 56 deletions

468
Core/Assembler.cpp Normal file
View file

@ -0,0 +1,468 @@
#include "stdafx.h"
#include <regex>
#include <unordered_map>
#include "../Utilities/HexUtilities.h"
#include "../Utilities/StringUtilities.h"
#include "Assembler.h"
#include "Cpu.h"
#include "CpuDisUtils.h"
#include "DisassemblyInfo.h"
#include "LabelManager.h"
static const std::regex instRegex = std::regex("^\\s*([a-zA-Z]{3})[\\s]*(#%|#){0,1}([([]{0,1})[\\s]*([$]{0,1})([^\\[\\],)(;:]*)[\\s]*((,[$][0-9a-f]{1,2}|,x\\)|\\),y|,x|,y|,s\\),y|,s|\\)|\\],y|\\]){0,1})\\s*(;*)(.*)", std::regex_constants::icase);
static const std::regex isCommentOrBlank = std::regex("^\\s*([;]+.*$|\\s*$)", std::regex_constants::icase);
static const std::regex labelRegex = std::regex("^\\s*([@_a-zA-Z][@_a-zA-Z0-9]*):(.*)", std::regex_constants::icase);
static const std::regex byteRegex = std::regex("^\\s*[.]db\\s+((\\$[a-fA-F0-9]{1,2}[ ])*)(\\$[a-fA-F0-9]{1,2})+\\s*(;*)(.*)$", std::regex_constants::icase);
void Assembler::ProcessLine(string code, uint32_t& instructionAddress, vector<int16_t>& output, std::unordered_map<string, uint32_t>& labels, bool firstPass, std::unordered_map<string, uint32_t>& currentPassLabels)
{
//Remove extra spaces as part of processing
size_t offset = code.find_first_of(',', 0);
if(offset != string::npos) {
code.erase(std::remove(code.begin() + offset + 1, code.end(), ' '), code.end());
}
offset = code.find_first_of(')', 0);
if(offset != string::npos) {
code.erase(std::remove(code.begin() + offset + 1, code.end(), ' '), code.end());
}
//Determine if the line is blank, a comment, a label or code
std::smatch match;
if(std::regex_search(code, match, byteRegex)) {
vector<string> bytes = StringUtilities::Split(match.str(1) + match.str(3), ' ');
for(string& byte : bytes) {
output.push_back((uint8_t)(HexUtilities::FromHex(byte.substr(1))));
instructionAddress++;
}
output.push_back(AssemblerSpecialCodes::EndOfLine);
} else if(std::regex_search(code, match, labelRegex)) {
string label = match.str(1);
string afterLabel = match.str(2);
if(currentPassLabels.find(match.str(1)) != currentPassLabels.end()) {
output.push_back(AssemblerSpecialCodes::LabelRedefinition);
} else {
labels[match.str(1)] = instructionAddress;
currentPassLabels[match.str(1)] = instructionAddress;
ProcessLine(afterLabel, instructionAddress, output, labels, firstPass, currentPassLabels);
}
return;
} else if(std::regex_search(code, match, isCommentOrBlank)) {
output.push_back(AssemblerSpecialCodes::EndOfLine);
return;
} else if(std::regex_search(code, match, instRegex) && match.size() > 1) {
LineData lineData;
AssemblerSpecialCodes result = GetLineData(match, lineData, labels, firstPass);
if(result == AssemblerSpecialCodes::OK) {
AssembleInstruction(lineData, instructionAddress, output, firstPass);
} else {
output.push_back(result);
}
} else {
output.push_back(AssemblerSpecialCodes::ParsingError);
}
}
AssemblerSpecialCodes Assembler::GetLineData(std::smatch match, LineData& lineData, std::unordered_map<string, uint32_t>& labels, bool firstPass)
{
bool isBinary = match.str(2).length() > 1 && match.str(2)[1] == '%'; //Immediate + binary: "#%"
lineData.OpCode = match.str(1);
lineData.IsImmediate = !match.str(2).empty();
lineData.IsHex = !match.str(4).empty();
lineData.HasComment = !match.str(8).empty();
lineData.OperandSuffix = match.str(6);
lineData.HasOpeningParenthesis = match.str(3) == "(";
lineData.HasOpeningBracket = match.str(3) == "[";
std::transform(lineData.OperandSuffix.begin(), lineData.OperandSuffix.end(), lineData.OperandSuffix.begin(), ::toupper);
std::transform(lineData.OpCode.begin(), lineData.OpCode.end(), lineData.OpCode.begin(), ::toupper);
bool foundSpace = false;
for(char c : match.str(5)) {
if(c != ' ' && c != '\t') {
if(foundSpace) {
//can't have spaces in operands (except at the very end)
return AssemblerSpecialCodes::InvalidSpaces;
} else if(lineData.IsHex && !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) {
//invalid hex
return AssemblerSpecialCodes::InvalidHex;
} else if(isBinary && c != '0' && c != '1') {
return AssemblerSpecialCodes::InvalidBinaryValue;
}
lineData.Operand.push_back(c);
} else {
foundSpace = true;
}
}
if(isBinary) {
//Convert the binary value to hex
if(lineData.Operand.size() == 0) {
return AssemblerSpecialCodes::MissingOperand;
} else if(lineData.Operand.size() <= 8) {
lineData.IsHex = true;
int value = 0;
for(size_t i = 0; i < lineData.Operand.size(); i++) {
value <<= 1;
value |= lineData.Operand[i] == '1' ? 1 : 0;
}
lineData.Operand = HexUtilities::ToHex(value, false);
} else {
return AssemblerSpecialCodes::OperandOutOfRange;
}
}
if(!lineData.HasComment && !match.str(9).empty()) {
//something is trailing at the end of the line, and it's not a comment
return AssemblerSpecialCodes::TrailingText;
}
if(!lineData.IsHex) {
bool allNumeric = true;
for(size_t i = 0; i < lineData.Operand.size(); i++) {
if(lineData.Operand[i] == '-' && i == 0 && lineData.Operand.size() > 1) {
//First char is a minus sign, and more characters follow, continue
continue;
}
if((lineData.Operand[i] < '0' || lineData.Operand[i] > '9')) {
allNumeric = false;
break;
}
}
if(allNumeric && !lineData.Operand.empty()) {
//Operand is not empty, and it only contains decimal values
lineData.IsDecimal = true;
} else {
lineData.IsDecimal = false;
}
}
return GetAddrModeAndOperandSize(lineData, labels, firstPass);
}
AssemblerSpecialCodes Assembler::GetAddrModeAndOperandSize(LineData& lineData, std::unordered_map<string, uint32_t>& labels, bool firstPass)
{
int opSize = 0;
bool invalid = false;
string operand = lineData.Operand;
if(lineData.IsHex) {
if(operand.size() == 0) {
return AssemblerSpecialCodes::MissingOperand;
} else if(operand.size() <= 2) {
opSize = 1;
} else if(operand.size() <= 4) {
opSize = 2;
} else if(operand.size() <= 6) {
opSize = 3;
} else {
return AssemblerSpecialCodes::OperandOutOfRange;
}
} else if(lineData.IsDecimal) {
int value = std::stoi(operand.c_str());
if(value < -0x800000) {
//< -2^23 is invalid
return AssemblerSpecialCodes::OperandOutOfRange;
} else if(value < -0x8000) {
opSize = 3;
} else if(value < -0x80) {
opSize = 2;
} else if(value <= 0xFF) {
opSize = 1;
} else if(value <= 0xFFFF) {
opSize = 2;
} else if(value <= 0xFFFFFF) {
opSize = 3;
} else {
//>= 2^23 is invalid
return AssemblerSpecialCodes::OperandOutOfRange;
}
} else if(!operand.empty()) {
//Check if the operand is a known label
auto findResult = labels.find(operand);
if(findResult != labels.end()) {
lineData.Operand = HexUtilities::ToHex((uint16_t)findResult->second);
lineData.IsHex = true;
opSize = 2;
} else if(operand.size() == 1 && (operand[0] == 'A' || operand[0] == 'a') && lineData.OperandSuffix.empty() && !lineData.IsHex && !lineData.IsImmediate && !lineData.HasOpeningParenthesis && !lineData.HasOpeningBracket) {
//Allow optional "A" after AddrMode == Accumulator instructions
lineData.Mode = AddrMode::Acc;
opSize = 0;
} else {
int32_t addr = _labelManager->GetLabelRelativeAddress(operand);
if(addr > 0xFFFF) {
lineData.Operand = HexUtilities::ToHex24(addr);
lineData.IsHex = true;
opSize = 3;
} else if(addr > 0xFF) {
lineData.Operand = HexUtilities::ToHex((uint16_t)addr);
lineData.IsHex = true;
opSize = 2;
} else if(addr >= 0) {
lineData.Operand = HexUtilities::ToHex((uint8_t)addr);
lineData.IsHex = true;
opSize = 1;
} else {
if(firstPass) {
//First pass, we couldn't find a matching label, so it might be defined later on
//Pretend it exists for now
_needSecondPass = true;
lineData.Operand = "FFFF";
lineData.IsHex = true;
opSize = 2;
} else {
return AssemblerSpecialCodes::UnknownLabel;
}
}
}
} else {
//No operand
opSize = 0;
}
if(lineData.Mode == AddrMode::Imp) {
if(lineData.OperandSuffix.substr(0, 2) == ",$") {
//Used by MVP, MVN
opSize = 2;
lineData.Mode = AddrMode::BlkMov;
uint8_t dest = HexUtilities::FromHex(lineData.OperandSuffix.substr(2));
lineData.Operand += HexUtilities::ToHex(dest);
} else if(lineData.IsImmediate) {
if(lineData.HasOpeningParenthesis || lineData.HasOpeningBracket|| opSize == 0) {
invalid = true;
} else if(opSize >= 3) {
invalid = true;
}
lineData.Mode = opSize == 2 ? AddrMode::Imm16 : AddrMode::Imm8; //or Rel
} else if(lineData.HasOpeningBracket) {
if(lineData.OperandSuffix == "]") {
switch(opSize){
case 1: lineData.Mode = AddrMode::DirIndLng; break;
case 2: lineData.Mode = AddrMode::AbsIndLng; break;
default: invalid = true; break;
}
} else if(lineData.OperandSuffix == "],Y") {
if(opSize == 1) {
lineData.Mode = AddrMode::DirIndLngIdxY;
} else {
invalid = true;
}
}
} else if(lineData.HasOpeningParenthesis) {
if(lineData.OperandSuffix == ")") {
lineData.Mode = opSize == 1 ? AddrMode::DirInd : AddrMode::AbsInd;
} else if(lineData.OperandSuffix == ",X)") {
lineData.Mode = opSize == 1 ? AddrMode::DirIdxIndX : AddrMode::AbsIdxXInd;
} else if(lineData.OperandSuffix == "),Y") {
if(opSize == 1) {
lineData.Mode = AddrMode::DirIndIdxY;
} else {
return AssemblerSpecialCodes::OperandOutOfRange;
}
} else if(lineData.OperandSuffix == ",S),Y") {
if(opSize == 1) {
lineData.Mode = AddrMode::StkRelIndIdxY;
} else {
return AssemblerSpecialCodes::OperandOutOfRange;
}
} else {
invalid = true;
}
} else {
if(lineData.OperandSuffix == ",X") {
if(opSize == 3) {
lineData.Mode = AddrMode::AbsLngIdxX;
} else if(opSize == 2) {
lineData.Mode = AddrMode::AbsIdxX;
} else if(opSize == 1) {
//Sometimes zero page addressing is not available, even if the operand is in the zero page
lineData.Mode = AddrMode::DirIdxX;
} else {
invalid = true;
}
} else if(lineData.OperandSuffix == ",Y") {
if(opSize == 2) {
lineData.Mode = AddrMode::AbsIdxY;
} else if(opSize == 1) {
//Sometimes zero page addressing is not available, even if the operand is in the zero page
lineData.Mode = AddrMode::DirIdxY;
} else {
invalid = true;
}
} else if(lineData.OperandSuffix == ",S") {
if(opSize == 1) {
lineData.Mode = AddrMode::StkRel;
} else {
return AssemblerSpecialCodes::OperandOutOfRange;
}
} else if(lineData.OperandSuffix.empty()) {
if(opSize == 0) {
lineData.Mode = AddrMode::Imp; //or Acc
} else if(opSize == 3) {
lineData.Mode = AddrMode::AbsLng;
} else if(opSize == 2) {
lineData.Mode = AddrMode::Abs;
} else if(opSize == 1) {
//Sometimes zero page addressing is not available, even if the operand is in the zero page
lineData.Mode = AddrMode::Dir;
} else {
invalid = true;
}
} else {
invalid = true;
}
}
}
/*if(lineData.Mode == AddrMode::None) {
invalid = true;
}*/
lineData.OperandSize = opSize;
return invalid ? AssemblerSpecialCodes::ParsingError : AssemblerSpecialCodes::OK;
}
bool Assembler::IsOpModeAvailable(string& opCode, AddrMode mode)
{
return _availableModesByOpName[opCode].find((int)mode) != _availableModesByOpName[opCode].end();
}
void Assembler::AssembleInstruction(LineData& lineData, uint32_t& instructionAddress, vector<int16_t>& output, bool firstPass)
{
bool foundMatch = false;
for(int i = 0; i < 256; i++) {
AddrMode opMode = CpuDisUtils::OpMode[i];
if(lineData.OpCode == CpuDisUtils::OpName[i]) {
bool modeMatch = opMode == lineData.Mode;
if(!modeMatch) {
if(lineData.Mode == AddrMode::Imp && (opMode == AddrMode::Acc || opMode == AddrMode::Stk)) {
modeMatch = true;
} else if(lineData.Mode == AddrMode::Imm8 && opMode == AddrMode::Sig8) {
modeMatch = true;
} else if((lineData.Mode == AddrMode::Imm8 || lineData.Mode == AddrMode::Imm16) && (opMode == AddrMode::ImmX || opMode == AddrMode::ImmM)) {
modeMatch = true;
} else if((opMode == AddrMode::Rel || opMode == AddrMode::RelLng) && (lineData.Mode == AddrMode::AbsLng || lineData.Mode == AddrMode::Abs || lineData.Mode == AddrMode::Dir)) {
bool lngBranch = opMode == AddrMode::RelLng;
modeMatch = true;
//Convert "absolute" jump to a relative jump
int value = lineData.IsHex ? HexUtilities::FromHex(lineData.Operand) : std::stoi(lineData.Operand);
if(lineData.Mode == AddrMode::Abs) {
value |= (instructionAddress & 0xFF0000);
}
int32_t addressGap;
if(lineData.Mode == AddrMode::Dir) {
addressGap = (int8_t)value;
} else {
addressGap = value - (instructionAddress + (lngBranch ? 3 : 2));
}
if(addressGap > (lngBranch ? 32767 : 127) || addressGap < (lngBranch ? -32768 : -128)) {
//Gap too long, can't jump that far
if(!firstPass) {
//Pretend this is ok on first pass, we're just trying to find all labels
output.push_back(AssemblerSpecialCodes::OutOfRangeJump);
return;
}
}
//Update data to match relative jump
lineData.OperandSize = lngBranch ? 2 : 1;
lineData.IsHex = true;
lineData.Operand = lngBranch ? HexUtilities::ToHex((uint16_t)addressGap) : HexUtilities::ToHex((uint8_t)addressGap);
}
}
if(modeMatch) {
output.push_back(i);
instructionAddress += (lineData.OperandSize + 1);
if(lineData.OperandSize == 1) {
int value = lineData.IsHex ? HexUtilities::FromHex(lineData.Operand) : std::stoi(lineData.Operand);
output.push_back(value & 0xFF);
} else if(lineData.OperandSize == 2) {
int value = lineData.IsHex ? HexUtilities::FromHex(lineData.Operand) : std::stoi(lineData.Operand);
output.push_back(value & 0xFF);
output.push_back((value >> 8) & 0xFF);
} else if(lineData.OperandSize == 3) {
int value = lineData.IsHex ? HexUtilities::FromHex(lineData.Operand) : std::stoi(lineData.Operand);
output.push_back(value & 0xFF);
output.push_back((value >> 8) & 0xFF);
output.push_back((value >> 16) & 0xFF);
}
foundMatch = true;
break;
}
}
}
if(!foundMatch) {
output.push_back(AssemblerSpecialCodes::InvalidInstruction);
} else {
output.push_back(AssemblerSpecialCodes::EndOfLine);
}
}
Assembler::Assembler(shared_ptr<LabelManager> labelManager)
{
_labelManager = labelManager;
}
uint32_t Assembler::AssembleCode(string code, uint32_t startAddress, int16_t* assembledCode)
{
for(uint8_t i = 0; i < 255; i++) {
if(_availableModesByOpName.find(CpuDisUtils::OpName[i]) == _availableModesByOpName.end()) {
_availableModesByOpName[CpuDisUtils::OpName[i]] = std::unordered_set<int>();
}
_availableModesByOpName[CpuDisUtils::OpName[i]].emplace((int)CpuDisUtils::OpMode[i]);
}
std::unordered_map<string, uint32_t> temporaryLabels;
std::unordered_map<string, uint32_t> currentPassLabels;
size_t i = 0;
vector<int16_t> output;
output.reserve(1000);
uint32_t originalStartAddr = startAddress;
vector<string> codeLines;
codeLines.reserve(100);
while(i < code.size()) {
size_t offset = code.find_first_of('\n', i);
string line;
if(offset != string::npos) {
line = code.substr(i, offset - i);
i = offset + 1;
} else {
line = code.substr(i);
i = code.size();
}
codeLines.push_back(line);
}
//Make 2 passes - first one to find all labels, second to assemble
_needSecondPass = false;
for(string& line : codeLines) {
ProcessLine(line, startAddress, output, temporaryLabels, true, currentPassLabels);
}
if(_needSecondPass) {
currentPassLabels.clear();
output.clear();
startAddress = originalStartAddr;
for(string& line : codeLines) {
ProcessLine(line, startAddress, output, temporaryLabels, false, currentPassLabels);
}
}
memcpy(assembledCode, output.data(), std::min<int>(100000, output.size()) * sizeof(uint16_t));
return (uint32_t)output.size();
}

59
Core/Assembler.h Normal file
View file

@ -0,0 +1,59 @@
#pragma once
#include "stdafx.h"
#include <unordered_set>
#include <regex>
#include "CpuDisUtils.h"
class LabelManager;
struct LineData
{
string OpCode;
string Operand;
string OperandSuffix;
AddrMode Mode = AddrMode::Imp;
int OperandSize = 0;
bool IsHex = false;
bool IsDecimal = false;
bool IsImmediate = false;
bool HasComment = false;
bool HasOpeningParenthesis = false;
bool HasOpeningBracket = false;
};
enum AssemblerSpecialCodes
{
OK = 0,
EndOfLine = -1,
ParsingError = -2,
OutOfRangeJump = -3,
LabelRedefinition = -4,
MissingOperand = -5,
OperandOutOfRange = -6,
InvalidHex = -7,
InvalidSpaces = -8,
TrailingText = -9,
UnknownLabel = -10,
InvalidInstruction = -11,
InvalidBinaryValue = -12,
};
class Assembler
{
private:
std::unordered_map<string, std::unordered_set<int>> _availableModesByOpName;
bool _needSecondPass;
shared_ptr<LabelManager> _labelManager;
void ProcessLine(string code, uint32_t& instructionAddress, vector<int16_t>& output, std::unordered_map<string, uint32_t>& labels, bool firstPass, std::unordered_map<string, uint32_t>& currentPassLabels);
AssemblerSpecialCodes GetLineData(std::smatch match, LineData& lineData, std::unordered_map<string, uint32_t>& labels, bool firstPass);
AssemblerSpecialCodes GetAddrModeAndOperandSize(LineData& lineData, std::unordered_map<string, uint32_t>& labels, bool firstPass);
void AssembleInstruction(LineData& lineData, uint32_t& instructionAddress, vector<int16_t>& output, bool firstPass);
bool IsOpModeAvailable(string& opCode, AddrMode mode);
public:
Assembler(shared_ptr<LabelManager> labelManager);
uint32_t AssembleCode(string code, uint32_t startAddress, int16_t* assembledCode);
};

View file

@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="AluMulDiv.h" />
<ClInclude Include="Assembler.h" />
<ClInclude Include="BaseCartridge.h" />
<ClInclude Include="BaseControlDevice.h" />
<ClInclude Include="BaseCoprocessor.h" />
@ -210,6 +211,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="AluMulDiv.cpp" />
<ClCompile Include="Assembler.cpp" />
<ClCompile Include="BaseCartridge.cpp" />
<ClCompile Include="BaseControlDevice.cpp" />
<ClCompile Include="BaseRenderer.cpp" />

View file

@ -491,6 +491,9 @@
<ClInclude Include="Profiler.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="Assembler.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@ -779,6 +782,9 @@
<ClCompile Include="Profiler.cpp">
<Filter>Debugger</Filter>
</ClCompile>
<ClCompile Include="Assembler.cpp">
<Filter>Debugger</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="SNES">

View file

@ -51,7 +51,7 @@ void CpuDisUtils::GetDisassembly(DisassemblyInfo &info, string &out, uint32_t me
case AddrMode::AbsLng: str.Write(operand); break;
case AddrMode::AbsLngJmp: str.Write(operand); break;
case AddrMode::Acc: break;
case AddrMode::BlkMov: str.WriteAll('$', operand[1], operand[2], " -> "); str.WriteAll('$', operand[3], operand[4]); break;
case AddrMode::BlkMov: str.WriteAll('$', operand[1], operand[2], ','); str.WriteAll('$', operand[3], operand[4]); break;
case AddrMode::DirIdxIndX: str.WriteAll('(', operand, ",X)"); break;
case AddrMode::DirIdxX: str.WriteAll(operand, ",X"); break;
case AddrMode::DirIdxY: str.WriteAll(operand, ",Y"); break;

View file

@ -11,15 +11,16 @@ enum class AddrMode : uint8_t;
class CpuDisUtils
{
private:
static string OpName[256];
static uint8_t OpSize[0x1F];
static AddrMode OpMode[256];
static uint32_t GetOperandAddress(DisassemblyInfo &info, uint32_t memoryAddr);
static uint8_t GetOpSize(AddrMode addrMode, uint8_t flags);
static bool HasEffectiveAddress(AddrMode addrMode);
public:
static string OpName[256];
static AddrMode OpMode[256];
static void GetDisassembly(DisassemblyInfo &info, string &out, uint32_t memoryAddr, LabelManager* labelManager, EmuSettings* settings);
static uint8_t GetOpSize(uint8_t opCode, uint8_t flags);
static int32_t GetEffectiveAddress(DisassemblyInfo &info, Console* console, CpuState &state);

View file

@ -20,6 +20,34 @@ public:
throw std::runtime_error("Invalid CPU type");
}
static CpuType ToCpuType(SnesMemoryType type)
{
switch(type) {
case SnesMemoryType::SpcMemory:
case SnesMemoryType::SpcRam:
case SnesMemoryType::SpcRom:
return CpuType::Spc;
case SnesMemoryType::GsuMemory:
case SnesMemoryType::GsuWorkRam:
return CpuType::Gsu;
case SnesMemoryType::Sa1InternalRam:
case SnesMemoryType::Sa1Memory:
return CpuType::Sa1;
case SnesMemoryType::DspDataRam:
case SnesMemoryType::DspDataRom:
case SnesMemoryType::DspProgramRom:
return CpuType::NecDsp;
default:
return CpuType::Cpu;
}
throw std::runtime_error("Invalid CPU type");
}
static constexpr SnesMemoryType GetLastCpuMemoryType()
{
return SnesMemoryType::GsuMemory;

View file

@ -36,6 +36,7 @@
#include "ExpressionEvaluator.h"
#include "InternalRegisters.h"
#include "AluMulDiv.h"
#include "Assembler.h"
#include "../Utilities/HexUtilities.h"
#include "../Utilities/FolderUtilities.h"
@ -58,13 +59,14 @@ Debugger::Debugger(shared_ptr<Console> console)
_watchExpEval[(int)CpuType::Gsu].reset(new ExpressionEvaluator(this, CpuType::Gsu));
_codeDataLogger.reset(new CodeDataLogger(_cart->DebugGetPrgRomSize(), _memoryManager.get()));
_memoryDumper.reset(new MemoryDumper(_ppu, console->GetSpc(), _memoryManager, _cart));
_memoryDumper.reset(new MemoryDumper(this));
_disassembler.reset(new Disassembler(console, _codeDataLogger, this));
_traceLogger.reset(new TraceLogger(this, _console));
_memoryAccessCounter.reset(new MemoryAccessCounter(this, console.get()));
_ppuTools.reset(new PpuTools(_console.get(), _ppu.get()));
_eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get(), _memoryManager.get(), _console->GetDmaController().get()));
_scriptManager.reset(new ScriptManager(this));
_assembler.reset(new Assembler(_labelManager));
_cpuDebugger.reset(new CpuDebugger(this, CpuType::Cpu));
_spcDebugger.reset(new SpcDebugger(this));
@ -468,7 +470,7 @@ AddressInfo Debugger::GetRelativeAddress(AddressInfo absAddress)
return { _spc->GetRelativeAddress(absAddress), SnesMemoryType::SpcMemory };
case SnesMemoryType::Register:
return { -1, SnesMemoryType::Register };
return { absAddress.Address & 0xFFFF, SnesMemoryType::Register };
default:
return { -1, SnesMemoryType::Register };
@ -583,6 +585,11 @@ shared_ptr<Console> Debugger::GetConsole()
return _console;
}
shared_ptr<Assembler> Debugger::GetAssembler()
{
return _assembler;
}
template void Debugger::ProcessMemoryRead<CpuType::Cpu>(uint32_t addr, uint8_t value, MemoryOperationType opType);
template void Debugger::ProcessMemoryRead<CpuType::Sa1>(uint32_t addr, uint8_t value, MemoryOperationType opType);
template void Debugger::ProcessMemoryRead<CpuType::Spc>(uint32_t addr, uint8_t value, MemoryOperationType opType);

View file

@ -31,6 +31,7 @@ class SpcDebugger;
class CpuDebugger;
class GsuDebugger;
class Breakpoint;
class Assembler;
enum class EventType;
enum class EvalResultType : int32_t;
@ -62,6 +63,7 @@ private:
shared_ptr<PpuTools> _ppuTools;
shared_ptr<EventManager> _eventManager;
shared_ptr<LabelManager> _labelManager;
shared_ptr<Assembler> _assembler;
unique_ptr<ExpressionEvaluator> _watchExpEval[(int)DebugUtilities::GetLastCpuType() + 1];
@ -135,4 +137,5 @@ public:
shared_ptr<ScriptManager> GetScriptManager();
shared_ptr<CallstackManager> GetCallstackManager(CpuType cpuType);
shared_ptr<Console> GetConsole();
shared_ptr<Assembler> GetAssembler();
};

View file

@ -306,10 +306,10 @@ void Disassembler::Disassemble(CpuType cpuType)
if((isData && inUnknownBlock) || (!isData && inVerifiedBlock)) {
if(isData && inUnknownBlock) {
//In an unknown block and the next byte is data, end the block
results.push_back(DisassemblyResult(addrInfo, i, LineFlags::BlockEnd | (showUnident ? LineFlags::ShowAsData : 0)));
results.push_back(DisassemblyResult(prevAddrInfo, i - 1, LineFlags::BlockEnd | (showUnident ? LineFlags::ShowAsData : 0)));
} else if(!isData && inVerifiedBlock) {
//In a verified data block and the next byte is unknown, end the block
results.push_back(DisassemblyResult(addrInfo, i, LineFlags::BlockEnd | LineFlags::VerifiedData | (showData ? LineFlags::ShowAsData : 0)));
results.push_back(DisassemblyResult(prevAddrInfo, i - 1, LineFlags::BlockEnd | LineFlags::VerifiedData | (showData ? LineFlags::ShowAsData : 0)));
}
inUnknownBlock = false;
inVerifiedBlock = false;
@ -420,6 +420,7 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d
DisassemblyResult result = source[lineIndex];
data.Address = -1;
data.AbsoluteAddress = -1;
data.EffectiveAddress = -1;
data.Flags = result.Flags;
switch(result.Address.Type) {
@ -433,7 +434,7 @@ bool Disassembler::GetLineData(CpuType type, uint32_t lineIndex, CodeLineData &d
if(!isBlockStartEnd && result.Address.Address >= 0) {
if((data.Flags & LineFlags::ShowAsData)) {
FastString str(".db", 3);
int nextAddr = lineIndex < source.size() - 2 ? source[lineIndex+1].CpuAddress : (maxAddr + 1);
int nextAddr = lineIndex < source.size() - 2 ? (source[lineIndex+1].CpuAddress + 1) : (maxAddr + 1);
for(int i = 0; i < 8 && result.CpuAddress+i < nextAddr; i++) {
str.Write(" $", 2);
str.Write(HexUtilities::ToHexChar(_memoryDumper->GetMemoryValue(memType, result.CpuAddress + i)), 2);

View file

@ -7,17 +7,22 @@
#include "Sa1.h"
#include "Cx4.h"
#include "Gsu.h"
#include "Console.h"
#include "MemoryDumper.h"
#include "BaseCartridge.h"
#include "VideoDecoder.h"
#include "DebugTypes.h"
#include "DebugBreakHelper.h"
#include "Disassembler.h"
MemoryDumper::MemoryDumper(shared_ptr<Ppu> ppu, shared_ptr<Spc> spc, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseCartridge> cartridge)
MemoryDumper::MemoryDumper(Debugger* debugger)
{
_ppu = ppu;
_spc = spc;
_memoryManager = memoryManager;
_cartridge = cartridge;
_debugger = debugger;
_disassembler = debugger->GetDisassembler().get();
_ppu = debugger->GetConsole()->GetPpu().get();
_spc = debugger->GetConsole()->GetSpc().get();
_memoryManager = debugger->GetConsole()->GetMemoryManager().get();
_cartridge = debugger->GetConsole()->GetCartridge().get();
}
void MemoryDumper::SetMemoryState(SnesMemoryType type, uint8_t *buffer, uint32_t length)
@ -131,6 +136,7 @@ void MemoryDumper::GetMemoryState(SnesMemoryType type, uint8_t *buffer)
void MemoryDumper::SetMemoryValues(SnesMemoryType memoryType, uint32_t address, uint8_t* data, uint32_t length)
{
DebugBreakHelper helper(_debugger);
for(uint32_t i = 0; i < length; i++) {
SetMemoryValue(memoryType, address+i, data[i], true);
}
@ -142,6 +148,20 @@ void MemoryDumper::SetMemoryValue(SnesMemoryType memoryType, uint32_t address, u
return;
}
if(disableSideEffects && memoryType <= DebugUtilities::GetLastCpuMemoryType()) {
AddressInfo addr = { address, memoryType };
addr = _debugger->GetAbsoluteAddress(addr);
if(addr.Address >= 0) {
SetMemoryValue(addr.Type, addr.Address, value, true);
}
return;
}
auto invalidateCache = [=]() {
AddressInfo addr = { address, memoryType };
_debugger->GetDisassembler()->InvalidateCache(addr, DebugUtilities::ToCpuType(memoryType));
};
switch(memoryType) {
default: break;
@ -150,23 +170,23 @@ void MemoryDumper::SetMemoryValue(SnesMemoryType memoryType, uint32_t address, u
case SnesMemoryType::Sa1Memory: _cartridge->GetSa1()->GetMemoryMappings()->DebugWrite(address, value); break;
case SnesMemoryType::GsuMemory: _cartridge->GetGsu()->GetMemoryMappings()->DebugWrite(address, value); break;
case SnesMemoryType::PrgRom: _cartridge->DebugGetPrgRom()[address] = value; break;
case SnesMemoryType::WorkRam: _memoryManager->DebugGetWorkRam()[address] = value; break;
case SnesMemoryType::SaveRam: _cartridge->DebugGetSaveRam()[address] = value; break;
case SnesMemoryType::PrgRom: _cartridge->DebugGetPrgRom()[address] = value; invalidateCache(); break;
case SnesMemoryType::WorkRam: _memoryManager->DebugGetWorkRam()[address] = value; invalidateCache(); break;
case SnesMemoryType::SaveRam: _cartridge->DebugGetSaveRam()[address] = value; invalidateCache(); break;
case SnesMemoryType::VideoRam: _ppu->GetVideoRam()[address] = value;
case SnesMemoryType::VideoRam: _ppu->GetVideoRam()[address] = value; break;
case SnesMemoryType::SpriteRam: _ppu->GetSpriteRam()[address] = value; break;
case SnesMemoryType::CGRam: _ppu->GetCgRam()[address] = value; break;
case SnesMemoryType::SpcRam: _spc->GetSpcRam()[address] = value; break;
case SnesMemoryType::SpcRom: _spc->GetSpcRom()[address] = value; break;
case SnesMemoryType::SpcRam: _spc->GetSpcRam()[address] = value; invalidateCache(); break;
case SnesMemoryType::SpcRom: _spc->GetSpcRom()[address] = value; invalidateCache(); break;
case SnesMemoryType::DspProgramRom: _cartridge->GetDsp()->DebugGetProgramRom()[address] = value;
case SnesMemoryType::DspDataRom: _cartridge->GetDsp()->DebugGetDataRom()[address] = value;
case SnesMemoryType::DspDataRam: _cartridge->GetDsp()->DebugGetDataRam()[address] = value;
case SnesMemoryType::DspProgramRom: _cartridge->GetDsp()->DebugGetProgramRom()[address] = value; invalidateCache(); break;
case SnesMemoryType::DspDataRom: _cartridge->GetDsp()->DebugGetDataRom()[address] = value; break;
case SnesMemoryType::DspDataRam: _cartridge->GetDsp()->DebugGetDataRam()[address] = value; break;
case SnesMemoryType::Sa1InternalRam: _cartridge->GetSa1()->DebugGetInternalRam()[address] = value;
case SnesMemoryType::GsuWorkRam: _cartridge->GetGsu()->DebugGetWorkRam()[address] = value;
case SnesMemoryType::Cx4DataRam: _cartridge->GetCx4()->DebugGetDataRam()[address] = value;
case SnesMemoryType::Sa1InternalRam: _cartridge->GetSa1()->DebugGetInternalRam()[address] = value; invalidateCache(); break;
case SnesMemoryType::GsuWorkRam: _cartridge->GetGsu()->DebugGetWorkRam()[address] = value; invalidateCache(); break;
case SnesMemoryType::Cx4DataRam: _cartridge->GetCx4()->DebugGetDataRam()[address] = value; break;
}
}
@ -214,6 +234,7 @@ uint16_t MemoryDumper::GetMemoryValueWord(SnesMemoryType memoryType, uint32_t ad
void MemoryDumper::SetMemoryValueWord(SnesMemoryType memoryType, uint32_t address, uint16_t value, bool disableSideEffects)
{
DebugBreakHelper helper(_debugger);
SetMemoryValue(memoryType, address, (uint8_t)value, disableSideEffects);
SetMemoryValue(memoryType, address + 1, (uint8_t)(value >> 8), disableSideEffects);
}

View file

@ -7,18 +7,22 @@ class MemoryManager;
class BaseCartridge;
class Ppu;
class Spc;
class Debugger;
class Disassembler;
enum class SnesMemoryType;
class MemoryDumper
{
private:
shared_ptr<Ppu> _ppu;
shared_ptr<Spc> _spc;
shared_ptr<MemoryManager> _memoryManager;
shared_ptr<BaseCartridge> _cartridge;
Ppu* _ppu;
Spc* _spc;
MemoryManager* _memoryManager;
BaseCartridge* _cartridge;
Debugger* _debugger;
Disassembler* _disassembler;
public:
MemoryDumper(shared_ptr<Ppu> ppu, shared_ptr<Spc> spc, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseCartridge> cartridge);
MemoryDumper(Debugger* debugger);
uint32_t GetMemorySize(SnesMemoryType type);
void GetMemoryState(SnesMemoryType type, uint8_t *buffer);

View file

@ -15,6 +15,7 @@
#include "../Core/LabelManager.h"
#include "../Core/ScriptManager.h"
#include "../Core/Profiler.h"
#include "../Core/Assembler.h"
extern shared_ptr<Console> _console;
@ -100,4 +101,6 @@ extern "C"
DllExport void __stdcall RemoveScript(int32_t scriptId) { GetDebugger()->GetScriptManager()->RemoveScript(scriptId); }
DllExport const char* __stdcall GetScriptLog(int32_t scriptId) { return GetDebugger()->GetScriptManager()->GetScriptLog(scriptId); }
//DllExport void __stdcall DebugSetScriptTimeout(uint32_t timeout) { LuaScriptingContext::SetScriptTimeout(timeout); }
DllExport uint32_t __stdcall AssembleCode(char* code, uint32_t startAddress, int16_t* assembledOutput) { return GetDebugger()->GetAssembler()->AssembleCode(code, startAddress, assembledOutput); }
};

View file

@ -21,6 +21,7 @@ SOURCES_C := $(SEVENZIP_DIR)/7zAlloc.c \
SOURCES_CXX := $(LIBRETRO_DIR)/libretro.cpp \
$(CORE_DIR)/AluMulDiv.cpp \
$(CORE_DIR)/Assembler.cpp \
$(CORE_DIR)/BaseCartridge.cpp \
$(CORE_DIR)/BaseControlDevice.cpp \
$(CORE_DIR)/BaseRenderer.cpp \

View file

@ -0,0 +1,17 @@
using Mesen.GUI.Controls;
using Mesen.GUI.Utilities;
using System.Drawing;
namespace Mesen.GUI.Config
{
public class AssemblerConfig
{
public Size WindowSize = new Size(0, 0);
public Point WindowLocation;
public string FontFamily = BaseControl.MonospaceFontFamily;
public FontStyle FontStyle = FontStyle.Regular;
public float FontSize = BaseControl.DefaultFontSize;
public int Zoom = 100;
}
}

View file

@ -28,6 +28,7 @@ namespace Mesen.GUI.Config
public DbgIntegrationConfig DbgIntegration = new DbgIntegrationConfig();
public ScriptWindowConfig ScriptWindow = new ScriptWindowConfig();
public ProfilerConfig Profiler = new ProfilerConfig();
public AssemblerConfig Assembler = new AssemblerConfig();
public DebugInfo()
{

View file

@ -67,8 +67,8 @@ namespace Mesen.GUI.Config
[ShortcutName("View in disassembly")]
public XmlKeys MemoryViewer_ViewInDisassembly = Keys.None;
[ShortcutName("Open APU Viewer")]
public XmlKeys OpenApuViewer = Keys.Control | Keys.U;
[ShortcutName("Open Assembler")]
public XmlKeys OpenAssembler = Keys.Control | Keys.U;
[ShortcutName("Open Debugger")]
public XmlKeys OpenDebugger = Keys.Control | Keys.D;
[ShortcutName("Open SPC Debugger")]

View file

@ -47,6 +47,7 @@
this.cboSourceFile = new System.Windows.Forms.ComboBox();
this.lblSourceFile = new System.Windows.Forms.Label();
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
this.mnuEditSelectedCode = new System.Windows.Forms.ToolStripMenuItem();
this.ctxMenu.SuspendLayout();
this.tlpMain.SuspendLayout();
this.SuspendLayout();
@ -81,6 +82,7 @@
//
this.ctxMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuMarkSelectionAs,
this.mnuEditSelectedCode,
this.sepMarkSelectionAs,
this.mnuToggleBreakpoint,
this.mnuAddToWatch,
@ -92,7 +94,7 @@
this.sepSwitchView,
this.mnuSwitchView});
this.ctxMenu.Name = "ctxMenu";
this.ctxMenu.Size = new System.Drawing.Size(227, 220);
this.ctxMenu.Size = new System.Drawing.Size(227, 242);
this.ctxMenu.Closing += new System.Windows.Forms.ToolStripDropDownClosingEventHandler(this.ctxMenu_Closing);
this.ctxMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ctxMenu_Opening);
//
@ -234,6 +236,13 @@
this.tlpMain.Size = new System.Drawing.Size(465, 398);
this.tlpMain.TabIndex = 3;
//
// mnuEditSelectedCode
//
this.mnuEditSelectedCode.Image = global::Mesen.GUI.Properties.Resources.Edit;
this.mnuEditSelectedCode.Name = "mnuEditSelectedCode";
this.mnuEditSelectedCode.Size = new System.Drawing.Size(226, 22);
this.mnuEditSelectedCode.Text = "Edit Selected Code";
//
// ctrlDisassemblyView
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -269,5 +278,6 @@
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsCode;
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsData;
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsUnidentifiedData;
private System.Windows.Forms.ToolStripMenuItem mnuEditSelectedCode;
}
}

View file

@ -74,6 +74,12 @@ namespace Mesen.GUI.Debugger.Controls
}
}
protected override void OnInvalidated(InvalidateEventArgs e)
{
base.OnInvalidated(e);
ctrlCode.Invalidate();
}
private void OnLabelUpdated(object sender, EventArgs e)
{
ctrlCode.Invalidate();
@ -147,7 +153,10 @@ namespace Mesen.GUI.Debugger.Controls
mnuEditInMemoryTools.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer));
mnuEditInMemoryTools.Click += (s, e) => EditInMemoryTools(GetActionTarget());
mnuEditSelectedCode.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditSelectedCode));
mnuEditSelectedCode.Click += (s, e) => EditSelectedCode();
mnuAddToWatch.InitShortcut(this, nameof(DebuggerShortcutsConfig.LabelList_AddToWatch));
mnuMarkAsCode.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsCode));
@ -158,7 +167,6 @@ namespace Mesen.GUI.Debugger.Controls
mnuMarkAsUnidentifiedData.Click += (s, e) => MarkSelectionAs(CdlFlags.None);
mnuSwitchView.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView));
mnuSwitchView.Click += (s, e) => { ToggleView(); };
}
@ -179,6 +187,21 @@ namespace Mesen.GUI.Debugger.Controls
}
private SelectedAddressRange GetSelectedAddressRange()
{
SelectedAddressRange range = GetSelectedRelativeAddressRange();
if(range != null && range.Start.Address >= 0 && range.End.Address >= 0) {
return new SelectedAddressRange() {
Start = DebugApi.GetAbsoluteAddress(range.Start),
End = DebugApi.GetAbsoluteAddress(range.End),
Display = $"${range.Start.Address.ToString("X4")} - ${range.End.Address.ToString("X4")}"
};
}
return null;
}
private SelectedAddressRange GetSelectedRelativeAddressRange()
{
int firstLineOfSelection = ctrlCode.SelectionStart;
int lineCount = ctrlCode.LineCount;
@ -196,8 +219,8 @@ namespace Mesen.GUI.Debugger.Controls
if(start >= 0 && end >= 0) {
return new SelectedAddressRange() {
Start = DebugApi.GetAbsoluteAddress(new AddressInfo() { Address = start, Type = _manager.RelativeMemoryType }),
End = DebugApi.GetAbsoluteAddress(new AddressInfo() { Address = end, Type = _manager.RelativeMemoryType }),
Start = new AddressInfo() { Address = start, Type = _manager.RelativeMemoryType },
End = new AddressInfo() { Address = end, Type = _manager.RelativeMemoryType },
Display = $"${start.ToString("X4")} - ${end.ToString("X4")}"
};
}
@ -452,6 +475,44 @@ namespace Mesen.GUI.Debugger.Controls
}
}
private string GetSelectedCode()
{
StringBuilder sb = new StringBuilder();
bool prevSeparator = false;
for(int i = ctrlCode.SelectionStart, end = ctrlCode.SelectionStart + ctrlCode.SelectionLength; i <= end; i++) {
CodeLineData line = _manager.Provider.GetCodeLineData(i);
if(line.Flags.HasFlag(LineFlags.BlockStart) || line.Flags.HasFlag(LineFlags.BlockEnd)|| line.Flags.HasFlag(LineFlags.SubStart)) {
if(!prevSeparator) {
prevSeparator = true;
sb.AppendLine(";-------");
}
} else {
prevSeparator = false;
sb.Append(line.Text.PadLeft(line.Indentation / 7 + line.Text.Length, ' '));
if(line.Comment.Length > 0) {
sb.Append(" " + line.Comment);
}
if(i < end) {
sb.AppendLine();
}
}
}
return sb.ToString();
}
private void EditSelectedCode()
{
SelectedAddressRange range = GetSelectedRelativeAddressRange();
if(range.Start.Address >= 0 && range.End.Address >= 0 && range.Start.Address <= range.End.Address) {
int length = range.End.Address - range.Start.Address + 1;
DebugWindowManager.OpenAssembler(GetSelectedCode(), range.Start.Address, length);
}
}
private LocationInfo GetActionTarget()
{
string word = _lastWord;
@ -584,8 +645,11 @@ namespace Mesen.GUI.Debugger.Controls
mnuMarkSelectionAs.Enabled = false;
mnuMarkSelectionAs.Text = "Mark selection as...";
}
mnuMarkSelectionAs.Visible = !_inSourceView;
sepMarkSelectionAs.Visible = !_inSourceView;
bool showMarkAs = !_inSourceView && (_manager.CpuType == CpuType.Cpu || _manager.CpuType == CpuType.Sa1);
mnuMarkSelectionAs.Visible = showMarkAs;
sepMarkSelectionAs.Visible = showMarkAs;
mnuEditSelectedCode.Visible = showMarkAs;
mnuAddToWatch.Enabled = active;
mnuEditInMemoryTools.Enabled = active;

View file

@ -40,6 +40,7 @@ namespace Mesen.GUI.Debugger
case DebugWindow.ScriptWindow: frm = new frmScript(); frm.Icon = Properties.Resources.Script; break;
case DebugWindow.RegisterViewer: frm = new frmRegisterViewer(); frm.Icon = Properties.Resources.RegisterIcon; break;
case DebugWindow.Profiler: frm = new frmProfiler(); frm.Icon = Properties.Resources.PerfTracker; break;
case DebugWindow.Assembler: frm = new frmAssembler(); frm.Icon = Properties.Resources.Chip; break;
}
if(_openedWindows.Count == 0) {
@ -101,6 +102,19 @@ namespace Mesen.GUI.Debugger
throw new Exception("Invalid CPU type");
}
public static void OpenAssembler(string code = "", int startAddress = 0, int blockLength = 0)
{
if(_openedWindows.Count == 0) {
DebugWorkspaceManager.GetWorkspace();
}
frmAssembler frm = new frmAssembler(code, startAddress, blockLength);
frm.Icon = Properties.Resources.Chip;
_openedWindows.Add(frm);
frm.FormClosed += Debugger_FormClosed;
frm.Show();
}
public static frmMemoryTools GetMemoryViewer()
{
return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmMemoryTools)) as frmMemoryTools;
@ -180,6 +194,7 @@ namespace Mesen.GUI.Debugger
EventViewer,
ScriptWindow,
RegisterViewer,
Profiler
Profiler,
Assembler
}
}

584
UI/Debugger/frmAssembler.Designer.cs generated Normal file
View file

@ -0,0 +1,584 @@
namespace Mesen.GUI.Debugger
{
partial class frmAssembler
{
/// <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.components = new System.ComponentModel.Container();
this.btnOk = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lstErrors = new System.Windows.Forms.ListBox();
this.grpSettings = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.label1 = new System.Windows.Forms.Label();
this.txtStartAddress = new System.Windows.Forms.TextBox();
this.picStartAddressWarning = new System.Windows.Forms.PictureBox();
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.label2 = new System.Windows.Forms.Label();
this.lblByteUsage = new System.Windows.Forms.Label();
this.picSizeWarning = new System.Windows.Forms.PictureBox();
this.lblNoChanges = new System.Windows.Forms.Label();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.panel1 = new System.Windows.Forms.Panel();
this.txtCode = new FastColoredTextBoxNS.FastColoredTextBox();
this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuCopy = new System.Windows.Forms.ToolStripMenuItem();
this.mnuCut = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPaste = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuSelectAll = new System.Windows.Forms.ToolStripMenuItem();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.ctrlHexBox = new Be.Windows.Forms.HexBox();
this.menuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.mnuDecreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.mnuResetFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuSelectFont = new System.Windows.Forms.ToolStripMenuItem();
this.mnuConfigureColors = new System.Windows.Forms.ToolStripMenuItem();
this.tableLayoutPanel1.SuspendLayout();
this.grpSettings.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picStartAddressWarning)).BeginInit();
this.flowLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picSizeWarning)).BeginInit();
this.flowLayoutPanel3.SuspendLayout();
this.groupBox1.SuspendLayout();
this.panel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.txtCode)).BeginInit();
this.contextMenu.SuspendLayout();
this.groupBox2.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
// btnOk
//
this.btnOk.Location = new System.Drawing.Point(120, 3);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(70, 23);
this.btnOk.TabIndex = 0;
this.btnOk.Text = "Apply";
this.btnOk.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnOk.UseVisualStyleBackColor = true;
this.btnOk.Click += new System.EventHandler(this.btnOk_Click);
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(196, 3);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(70, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.Controls.Add(this.lstErrors, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.grpSettings, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.groupBox1, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.groupBox2, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 24);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 141F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(683, 432);
this.tableLayoutPanel1.TabIndex = 2;
//
// lstErrors
//
this.lstErrors.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstErrors.FormattingEnabled = true;
this.lstErrors.Location = new System.Drawing.Point(3, 294);
this.lstErrors.Name = "lstErrors";
this.lstErrors.Size = new System.Drawing.Size(396, 135);
this.lstErrors.TabIndex = 2;
this.lstErrors.DoubleClick += new System.EventHandler(this.lstErrors_DoubleClick);
//
// grpSettings
//
this.grpSettings.Controls.Add(this.tableLayoutPanel2);
this.grpSettings.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpSettings.Location = new System.Drawing.Point(405, 294);
this.grpSettings.Name = "grpSettings";
this.grpSettings.Size = new System.Drawing.Size(275, 135);
this.grpSettings.TabIndex = 3;
this.grpSettings.TabStop = false;
this.grpSettings.Text = "Settings";
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 1;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel1, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.lblNoChanges, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel3, 0, 3);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 4;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.Size = new System.Drawing.Size(269, 116);
this.tableLayoutPanel2.TabIndex = 0;
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Controls.Add(this.label1);
this.flowLayoutPanel1.Controls.Add(this.txtStartAddress);
this.flowLayoutPanel1.Controls.Add(this.picStartAddressWarning);
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(269, 25);
this.flowLayoutPanel1.TabIndex = 3;
//
// label1
//
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(3, 6);
this.label1.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(81, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Start address: $";
//
// txtStartAddress
//
this.txtStartAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.txtStartAddress.Location = new System.Drawing.Point(84, 3);
this.txtStartAddress.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
this.txtStartAddress.MaxLength = 6;
this.txtStartAddress.Name = "txtStartAddress";
this.txtStartAddress.Size = new System.Drawing.Size(59, 20);
this.txtStartAddress.TabIndex = 1;
this.txtStartAddress.TextChanged += new System.EventHandler(this.txtStartAddress_TextChanged);
//
// picStartAddressWarning
//
this.picStartAddressWarning.Image = global::Mesen.GUI.Properties.Resources.Warning;
this.picStartAddressWarning.Location = new System.Drawing.Point(149, 5);
this.picStartAddressWarning.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
this.picStartAddressWarning.Name = "picStartAddressWarning";
this.picStartAddressWarning.Size = new System.Drawing.Size(18, 18);
this.picStartAddressWarning.TabIndex = 11;
this.picStartAddressWarning.TabStop = false;
this.picStartAddressWarning.Visible = false;
//
// flowLayoutPanel2
//
this.flowLayoutPanel2.Controls.Add(this.label2);
this.flowLayoutPanel2.Controls.Add(this.lblByteUsage);
this.flowLayoutPanel2.Controls.Add(this.picSizeWarning);
this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel2.Location = new System.Drawing.Point(0, 25);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(269, 25);
this.flowLayoutPanel2.TabIndex = 4;
//
// label2
//
this.label2.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 6);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(63, 13);
this.label2.TabIndex = 2;
this.label2.Text = "Byte usage:";
//
// lblByteUsage
//
this.lblByteUsage.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblByteUsage.AutoSize = true;
this.lblByteUsage.Location = new System.Drawing.Point(72, 6);
this.lblByteUsage.Name = "lblByteUsage";
this.lblByteUsage.Size = new System.Drawing.Size(30, 13);
this.lblByteUsage.TabIndex = 3;
this.lblByteUsage.Text = "0 / 0";
//
// picSizeWarning
//
this.picSizeWarning.Image = global::Mesen.GUI.Properties.Resources.Warning;
this.picSizeWarning.Location = new System.Drawing.Point(108, 5);
this.picSizeWarning.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
this.picSizeWarning.Name = "picSizeWarning";
this.picSizeWarning.Size = new System.Drawing.Size(18, 18);
this.picSizeWarning.TabIndex = 10;
this.picSizeWarning.TabStop = false;
this.picSizeWarning.Visible = false;
//
// lblNoChanges
//
this.lblNoChanges.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.lblNoChanges.AutoSize = true;
this.lblNoChanges.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
this.lblNoChanges.ForeColor = System.Drawing.SystemColors.GrayText;
this.lblNoChanges.Location = new System.Drawing.Point(104, 70);
this.lblNoChanges.Margin = new System.Windows.Forms.Padding(3, 0, 3, 3);
this.lblNoChanges.Name = "lblNoChanges";
this.lblNoChanges.Size = new System.Drawing.Size(162, 13);
this.lblNoChanges.TabIndex = 2;
this.lblNoChanges.Text = "New code matches original code";
//
// flowLayoutPanel3
//
this.flowLayoutPanel3.Controls.Add(this.btnCancel);
this.flowLayoutPanel3.Controls.Add(this.btnOk);
this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Bottom;
this.flowLayoutPanel3.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
this.flowLayoutPanel3.Location = new System.Drawing.Point(0, 86);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(269, 30);
this.flowLayoutPanel3.TabIndex = 5;
//
// groupBox1
//
this.groupBox1.Controls.Add(this.panel1);
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox1.Location = new System.Drawing.Point(3, 3);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(396, 285);
this.groupBox1.TabIndex = 4;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Code Editor";
//
// panel1
//
this.panel1.BackColor = System.Drawing.SystemColors.ControlDark;
this.panel1.Controls.Add(this.txtCode);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(3, 16);
this.panel1.Name = "panel1";
this.panel1.Padding = new System.Windows.Forms.Padding(1);
this.panel1.Size = new System.Drawing.Size(390, 266);
this.panel1.TabIndex = 4;
//
// txtCode
//
this.txtCode.AutoCompleteBracketsList = new char[] {
'(',
')',
'{',
'}',
'[',
']',
'\"',
'\"',
'\'',
'\''};
this.txtCode.AutoIndentChars = false;
this.txtCode.AutoIndentExistingLines = false;
this.txtCode.AutoScrollMinSize = new System.Drawing.Size(43, 14);
this.txtCode.BackBrush = null;
this.txtCode.CharHeight = 14;
this.txtCode.CharWidth = 8;
this.txtCode.ContextMenuStrip = this.contextMenu;
this.txtCode.CurrentLineColor = System.Drawing.Color.Gainsboro;
this.txtCode.Cursor = System.Windows.Forms.Cursors.IBeam;
this.txtCode.DisabledColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))), ((int)(((byte)(180)))));
this.txtCode.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtCode.Font = new System.Drawing.Font("Courier New", 9.75F);
this.txtCode.IsReplaceMode = false;
this.txtCode.Location = new System.Drawing.Point(1, 1);
this.txtCode.Name = "txtCode";
this.txtCode.Paddings = new System.Windows.Forms.Padding(0);
this.txtCode.ReservedCountOfLineNumberChars = 3;
this.txtCode.SelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(60)))), ((int)(((byte)(0)))), ((int)(((byte)(0)))), ((int)(((byte)(255)))));
this.txtCode.Size = new System.Drawing.Size(388, 264);
this.txtCode.TabIndex = 6;
this.txtCode.TabLength = 2;
this.txtCode.Zoom = 100;
this.txtCode.TextChanged += new System.EventHandler<FastColoredTextBoxNS.TextChangedEventArgs>(this.txtCode_TextChanged);
//
// contextMenu
//
this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuCopy,
this.mnuCut,
this.mnuPaste,
this.toolStripMenuItem5,
this.mnuSelectAll});
this.contextMenu.Name = "contextMenu";
this.contextMenu.Size = new System.Drawing.Size(123, 98);
//
// mnuCopy
//
this.mnuCopy.Name = "mnuCopy";
this.mnuCopy.Size = new System.Drawing.Size(122, 22);
this.mnuCopy.Text = "Copy";
this.mnuCopy.Click += new System.EventHandler(this.mnuCopy_Click);
//
// mnuCut
//
this.mnuCut.Name = "mnuCut";
this.mnuCut.Size = new System.Drawing.Size(122, 22);
this.mnuCut.Text = "Cut";
this.mnuCut.Click += new System.EventHandler(this.mnuCut_Click);
//
// mnuPaste
//
this.mnuPaste.Name = "mnuPaste";
this.mnuPaste.Size = new System.Drawing.Size(122, 22);
this.mnuPaste.Text = "Paste";
this.mnuPaste.Click += new System.EventHandler(this.mnuPaste_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(119, 6);
//
// mnuSelectAll
//
this.mnuSelectAll.Name = "mnuSelectAll";
this.mnuSelectAll.Size = new System.Drawing.Size(122, 22);
this.mnuSelectAll.Text = "Select All";
this.mnuSelectAll.Click += new System.EventHandler(this.mnuSelectAll_Click);
//
// groupBox2
//
this.groupBox2.Controls.Add(this.ctrlHexBox);
this.groupBox2.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox2.Location = new System.Drawing.Point(405, 3);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(275, 285);
this.groupBox2.TabIndex = 5;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Assembled Byte Code";
//
// ctrlHexBox
//
this.ctrlHexBox.ByteColorProvider = null;
this.ctrlHexBox.ByteEditingMode = false;
this.ctrlHexBox.BytesPerLine = 8;
this.ctrlHexBox.ColumnInfoVisible = true;
this.ctrlHexBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlHexBox.EnablePerByteNavigation = false;
this.ctrlHexBox.Font = new System.Drawing.Font("Segoe UI", 9F);
this.ctrlHexBox.HighDensityMode = false;
this.ctrlHexBox.InfoBackColor = System.Drawing.Color.DarkGray;
this.ctrlHexBox.LineInfoVisible = true;
this.ctrlHexBox.Location = new System.Drawing.Point(3, 16);
this.ctrlHexBox.Name = "ctrlHexBox";
this.ctrlHexBox.ReadOnly = true;
this.ctrlHexBox.ShadowSelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(60)))), ((int)(((byte)(188)))), ((int)(((byte)(255)))));
this.ctrlHexBox.Size = new System.Drawing.Size(269, 266);
this.ctrlHexBox.TabIndex = 1;
this.ctrlHexBox.UseFixedBytesPerLine = true;
this.ctrlHexBox.VScrollBarVisible = true;
//
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.viewToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(683, 24);
this.menuStrip1.TabIndex = 3;
this.menuStrip1.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuClose});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// mnuClose
//
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuClose.Name = "mnuClose";
this.mnuClose.Size = new System.Drawing.Size(103, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
// viewToolStripMenuItem
//
this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fontSizeToolStripMenuItem,
this.mnuConfigureColors});
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.viewToolStripMenuItem.Text = "View";
//
// fontSizeToolStripMenuItem
//
this.fontSizeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuIncreaseFontSize,
this.mnuDecreaseFontSize,
this.mnuResetFontSize,
this.toolStripMenuItem2,
this.mnuSelectFont});
this.fontSizeToolStripMenuItem.Image = global::Mesen.GUI.Properties.Resources.Font;
this.fontSizeToolStripMenuItem.Name = "fontSizeToolStripMenuItem";
this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.fontSizeToolStripMenuItem.Text = "Font Options";
//
// mnuIncreaseFontSize
//
this.mnuIncreaseFontSize.Name = "mnuIncreaseFontSize";
this.mnuIncreaseFontSize.ShortcutKeyDisplayString = "";
this.mnuIncreaseFontSize.Size = new System.Drawing.Size(157, 22);
this.mnuIncreaseFontSize.Text = "Increase Size";
this.mnuIncreaseFontSize.Click += new System.EventHandler(this.mnuIncreaseFontSize_Click);
//
// mnuDecreaseFontSize
//
this.mnuDecreaseFontSize.Name = "mnuDecreaseFontSize";
this.mnuDecreaseFontSize.ShortcutKeyDisplayString = "";
this.mnuDecreaseFontSize.Size = new System.Drawing.Size(157, 22);
this.mnuDecreaseFontSize.Text = "Decrease Size";
this.mnuDecreaseFontSize.Click += new System.EventHandler(this.mnuDecreaseFontSize_Click);
//
// mnuResetFontSize
//
this.mnuResetFontSize.Name = "mnuResetFontSize";
this.mnuResetFontSize.ShortcutKeyDisplayString = "";
this.mnuResetFontSize.Size = new System.Drawing.Size(157, 22);
this.mnuResetFontSize.Text = "Reset to Default";
this.mnuResetFontSize.Click += new System.EventHandler(this.mnuResetFontSize_Click);
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(154, 6);
//
// mnuSelectFont
//
this.mnuSelectFont.Name = "mnuSelectFont";
this.mnuSelectFont.Size = new System.Drawing.Size(157, 22);
this.mnuSelectFont.Text = "Select Font...";
this.mnuSelectFont.Click += new System.EventHandler(this.mnuSelectFont_Click);
//
// mnuConfigureColors
//
this.mnuConfigureColors.Image = global::Mesen.GUI.Properties.Resources.PipetteSmall;
this.mnuConfigureColors.Name = "mnuConfigureColors";
this.mnuConfigureColors.Size = new System.Drawing.Size(180, 22);
this.mnuConfigureColors.Text = "Configure Colors";
this.mnuConfigureColors.Click += new System.EventHandler(this.mnuConfigureColors_Click);
//
// frmAssembler
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(683, 456);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.MinimumSize = new System.Drawing.Size(551, 402);
this.Name = "frmAssembler";
this.Text = "Assembler";
this.Controls.SetChildIndex(this.menuStrip1, 0);
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.grpSettings.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picStartAddressWarning)).EndInit();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picSizeWarning)).EndInit();
this.flowLayoutPanel3.ResumeLayout(false);
this.groupBox1.ResumeLayout(false);
this.panel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.txtCode)).EndInit();
this.contextMenu.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private Be.Windows.Forms.HexBox ctrlHexBox;
private System.Windows.Forms.ListBox lstErrors;
private System.Windows.Forms.GroupBox grpSettings;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtStartAddress;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label lblByteUsage;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOk;
private System.Windows.Forms.PictureBox picSizeWarning;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label lblNoChanges;
private System.Windows.Forms.PictureBox picStartAddressWarning;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private FastColoredTextBoxNS.FastColoredTextBox txtCode;
private Mesen.GUI.Controls.ctrlMesenMenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuClose;
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuConfigureColors;
private System.Windows.Forms.ToolStripMenuItem fontSizeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuIncreaseFontSize;
private System.Windows.Forms.ToolStripMenuItem mnuDecreaseFontSize;
private System.Windows.Forms.ToolStripMenuItem mnuResetFontSize;
private System.Windows.Forms.ContextMenuStrip contextMenu;
private System.Windows.Forms.ToolStripMenuItem mnuCopy;
private System.Windows.Forms.ToolStripMenuItem mnuCut;
private System.Windows.Forms.ToolStripMenuItem mnuPaste;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
private System.Windows.Forms.ToolStripMenuItem mnuSelectAll;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem mnuSelectFont;
}
}

397
UI/Debugger/frmAssembler.cs Normal file
View file

@ -0,0 +1,397 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using Be.Windows.Forms;
using FastColoredTextBoxNS;
using Mesen.GUI.Config;
using Mesen.GUI.Controls;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmAssembler : BaseForm
{
private int _startAddress;
private int _blockLength;
private bool _hasParsingErrors = false;
private bool _isEditMode = false;
private bool _startAddressValid = true;
private string _initialCode = "";
private int _textVersion = 0;
private bool _updating = false;
public frmAssembler(string code = "", int startAddress = 0, int blockLength = 0)
{
InitializeComponent();
txtCode.ForeColor = Color.Black;
AssemblerConfig cfg = ConfigManager.Config.Debug.Assembler;
RestoreLocation(cfg.WindowLocation, cfg.WindowSize);
txtCode.Font = new Font(cfg.FontFamily, cfg.FontSize, cfg.FontStyle);
txtCode.Zoom = cfg.Zoom;
UpdateCodeHighlighting();
_initialCode = code;
_startAddress = startAddress;
_blockLength = blockLength;
ctrlHexBox.Font = new Font(BaseControl.MonospaceFontFamily, 10, FontStyle.Regular);
ctrlHexBox.SelectionForeColor = Color.White;
ctrlHexBox.SelectionBackColor = Color.FromArgb(31, 123, 205);
ctrlHexBox.InfoBackColor = Color.FromArgb(235, 235, 235);
ctrlHexBox.InfoForeColor = Color.Gray;
ctrlHexBox.Width = ctrlHexBox.RequiredWidth;
ctrlHexBox.ByteProvider = new StaticByteProvider(new byte[0]);
txtStartAddress.Text = _startAddress.ToString("X6");
}
private void InitShortcuts()
{
mnuIncreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.IncreaseFontSize));
mnuDecreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.DecreaseFontSize));
mnuResetFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.ResetFontSize));
mnuPaste.InitShortcut(this, nameof(DebuggerShortcutsConfig.Paste));
mnuCopy.InitShortcut(this, nameof(DebuggerShortcutsConfig.Copy));
mnuCut.InitShortcut(this, nameof(DebuggerShortcutsConfig.Cut));
mnuSelectAll.InitShortcut(this, nameof(DebuggerShortcutsConfig.SelectAll));
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!string.IsNullOrWhiteSpace(_initialCode)) {
_isEditMode = true;
txtCode.Text = _initialCode;
} else {
_initialCode = "";
txtCode.Text = _initialCode;
}
txtCode.ClearUndo();
toolTip.SetToolTip(picSizeWarning, "Warning: The new code exceeds the original code's length." + Environment.NewLine + "Applying this modification will overwrite other portions of the code and potentially cause problems.");
toolTip.SetToolTip(picStartAddressWarning, "Warning: Start address is invalid. Must be a valid hexadecimal string.");
UpdateWindow();
InitShortcuts();
}
private void UpdateCodeHighlighting()
{
if(txtCode.SyntaxDescriptor != null) {
SyntaxDescriptor desc = txtCode.SyntaxDescriptor;
txtCode.SyntaxDescriptor = null;
txtCode.ClearStylesBuffer();
desc.Dispose();
}
DebuggerInfo cfg = ConfigManager.Config.Debug.Debugger;
SyntaxDescriptor syntax = new SyntaxDescriptor();
syntax.styles.Add(new TextStyle(new SolidBrush(cfg.CodeOpcodeColor), Brushes.Transparent, FontStyle.Regular));
syntax.styles.Add(new TextStyle(new SolidBrush(cfg.CodeLabelDefinitionColor), Brushes.Transparent, FontStyle.Regular));
syntax.styles.Add(new TextStyle(new SolidBrush(cfg.CodeImmediateColor), Brushes.Transparent, FontStyle.Regular));
syntax.styles.Add(new TextStyle(new SolidBrush(cfg.CodeAddressColor), Brushes.Transparent, FontStyle.Regular));
syntax.styles.Add(new TextStyle(new SolidBrush(cfg.CodeCommentColor), Brushes.Transparent, FontStyle.Regular));
syntax.rules.Add(new RuleDesc() { style = syntax.styles[0], pattern = @"(\n|^)[ \t]*(?<range>[a-zA-Z]{3}[*]{0,1})( |[^:a-zA-Z])" });
syntax.rules.Add(new RuleDesc() { style = syntax.styles[1], pattern = @"(\n|^)[ \t]*(?<range>[a-zA-Z_]*):" });
syntax.rules.Add(new RuleDesc() { style = syntax.styles[1], pattern = @"(\n|^)[ \t]*[a-zA-Z]{3}[ \t]+[(]{0,1}(?<range>[@_a-zA-Z]([@_a-zA-Z0-9])+)" });
syntax.rules.Add(new RuleDesc() { style = syntax.styles[2], pattern = @"(\n|^)[ \t]*[a-zA-Z]{3}[ \t]+(?<range>#[$]{0,1}([A-Fa-f0-9])+)" });
syntax.rules.Add(new RuleDesc() { style = syntax.styles[3], pattern = @"(\n|^)[ \t]*[a-zA-Z]{3}[ \t]+[\[(]{0,1}(?<range>([$][A-Fa-f0-9]+)|([0-9]+))[\])]{0,1}[ \t]*(,X|,Y|,x|,y|,s|,s\),y){0,1}[\])]{0,1}" });
syntax.rules.Add(new RuleDesc() { style = syntax.styles[4], pattern = @"(\n|^)[^\n;]*(?<range>;[^\n]*)" });
txtCode.SyntaxDescriptor = syntax;
txtCode.OnTextChanged();
}
private bool SizeExceeded
{
get { return ctrlHexBox.ByteProvider.Length > _blockLength; }
}
private bool IsIdentical
{
get
{
if(ctrlHexBox.ByteProvider.Length != _blockLength) {
return false;
} else {
for(int i = 0; i < ctrlHexBox.ByteProvider.Length; i++) {
if(DebugApi.GetMemoryValue(SnesMemoryType.CpuMemory, (UInt32)(_startAddress + i)) != ctrlHexBox.ByteProvider.ReadByte(i)) {
return false;
}
}
return true;
}
}
}
private void UpdateWindow()
{
if(!this.IsHandleCreated) {
return;
}
btnOk.Enabled = false;
_textVersion++;
if(_updating) {
return;
}
_updating = true;
string text = txtCode.Text;
int version = _textVersion;
Task.Run(() => {
short[] byteCode = DebugApi.AssembleCode(text, (UInt32)_startAddress);
this.BeginInvoke((Action)(() => {
_updating = false;
if(_textVersion != version) {
UpdateWindow();
}
List<byte> convertedByteCode = new List<byte>();
List<ErrorDetail> errorList = new List<ErrorDetail>();
string[] codeLines = text.Replace("\r", "").Split('\n');
int line = 1;
foreach(short s in byteCode) {
if(s >= 0) {
convertedByteCode.Add((byte)s);
} else if(s == (int)AssemblerSpecialCodes.EndOfLine) {
line++;
} else if(s < (int)AssemblerSpecialCodes.EndOfLine) {
string message = "unknown error";
switch((AssemblerSpecialCodes)s) {
case AssemblerSpecialCodes.ParsingError: message = "Invalid syntax"; break;
case AssemblerSpecialCodes.OutOfRangeJump: message = "Relative jump is out of range (-128 to 127)"; break;
case AssemblerSpecialCodes.LabelRedefinition: message = "Cannot redefine an existing label"; break;
case AssemblerSpecialCodes.MissingOperand: message = "Operand is missing"; break;
case AssemblerSpecialCodes.OperandOutOfRange: message = "Operand is out of range (invalid value)"; break;
case AssemblerSpecialCodes.InvalidHex: message = "Hexadecimal string is invalid"; break;
case AssemblerSpecialCodes.InvalidSpaces: message = "Operand cannot contain spaces"; break;
case AssemblerSpecialCodes.TrailingText: message = "Invalid text trailing at the end of line"; break;
case AssemblerSpecialCodes.UnknownLabel: message = "Unknown label"; break;
case AssemblerSpecialCodes.InvalidInstruction: message = "Invalid instruction"; break;
case AssemblerSpecialCodes.InvalidBinaryValue: message = "Invalid binary value"; break;
}
errorList.Add(new ErrorDetail() { Message = message + " - " + codeLines[line-1], LineNumber = line });
line++;
}
}
_hasParsingErrors = errorList.Count > 0;
lstErrors.BeginUpdate();
lstErrors.Items.Clear();
lstErrors.Items.AddRange(errorList.ToArray());
lstErrors.EndUpdate();
ctrlHexBox.ByteProvider = new StaticByteProvider(convertedByteCode.ToArray());
UpdateButtons();
}));
});
}
private void UpdateButtons()
{
if(_isEditMode) {
lblByteUsage.Text = ctrlHexBox.ByteProvider.Length.ToString() + " / " + _blockLength.ToString();
lblByteUsage.ForeColor = SizeExceeded ? Color.Red : Color.Black;
picSizeWarning.Visible = SizeExceeded;
bool isIdentical = IsIdentical;
lblNoChanges.Visible = isIdentical;
btnOk.Image = _hasParsingErrors || SizeExceeded ? Properties.Resources.Warning : null;
btnOk.Enabled = !isIdentical && _startAddressValid && ctrlHexBox.ByteProvider.Length > 0;
} else {
lblNoChanges.Visible = false;
btnOk.Image = _hasParsingErrors ? Properties.Resources.Warning : null;
btnOk.Enabled = _startAddressValid && ctrlHexBox.ByteProvider.Length > 0;
lblByteUsage.Text = ctrlHexBox.ByteProvider.Length.ToString();
}
picStartAddressWarning.Visible = !_startAddressValid;
}
private void txtCode_TextChanged(object sender, FastColoredTextBoxNS.TextChangedEventArgs e)
{
UpdateWindow();
}
private void txtStartAddress_TextChanged(object sender, EventArgs e)
{
try {
_startAddress = int.Parse(txtStartAddress.Text, System.Globalization.NumberStyles.HexNumber);
_startAddressValid = true;
} catch {
_startAddressValid = false;
}
UpdateWindow();
}
private void btnOk_Click(object sender, EventArgs e)
{
List<string> warningMessages = new List<string>();
if(_hasParsingErrors) {
warningMessages.Add("Warning: The code contains parsing errors - lines with errors will be ignored.");
}
if(_isEditMode) {
if(SizeExceeded) {
warningMessages.Add("Warning: The new code exceeds the original code's length." + Environment.NewLine + "Applying this modification will overwrite other portions of the code and potentially cause problems.");
}
} else {
warningMessages.Add($"Warning: The contents currently mapped to CPU memory addresses ${_startAddress.ToString("X6")} to ${(_startAddress+ctrlHexBox.ByteProvider.Length).ToString("X6")} will be overridden.");
}
if(warningMessages.Count == 0 || MessageBox.Show(string.Join(Environment.NewLine+Environment.NewLine, warningMessages.ToArray()) + Environment.NewLine + Environment.NewLine + "OK?", "Warning", MessageBoxButtons.OKCancel) == DialogResult.OK) {
List<byte> bytes = new List<byte>(((StaticByteProvider)ctrlHexBox.ByteProvider).Bytes);
int byteGap = (int)(_blockLength - ctrlHexBox.ByteProvider.Length);
for(int i = 0; i < byteGap; i++) {
//Pad data with NOPs as needed
bytes.Add(0xEA);
}
DebugApi.SetMemoryValues(SnesMemoryType.CpuMemory, (UInt32)_startAddress, bytes.ToArray(), bytes.Count);
DebugApi.MarkBytesAs((uint)_startAddress, (uint)(_startAddress + bytes.Count), CdlFlags.Code);
frmDebugger debugger = DebugWindowManager.OpenDebugger(CpuType.Cpu);
if(debugger != null) {
debugger.RefreshDisassembly();
}
this.DialogResult = DialogResult.OK;
this.Close();
}
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.Close();
}
protected override void OnClosing(CancelEventArgs e)
{
if(_updating) {
e.Cancel = true;
return;
}
base.OnClosing(e);
AssemblerConfig cfg = ConfigManager.Config.Debug.Assembler;
cfg.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
cfg.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
cfg.Zoom = txtCode.Zoom;
cfg.FontFamily = txtCode.OriginalFont.FontFamily.Name;
cfg.FontSize = txtCode.OriginalFont.Size;
cfg.FontStyle = txtCode.OriginalFont.Style;
ConfigManager.ApplyChanges();
}
private void mnuClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void mnuConfigureColors_Click(object sender, EventArgs e)
{
using(frmDebuggerColors frm = new frmDebuggerColors()) {
if(frm.ShowDialog(this, this) == DialogResult.OK) {
UpdateCodeHighlighting();
}
}
}
private void mnuIncreaseFontSize_Click(object sender, EventArgs e)
{
txtCode.Zoom += 10;
}
private void mnuDecreaseFontSize_Click(object sender, EventArgs e)
{
txtCode.Zoom -= 10;
}
private void mnuResetFontSize_Click(object sender, EventArgs e)
{
txtCode.Zoom = 100;
}
private void mnuSelectFont_Click(object sender, EventArgs e)
{
txtCode.Font = FontDialogHelper.SelectFont(txtCode.OriginalFont);
txtCode.Zoom = txtCode.Zoom;
}
private void mnuCopy_Click(object sender, EventArgs e)
{
txtCode.Copy();
}
private void mnuCut_Click(object sender, EventArgs e)
{
txtCode.Cut();
}
private void mnuPaste_Click(object sender, EventArgs e)
{
txtCode.Paste();
}
private void mnuSelectAll_Click(object sender, EventArgs e)
{
txtCode.SelectAll();
}
enum AssemblerSpecialCodes
{
OK = 0,
EndOfLine = -1,
ParsingError = -2,
OutOfRangeJump = -3,
LabelRedefinition = -4,
MissingOperand = -5,
OperandOutOfRange = -6,
InvalidHex = -7,
InvalidSpaces = -8,
TrailingText = -9,
UnknownLabel = -10,
InvalidInstruction = -11,
InvalidBinaryValue = -12
}
private void lstErrors_DoubleClick(object sender, EventArgs e)
{
if(lstErrors.SelectedItem != null) {
int lineNumber = (lstErrors.SelectedItem as ErrorDetail).LineNumber;
txtCode.Selection = txtCode.GetLine(lineNumber - 1);
txtCode.SelectionLength = 0;
txtCode.DoCaretVisible();
txtCode.Focus();
}
}
private class ErrorDetail
{
public string Message { get; set; }
public int LineNumber { get; set; }
public override string ToString()
{
return "Line " + LineNumber.ToString() + ": " + this.Message;
}
}
}
}

View file

@ -0,0 +1,129 @@
<?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>
<metadata name="contextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>231, 17</value>
</metadata>
</root>

View file

@ -43,7 +43,7 @@ namespace Mesen.GUI.Debugger
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInDisassembly)),
//GetMember(nameof(DebuggerShortcutsConfig.OpenAssembler)),
GetMember(nameof(DebuggerShortcutsConfig.OpenAssembler)),
GetMember(nameof(DebuggerShortcutsConfig.OpenDebugger)),
GetMember(nameof(DebuggerShortcutsConfig.OpenEventViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenMemoryTools)),
@ -101,9 +101,9 @@ namespace Mesen.GUI.Debugger
GetMember(nameof(DebuggerShortcutsConfig.GoToProgramCounter)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_SetNextStatement)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSubroutine)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSelectedCode)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSelectedCode)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSourceFile)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditLabel)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditLabel)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack)),
//GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_ToggleBreakpoint)),

View file

@ -132,6 +132,7 @@
this.grpCallstack = new System.Windows.Forms.GroupBox();
this.ctrlCallstack = new Mesen.GUI.Debugger.Controls.ctrlCallstack();
this.tsToolbar = new Mesen.GUI.Controls.ctrlMesenToolStrip();
this.mnuConfigureColors = new System.Windows.Forms.ToolStripMenuItem();
this.ctrlMesenMenuStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainer)).BeginInit();
this.ctrlSplitContainer.Panel1.SuspendLayout();
@ -527,6 +528,7 @@
this.toolStripMenuItem5,
this.mnuFontOptions,
this.toolStripMenuItem4,
this.mnuConfigureColors,
this.mnuPreferences});
this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
this.optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
@ -743,32 +745,32 @@
//
this.mnuIncreaseFontSize.Name = "mnuIncreaseFontSize";
this.mnuIncreaseFontSize.ShortcutKeyDisplayString = "";
this.mnuIncreaseFontSize.Size = new System.Drawing.Size(157, 22);
this.mnuIncreaseFontSize.Size = new System.Drawing.Size(180, 22);
this.mnuIncreaseFontSize.Text = "Increase Size";
//
// mnuDecreaseFontSize
//
this.mnuDecreaseFontSize.Name = "mnuDecreaseFontSize";
this.mnuDecreaseFontSize.ShortcutKeyDisplayString = "";
this.mnuDecreaseFontSize.Size = new System.Drawing.Size(157, 22);
this.mnuDecreaseFontSize.Size = new System.Drawing.Size(180, 22);
this.mnuDecreaseFontSize.Text = "Decrease Size";
//
// mnuResetFontSize
//
this.mnuResetFontSize.Name = "mnuResetFontSize";
this.mnuResetFontSize.ShortcutKeyDisplayString = "";
this.mnuResetFontSize.Size = new System.Drawing.Size(157, 22);
this.mnuResetFontSize.Size = new System.Drawing.Size(180, 22);
this.mnuResetFontSize.Text = "Reset to Default";
//
// toolStripMenuItem21
//
this.toolStripMenuItem21.Name = "toolStripMenuItem21";
this.toolStripMenuItem21.Size = new System.Drawing.Size(154, 6);
this.toolStripMenuItem21.Size = new System.Drawing.Size(177, 6);
//
// mnuSelectFont
//
this.mnuSelectFont.Name = "mnuSelectFont";
this.mnuSelectFont.Size = new System.Drawing.Size(157, 22);
this.mnuSelectFont.Size = new System.Drawing.Size(180, 22);
this.mnuSelectFont.Text = "Select Font...";
this.mnuSelectFont.Click += new System.EventHandler(this.mnuSelectFont_Click);
//
@ -962,6 +964,14 @@
this.tsToolbar.TabIndex = 3;
this.tsToolbar.Text = "ctrlMesenToolStrip1";
//
// mnuConfigureColors
//
this.mnuConfigureColors.Image = global::Mesen.GUI.Properties.Resources.PipetteSmall;
this.mnuConfigureColors.Name = "mnuConfigureColors";
this.mnuConfigureColors.Size = new System.Drawing.Size(209, 22);
this.mnuConfigureColors.Text = "Configure colors";
this.mnuConfigureColors.Click += new System.EventHandler(this.mnuConfigureColors_Click);
//
// frmDebugger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -1096,5 +1106,6 @@
private System.Windows.Forms.ToolStripMenuItem mnuUseLowerCaseDisassembly;
private System.Windows.Forms.ToolStripMenuItem mnuGoToAll;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11;
private System.Windows.Forms.ToolStripMenuItem mnuConfigureColors;
}
}

View file

@ -498,6 +498,14 @@ namespace Mesen.GUI.Debugger
}
}
private void mnuConfigureColors_Click(object sender, EventArgs e)
{
using(frmDebuggerColors frm = new frmDebuggerColors()) {
frm.ShowDialog(sender, this);
ctrlDisassemblyView.Invalidate();
}
}
private void ctrlBreakpoints_BreakpointNavigation(Breakpoint bp)
{
ctrlDisassemblyView.ScrollToAddress((uint)bp.GetRelativeAddress());

481
UI/Debugger/frmDebuggerColors.Designer.cs generated Normal file
View file

@ -0,0 +1,481 @@
namespace Mesen.GUI.Debugger
{
partial class frmDebuggerColors
{
/// <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.lblOpcode = new System.Windows.Forms.Label();
this.lblPauseBackgroundSettings = new System.Windows.Forms.Label();
this.picActiveStatement = new ctrlColorPicker();
this.lblActiveStatement = new System.Windows.Forms.Label();
this.lblExecBreakpoint = new System.Windows.Forms.Label();
this.lblUnidentifiedData = new System.Windows.Forms.Label();
this.picExecBreakpoint = new ctrlColorPicker();
this.picUnidentifiedData = new ctrlColorPicker();
this.picWriteBreakpoint = new ctrlColorPicker();
this.lblWriteBreakpoint = new System.Windows.Forms.Label();
this.lblUnexecutedCode = new System.Windows.Forms.Label();
this.lblVerifiedData = new System.Windows.Forms.Label();
this.picUnexecutedCode = new ctrlColorPicker();
this.picVerifiedData = new ctrlColorPicker();
this.lblReadBreakpoint = new System.Windows.Forms.Label();
this.picReadBreakpoint = new ctrlColorPicker();
this.picOpcode = new ctrlColorPicker();
this.lblLabelDefinition = new System.Windows.Forms.Label();
this.picLabelDefinition = new ctrlColorPicker();
this.lblImmediate = new System.Windows.Forms.Label();
this.picImmediate = new ctrlColorPicker();
this.lblAddress = new System.Windows.Forms.Label();
this.picAddress = new ctrlColorPicker();
this.lblComment = new System.Windows.Forms.Label();
this.picComment = new ctrlColorPicker();
this.lblEffectiveAddress = new System.Windows.Forms.Label();
this.picEffectiveAddress = new ctrlColorPicker();
this.btnReset = new System.Windows.Forms.Button();
this.baseConfigPanel.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picActiveStatement)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picExecBreakpoint)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picUnidentifiedData)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picWriteBreakpoint)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picUnexecutedCode)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picVerifiedData)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picReadBreakpoint)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picOpcode)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picLabelDefinition)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picImmediate)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picAddress)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picComment)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picEffectiveAddress)).BeginInit();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Controls.Add(this.btnReset);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 212);
this.baseConfigPanel.Size = new System.Drawing.Size(555, 29);
this.baseConfigPanel.Controls.SetChildIndex(this.btnReset, 0);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 8;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33332F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33334F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.Controls.Add(this.lblOpcode, 0, 4);
this.tableLayoutPanel1.Controls.Add(this.lblPauseBackgroundSettings, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.picActiveStatement, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.lblActiveStatement, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.lblExecBreakpoint, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.lblUnidentifiedData, 3, 0);
this.tableLayoutPanel1.Controls.Add(this.picExecBreakpoint, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.picUnidentifiedData, 4, 0);
this.tableLayoutPanel1.Controls.Add(this.picWriteBreakpoint, 4, 1);
this.tableLayoutPanel1.Controls.Add(this.lblWriteBreakpoint, 3, 1);
this.tableLayoutPanel1.Controls.Add(this.lblUnexecutedCode, 6, 0);
this.tableLayoutPanel1.Controls.Add(this.lblVerifiedData, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.picUnexecutedCode, 7, 0);
this.tableLayoutPanel1.Controls.Add(this.picVerifiedData, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.lblReadBreakpoint, 6, 1);
this.tableLayoutPanel1.Controls.Add(this.picReadBreakpoint, 7, 1);
this.tableLayoutPanel1.Controls.Add(this.picOpcode, 1, 4);
this.tableLayoutPanel1.Controls.Add(this.lblLabelDefinition, 3, 4);
this.tableLayoutPanel1.Controls.Add(this.picLabelDefinition, 4, 4);
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 5);
this.tableLayoutPanel1.Controls.Add(this.picAddress, 1, 5);
this.tableLayoutPanel1.Controls.Add(this.lblEffectiveAddress, 3, 2);
this.tableLayoutPanel1.Controls.Add(this.picEffectiveAddress, 4, 2);
this.tableLayoutPanel1.Controls.Add(this.lblImmediate, 3, 5);
this.tableLayoutPanel1.Controls.Add(this.lblComment, 6, 4);
this.tableLayoutPanel1.Controls.Add(this.picImmediate, 4, 5);
this.tableLayoutPanel1.Controls.Add(this.picComment, 7, 4);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 7;
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.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.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(555, 241);
this.tableLayoutPanel1.TabIndex = 2;
//
// lblOpcode
//
this.lblOpcode.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblOpcode.AutoSize = true;
this.lblOpcode.Location = new System.Drawing.Point(3, 146);
this.lblOpcode.Name = "lblOpcode";
this.lblOpcode.Size = new System.Drawing.Size(48, 13);
this.lblOpcode.TabIndex = 25;
this.lblOpcode.Text = "Opcode:";
//
// lblPauseBackgroundSettings
//
this.lblPauseBackgroundSettings.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lblPauseBackgroundSettings.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.lblPauseBackgroundSettings, 3);
this.lblPauseBackgroundSettings.ForeColor = System.Drawing.SystemColors.GrayText;
this.lblPauseBackgroundSettings.Location = new System.Drawing.Point(0, 121);
this.lblPauseBackgroundSettings.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.lblPauseBackgroundSettings.Name = "lblPauseBackgroundSettings";
this.lblPauseBackgroundSettings.Size = new System.Drawing.Size(97, 13);
this.lblPauseBackgroundSettings.TabIndex = 24;
this.lblPauseBackgroundSettings.Text = "Syntax Highlighting";
//
// picActiveStatement
//
this.picActiveStatement.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picActiveStatement.Cursor = System.Windows.Forms.Cursors.Hand;
this.picActiveStatement.Location = new System.Drawing.Point(136, 79);
this.picActiveStatement.Name = "picActiveStatement";
this.picActiveStatement.Size = new System.Drawing.Size(32, 32);
this.picActiveStatement.TabIndex = 7;
this.picActiveStatement.TabStop = false;
//
// lblActiveStatement
//
this.lblActiveStatement.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblActiveStatement.AutoSize = true;
this.lblActiveStatement.Location = new System.Drawing.Point(3, 88);
this.lblActiveStatement.Name = "lblActiveStatement";
this.lblActiveStatement.Size = new System.Drawing.Size(91, 13);
this.lblActiveStatement.TabIndex = 4;
this.lblActiveStatement.Text = "Active Statement:";
//
// lblExecBreakpoint
//
this.lblExecBreakpoint.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblExecBreakpoint.AutoSize = true;
this.lblExecBreakpoint.Location = new System.Drawing.Point(3, 50);
this.lblExecBreakpoint.Name = "lblExecBreakpoint";
this.lblExecBreakpoint.Size = new System.Drawing.Size(88, 13);
this.lblExecBreakpoint.TabIndex = 2;
this.lblExecBreakpoint.Text = "Exec Breakpoint:";
//
// lblUnidentifiedData
//
this.lblUnidentifiedData.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblUnidentifiedData.AutoSize = true;
this.lblUnidentifiedData.Location = new System.Drawing.Point(194, 12);
this.lblUnidentifiedData.Name = "lblUnidentifiedData";
this.lblUnidentifiedData.Size = new System.Drawing.Size(122, 13);
this.lblUnidentifiedData.TabIndex = 10;
this.lblUnidentifiedData.Text = "Unidentified Code/Data:";
//
// picExecBreakpoint
//
this.picExecBreakpoint.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picExecBreakpoint.Cursor = System.Windows.Forms.Cursors.Hand;
this.picExecBreakpoint.Location = new System.Drawing.Point(136, 41);
this.picExecBreakpoint.Name = "picExecBreakpoint";
this.picExecBreakpoint.Size = new System.Drawing.Size(32, 32);
this.picExecBreakpoint.TabIndex = 6;
this.picExecBreakpoint.TabStop = false;
//
// picUnidentifiedData
//
this.picUnidentifiedData.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picUnidentifiedData.Cursor = System.Windows.Forms.Cursors.Hand;
this.picUnidentifiedData.Location = new System.Drawing.Point(327, 3);
this.picUnidentifiedData.Name = "picUnidentifiedData";
this.picUnidentifiedData.Size = new System.Drawing.Size(32, 32);
this.picUnidentifiedData.TabIndex = 8;
this.picUnidentifiedData.TabStop = false;
//
// picWriteBreakpoint
//
this.picWriteBreakpoint.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picWriteBreakpoint.Cursor = System.Windows.Forms.Cursors.Hand;
this.picWriteBreakpoint.Location = new System.Drawing.Point(327, 41);
this.picWriteBreakpoint.Name = "picWriteBreakpoint";
this.picWriteBreakpoint.Size = new System.Drawing.Size(32, 32);
this.picWriteBreakpoint.TabIndex = 12;
this.picWriteBreakpoint.TabStop = false;
//
// lblWriteBreakpoint
//
this.lblWriteBreakpoint.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblWriteBreakpoint.AutoSize = true;
this.lblWriteBreakpoint.Location = new System.Drawing.Point(194, 50);
this.lblWriteBreakpoint.Name = "lblWriteBreakpoint";
this.lblWriteBreakpoint.Size = new System.Drawing.Size(89, 13);
this.lblWriteBreakpoint.TabIndex = 1;
this.lblWriteBreakpoint.Text = "Write Breakpoint:";
//
// lblUnexecutedCode
//
this.lblUnexecutedCode.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblUnexecutedCode.AutoSize = true;
this.lblUnexecutedCode.Location = new System.Drawing.Point(385, 12);
this.lblUnexecutedCode.Name = "lblUnexecutedCode";
this.lblUnexecutedCode.Size = new System.Drawing.Size(96, 13);
this.lblUnexecutedCode.TabIndex = 0;
this.lblUnexecutedCode.Text = "Unexecuted Code:";
//
// lblVerifiedData
//
this.lblVerifiedData.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblVerifiedData.AutoSize = true;
this.lblVerifiedData.Location = new System.Drawing.Point(3, 12);
this.lblVerifiedData.Name = "lblVerifiedData";
this.lblVerifiedData.Size = new System.Drawing.Size(71, 13);
this.lblVerifiedData.TabIndex = 11;
this.lblVerifiedData.Text = "Verified Data:";
//
// picUnexecutedCode
//
this.picUnexecutedCode.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picUnexecutedCode.Cursor = System.Windows.Forms.Cursors.Hand;
this.picUnexecutedCode.Location = new System.Drawing.Point(518, 3);
this.picUnexecutedCode.Name = "picUnexecutedCode";
this.picUnexecutedCode.Size = new System.Drawing.Size(32, 32);
this.picUnexecutedCode.TabIndex = 5;
this.picUnexecutedCode.TabStop = false;
//
// picVerifiedData
//
this.picVerifiedData.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picVerifiedData.Cursor = System.Windows.Forms.Cursors.Hand;
this.picVerifiedData.Location = new System.Drawing.Point(136, 3);
this.picVerifiedData.Name = "picVerifiedData";
this.picVerifiedData.Size = new System.Drawing.Size(32, 32);
this.picVerifiedData.TabIndex = 9;
this.picVerifiedData.TabStop = false;
//
// lblReadBreakpoint
//
this.lblReadBreakpoint.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblReadBreakpoint.AutoSize = true;
this.lblReadBreakpoint.Location = new System.Drawing.Point(385, 50);
this.lblReadBreakpoint.Name = "lblReadBreakpoint";
this.lblReadBreakpoint.Size = new System.Drawing.Size(90, 13);
this.lblReadBreakpoint.TabIndex = 16;
this.lblReadBreakpoint.Text = "Read Breakpoint:";
//
// picReadBreakpoint
//
this.picReadBreakpoint.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picReadBreakpoint.Cursor = System.Windows.Forms.Cursors.Hand;
this.picReadBreakpoint.Location = new System.Drawing.Point(518, 41);
this.picReadBreakpoint.Name = "picReadBreakpoint";
this.picReadBreakpoint.Size = new System.Drawing.Size(32, 32);
this.picReadBreakpoint.TabIndex = 17;
this.picReadBreakpoint.TabStop = false;
//
// picOpcode
//
this.picOpcode.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picOpcode.Cursor = System.Windows.Forms.Cursors.Hand;
this.picOpcode.Location = new System.Drawing.Point(136, 137);
this.picOpcode.Name = "picOpcode";
this.picOpcode.Size = new System.Drawing.Size(32, 32);
this.picOpcode.TabIndex = 26;
this.picOpcode.TabStop = false;
//
// lblLabelDefinition
//
this.lblLabelDefinition.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblLabelDefinition.AutoSize = true;
this.lblLabelDefinition.Location = new System.Drawing.Point(194, 146);
this.lblLabelDefinition.Name = "lblLabelDefinition";
this.lblLabelDefinition.Size = new System.Drawing.Size(36, 13);
this.lblLabelDefinition.TabIndex = 27;
this.lblLabelDefinition.Text = "Label:";
//
// picLabelDefinition
//
this.picLabelDefinition.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picLabelDefinition.Cursor = System.Windows.Forms.Cursors.Hand;
this.picLabelDefinition.Location = new System.Drawing.Point(327, 137);
this.picLabelDefinition.Name = "picLabelDefinition";
this.picLabelDefinition.Size = new System.Drawing.Size(32, 32);
this.picLabelDefinition.TabIndex = 28;
this.picLabelDefinition.TabStop = false;
//
// lblImmediate
//
this.lblImmediate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblImmediate.AutoSize = true;
this.lblImmediate.Location = new System.Drawing.Point(194, 184);
this.lblImmediate.Name = "lblImmediate";
this.lblImmediate.Size = new System.Drawing.Size(88, 13);
this.lblImmediate.TabIndex = 29;
this.lblImmediate.Text = "Immediate Value:";
//
// picImmediate
//
this.picImmediate.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picImmediate.Cursor = System.Windows.Forms.Cursors.Hand;
this.picImmediate.Location = new System.Drawing.Point(327, 175);
this.picImmediate.Name = "picImmediate";
this.picImmediate.Size = new System.Drawing.Size(32, 32);
this.picImmediate.TabIndex = 30;
this.picImmediate.TabStop = false;
//
// lblAddress
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 184);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(77, 13);
this.lblAddress.TabIndex = 31;
this.lblAddress.Text = "Address value:";
//
// picAddress
//
this.picAddress.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picAddress.Cursor = System.Windows.Forms.Cursors.Hand;
this.picAddress.Location = new System.Drawing.Point(136, 175);
this.picAddress.Name = "picAddress";
this.picAddress.Size = new System.Drawing.Size(32, 32);
this.picAddress.TabIndex = 32;
this.picAddress.TabStop = false;
//
// lblComment
//
this.lblComment.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblComment.AutoSize = true;
this.lblComment.Location = new System.Drawing.Point(385, 146);
this.lblComment.Name = "lblComment";
this.lblComment.Size = new System.Drawing.Size(51, 13);
this.lblComment.TabIndex = 33;
this.lblComment.Text = "Comment";
//
// picComment
//
this.picComment.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picComment.Cursor = System.Windows.Forms.Cursors.Hand;
this.picComment.Location = new System.Drawing.Point(518, 137);
this.picComment.Name = "picComment";
this.picComment.Size = new System.Drawing.Size(32, 32);
this.picComment.TabIndex = 34;
this.picComment.TabStop = false;
//
// lblEffectiveAddress
//
this.lblEffectiveAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblEffectiveAddress.AutoSize = true;
this.lblEffectiveAddress.Location = new System.Drawing.Point(194, 88);
this.lblEffectiveAddress.Name = "lblEffectiveAddress";
this.lblEffectiveAddress.Size = new System.Drawing.Size(93, 13);
this.lblEffectiveAddress.TabIndex = 35;
this.lblEffectiveAddress.Text = "Effective Address:";
//
// picEffectiveAddress
//
this.picEffectiveAddress.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picEffectiveAddress.Cursor = System.Windows.Forms.Cursors.Hand;
this.picEffectiveAddress.Location = new System.Drawing.Point(327, 79);
this.picEffectiveAddress.Name = "picEffectiveAddress";
this.picEffectiveAddress.Size = new System.Drawing.Size(32, 32);
this.picEffectiveAddress.TabIndex = 36;
this.picEffectiveAddress.TabStop = false;
//
// btnReset
//
this.btnReset.Location = new System.Drawing.Point(3, 3);
this.btnReset.Name = "btnReset";
this.btnReset.Size = new System.Drawing.Size(102, 23);
this.btnReset.TabIndex = 3;
this.btnReset.Text = "Use default colors";
this.btnReset.UseVisualStyleBackColor = true;
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
//
// frmDebuggerColors
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(555, 241);
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "frmDebuggerColors";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Configure Colors...";
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.baseConfigPanel.ResumeLayout(false);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picActiveStatement)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picExecBreakpoint)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picUnidentifiedData)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picWriteBreakpoint)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picUnexecutedCode)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picVerifiedData)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picReadBreakpoint)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picOpcode)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picLabelDefinition)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picImmediate)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picAddress)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picComment)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picEffectiveAddress)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblActiveStatement;
private System.Windows.Forms.Label lblExecBreakpoint;
private System.Windows.Forms.Label lblUnexecutedCode;
private System.Windows.Forms.Label lblWriteBreakpoint;
private ctrlColorPicker picVerifiedData;
private ctrlColorPicker picUnidentifiedData;
private ctrlColorPicker picActiveStatement;
private ctrlColorPicker picExecBreakpoint;
private ctrlColorPicker picUnexecutedCode;
private System.Windows.Forms.Label lblUnidentifiedData;
private System.Windows.Forms.Label lblVerifiedData;
private ctrlColorPicker picWriteBreakpoint;
private System.Windows.Forms.Button btnReset;
private System.Windows.Forms.Label lblReadBreakpoint;
private ctrlColorPicker picReadBreakpoint;
private System.Windows.Forms.Label lblPauseBackgroundSettings;
private System.Windows.Forms.Label lblOpcode;
private ctrlColorPicker picOpcode;
private System.Windows.Forms.Label lblLabelDefinition;
private ctrlColorPicker picLabelDefinition;
private System.Windows.Forms.Label lblImmediate;
private ctrlColorPicker picImmediate;
private System.Windows.Forms.Label lblAddress;
private ctrlColorPicker picAddress;
private System.Windows.Forms.Label lblComment;
private ctrlColorPicker picComment;
private System.Windows.Forms.Label lblEffectiveAddress;
private ctrlColorPicker picEffectiveAddress;
}
}

View file

@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmDebuggerColors : BaseConfigForm
{
public frmDebuggerColors()
{
InitializeComponent();
Entity = ConfigManager.Config.Debug.Debugger;
AddBinding(nameof(DebuggerInfo.CodeActiveStatementColor), picActiveStatement);
AddBinding(nameof(DebuggerInfo.CodeAddressColor), picAddress);
AddBinding(nameof(DebuggerInfo.CodeCommentColor), picComment);
AddBinding(nameof(DebuggerInfo.CodeEffectiveAddressColor), picEffectiveAddress);
AddBinding(nameof(DebuggerInfo.CodeExecBreakpointColor), picExecBreakpoint);
AddBinding(nameof(DebuggerInfo.CodeImmediateColor), picImmediate);
AddBinding(nameof(DebuggerInfo.CodeLabelDefinitionColor), picLabelDefinition);
AddBinding(nameof(DebuggerInfo.CodeOpcodeColor), picOpcode);
AddBinding(nameof(DebuggerInfo.CodeReadBreakpointColor), picReadBreakpoint);
AddBinding(nameof(DebuggerInfo.CodeUnexecutedCodeColor), picUnexecutedCode);
AddBinding(nameof(DebuggerInfo.CodeUnidentifiedDataColor), picUnidentifiedData);
AddBinding(nameof(DebuggerInfo.CodeVerifiedDataColor), picVerifiedData);
AddBinding(nameof(DebuggerInfo.CodeWriteBreakpointColor), picWriteBreakpoint);
}
private void btnReset_Click(object sender, EventArgs e)
{
picVerifiedData.BackColor = Color.FromArgb(255, 252, 236);
picUnidentifiedData.BackColor = Color.FromArgb(255, 242, 242);
picUnexecutedCode.BackColor = Color.FromArgb(225, 244, 228);
picExecBreakpoint.BackColor = Color.FromArgb(140, 40, 40);
picWriteBreakpoint.BackColor = Color.FromArgb(40, 120, 80);
picReadBreakpoint.BackColor = Color.FromArgb(40, 40, 200);
picActiveStatement.BackColor = Color.Yellow;
picEffectiveAddress.BackColor = Color.SteelBlue;
picOpcode.BackColor = Color.FromArgb(22, 37, 37);
picLabelDefinition.BackColor = Color.Blue;
picImmediate.BackColor = Color.Chocolate;
picAddress.BackColor = Color.DarkRed;
picComment.BackColor = Color.Green;
}
}
}

View file

@ -151,6 +151,7 @@
this.mnuDebugger = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMemoryTools = new System.Windows.Forms.ToolStripMenuItem();
this.mnuProfiler = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRegisterViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuScriptWindow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
@ -171,7 +172,8 @@
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
this.pnlRenderer = new System.Windows.Forms.Panel();
this.ctrlRecentGames = new Mesen.GUI.Controls.ctrlRecentGames();
this.mnuProfiler = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAssembler = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem26 = new System.Windows.Forms.ToolStripSeparator();
this.mnuMain.SuspendLayout();
this.pnlRenderer.SuspendLayout();
this.SuspendLayout();
@ -1082,10 +1084,12 @@
this.mnuDebugger,
this.mnuEventViewer,
this.mnuMemoryTools,
this.mnuProfiler,
this.mnuRegisterViewer,
this.mnuScriptWindow,
this.mnuTraceLogger,
this.toolStripMenuItem26,
this.mnuAssembler,
this.mnuProfiler,
this.mnuScriptWindow,
this.toolStripMenuItem12,
this.mnuTilemapViewer,
this.mnuTileViewer,
@ -1122,6 +1126,13 @@
this.mnuMemoryTools.Size = new System.Drawing.Size(183, 22);
this.mnuMemoryTools.Text = "Memory Tools";
//
// mnuProfiler
//
this.mnuProfiler.Image = global::Mesen.GUI.Properties.Resources.PerfTracker;
this.mnuProfiler.Name = "mnuProfiler";
this.mnuProfiler.Size = new System.Drawing.Size(183, 22);
this.mnuProfiler.Text = "Performance Profiler";
//
// mnuRegisterViewer
//
this.mnuRegisterViewer.Image = global::Mesen.GUI.Properties.Resources.RegisterIcon;
@ -1270,12 +1281,17 @@
this.ctrlRecentGames.TabIndex = 1;
this.ctrlRecentGames.Visible = false;
//
// mnuProfiler
// mnuAssembler
//
this.mnuProfiler.Image = global::Mesen.GUI.Properties.Resources.PerfTracker;
this.mnuProfiler.Name = "mnuProfiler";
this.mnuProfiler.Size = new System.Drawing.Size(183, 22);
this.mnuProfiler.Text = "Performance Profiler";
this.mnuAssembler.Image = global::Mesen.GUI.Properties.Resources.Chip;
this.mnuAssembler.Name = "mnuAssembler";
this.mnuAssembler.Size = new System.Drawing.Size(183, 22);
this.mnuAssembler.Text = "Assembler";
//
// toolStripMenuItem26
//
this.toolStripMenuItem26.Name = "toolStripMenuItem26";
this.toolStripMenuItem26.Size = new System.Drawing.Size(180, 6);
//
// frmMain
//
@ -1447,5 +1463,7 @@
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem mnuProfile;
private System.Windows.Forms.ToolStripMenuItem mnuProfiler;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem26;
private System.Windows.Forms.ToolStripMenuItem mnuAssembler;
}
}

View file

@ -289,6 +289,7 @@ namespace Mesen.GUI.Forms
mnuScriptWindow.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenScriptWindow));
mnuRegisterViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenRegisterViewer));
mnuProfiler.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenProfiler));
mnuAssembler.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenAssembler));
mnuNoneFilter.Click += (s, e) => { _shortcuts.SetVideoFilter(VideoFilterType.None); };
mnuNtscFilter.Click += (s, e) => { _shortcuts.SetVideoFilter(VideoFilterType.NTSC); };
@ -350,6 +351,7 @@ namespace Mesen.GUI.Forms
mnuScriptWindow.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.ScriptWindow); };
mnuRegisterViewer.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.RegisterViewer); };
mnuProfiler.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.Profiler); };
mnuAssembler.Click += (s, e) => { DebugWindowManager.OpenDebugWindow(DebugWindow.Assembler); };
mnuTestRun.Click += (s, e) => { RomTestHelper.RunTest(); };
mnuTestRecord.Click += (s, e) => { RomTestHelper.RecordTest(); };
@ -442,6 +444,7 @@ namespace Mesen.GUI.Forms
mnuEventViewer.Enabled = running;
mnuRegisterViewer.Enabled = running;
mnuProfiler.Enabled = running;
mnuAssembler.Enabled = running;
}
private void ResizeRecentGames()

View file

@ -169,6 +169,16 @@ namespace Mesen.GUI
[DllImport(DllPath)] public static extern void SetCdlData([In]byte[] cdlData, Int32 length);
[DllImport(DllPath)] public static extern void MarkBytesAs(UInt32 start, UInt32 end, CdlFlags type);
[DllImport(DllPath, EntryPoint = "AssembleCode")] private static extern UInt32 AssembleCodeWrapper([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string code, UInt32 startAddress, [In, Out]Int16[] assembledCodeBuffer);
public static Int16[] AssembleCode(string code, UInt32 startAddress)
{
code = code.Replace(Environment.NewLine, "\n");
Int16[] assembledCode = new Int16[100000];
UInt32 size = DebugApi.AssembleCodeWrapper(code, startAddress, assembledCode);
Array.Resize(ref assembledCode, (int)size);
return assembledCode;
}
}
public enum SnesMemoryType

View file

@ -272,6 +272,7 @@
<Compile Include="Debugger\Code\IDisassemblyManager.cs" />
<Compile Include="Debugger\Config\DebuggerShortcutsConfig.cs" />
<Compile Include="Debugger\Config\DebuggerInfo.cs" />
<Compile Include="Debugger\Config\AssemblerConfig.cs" />
<Compile Include="Debugger\Config\ProfilerConfig.cs" />
<Compile Include="Debugger\Config\ScriptWindowConfig.cs" />
<Compile Include="Debugger\Config\SpriteViewerConfig.cs" />
@ -317,6 +318,12 @@
<Compile Include="Debugger\EventViewer\ctrlEventViewerListView.Designer.cs">
<DependentUpon>ctrlEventViewerListView.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmAssembler.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmAssembler.designer.cs">
<DependentUpon>frmAssembler.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmBreakIn.cs">
<SubType>Form</SubType>
</Compile>
@ -329,6 +336,12 @@
<Compile Include="Debugger\frmBreakOn.Designer.cs">
<DependentUpon>frmBreakOn.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmDebuggerColors.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmDebuggerColors.designer.cs">
<DependentUpon>frmDebuggerColors.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmGoToAll.cs">
<SubType>Form</SubType>
</Compile>
@ -1025,6 +1038,9 @@
<EmbeddedResource Include="Debugger\EventViewer\ctrlEventViewerListView.resx">
<DependentUpon>ctrlEventViewerListView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmAssembler.resx">
<DependentUpon>frmAssembler.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmBreakIn.resx">
<DependentUpon>frmBreakIn.cs</DependentUpon>
</EmbeddedResource>