Debugger: Improved code window performance

This commit is contained in:
Sour 2018-07-25 00:41:52 -04:00
parent 204377b810
commit 49eae73d43
22 changed files with 266 additions and 186 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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" />

View file

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