Debugger: Improved code window performance
This commit is contained in:
parent
204377b810
commit
49eae73d43
22 changed files with 266 additions and 186 deletions
|
@ -497,6 +497,7 @@ string Disassembler::GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uin
|
|||
string label;
|
||||
string commentString;
|
||||
string commentLines;
|
||||
shared_ptr<DisassemblyInfo> tmpInfo(new DisassemblyInfo());
|
||||
shared_ptr<DisassemblyInfo> info;
|
||||
DataType dataType = DataType::UnidentifiedData;
|
||||
string spaces = " ";
|
||||
|
@ -542,7 +543,8 @@ string Disassembler::GetCode(AddressTypeInfo &addressInfo, uint32_t endAddr, uin
|
|||
isVerifiedData = addressInfo.Type == AddressType::PrgRom && cdl->IsData(addr&mask);
|
||||
if(!info && ((disassembleUnidentifiedData && !isVerifiedData) || (disassembleVerifiedData && isVerifiedData))) {
|
||||
dataType = isVerifiedData ? DataType::VerifiedData : (addressInfo.Type == AddressType::PrgRom ? DataType::UnidentifiedData : DataType::VerifiedCode);
|
||||
info.reset(new DisassemblyInfo(source + (addr & mask), false));
|
||||
tmpInfo->Initialize(source + (addr & mask), false);
|
||||
info = tmpInfo;
|
||||
} else if(info) {
|
||||
dataType = DataType::VerifiedCode;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,11 @@ DisassemblyInfo::DisassemblyInfo()
|
|||
{
|
||||
}
|
||||
|
||||
DisassemblyInfo::DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint)
|
||||
{
|
||||
Initialize(opPointer, isSubEntryPoint);
|
||||
}
|
||||
|
||||
void DisassemblyInfo::ToString(string &out, uint32_t memoryAddr, MemoryManager* memoryManager, LabelManager* labelManager, bool extendZeroPage)
|
||||
{
|
||||
char buffer[500];
|
||||
|
@ -143,7 +148,7 @@ uint16_t DisassemblyInfo::GetOpAddr(uint16_t memoryAddr)
|
|||
return opAddr;
|
||||
}
|
||||
|
||||
DisassemblyInfo::DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint)
|
||||
void DisassemblyInfo::Initialize(uint8_t* opPointer, bool isSubEntryPoint)
|
||||
{
|
||||
_isSubEntryPoint = isSubEntryPoint;
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ public:
|
|||
DisassemblyInfo();
|
||||
DisassemblyInfo(uint8_t* opPointer, bool isSubEntryPoint);
|
||||
|
||||
void Initialize(uint8_t * opPointer, bool isSubEntryPoint);
|
||||
|
||||
void SetSubEntryPoint();
|
||||
|
||||
int32_t GetEffectiveAddress(State& cpuState, MemoryManager* memoryManager);
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
}
|
||||
|
||||
public bool Matches(int relativeAddress, ref AddressTypeInfo info)
|
||||
public bool Matches(int relativeAddress, AddressTypeInfo info)
|
||||
{
|
||||
if(this.IsCpuBreakpoint && this.AddressType == BreakpointAddressType.SingleAddress) {
|
||||
if(this.MemoryType == DebugMemoryType.CpuMemory) {
|
||||
|
|
|
@ -70,7 +70,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public static Breakpoint GetMatchingBreakpoint(int relativeAddress, AddressTypeInfo info)
|
||||
{
|
||||
return Breakpoints.Where((bp) => bp.Matches(relativeAddress, ref info)).FirstOrDefault();
|
||||
return Breakpoints.Where((bp) => bp.Matches(relativeAddress, info)).FirstOrDefault();
|
||||
}
|
||||
|
||||
public static Breakpoint GetMatchingBreakpoint(UInt32 startAddress, UInt32 endAddress, DebugMemoryType memoryType)
|
||||
|
|
130
GUI.NET/Debugger/CodeInfo.cs
Normal file
130
GUI.NET/Debugger/CodeInfo.cs
Normal file
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public class CodeInfo
|
||||
{
|
||||
public int[] LineNumbers { get; private set; }
|
||||
public string[] LineNumberNotes { get; private set; }
|
||||
public char[] LineMemoryType { get; private set; }
|
||||
public int[] AbsoluteLineNumbers { get; private set; }
|
||||
public string[] CodeNotes { get; private set; }
|
||||
public string[] CodeLines { get; private set; }
|
||||
public HashSet<int> UnexecutedAddresses { get; private set; }
|
||||
public HashSet<int> VerifiedDataAddresses { get; private set; }
|
||||
public HashSet<int> SpeculativeCodeAddreses { get; private set; }
|
||||
public Dictionary<int, string> CodeContent { get; private set; }
|
||||
public Dictionary<int, string> CodeByteCode { get; private set; }
|
||||
public string[] Addressing { get; private set; }
|
||||
public string[] Comments { get; private set; }
|
||||
public int[] LineIndentations { get; private set; }
|
||||
|
||||
public CodeInfo(string code)
|
||||
{
|
||||
string[] token = code.Split('\x1');
|
||||
|
||||
int lineCount = token.Length / 8;
|
||||
LineNumbers = new int[lineCount];
|
||||
LineNumberNotes = new string[lineCount];
|
||||
LineMemoryType = new char[lineCount];
|
||||
AbsoluteLineNumbers = new int[lineCount];
|
||||
CodeNotes = new string[lineCount];
|
||||
CodeLines = new string[lineCount];
|
||||
Addressing = new string[lineCount];
|
||||
Comments = new string[lineCount];
|
||||
LineIndentations = new int[lineCount];
|
||||
|
||||
UnexecutedAddresses = new HashSet<int>();
|
||||
VerifiedDataAddresses = new HashSet<int>();
|
||||
SpeculativeCodeAddreses = new HashSet<int>();
|
||||
|
||||
int tokenIndex = 0;
|
||||
int lineNumber = 0;
|
||||
|
||||
while(tokenIndex < token.Length - 8) {
|
||||
int relativeAddress = ParseHexAddress(token[tokenIndex + 1]);
|
||||
|
||||
//Flags:
|
||||
//1: Executed code
|
||||
//2: Speculative Code
|
||||
//4: Indented line
|
||||
switch(token[tokenIndex][0]) {
|
||||
case '2':
|
||||
SpeculativeCodeAddreses.Add(lineNumber);
|
||||
LineIndentations[lineNumber] = 0;
|
||||
break;
|
||||
|
||||
case '4':
|
||||
UnexecutedAddresses.Add(lineNumber);
|
||||
LineIndentations[lineNumber] = 20;
|
||||
break;
|
||||
|
||||
case '6':
|
||||
SpeculativeCodeAddreses.Add(lineNumber);
|
||||
LineIndentations[lineNumber] = 20;
|
||||
break;
|
||||
|
||||
case '5':
|
||||
LineIndentations[lineNumber] = 20;
|
||||
break;
|
||||
|
||||
case '8':
|
||||
VerifiedDataAddresses.Add(lineNumber);
|
||||
LineIndentations[lineNumber] = 0;
|
||||
break;
|
||||
|
||||
case '9':
|
||||
VerifiedDataAddresses.Add(lineNumber);
|
||||
LineIndentations[lineNumber] = 20;
|
||||
break;
|
||||
|
||||
default:
|
||||
LineIndentations[lineNumber] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
LineNumbers[lineNumber] = relativeAddress;
|
||||
LineMemoryType[lineNumber] = token[tokenIndex + 2][0];
|
||||
LineNumberNotes[lineNumber] = token[tokenIndex + 3];
|
||||
AbsoluteLineNumbers[lineNumber] = this.ParseHexAddress(token[tokenIndex + 3]);
|
||||
CodeNotes[lineNumber] = token[tokenIndex + 4];
|
||||
CodeLines[lineNumber] = token[tokenIndex + 5];
|
||||
|
||||
Addressing[lineNumber] = token[tokenIndex + 6];
|
||||
Comments[lineNumber] = token[tokenIndex + 7];
|
||||
|
||||
|
||||
lineNumber++;
|
||||
tokenIndex += 8;
|
||||
}
|
||||
}
|
||||
|
||||
public void InitAssemblerValues()
|
||||
{
|
||||
if(CodeContent == null) {
|
||||
CodeContent = new Dictionary<int, string>(LineNumbers.Length);
|
||||
CodeByteCode = new Dictionary<int, string>(LineNumbers.Length);
|
||||
|
||||
for(int i = 0; i < LineNumbers.Length; i++) {
|
||||
//Used by assembler
|
||||
int relativeAddress = LineNumbers[i];
|
||||
CodeByteCode[relativeAddress] = CodeNotes[i];
|
||||
CodeContent[relativeAddress] = CodeLines[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int ParseHexAddress(string hexAddress)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(hexAddress)) {
|
||||
return -1;
|
||||
} else {
|
||||
return HexConverter.FromHex(hexAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@ namespace Mesen.GUI.Debugger
|
|||
private Control _owner = null;
|
||||
private ctrlScrollableTextbox _codeViewer = null;
|
||||
|
||||
public string Code { get; set; }
|
||||
public CodeInfo Code { get; set; }
|
||||
public Ld65DbgImporter SymbolProvider { get; set; }
|
||||
|
||||
public CodeTooltipManager(Control owner, ctrlScrollableTextbox codeViewer)
|
||||
|
@ -29,7 +29,7 @@ namespace Mesen.GUI.Debugger
|
|||
_codeViewer = codeViewer;
|
||||
}
|
||||
|
||||
public void ShowTooltip(string word, Dictionary<string, string> values, int lineAddress, AddressTypeInfo? previewAddress)
|
||||
public void ShowTooltip(string word, Dictionary<string, string> values, int lineAddress, AddressTypeInfo previewAddress)
|
||||
{
|
||||
if(ConfigManager.Config.DebugInfo.OnlyShowTooltipsOnShift && Control.ModifierKeys != Keys.Shift) {
|
||||
return;
|
||||
|
@ -46,7 +46,7 @@ namespace Mesen.GUI.Debugger
|
|||
if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
||||
_codeTooltip = new frmOpCodeTooltip(parentForm, word, lineAddress);
|
||||
} else {
|
||||
_codeTooltip = new frmCodeTooltip(parentForm, values, previewAddress.HasValue && previewAddress.Value.Type == AddressType.PrgRom ? previewAddress : null, Code, SymbolProvider);
|
||||
_codeTooltip = new frmCodeTooltip(parentForm, values, previewAddress != null && previewAddress.Type == AddressType.PrgRom ? previewAddress : null, Code, SymbolProvider);
|
||||
}
|
||||
_codeTooltip.FormClosed += (s, e) => { _codeTooltip = null; };
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ namespace Mesen.GUI.Debugger
|
|||
};
|
||||
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, ref addressInfo);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, addressInfo);
|
||||
this.ShowTooltip(word, values, -1, addressInfo);
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ namespace Mesen.GUI.Debugger
|
|||
byte byteValue = relativeAddress >= 0 ? InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress) : (byte)0;
|
||||
UInt16 wordValue = relativeAddress >= 0 ? (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress + 1) << 8)) : (UInt16)0;
|
||||
|
||||
AddressTypeInfo? addressInfo = SymbolProvider.GetSymbolAddressInfo(symbol);
|
||||
AddressTypeInfo addressInfo = SymbolProvider.GetSymbolAddressInfo(symbol);
|
||||
|
||||
if(addressInfo != null) {
|
||||
var values = new Dictionary<string, string>() {
|
||||
|
@ -119,8 +119,8 @@ namespace Mesen.GUI.Debugger
|
|||
values["CPU Address"] = "$" + relativeAddress.ToString("X4");
|
||||
};
|
||||
|
||||
if(addressInfo.Value.Type == AddressType.PrgRom) {
|
||||
values["PRG Offset"] = "$" + addressInfo.Value.Address.ToString("X4");
|
||||
if(addressInfo.Type == AddressType.PrgRom) {
|
||||
values["PRG Offset"] = "$" + addressInfo.Address.ToString("X4");
|
||||
}
|
||||
|
||||
values["Value"] = (relativeAddress >= 0 ? $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" : "n/a");
|
||||
|
@ -148,7 +148,7 @@ namespace Mesen.GUI.Debugger
|
|||
UInt32 address = UInt32.Parse(word.Substring(1), NumberStyles.AllowHexSpecifier);
|
||||
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, info);
|
||||
|
||||
if(info.Address >= 0) {
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)info.Address, info.Type);
|
||||
|
|
|
@ -239,7 +239,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
{
|
||||
if(UpdateContextMenu(_lastLocation)) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)_lastClickedAddress, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)_lastClickedAddress, info);
|
||||
if(info.Address >= 0) {
|
||||
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
||||
}
|
||||
|
|
|
@ -18,22 +18,6 @@ namespace Mesen.GUI.Debugger
|
|||
public delegate void AssemblerEventHandler(AssemblerEventArgs args);
|
||||
public event AssemblerEventHandler OnEditCode;
|
||||
|
||||
private List<int> _lineNumbers = new List<int>(10000);
|
||||
private List<string> _lineNumberNotes = new List<string>(10000);
|
||||
private List<char> _lineMemoryType = new List<char>(10000);
|
||||
private List<int> _absoluteLineNumbers = new List<int>(10000);
|
||||
private List<string> _codeNotes = new List<string>(10000);
|
||||
private List<string> _codeLines = new List<string>(10000);
|
||||
private HashSet<int> _unexecutedAddresses = new HashSet<int>();
|
||||
private HashSet<int> _verifiedDataAddresses = new HashSet<int>();
|
||||
private HashSet<int> _speculativeCodeAddreses = new HashSet<int>();
|
||||
private Dictionary<int, string> _codeContent = new Dictionary<int, string>(10000);
|
||||
private Dictionary<int, string> _codeComments = new Dictionary<int, string>(10000);
|
||||
private Dictionary<int, string> _codeByteCode = new Dictionary<int, string>(10000);
|
||||
private List<string> _addressing = new List<string>(10000);
|
||||
private List<string> _comments = new List<string>(10000);
|
||||
private List<int> _lineIndentations = new List<int>(10000);
|
||||
|
||||
private UInt32? _currentActiveAddress { get; set; } = null;
|
||||
|
||||
private DebugViewInfo _config;
|
||||
|
@ -81,19 +65,19 @@ namespace Mesen.GUI.Debugger
|
|||
set { _symbolProvider = value; }
|
||||
}
|
||||
|
||||
private string _code;
|
||||
private CodeInfo _code = new CodeInfo("");
|
||||
private bool _codeChanged;
|
||||
public string Code
|
||||
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public CodeInfo Code
|
||||
{
|
||||
get { return _code; }
|
||||
set
|
||||
{
|
||||
if(value != null) {
|
||||
_codeChanged = true;
|
||||
_code = value;
|
||||
_tooltipManager.Code = value;
|
||||
UpdateCode();
|
||||
}
|
||||
_codeChanged = true;
|
||||
_code = value;
|
||||
_tooltipManager.Code = value;
|
||||
UpdateCode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +125,8 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public List<string> GetCode(out int byteLength, ref int startAddress, int endAddress = -1)
|
||||
{
|
||||
_code.InitAssemblerValues();
|
||||
|
||||
List<string> result = new List<string>();
|
||||
byteLength = 0;
|
||||
|
||||
|
@ -154,7 +140,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
for(int i = startAddress; (i <= endAddress || endAddress == -1) && endAddress < 65536; ) {
|
||||
string code;
|
||||
if(_codeContent.TryGetValue(i, out code)) {
|
||||
if(_code.CodeContent.TryGetValue(i, out code)) {
|
||||
code = code.Split('\x2')[0].Trim();
|
||||
|
||||
if(code.StartsWith("--") || code.StartsWith("__")) {
|
||||
|
@ -163,7 +149,7 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)i, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)i, info);
|
||||
CodeLabel codeLabel = info.Address >= 0 ? LabelManager.GetLabel((UInt32)info.Address, AddressType.PrgRom) : null;
|
||||
string comment = codeLabel?.Comment;
|
||||
string label = codeLabel?.Label;
|
||||
|
@ -176,7 +162,7 @@ namespace Mesen.GUI.Debugger
|
|||
} else {
|
||||
comment = code;
|
||||
}
|
||||
code = ".byte " + string.Join(",", _codeByteCode[i].Split(' '));
|
||||
code = ".byte " + string.Join(",", _code.CodeByteCode[i].Split(' '));
|
||||
addPadding = false;
|
||||
}
|
||||
|
||||
|
@ -189,7 +175,7 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
result.Add((addPadding ? " " : "") + code + (!string.IsNullOrWhiteSpace(comment) ? (" ;" + comment) : ""));
|
||||
|
||||
int length = _codeByteCode[i].Count(c => c == ' ') + 1;
|
||||
int length = _code.CodeByteCode[i].Count(c => c == ' ') + 1;
|
||||
byteLength += length;
|
||||
i += length;
|
||||
|
||||
|
@ -218,101 +204,15 @@ namespace Mesen.GUI.Debugger
|
|||
scrollOffset++;
|
||||
} while(centerLineAddress < 0 && centerLineIndex > 0);
|
||||
|
||||
_lineNumbers.Clear();
|
||||
_codeContent.Clear();
|
||||
_codeComments.Clear();
|
||||
_codeByteCode.Clear();
|
||||
_unexecutedAddresses.Clear();
|
||||
_speculativeCodeAddreses.Clear();
|
||||
_verifiedDataAddresses.Clear();
|
||||
_lineMemoryType.Clear();
|
||||
_absoluteLineNumbers.Clear();
|
||||
|
||||
string[] token = new string[8];
|
||||
int tokenIndex = 0;
|
||||
int startPos = 0;
|
||||
int endPos = 0;
|
||||
int lineNumber = 0;
|
||||
ctrlCodeViewer.LineIndentations = _code.LineIndentations;
|
||||
ctrlCodeViewer.Addressing = _code.Addressing;
|
||||
ctrlCodeViewer.Comments = _code.Comments;
|
||||
|
||||
Action readToken = () => {
|
||||
endPos = _code.IndexOf('\x1', endPos) + 1;
|
||||
token[tokenIndex++] = _code.Substring(startPos, endPos - startPos - 1);
|
||||
startPos = endPos;
|
||||
};
|
||||
|
||||
Action readLine = () => {
|
||||
tokenIndex = 0;
|
||||
readToken(); readToken(); readToken(); readToken(); readToken(); readToken(); readToken(); readToken();
|
||||
};
|
||||
|
||||
Func<bool> processLine = () => {
|
||||
readLine();
|
||||
|
||||
int relativeAddress = ParseHexAddress(token[1]);
|
||||
|
||||
//Flags:
|
||||
//1: Executed code
|
||||
//2: Speculative Code
|
||||
//4: Indented line
|
||||
if(token[0] == "2") {
|
||||
_speculativeCodeAddreses.Add(lineNumber);
|
||||
_lineIndentations.Add(0);
|
||||
} else if(token[0] == "4") {
|
||||
_unexecutedAddresses.Add(lineNumber);
|
||||
_lineIndentations.Add(20);
|
||||
} else if(token[0] == "6") {
|
||||
_speculativeCodeAddreses.Add(lineNumber);
|
||||
_lineIndentations.Add(20);
|
||||
} else if(token[0] == "5") {
|
||||
_lineIndentations.Add(20);
|
||||
} else if(token[0] == "8") {
|
||||
_verifiedDataAddresses.Add(lineNumber);
|
||||
_lineIndentations.Add(0);
|
||||
} else if(token[0] == "9") {
|
||||
_verifiedDataAddresses.Add(lineNumber);
|
||||
_lineIndentations.Add(20);
|
||||
} else {
|
||||
_lineIndentations.Add(0);
|
||||
}
|
||||
|
||||
_lineNumbers.Add(relativeAddress);
|
||||
_lineMemoryType.Add(token[2][0]);
|
||||
_lineNumberNotes.Add(string.IsNullOrWhiteSpace(token[3]) ? "" : (token[3].Length > 5 ? token[3].TrimStart('0').PadLeft(4, '0') : token[3]));
|
||||
_absoluteLineNumbers.Add(this.ParseHexAddress(token[3]));
|
||||
_codeNotes.Add(token[4]);
|
||||
_codeLines.Add(token[5]);
|
||||
|
||||
_addressing.Add(token[6]);
|
||||
_comments.Add(token[7]);
|
||||
|
||||
//Used by assembler
|
||||
_codeByteCode[relativeAddress] = token[4];
|
||||
_codeContent[relativeAddress] = token[5];
|
||||
_codeComments[relativeAddress] = token[7];
|
||||
|
||||
lineNumber++;
|
||||
|
||||
return endPos < _code.Length;
|
||||
};
|
||||
|
||||
while(processLine());
|
||||
|
||||
ctrlCodeViewer.LineIndentations = _lineIndentations.ToArray();
|
||||
ctrlCodeViewer.Addressing = _addressing.ToArray();
|
||||
ctrlCodeViewer.Comments = _comments.ToArray();
|
||||
|
||||
ctrlCodeViewer.LineNumbers = _lineNumbers.ToArray();
|
||||
ctrlCodeViewer.TextLineNotes = _codeNotes.ToArray();
|
||||
ctrlCodeViewer.LineNumberNotes = _lineNumberNotes.ToArray();
|
||||
ctrlCodeViewer.TextLines = _codeLines.ToArray();
|
||||
|
||||
//These are all temporary and can be cleared right away
|
||||
_lineNumberNotes.Clear();
|
||||
_codeNotes.Clear();
|
||||
_codeLines.Clear();
|
||||
_addressing.Clear();
|
||||
_comments.Clear();
|
||||
_lineIndentations.Clear();
|
||||
ctrlCodeViewer.LineNumbers = _code.LineNumbers;
|
||||
ctrlCodeViewer.TextLineNotes = _code.CodeNotes;
|
||||
ctrlCodeViewer.LineNumberNotes = _code.LineNumberNotes;
|
||||
ctrlCodeViewer.TextLines = _code.CodeLines;
|
||||
|
||||
_codeChanged = false;
|
||||
UpdateLineColors();
|
||||
|
@ -328,16 +228,7 @@ namespace Mesen.GUI.Debugger
|
|||
UpdateLineColors();
|
||||
return false;
|
||||
}
|
||||
|
||||
private int ParseHexAddress(string hexAddress)
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(hexAddress)) {
|
||||
return -1;
|
||||
} else {
|
||||
return (int)UInt32.Parse(hexAddress, System.Globalization.NumberStyles.AllowHexSpecifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void ctrlCodeViewer_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
_tooltipManager.Close();
|
||||
|
@ -389,9 +280,9 @@ namespace Mesen.GUI.Debugger
|
|||
public AddressTypeInfo GetAddressInfo(int lineNumber)
|
||||
{
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
if(lineNumber < this._absoluteLineNumbers.Count) {
|
||||
info.Address = this._absoluteLineNumbers[lineNumber];
|
||||
switch(this._lineMemoryType[lineNumber]) {
|
||||
if(lineNumber < this._code.AbsoluteLineNumbers.Length) {
|
||||
info.Address = this._code.AbsoluteLineNumbers[lineNumber];
|
||||
switch(this._code.LineMemoryType[lineNumber]) {
|
||||
case 'P': info.Type = AddressType.PrgRom; break;
|
||||
case 'W': info.Type = AddressType.WorkRam; break;
|
||||
case 'S': info.Type = AddressType.SaveRam; break;
|
||||
|
@ -514,15 +405,15 @@ namespace Mesen.GUI.Debugger
|
|||
props.FgColor = Color.Black;
|
||||
props.TextBgColor = info.CodeActiveStatementColor;
|
||||
props.Symbol |= LineSymbol.Arrow;
|
||||
} else if(_code._unexecutedAddresses.Contains(lineNumber)) {
|
||||
} else if(_code._code.UnexecutedAddresses.Contains(lineNumber)) {
|
||||
props.LineBgColor = info.CodeUnexecutedCodeColor;
|
||||
} else if(_code._speculativeCodeAddreses.Contains(lineNumber)) {
|
||||
} else if(_code._code.SpeculativeCodeAddreses.Contains(lineNumber)) {
|
||||
props.LineBgColor = info.CodeUnidentifiedDataColor;
|
||||
} else if(_code._verifiedDataAddresses.Contains(lineNumber)) {
|
||||
} else if(_code._code.VerifiedDataAddresses.Contains(lineNumber)) {
|
||||
props.LineBgColor = info.CodeVerifiedDataColor;
|
||||
}
|
||||
|
||||
switch(_code._lineMemoryType[lineNumber]) {
|
||||
switch(_code._code.LineMemoryType[lineNumber]) {
|
||||
case 'P': props.AddressColor = Color.Gray; break;
|
||||
case 'W': props.AddressColor = Color.DarkBlue; break;
|
||||
case 'S': props.AddressColor = Color.DarkRed; break;
|
||||
|
@ -536,7 +427,7 @@ namespace Mesen.GUI.Debugger
|
|||
{
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
if(breakpoint.Matches(cpuAddress, ref addressInfo)) {
|
||||
if(breakpoint.Matches(cpuAddress, addressInfo)) {
|
||||
Color fgColor = Color.White;
|
||||
Color? bgColor = null;
|
||||
Color bpColor = breakpoint.BreakOnExec ? info.CodeExecBreakpointColor : (breakpoint.BreakOnWrite ? info.CodeWriteBreakpointColor : info.CodeReadBreakpointColor);
|
||||
|
@ -578,7 +469,7 @@ namespace Mesen.GUI.Debugger
|
|||
{
|
||||
_code = code;
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
int len = _code._absoluteLineNumbers.Count;
|
||||
int len = _code._code.AbsoluteLineNumbers.Length;
|
||||
|
||||
AddressTypeInfo[] addressInfo = new AddressTypeInfo[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
|
@ -587,7 +478,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
for(int i = 0; i < len; i++) {
|
||||
if(breakpoint.Matches(_code._lineNumbers[i], ref addressInfo[i])) {
|
||||
if(breakpoint.Matches(_code._code.LineNumbers[i], addressInfo[i])) {
|
||||
Color bpColor = breakpoint.BreakOnExec ? info.CodeExecBreakpointColor : (breakpoint.BreakOnWrite ? info.CodeWriteBreakpointColor : info.CodeReadBreakpointColor);
|
||||
_breakpointColors[i] = bpColor;
|
||||
}
|
||||
|
@ -598,17 +489,17 @@ namespace Mesen.GUI.Debugger
|
|||
public Color GetBackgroundColor(float position)
|
||||
{
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
int lineIndex = (int)((_code._lineMemoryType.Count - 1) * position);
|
||||
int lineIndex = (int)((_code._code.LineMemoryType.Length - 1) * position);
|
||||
|
||||
if(lineIndex < _code._lineMemoryType.Count) {
|
||||
switch(_code._lineMemoryType[lineIndex]) {
|
||||
if(lineIndex < _code._code.LineMemoryType.Length) {
|
||||
switch(_code._code.LineMemoryType[lineIndex]) {
|
||||
case 'N': return _nesRamColor;
|
||||
case 'P':
|
||||
if(_code._unexecutedAddresses.Contains(lineIndex)) {
|
||||
if(_code._code.UnexecutedAddresses.Contains(lineIndex)) {
|
||||
return info.CodeUnexecutedCodeColor;
|
||||
} else if(_code._verifiedDataAddresses.Contains(lineIndex)) {
|
||||
} else if(_code._code.VerifiedDataAddresses.Contains(lineIndex)) {
|
||||
return info.CodeVerifiedDataColor;
|
||||
} else if(_code._speculativeCodeAddreses.Contains(lineIndex)) {
|
||||
} else if(_code._code.SpeculativeCodeAddreses.Contains(lineIndex)) {
|
||||
return info.CodeUnidentifiedDataColor;
|
||||
}
|
||||
return Color.White;
|
||||
|
@ -622,8 +513,8 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public frmCodePreviewTooltip GetPreview(int lineIndex)
|
||||
{
|
||||
if(lineIndex < _code._lineNumbers.Count) {
|
||||
while(lineIndex > 0 && _code._lineNumbers[lineIndex] < 0) {
|
||||
if(lineIndex < _code._code.LineNumbers.Length) {
|
||||
while(lineIndex > 0 && _code._code.LineNumbers[lineIndex] < 0) {
|
||||
lineIndex--;
|
||||
}
|
||||
return new frmCodePreviewTooltip(_code.FindForm(), lineIndex, _code._code);
|
||||
|
@ -648,7 +539,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
public Color GetMarkerColor(float position, int linesPerPixel)
|
||||
{
|
||||
int lineIndex = (int)((_code._lineMemoryType.Count - 1) * position);
|
||||
int lineIndex = (int)((_code._code.LineMemoryType.Length - 1) * position);
|
||||
|
||||
Color bpColor;
|
||||
for(int i = 0; i < linesPerPixel; i++) {
|
||||
|
|
|
@ -504,7 +504,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
UInt32 address = (UInt32)ctrlHexBox.SelectionStart;
|
||||
if(this._memoryType == DebugMemoryType.CpuMemory) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, info);
|
||||
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
||||
} else {
|
||||
ctrlLabelList.EditLabel(address, GetAddressType().Value);
|
||||
|
@ -594,7 +594,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
bool disableEditLabel = false;
|
||||
if(this._memoryType == DebugMemoryType.CpuMemory) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(startAddress, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(startAddress, info);
|
||||
disableEditLabel = info.Address == -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -254,7 +254,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
CodeLabel label = (CodeLabel)GetSelectedItem().SubItems[1].Tag;
|
||||
if(label.AddressType == AddressType.InternalRam || label.AddressType == AddressType.Register) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(label.Address, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(label.Address, info);
|
||||
if(BreakpointManager.GetMatchingBreakpoint((Int32)label.Address, info) == null) {
|
||||
BreakpointManager.AddBreakpoint(new Breakpoint() {
|
||||
MemoryType = DebugMemoryType.CpuMemory,
|
||||
|
|
|
@ -334,7 +334,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
}
|
||||
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((uint)cpuAddress, ref addressInfo);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((uint)cpuAddress, addressInfo);
|
||||
if(addressInfo.Address >= 0 && addressInfo.Type == AddressType.PrgRom) {
|
||||
LineInfo line = _symbolProvider.GetSourceCodeLineInfo(addressInfo.Address);
|
||||
return CurrentFile.ID == line?.FileID;
|
||||
|
@ -345,7 +345,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
public void ScrollToLineNumber(int lineNumber, bool scrollToTop = false)
|
||||
{
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((uint)lineNumber, ref addressInfo);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((uint)lineNumber, addressInfo);
|
||||
ScrollToAddress(addressInfo, scrollToTop);
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
for(int i = 0; i < len; i++) {
|
||||
if(breakpoint.Matches(relativeAddresses[i], ref addressInfo[i])) {
|
||||
if(breakpoint.Matches(relativeAddresses[i], addressInfo[i])) {
|
||||
Color bpColor = breakpoint.BreakOnExec ? info.CodeExecBreakpointColor : (breakpoint.BreakOnWrite ? info.CodeWriteBreakpointColor : info.CodeReadBreakpointColor);
|
||||
_breakpointColors[i] = bpColor;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace Mesen.GUI.Debugger
|
|||
return null;
|
||||
}
|
||||
|
||||
public AddressTypeInfo? GetSymbolAddressInfo(SymbolInfo symbol)
|
||||
public AddressTypeInfo GetSymbolAddressInfo(SymbolInfo symbol)
|
||||
{
|
||||
if(symbol.SegmentID == null || symbol.Address == null) {
|
||||
return null;
|
||||
|
@ -310,7 +310,7 @@ namespace Mesen.GUI.Debugger
|
|||
count++;
|
||||
}
|
||||
|
||||
int address = GetSymbolAddressInfo(symbol).Value.Address;
|
||||
int address = GetSymbolAddressInfo(symbol).Address;
|
||||
if(segment.IsRam) {
|
||||
_ramLabels[address] = new CodeLabel() { Label = newName, Address = (UInt32)address, AddressType = AddressType.InternalRam, Comment = string.Empty };
|
||||
} else {
|
||||
|
|
49
GUI.NET/Debugger/HexConverter.cs
Normal file
49
GUI.NET/Debugger/HexConverter.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
class HexConverter
|
||||
{
|
||||
private static byte[] _hexLookup = new byte[256];
|
||||
|
||||
static HexConverter()
|
||||
{
|
||||
_hexLookup['0'] = 0;
|
||||
_hexLookup['1'] = 1;
|
||||
_hexLookup['2'] = 2;
|
||||
_hexLookup['3'] = 3;
|
||||
_hexLookup['4'] = 4;
|
||||
_hexLookup['5'] = 5;
|
||||
_hexLookup['6'] = 6;
|
||||
_hexLookup['7'] = 7;
|
||||
_hexLookup['8'] = 8;
|
||||
_hexLookup['9'] = 9;
|
||||
_hexLookup['a'] = 10;
|
||||
_hexLookup['b'] = 11;
|
||||
_hexLookup['c'] = 12;
|
||||
_hexLookup['d'] = 13;
|
||||
_hexLookup['e'] = 14;
|
||||
_hexLookup['f'] = 15;
|
||||
_hexLookup['A'] = 10;
|
||||
_hexLookup['B'] = 11;
|
||||
_hexLookup['C'] = 12;
|
||||
_hexLookup['D'] = 13;
|
||||
_hexLookup['E'] = 14;
|
||||
_hexLookup['F'] = 15;
|
||||
}
|
||||
|
||||
public static int FromHex(string hex)
|
||||
{
|
||||
int value = 0;
|
||||
for(int i = 0; i < hex.Length; i++) {
|
||||
value <<= 4;
|
||||
value |= _hexLookup[hex[i]];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ namespace Mesen.GUI.Debugger
|
|||
public static CodeLabel GetLabel(UInt16 relativeAddress)
|
||||
{
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)relativeAddress, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)relativeAddress, info);
|
||||
if(info.Address >= 0) {
|
||||
return GetLabel((UInt32)info.Address, info.Type);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Mesen.GUI.Debugger
|
|||
private ICodeViewer _codeViewer;
|
||||
|
||||
private int _lineIndex;
|
||||
private string _code;
|
||||
private CodeInfo _code;
|
||||
private Ld65DbgImporter _symbolProvider;
|
||||
private Ld65DbgImporter.FileInfo _selectedFile;
|
||||
|
||||
|
@ -27,7 +27,7 @@ namespace Mesen.GUI.Debugger
|
|||
get { return true; }
|
||||
}
|
||||
|
||||
public frmCodePreviewTooltip(Form parent, int lineIndex, string code = null, Ld65DbgImporter symbolProvider = null, Ld65DbgImporter.FileInfo selectedFile = null)
|
||||
public frmCodePreviewTooltip(Form parent, int lineIndex, CodeInfo code = null, Ld65DbgImporter symbolProvider = null, Ld65DbgImporter.FileInfo selectedFile = null)
|
||||
{
|
||||
_parentForm = parent;
|
||||
_code = code;
|
||||
|
|
|
@ -17,8 +17,8 @@ namespace Mesen.GUI.Debugger
|
|||
{
|
||||
private ICodeViewer _codeViewer;
|
||||
private Dictionary<string, string> _values;
|
||||
private AddressTypeInfo? _previewAddress;
|
||||
private string _code;
|
||||
private AddressTypeInfo _previewAddress;
|
||||
private CodeInfo _code;
|
||||
private Ld65DbgImporter _symbolProvider;
|
||||
|
||||
protected override bool ShowWithoutActivation
|
||||
|
@ -26,7 +26,7 @@ namespace Mesen.GUI.Debugger
|
|||
get { return true; }
|
||||
}
|
||||
|
||||
public frmCodeTooltip(Form parent, Dictionary<string, string> values, AddressTypeInfo? previewAddress = null, string code = null, Ld65DbgImporter symbolProvider = null)
|
||||
public frmCodeTooltip(Form parent, Dictionary<string, string> values, AddressTypeInfo previewAddress = null, CodeInfo code = null, Ld65DbgImporter symbolProvider = null)
|
||||
{
|
||||
_parentForm = parent;
|
||||
_values = values;
|
||||
|
@ -66,7 +66,7 @@ namespace Mesen.GUI.Debugger
|
|||
i++;
|
||||
}
|
||||
|
||||
if(_previewAddress.HasValue) {
|
||||
if(_previewAddress != null) {
|
||||
tlpMain.RowStyles.Insert(1, new RowStyle());
|
||||
|
||||
if(_code != null) {
|
||||
|
@ -81,7 +81,7 @@ namespace Mesen.GUI.Debugger
|
|||
_codeViewer.CodeViewer.BaseFont = new Font(ConfigManager.Config.DebugInfo.FontFamily, ConfigManager.Config.DebugInfo.FontSize, ConfigManager.Config.DebugInfo.FontStyle);
|
||||
_codeViewer.CodeViewer.HideSelection = true;
|
||||
_codeViewer.CodeViewer.ShowScrollbars = false;
|
||||
_codeViewer.ScrollToAddress(_previewAddress.Value, true);
|
||||
_codeViewer.ScrollToAddress(_previewAddress, true);
|
||||
_codeViewer.SetConfig(ConfigManager.Config.DebugInfo.LeftView, true);
|
||||
|
||||
Control control = _codeViewer as Control;
|
||||
|
|
2
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
2
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
|
@ -322,7 +322,6 @@ namespace Mesen.GUI.Debugger
|
|||
//
|
||||
// ctrlDebuggerCode
|
||||
//
|
||||
this.ctrlDebuggerCode.Code = null;
|
||||
this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlDebuggerCode.HideSelection = false;
|
||||
this.ctrlDebuggerCode.Location = new System.Drawing.Point(0, 0);
|
||||
|
@ -359,7 +358,6 @@ namespace Mesen.GUI.Debugger
|
|||
//
|
||||
// ctrlDebuggerCodeSplit
|
||||
//
|
||||
this.ctrlDebuggerCodeSplit.Code = null;
|
||||
this.ctrlDebuggerCodeSplit.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlDebuggerCodeSplit.HideSelection = false;
|
||||
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(0, 0);
|
||||
|
|
|
@ -557,7 +557,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
string newCode = InteropEmu.DebugGetCode(_firstBreak);
|
||||
if(newCode != null) {
|
||||
ctrlDebuggerCode.Code = newCode;
|
||||
ctrlDebuggerCode.Code = new CodeInfo(newCode);
|
||||
}
|
||||
|
||||
DebugState state = new DebugState();
|
||||
|
|
|
@ -582,7 +582,7 @@ namespace Mesen.GUI.Debugger
|
|||
switch(_memoryType) {
|
||||
case DebugMemoryType.CpuMemory:
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)address, ref info);
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)address, info);
|
||||
if(info.Address >= 0) {
|
||||
label = LabelManager.GetLabel((UInt32)info.Address, info.Type);
|
||||
}
|
||||
|
|
|
@ -326,6 +326,7 @@
|
|||
<Compile Include="Debugger\BreakpointManager.cs" />
|
||||
<Compile Include="Debugger\ChrByteColorProvider.cs" />
|
||||
<Compile Include="Debugger\ByteColorProvider.cs" />
|
||||
<Compile Include="Debugger\CodeInfo.cs" />
|
||||
<Compile Include="Debugger\CodeTooltipManager.cs" />
|
||||
<Compile Include="Debugger\Controls\ApuViewer\ctrlEnvelopeInfo.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
|
@ -825,6 +826,7 @@
|
|||
<Compile Include="Debugger\HexBox\StaticByteProvider.cs" />
|
||||
<Compile Include="Debugger\HexBox\TblByteCharConverter.cs" />
|
||||
<Compile Include="Debugger\HexBox\Util.cs" />
|
||||
<Compile Include="Debugger\HexConverter.cs" />
|
||||
<Compile Include="Debugger\LabelManager.cs" />
|
||||
<Compile Include="Debugger\MesenLabelFile.cs" />
|
||||
<Compile Include="Debugger\TblLoader.cs" />
|
||||
|
|
|
@ -278,7 +278,7 @@ namespace Mesen.GUI
|
|||
}
|
||||
}
|
||||
|
||||
[DllImport(DLLPath)] public static extern void DebugGetAbsoluteAddressAndType(UInt32 relativeAddr, ref AddressTypeInfo addressTypeInfo);
|
||||
[DllImport(DLLPath)] public static extern void DebugGetAbsoluteAddressAndType(UInt32 relativeAddr, AddressTypeInfo addressTypeInfo);
|
||||
[DllImport(DLLPath)] public static extern void DebugSetPpuViewerScanlineCycle(Int32 ppuViewerId, Int32 scanline, Int32 cycle);
|
||||
[DllImport(DLLPath)] public static extern void DebugClearPpuViewerSettings(Int32 ppuViewerId);
|
||||
|
||||
|
@ -2251,12 +2251,13 @@ namespace Mesen.GUI
|
|||
IgnoreOverscan = 8,
|
||||
}
|
||||
|
||||
public struct AddressTypeInfo
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class AddressTypeInfo
|
||||
{
|
||||
public Int32 Address;
|
||||
public AddressType Type;
|
||||
}
|
||||
|
||||
|
||||
public class MD5Helper
|
||||
{
|
||||
public static string GetMD5Hash(string filename)
|
||||
|
|
Loading…
Add table
Reference in a new issue