2015-07-01 23:17:14 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
2015-08-05 20:40:10 -04:00
|
|
|
|
using Mesen.GUI.Debugger.Controls;
|
2016-06-04 14:43:13 -04:00
|
|
|
|
using Mesen.GUI.Config;
|
2016-12-11 14:25:29 -05:00
|
|
|
|
using Mesen.GUI.Controls;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
|
|
|
|
|
namespace Mesen.GUI.Debugger
|
|
|
|
|
{
|
2015-08-05 20:40:10 -04:00
|
|
|
|
public partial class ctrlDebuggerCode : BaseScrollableTextboxUserControl
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2018-01-02 14:44:28 -05:00
|
|
|
|
public delegate void AddressEventHandler(ctrlDebuggerCode sender, AddressEventArgs args);
|
2016-11-24 19:47:59 -05:00
|
|
|
|
public delegate void WatchEventHandler(WatchEventArgs args);
|
2017-03-07 17:51:14 -05:00
|
|
|
|
public delegate void AssemblerEventHandler(AssemblerEventArgs args);
|
|
|
|
|
public event AssemblerEventHandler OnEditCode;
|
2015-08-17 21:59:22 -04:00
|
|
|
|
public event AddressEventHandler OnSetNextStatement;
|
2018-01-02 14:44:28 -05:00
|
|
|
|
public event AddressEventHandler OnScrollToAddress;
|
2016-06-04 14:43:13 -04:00
|
|
|
|
private DebugViewInfo _config;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
|
|
|
|
List<int> _lineNumbers = new List<int>(10000);
|
|
|
|
|
List<string> _lineNumberNotes = new List<string>(10000);
|
2018-02-10 21:23:22 -05:00
|
|
|
|
List<char> _lineMemoryType = new List<char>(10000);
|
2017-03-09 23:50:20 -05:00
|
|
|
|
List<string> _codeNotes = new List<string>(10000);
|
|
|
|
|
List<string> _codeLines = new List<string>(10000);
|
2016-12-05 23:35:07 -05:00
|
|
|
|
private HashSet<int> _unexecutedAddresses = new HashSet<int>();
|
2018-01-03 18:48:16 -05:00
|
|
|
|
private HashSet<int> _verifiedDataAddresses = new HashSet<int>();
|
2016-12-05 23:35:07 -05:00
|
|
|
|
private HashSet<int> _speculativeCodeAddreses = new HashSet<int>();
|
2017-03-09 23:50:20 -05:00
|
|
|
|
Dictionary<int, string> _codeContent = new Dictionary<int, string>(10000);
|
|
|
|
|
Dictionary<int, string> _codeComments = new Dictionary<int, string>(10000);
|
|
|
|
|
Dictionary<int, string> _codeByteCode = new Dictionary<int, string>(10000);
|
|
|
|
|
List<string> _addressing = new List<string>(10000);
|
|
|
|
|
List<string> _comments = new List<string>(10000);
|
|
|
|
|
List<int> _lineIndentations = new List<int>(10000);
|
|
|
|
|
|
|
|
|
|
private UInt32? _currentActiveAddress { get; set; } = null;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
|
2018-01-02 22:32:17 -05:00
|
|
|
|
private Form _codeTooltip = null;
|
2016-11-24 19:47:59 -05:00
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
public ctrlDebuggerCode()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2016-12-11 14:25:29 -05:00
|
|
|
|
this.lstSearchResult.Font = new System.Drawing.Font(BaseControl.MonospaceFontFamily, 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
2016-11-27 10:56:37 -05:00
|
|
|
|
splitContainer.Panel2Collapsed = true;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-11 11:46:29 -05:00
|
|
|
|
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
2017-03-11 00:56:00 -05:00
|
|
|
|
public List<ToolStripItem> ContextMenuItems
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
List<ToolStripItem> items = new List<ToolStripItem>();
|
|
|
|
|
foreach(ToolStripItem item in this.contextMenuCode.Items) {
|
|
|
|
|
items.Add(item);
|
|
|
|
|
}
|
|
|
|
|
return items;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this.contextMenuCode.Items.AddRange(value.ToArray());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-06-04 14:43:13 -04:00
|
|
|
|
public void SetConfig(DebugViewInfo config)
|
|
|
|
|
{
|
|
|
|
|
_config = config;
|
|
|
|
|
|
2016-12-04 14:02:22 -05:00
|
|
|
|
mnuPrgAddressReplace.Checked = false;
|
|
|
|
|
mnuPrgAddressBelow.Checked = false;
|
|
|
|
|
mnuHidePrgAddresses.Checked = false;
|
|
|
|
|
|
|
|
|
|
mnuShowByteCodeOnLeft.Checked = false;
|
|
|
|
|
mnuShowByteCodeBelow.Checked = false;
|
|
|
|
|
mnuHideByteCode.Checked = false;
|
|
|
|
|
|
|
|
|
|
switch(config.ByteCodePosition) {
|
|
|
|
|
case ByteCodePosition.Left:
|
|
|
|
|
this.ctrlCodeViewer.ShowContentNotes = true;
|
|
|
|
|
this.ctrlCodeViewer.ShowSingleContentLineNotes = true;
|
|
|
|
|
this.mnuShowByteCodeOnLeft.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ByteCodePosition.Below:
|
|
|
|
|
this.ctrlCodeViewer.ShowContentNotes = true;
|
|
|
|
|
this.ctrlCodeViewer.ShowSingleContentLineNotes = false;
|
|
|
|
|
this.mnuShowByteCodeBelow.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ByteCodePosition.Hidden:
|
|
|
|
|
this.ctrlCodeViewer.ShowContentNotes = false;
|
|
|
|
|
this.ctrlCodeViewer.ShowSingleContentLineNotes = false;
|
|
|
|
|
this.mnuHideByteCode.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(config.PrgAddressPosition) {
|
|
|
|
|
case PrgAddressPosition.Replace:
|
|
|
|
|
this.ctrlCodeViewer.ShowLineNumberNotes = true;
|
|
|
|
|
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = true;
|
|
|
|
|
this.mnuPrgAddressReplace.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PrgAddressPosition.Below:
|
|
|
|
|
this.ctrlCodeViewer.ShowLineNumberNotes = true;
|
|
|
|
|
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = false;
|
|
|
|
|
this.mnuPrgAddressBelow.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PrgAddressPosition.Hidden:
|
|
|
|
|
this.ctrlCodeViewer.ShowLineNumberNotes = false;
|
|
|
|
|
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = false;
|
|
|
|
|
this.mnuHidePrgAddresses.Checked = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(this.FontSize != config.FontSize) {
|
|
|
|
|
this.FontSize = config.FontSize;
|
|
|
|
|
}
|
2016-06-04 14:43:13 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateConfig()
|
|
|
|
|
{
|
2016-12-04 14:02:22 -05:00
|
|
|
|
this.SetConfig(_config);
|
2016-06-04 14:43:13 -04:00
|
|
|
|
ConfigManager.ApplyChanges();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override float FontSize
|
|
|
|
|
{
|
|
|
|
|
get { return base.FontSize; }
|
|
|
|
|
set { base.FontSize=value; UpdateConfig(); }
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 20:40:10 -04:00
|
|
|
|
protected override ctrlScrollableTextbox ScrollableTextbox
|
|
|
|
|
{
|
|
|
|
|
get { return this.ctrlCodeViewer; }
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
private string _code;
|
|
|
|
|
private bool _codeChanged;
|
|
|
|
|
public string Code
|
|
|
|
|
{
|
|
|
|
|
get { return _code; }
|
|
|
|
|
set
|
|
|
|
|
{
|
2017-03-10 18:35:01 -05:00
|
|
|
|
if(value != null) {
|
2015-07-01 23:17:14 -04:00
|
|
|
|
_codeChanged = true;
|
|
|
|
|
_code = value;
|
2015-08-02 19:27:02 -04:00
|
|
|
|
UpdateCode();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-02 11:11:50 -05:00
|
|
|
|
public bool ShowScrollbars
|
|
|
|
|
{
|
|
|
|
|
set { this.ctrlCodeViewer.ShowScrollbars = value; }
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
public void SelectActiveAddress(UInt32 address)
|
|
|
|
|
{
|
2015-08-02 19:27:02 -04:00
|
|
|
|
this.SetActiveAddress(address);
|
2016-11-27 12:14:32 -05:00
|
|
|
|
this.ctrlCodeViewer.ScrollToLineNumber((int)address, eHistoryType.OnScroll);
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-02 19:27:02 -04:00
|
|
|
|
public void SetActiveAddress(UInt32 address)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2015-08-02 19:27:02 -04:00
|
|
|
|
_currentActiveAddress = address;
|
2017-03-11 10:59:26 -05:00
|
|
|
|
this.UpdateLineColors();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
2015-08-02 19:27:02 -04:00
|
|
|
|
|
|
|
|
|
public void ClearActiveAddress()
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2015-08-02 19:27:02 -04:00
|
|
|
|
_currentActiveAddress = null;
|
2017-03-11 10:59:26 -05:00
|
|
|
|
this.UpdateLineColors();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
2015-08-03 21:53:46 -04:00
|
|
|
|
|
2016-11-27 19:43:17 -05:00
|
|
|
|
public void UpdateLineColors()
|
|
|
|
|
{
|
2017-03-09 23:50:20 -05:00
|
|
|
|
this.ctrlCodeViewer.StyleProvider = new LineStyleProvider(this);
|
2016-11-27 19:43:17 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:42:53 -05:00
|
|
|
|
public List<string> GetCode(out int byteLength, ref int startAddress, int endAddress = -1)
|
2017-03-07 17:51:14 -05:00
|
|
|
|
{
|
|
|
|
|
List<string> result = new List<string>();
|
|
|
|
|
byteLength = 0;
|
|
|
|
|
|
2017-03-09 20:42:53 -05:00
|
|
|
|
if(endAddress == -1) {
|
|
|
|
|
//When no end address is specified, find the start of the function based on startAddress
|
|
|
|
|
int address = InteropEmu.DebugFindSubEntryPoint((UInt16)startAddress);
|
|
|
|
|
if(address != -1) {
|
|
|
|
|
startAddress = address;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(int i = startAddress; (i <= endAddress || endAddress == -1) && endAddress < 65536; ) {
|
2017-03-09 23:50:20 -05:00
|
|
|
|
string code;
|
|
|
|
|
if(_codeContent.TryGetValue(i, out code)) {
|
|
|
|
|
code = code.Split('\x2')[0].Trim();
|
|
|
|
|
|
2017-03-11 10:59:26 -05:00
|
|
|
|
if(code.StartsWith("--") || code.StartsWith("__")) {
|
2017-03-09 20:42:53 -05:00
|
|
|
|
//Stop adding code when we find a new section (new function, data blocks, etc.)
|
2017-03-07 17:51:14 -05:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:42:53 -05:00
|
|
|
|
AddressTypeInfo info = new AddressTypeInfo();
|
|
|
|
|
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)i, ref info);
|
|
|
|
|
CodeLabel codeLabel = info.Address >= 0 ? LabelManager.GetLabel((UInt32)info.Address, AddressType.PrgRom) : null;
|
|
|
|
|
string comment = codeLabel?.Comment;
|
|
|
|
|
string label = codeLabel?.Label;
|
|
|
|
|
|
2017-03-11 21:37:58 -05:00
|
|
|
|
bool addPadding = true;
|
|
|
|
|
if(code.StartsWith("STP*") || code.StartsWith("NOP*")) {
|
2017-03-09 23:50:20 -05:00
|
|
|
|
//Transform unofficial opcodes that can't be reassembled properly into .byte statements
|
|
|
|
|
if(comment != null) {
|
2017-09-02 00:17:00 -04:00
|
|
|
|
comment.Insert(0, code + " - ");
|
2017-03-09 23:50:20 -05:00
|
|
|
|
} else {
|
|
|
|
|
comment = code;
|
|
|
|
|
}
|
2017-03-11 21:37:58 -05:00
|
|
|
|
code = ".byte " + string.Join(",", _codeByteCode[i].Split(' '));
|
|
|
|
|
addPadding = false;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
}
|
|
|
|
|
|
2017-03-09 20:42:53 -05:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(comment) && comment.Contains("\n")) {
|
|
|
|
|
result.AddRange(comment.Replace("\r", "").Split('\n').Select(cmt => ";" + cmt));
|
|
|
|
|
comment = null;
|
|
|
|
|
}
|
|
|
|
|
if(!string.IsNullOrWhiteSpace(label)) {
|
|
|
|
|
result.Add(label + ":");
|
|
|
|
|
}
|
2017-03-11 21:37:58 -05:00
|
|
|
|
result.Add((addPadding ? " " : "") + code + (!string.IsNullOrWhiteSpace(comment) ? (" ;" + comment) : ""));
|
2017-03-09 20:42:53 -05:00
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
int length = _codeByteCode[i].Count(c => c == ' ') + 1;
|
2017-03-07 17:51:14 -05:00
|
|
|
|
byteLength += length;
|
|
|
|
|
i += length;
|
|
|
|
|
|
|
|
|
|
if(endAddress == -1 && (string.Compare(code, "RTI", true) == 0 || string.Compare(code, "RTS", true) == 0)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-03 21:33:04 -05:00
|
|
|
|
result.Add("");
|
2017-03-07 17:51:14 -05:00
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
public bool UpdateCode(bool forceUpdate = false)
|
|
|
|
|
{
|
|
|
|
|
if(_codeChanged || forceUpdate) {
|
2018-01-07 13:34:18 -05:00
|
|
|
|
int centerLineIndex = ctrlCodeViewer.GetLineIndexAtPosition(this.Height / 2);
|
|
|
|
|
int centerLineAddress;
|
|
|
|
|
do {
|
|
|
|
|
//Save the address at the center of the debug view
|
|
|
|
|
centerLineAddress = ctrlCodeViewer.GetLineNumber(centerLineIndex);
|
|
|
|
|
centerLineIndex--;
|
|
|
|
|
} while(centerLineAddress < 0 && centerLineIndex > 0);
|
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
_codeContent.Clear();
|
|
|
|
|
_codeComments.Clear();
|
|
|
|
|
_codeByteCode.Clear();
|
|
|
|
|
_unexecutedAddresses.Clear();
|
|
|
|
|
_speculativeCodeAddreses.Clear();
|
2018-01-03 18:48:16 -05:00
|
|
|
|
_verifiedDataAddresses.Clear();
|
2018-02-10 21:23:22 -05:00
|
|
|
|
_lineMemoryType.Clear();
|
|
|
|
|
_lineNumberNotes.Clear();
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
string[] token = new string[8];
|
2017-03-09 23:50:20 -05:00
|
|
|
|
int tokenIndex = 0;
|
|
|
|
|
int startPos = 0;
|
|
|
|
|
int endPos = 0;
|
2018-01-03 18:48:16 -05:00
|
|
|
|
int lineNumber = 0;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
|
|
|
|
Action readToken = () => {
|
|
|
|
|
endPos = _code.IndexOf('\x1', endPos) + 1;
|
|
|
|
|
token[tokenIndex++] = _code.Substring(startPos, endPos - startPos - 1);
|
|
|
|
|
startPos = endPos;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Action readLine = () => {
|
|
|
|
|
tokenIndex = 0;
|
2018-02-10 21:23:22 -05:00
|
|
|
|
readToken(); readToken(); readToken(); readToken(); readToken(); readToken(); readToken(); readToken();
|
2017-03-09 23:50:20 -05:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Func<bool> processLine = () => {
|
|
|
|
|
readLine();
|
|
|
|
|
|
|
|
|
|
int relativeAddress = ParseHexAddress(token[1]);
|
|
|
|
|
|
|
|
|
|
//Flags:
|
|
|
|
|
//1: Executed code
|
|
|
|
|
//2: Speculative Code
|
|
|
|
|
//4: Indented line
|
2018-01-03 18:48:16 -05:00
|
|
|
|
if(token[0] == "2") {
|
|
|
|
|
_speculativeCodeAddreses.Add(lineNumber);
|
|
|
|
|
_lineIndentations.Add(0);
|
|
|
|
|
} else if(token[0] == "4") {
|
|
|
|
|
_unexecutedAddresses.Add(lineNumber);
|
2017-03-09 23:50:20 -05:00
|
|
|
|
_lineIndentations.Add(20);
|
|
|
|
|
} else if(token[0] == "6") {
|
2018-01-03 18:48:16 -05:00
|
|
|
|
_speculativeCodeAddreses.Add(lineNumber);
|
2017-03-09 23:50:20 -05:00
|
|
|
|
_lineIndentations.Add(20);
|
|
|
|
|
} else if(token[0] == "5") {
|
|
|
|
|
_lineIndentations.Add(20);
|
2018-01-03 18:48:16 -05:00
|
|
|
|
} else if(token[0] == "8") {
|
|
|
|
|
_verifiedDataAddresses.Add(lineNumber);
|
|
|
|
|
_lineIndentations.Add(0);
|
|
|
|
|
} else if(token[0] == "9") {
|
|
|
|
|
_verifiedDataAddresses.Add(lineNumber);
|
|
|
|
|
_lineIndentations.Add(20);
|
2017-03-09 23:50:20 -05:00
|
|
|
|
} else {
|
|
|
|
|
_lineIndentations.Add(0);
|
|
|
|
|
}
|
2016-11-27 19:43:17 -05:00
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
_lineNumbers.Add(relativeAddress);
|
2018-02-10 21:23:22 -05:00
|
|
|
|
_lineMemoryType.Add(token[2][0]);
|
|
|
|
|
_lineNumberNotes.Add(string.IsNullOrWhiteSpace(token[3]) ? "" : (token[3].Length > 5 ? token[3].TrimStart('0').PadLeft(4, '0') : token[3]));
|
|
|
|
|
_codeNotes.Add(token[4]);
|
|
|
|
|
_codeLines.Add(token[5]);
|
2017-03-07 17:51:14 -05:00
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
_addressing.Add(token[6]);
|
|
|
|
|
_comments.Add(token[7]);
|
2016-11-26 14:15:50 -05:00
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
//Used by assembler
|
2018-02-10 21:23:22 -05:00
|
|
|
|
_codeByteCode[relativeAddress] = token[4];
|
|
|
|
|
_codeContent[relativeAddress] = token[5];
|
|
|
|
|
_codeComments[relativeAddress] = token[7];
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
2018-01-03 18:48:16 -05:00
|
|
|
|
lineNumber++;
|
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
return endPos < _code.Length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
while(processLine());
|
2015-08-02 19:27:02 -04:00
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
ctrlCodeViewer.LineIndentations = _lineIndentations.ToArray();
|
|
|
|
|
ctrlCodeViewer.Addressing = _addressing.ToArray();
|
|
|
|
|
ctrlCodeViewer.Comments = _comments.ToArray();
|
|
|
|
|
|
|
|
|
|
ctrlCodeViewer.LineNumbers = _lineNumbers.ToArray();
|
|
|
|
|
ctrlCodeViewer.TextLineNotes = _codeNotes.ToArray();
|
|
|
|
|
ctrlCodeViewer.LineNumberNotes = _lineNumberNotes.ToArray();
|
2017-09-12 19:38:42 -04:00
|
|
|
|
ctrlCodeViewer.TextLines = _codeLines.ToArray();
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
|
|
|
|
//These are all temporary and can be cleared right away
|
|
|
|
|
_lineNumbers.Clear();
|
|
|
|
|
_codeNotes.Clear();
|
|
|
|
|
_codeLines.Clear();
|
|
|
|
|
_addressing.Clear();
|
|
|
|
|
_comments.Clear();
|
|
|
|
|
_lineIndentations.Clear();
|
2016-11-27 19:43:17 -05:00
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
_codeChanged = false;
|
2016-11-27 19:43:17 -05:00
|
|
|
|
UpdateLineColors();
|
2018-01-07 13:34:18 -05:00
|
|
|
|
|
|
|
|
|
if(centerLineAddress >= 0) {
|
|
|
|
|
//Scroll to the same address as before, to prevent the code view from changing due to setting or banking changes, etc.
|
|
|
|
|
ctrlCodeViewer.ScrollToLineNumber(centerLineAddress, eHistoryType.None, false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2016-11-27 19:43:17 -05:00
|
|
|
|
UpdateLineColors();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-21 22:34:47 -05:00
|
|
|
|
private int ParseHexAddress(string hexAddress)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2016-11-21 22:34:47 -05:00
|
|
|
|
if(string.IsNullOrWhiteSpace(hexAddress)) {
|
|
|
|
|
return -1;
|
|
|
|
|
} else {
|
|
|
|
|
return (int)UInt32.Parse(hexAddress, System.Globalization.NumberStyles.AllowHexSpecifier);
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region Events
|
|
|
|
|
private Point _previousLocation;
|
2016-11-24 19:47:59 -05:00
|
|
|
|
private bool _preventCloseTooltip = false;
|
|
|
|
|
private string _hoverLastWord = "";
|
2018-02-10 23:01:16 -05:00
|
|
|
|
private int _hoverLastLineAddress = -1;
|
2016-11-24 19:47:59 -05:00
|
|
|
|
|
2018-02-10 23:01:16 -05:00
|
|
|
|
private void ShowTooltip(string word, Dictionary<string, string> values, int address, int lineAddress)
|
2016-11-24 19:47:59 -05:00
|
|
|
|
{
|
2018-02-10 23:01:16 -05:00
|
|
|
|
if(_hoverLastWord != word || _hoverLastLineAddress != lineAddress || _codeTooltip == null) {
|
2016-11-24 19:47:59 -05:00
|
|
|
|
if(!_preventCloseTooltip && _codeTooltip != null) {
|
|
|
|
|
_codeTooltip.Close();
|
|
|
|
|
_codeTooltip = null;
|
|
|
|
|
}
|
2018-01-02 11:11:50 -05:00
|
|
|
|
|
2018-01-02 22:32:17 -05:00
|
|
|
|
if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
2018-02-10 23:01:16 -05:00
|
|
|
|
_codeTooltip = new frmOpCodeTooltip(word, lineAddress);
|
2018-01-02 22:32:17 -05:00
|
|
|
|
} else {
|
|
|
|
|
bool isPrgRom = false;
|
|
|
|
|
if(address >= 0 && ConfigManager.Config.DebugInfo.ShowCodePreview) {
|
|
|
|
|
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
|
|
|
|
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)address, ref addressInfo);
|
|
|
|
|
isPrgRom = addressInfo.Type == AddressType.PrgRom;
|
|
|
|
|
}
|
2018-01-02 11:11:50 -05:00
|
|
|
|
|
2018-01-02 22:32:17 -05:00
|
|
|
|
_codeTooltip = new frmCodeTooltip(values, isPrgRom ? address : -1, isPrgRom ? _code : null);
|
|
|
|
|
}
|
2016-12-19 18:25:52 -05:00
|
|
|
|
_codeTooltip.Left = Cursor.Position.X + 10;
|
|
|
|
|
_codeTooltip.Top = Cursor.Position.Y + 10;
|
2016-11-24 19:47:59 -05:00
|
|
|
|
_codeTooltip.Show(this);
|
|
|
|
|
}
|
|
|
|
|
_codeTooltip.Left = Cursor.Position.X + 10;
|
|
|
|
|
_codeTooltip.Top = Cursor.Position.Y + 10;
|
|
|
|
|
|
|
|
|
|
_preventCloseTooltip = true;
|
|
|
|
|
_hoverLastWord = word;
|
2018-02-10 23:01:16 -05:00
|
|
|
|
_hoverLastLineAddress = lineAddress;
|
2016-11-24 19:47:59 -05:00
|
|
|
|
}
|
2016-12-03 09:57:58 -05:00
|
|
|
|
|
|
|
|
|
private void ctrlCodeViewer_MouseLeave(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(_codeTooltip != null) {
|
|
|
|
|
_codeTooltip.Close();
|
|
|
|
|
_codeTooltip = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-24 19:47:59 -05:00
|
|
|
|
|
2015-08-02 19:27:02 -04:00
|
|
|
|
private void ctrlCodeViewer_MouseMove(object sender, MouseEventArgs e)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2016-12-03 09:57:58 -05:00
|
|
|
|
//Always enable to allow F2 shortcut
|
|
|
|
|
mnuEditLabel.Enabled = true;
|
|
|
|
|
|
2016-12-22 20:29:14 -05:00
|
|
|
|
if(e.Location.X < this.ctrlCodeViewer.CodeMargin / 4) {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
this.ctrlCodeViewer.ContextMenuStrip = contextMenuMargin;
|
2016-01-10 00:33:33 -05:00
|
|
|
|
} else {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
this.ctrlCodeViewer.ContextMenuStrip = contextMenuCode;
|
2016-01-10 00:33:33 -05:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
if(_previousLocation != e.Location) {
|
2016-11-24 19:47:59 -05:00
|
|
|
|
if(!_preventCloseTooltip && _codeTooltip != null) {
|
|
|
|
|
_codeTooltip.Close();
|
|
|
|
|
_codeTooltip = null;
|
|
|
|
|
}
|
|
|
|
|
_preventCloseTooltip = false;
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
string word = GetWordUnderLocation(e.Location);
|
|
|
|
|
if(word.StartsWith("$")) {
|
2016-11-23 23:03:29 -05:00
|
|
|
|
try {
|
|
|
|
|
UInt32 address = UInt32.Parse(word.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier);
|
2016-11-24 19:47:59 -05:00
|
|
|
|
|
2016-11-27 21:05:15 -05:00
|
|
|
|
AddressTypeInfo info = new AddressTypeInfo();
|
|
|
|
|
InteropEmu.DebugGetAbsoluteAddressAndType(address, ref info);
|
|
|
|
|
|
|
|
|
|
if(info.Address >= 0) {
|
|
|
|
|
CodeLabel label = LabelManager.GetLabel((UInt32)info.Address, info.Type);
|
|
|
|
|
if(label == null) {
|
|
|
|
|
DisplayAddressTooltip(word, address);
|
|
|
|
|
} else {
|
|
|
|
|
DisplayLabelTooltip(word, label);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
DisplayAddressTooltip(word, address);
|
|
|
|
|
}
|
2016-11-23 23:03:29 -05:00
|
|
|
|
} catch { }
|
2015-08-09 18:24:24 -04:00
|
|
|
|
} else {
|
2016-11-21 22:34:47 -05:00
|
|
|
|
CodeLabel label = LabelManager.GetLabel(word);
|
|
|
|
|
|
2016-11-24 19:47:59 -05:00
|
|
|
|
if(label != null) {
|
2016-11-27 21:05:15 -05:00
|
|
|
|
DisplayLabelTooltip(word, label);
|
2018-01-02 22:32:17 -05:00
|
|
|
|
} else if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
2018-02-10 23:01:16 -05:00
|
|
|
|
ShowTooltip(word, null, -1, ctrlCodeViewer.GetLineNumberAtPosition(e.Y));
|
2016-11-27 21:05:15 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_previousLocation = e.Location;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DisplayAddressTooltip(string word, UInt32 address)
|
|
|
|
|
{
|
2017-03-04 21:50:19 -05:00
|
|
|
|
byte byteValue = InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, address);
|
|
|
|
|
UInt16 wordValue = (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, address+1) << 8));
|
2016-11-27 21:05:15 -05:00
|
|
|
|
|
|
|
|
|
var values = new Dictionary<string, string>() {
|
|
|
|
|
{ "Address", "$" + address.ToString("X4") },
|
|
|
|
|
{ "Value", $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" }
|
|
|
|
|
};
|
|
|
|
|
|
2018-02-10 23:01:16 -05:00
|
|
|
|
ShowTooltip(word, values, (int)address, -1);
|
2016-11-27 21:05:15 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DisplayLabelTooltip(string word, CodeLabel label)
|
|
|
|
|
{
|
|
|
|
|
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
2017-03-04 21:50:19 -05:00
|
|
|
|
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;
|
2018-01-02 11:11:50 -05:00
|
|
|
|
int address = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
2016-11-27 21:05:15 -05:00
|
|
|
|
var values = new Dictionary<string, string>() {
|
2016-11-24 19:47:59 -05:00
|
|
|
|
{ "Label", label.Label },
|
2018-01-02 11:11:50 -05:00
|
|
|
|
{ "Address", "$" + address.ToString("X4") },
|
2016-11-27 20:59:33 -05:00
|
|
|
|
{ "Value", (relativeAddress >= 0 ? $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" : "n/a") },
|
2016-11-24 19:47:59 -05:00
|
|
|
|
};
|
|
|
|
|
|
2016-11-27 21:05:15 -05:00
|
|
|
|
if(!string.IsNullOrWhiteSpace(label.Comment)) {
|
|
|
|
|
values["Comment"] = label.Comment;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
2016-11-27 21:05:15 -05:00
|
|
|
|
|
2018-02-10 23:01:16 -05:00
|
|
|
|
ShowTooltip(word, values, address, -1);
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-03 09:57:58 -05:00
|
|
|
|
private bool UpdateContextMenu(Point mouseLocation)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2017-03-11 00:56:00 -05:00
|
|
|
|
UpdateContextMenuItemVisibility(true);
|
|
|
|
|
|
2016-12-03 09:57:58 -05:00
|
|
|
|
string word = GetWordUnderLocation(mouseLocation);
|
2016-11-24 19:47:59 -05:00
|
|
|
|
if(word.StartsWith("$") || LabelManager.GetLabel(word) != null) {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
//Cursor is on a numeric value or label
|
2016-11-27 10:56:37 -05:00
|
|
|
|
_lastWord = word;
|
|
|
|
|
|
2016-11-24 19:47:59 -05:00
|
|
|
|
if(word.StartsWith("$")) {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
_lastClickedAddress = Int32.Parse(word.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier);
|
2016-11-24 19:47:59 -05:00
|
|
|
|
_newWatchValue = "[$" + _lastClickedAddress.ToString("X") + "]";
|
|
|
|
|
} else {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
_lastClickedAddress = (Int32)InteropEmu.DebugGetRelativeAddress(LabelManager.GetLabel(word).Address, LabelManager.GetLabel(word).AddressType);
|
2016-11-24 19:47:59 -05:00
|
|
|
|
_newWatchValue = "[" + word + "]";
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
mnuGoToLocation.Enabled = true;
|
2016-11-27 20:30:19 -05:00
|
|
|
|
mnuGoToLocation.Text = $"Go to Location ({word})";
|
2015-07-01 23:17:14 -04:00
|
|
|
|
|
2018-01-02 14:44:28 -05:00
|
|
|
|
mnuShowInSplitView.Enabled = true;
|
|
|
|
|
mnuShowInSplitView.Text = $"Show in Split View ({word})";
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
mnuAddToWatch.Enabled = true;
|
2016-11-27 20:30:19 -05:00
|
|
|
|
mnuAddToWatch.Text = $"Add to Watch ({word})";
|
2016-11-27 10:56:37 -05:00
|
|
|
|
|
|
|
|
|
mnuFindOccurrences.Enabled = true;
|
2016-11-27 20:30:19 -05:00
|
|
|
|
mnuFindOccurrences.Text = $"Find Occurrences ({word})";
|
|
|
|
|
|
|
|
|
|
mnuEditLabel.Enabled = true;
|
|
|
|
|
mnuEditLabel.Text = $"Edit Label ({word})";
|
2016-12-03 09:57:58 -05:00
|
|
|
|
|
2017-12-26 15:59:58 -05:00
|
|
|
|
mnuEditInMemoryViewer.Enabled = true;
|
|
|
|
|
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer ({word})";
|
|
|
|
|
|
2016-12-03 09:57:58 -05:00
|
|
|
|
return true;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
} else {
|
|
|
|
|
mnuGoToLocation.Enabled = false;
|
|
|
|
|
mnuGoToLocation.Text = "Go to Location";
|
2018-01-02 14:44:28 -05:00
|
|
|
|
mnuShowInSplitView.Enabled = false;
|
|
|
|
|
mnuShowInSplitView.Text = "Show in Split View";
|
2015-07-01 23:17:14 -04:00
|
|
|
|
mnuAddToWatch.Enabled = false;
|
|
|
|
|
mnuAddToWatch.Text = "Add to Watch";
|
2016-11-27 10:56:37 -05:00
|
|
|
|
mnuFindOccurrences.Enabled = false;
|
|
|
|
|
mnuFindOccurrences.Text = "Find Occurrences";
|
2016-11-27 20:30:19 -05:00
|
|
|
|
mnuEditLabel.Enabled = false;
|
|
|
|
|
mnuEditLabel.Text = "Edit Label";
|
2017-12-26 15:59:58 -05:00
|
|
|
|
mnuEditInMemoryViewer.Enabled = false;
|
|
|
|
|
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(mouseLocation.X < this.ctrlCodeViewer.CodeMargin) {
|
|
|
|
|
_lastClickedAddress = ctrlCodeViewer.GetLineNumberAtPosition(mouseLocation.Y);
|
|
|
|
|
} else {
|
|
|
|
|
_lastClickedAddress = ctrlCodeViewer.LastSelectedLine;
|
|
|
|
|
}
|
2016-11-27 20:30:19 -05:00
|
|
|
|
|
2017-12-26 15:59:58 -05:00
|
|
|
|
if(_lastClickedAddress >= 0) {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
//Cursor is in the margin, over an address label
|
|
|
|
|
string address = $"${_lastClickedAddress.ToString("X4")}";
|
2016-11-27 20:30:19 -05:00
|
|
|
|
_newWatchValue = $"[{address}]";
|
|
|
|
|
_lastWord = address;
|
|
|
|
|
|
2018-01-02 14:44:28 -05:00
|
|
|
|
mnuShowInSplitView.Enabled = true;
|
|
|
|
|
mnuShowInSplitView.Text = $"Show in Split View ({address})";
|
2016-11-27 20:30:19 -05:00
|
|
|
|
mnuAddToWatch.Enabled = true;
|
|
|
|
|
mnuAddToWatch.Text = $"Add to Watch ({address})";
|
|
|
|
|
mnuFindOccurrences.Enabled = true;
|
|
|
|
|
mnuFindOccurrences.Text = $"Find Occurrences ({address})";
|
|
|
|
|
mnuEditLabel.Enabled = true;
|
|
|
|
|
mnuEditLabel.Text = $"Edit Label ({address})";
|
2017-12-26 15:59:58 -05:00
|
|
|
|
mnuEditInMemoryViewer.Enabled = true;
|
|
|
|
|
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer ({address})";
|
2016-12-03 09:57:58 -05:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-03-11 00:56:00 -05:00
|
|
|
|
public void UpdateContextMenuItemVisibility(bool visible)
|
|
|
|
|
{
|
|
|
|
|
mnuShowNextStatement.Enabled = _currentActiveAddress.HasValue;
|
|
|
|
|
mnuSetNextStatement.Enabled = _currentActiveAddress.HasValue;
|
|
|
|
|
mnuEditSelectedCode.Enabled = mnuEditSubroutine.Enabled = InteropEmu.DebugIsExecutionStopped() && ctrlCodeViewer.CurrentLine >= 0;
|
|
|
|
|
|
|
|
|
|
mnuAddToWatch.Visible = visible;
|
|
|
|
|
mnuFindOccurrences.Visible = visible;
|
|
|
|
|
mnuEditLabel.Visible = visible;
|
|
|
|
|
mnuGoToLocation.Visible = visible;
|
2017-03-11 11:46:29 -05:00
|
|
|
|
mnuToggleBreakpoint.Visible = visible;
|
|
|
|
|
sepAddToWatch.Visible = visible;
|
|
|
|
|
sepEditLabel.Visible = visible;
|
2017-03-11 00:56:00 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-03 09:57:58 -05:00
|
|
|
|
int _lastClickedAddress = Int32.MaxValue;
|
|
|
|
|
string _newWatchValue = string.Empty;
|
|
|
|
|
string _lastWord = string.Empty;
|
|
|
|
|
private void ctrlCodeViewer_MouseUp(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(UpdateContextMenu(e.Location)) {
|
|
|
|
|
if(e.Button == MouseButtons.Left) {
|
2018-01-02 14:44:28 -05:00
|
|
|
|
if(ModifierKeys.HasFlag(Keys.Control) && ModifierKeys.HasFlag(Keys.Alt)) {
|
|
|
|
|
ShowInSplitView();
|
|
|
|
|
} else if(ModifierKeys.HasFlag(Keys.Control)) {
|
2016-12-03 09:57:58 -05:00
|
|
|
|
AddWatch();
|
|
|
|
|
} else if(ModifierKeys.HasFlag(Keys.Alt)) {
|
|
|
|
|
FindAllOccurrences(_lastWord, true, true);
|
|
|
|
|
}
|
2016-11-27 20:30:19 -05:00
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-10 00:33:33 -05:00
|
|
|
|
Breakpoint _lineBreakpoint = null;
|
|
|
|
|
private void ctrlCodeViewer_MouseDown(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2016-11-24 19:47:59 -05:00
|
|
|
|
if(_codeTooltip != null) {
|
|
|
|
|
_codeTooltip.Close();
|
|
|
|
|
_codeTooltip = null;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
int relativeAddress = ctrlCodeViewer.GetLineNumberAtPosition(e.Y);
|
|
|
|
|
AddressTypeInfo info = GetLineAddressTypeInfo(ctrlCodeViewer.GetLineIndexAtPosition(e.Y));
|
|
|
|
|
_lineBreakpoint = BreakpointManager.GetMatchingBreakpoint(relativeAddress, info);
|
2016-01-10 00:33:33 -05:00
|
|
|
|
|
2017-08-03 21:30:44 -04:00
|
|
|
|
if(e.Button == MouseButtons.Left && e.Location.X < this.ctrlCodeViewer.CodeMargin / 4) {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
BreakpointManager.ToggleBreakpoint(relativeAddress, info, false);
|
2016-01-10 00:33:33 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-24 19:47:59 -05:00
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
private AddressTypeInfo GetLineAddressTypeInfo(int lineNumber)
|
|
|
|
|
{
|
|
|
|
|
AddressTypeInfo info = new AddressTypeInfo();
|
|
|
|
|
if(Int32.TryParse(this._lineNumberNotes[lineNumber], System.Globalization.NumberStyles.AllowHexSpecifier, null, out info.Address)) {
|
|
|
|
|
switch(this._lineMemoryType[lineNumber]) {
|
|
|
|
|
case 'P': info.Type = AddressType.PrgRom; break;
|
|
|
|
|
case 'W': info.Type = AddressType.WorkRam; break;
|
|
|
|
|
case 'S': info.Type = AddressType.SaveRam; break;
|
|
|
|
|
case 'N': info.Type = AddressType.InternalRam; break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
info.Address = -1;
|
|
|
|
|
}
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 19:47:59 -05:00
|
|
|
|
private void ctrlCodeViewer_ScrollPositionChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(_codeTooltip != null) {
|
|
|
|
|
_codeTooltip.Close();
|
|
|
|
|
_codeTooltip = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-21 22:34:47 -05:00
|
|
|
|
private void ctrlCodeViewer_MouseDoubleClick(object sender, MouseEventArgs e)
|
|
|
|
|
{
|
2017-03-11 11:46:29 -05:00
|
|
|
|
if(e.Location.X > this.ctrlCodeViewer.CodeMargin / 2 && e.Location.X < this.ctrlCodeViewer.CodeMargin) {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
AddressTypeInfo info = GetLineAddressTypeInfo(ctrlCodeViewer.GetLineIndexAtPosition(e.Y));
|
|
|
|
|
if(info.Address >= 0) {
|
|
|
|
|
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
2016-11-21 22:34:47 -05:00
|
|
|
|
}
|
2017-03-11 11:46:29 -05:00
|
|
|
|
} else if(UpdateContextMenu(e.Location) && mnuGoToLocation.Enabled) {
|
|
|
|
|
GoToLocation();
|
2016-11-21 22:34:47 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-01-10 00:33:33 -05:00
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
#region Context Menu
|
2016-01-10 00:33:33 -05:00
|
|
|
|
|
|
|
|
|
private void contextMenuMargin_Opening(object sender, CancelEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(_lineBreakpoint == null) {
|
|
|
|
|
e.Cancel = true;
|
|
|
|
|
} else {
|
|
|
|
|
mnuDisableBreakpoint.Text = _lineBreakpoint.Enabled ? "Disable breakpoint" : "Enable breakpoint";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuRemoveBreakpoint_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
BreakpointManager.RemoveBreakpoint(_lineBreakpoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuEditBreakpoint_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
BreakpointManager.EditBreakpoint(_lineBreakpoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuDisableBreakpoint_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lineBreakpoint.SetEnabled(!_lineBreakpoint.Enabled);
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
private void contextMenuCode_Opening(object sender, CancelEventArgs e)
|
|
|
|
|
{
|
2017-03-11 00:56:00 -05:00
|
|
|
|
UpdateContextMenuItemVisibility(true);
|
2018-01-03 18:48:16 -05:00
|
|
|
|
|
|
|
|
|
int startAddress, endAddress;
|
|
|
|
|
string range;
|
|
|
|
|
GetSelectedAddressRange(out startAddress, out endAddress, out range);
|
|
|
|
|
mnuMarkSelectionAs.Enabled = startAddress >= 0 && endAddress >= 0 && startAddress <= endAddress;
|
|
|
|
|
if(mnuMarkSelectionAs.Enabled) {
|
|
|
|
|
mnuMarkSelectionAs.Text = "Mark selection as... (" + range + ")";
|
|
|
|
|
} else {
|
|
|
|
|
mnuMarkSelectionAs.Text = "Mark selection as...";
|
|
|
|
|
}
|
2017-03-07 17:51:14 -05:00
|
|
|
|
}
|
2018-01-03 18:48:16 -05:00
|
|
|
|
|
2017-03-07 17:51:14 -05:00
|
|
|
|
private void contextMenuCode_Closed(object sender, ToolStripDropDownClosedEventArgs e)
|
|
|
|
|
{
|
2017-03-11 00:56:00 -05:00
|
|
|
|
mnuEditSelectedCode.Enabled = true;
|
2017-03-07 17:51:14 -05:00
|
|
|
|
mnuEditSubroutine.Enabled = true;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuShowNextStatement_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-08-03 21:53:46 -04:00
|
|
|
|
this.ctrlCodeViewer.ScrollToLineNumber((int)_currentActiveAddress.Value);
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuShowOnlyDisassembledCode_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
UpdateCode(true);
|
2015-08-02 19:27:02 -04:00
|
|
|
|
if(_currentActiveAddress.HasValue) {
|
|
|
|
|
SelectActiveAddress(_currentActiveAddress.Value);
|
|
|
|
|
}
|
2016-06-04 14:43:13 -04:00
|
|
|
|
this.UpdateConfig();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
2015-08-21 22:42:44 -04:00
|
|
|
|
|
|
|
|
|
private void mnuShowLineNotes_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.ctrlCodeViewer.ShowLineNumberNotes = this.mnuShowLineNotes.Checked;
|
2016-06-04 14:43:13 -04:00
|
|
|
|
this.UpdateConfig();
|
2015-08-21 22:42:44 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
private void mnuGoToLocation_Click(object sender, EventArgs e)
|
2016-11-24 19:47:59 -05:00
|
|
|
|
{
|
|
|
|
|
GoToLocation();
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 10:56:37 -05:00
|
|
|
|
private void mnuFindOccurrences_Click(object sender, EventArgs e)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2016-12-01 20:45:13 -05:00
|
|
|
|
this.FindAllOccurrences(_lastWord, true, true);
|
2016-11-27 10:56:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
2016-12-01 20:45:13 -05:00
|
|
|
|
public void FindAllOccurrences(string text, bool matchWholeWord, bool matchCase)
|
2016-11-27 10:56:37 -05:00
|
|
|
|
{
|
|
|
|
|
this.lstSearchResult.Items.Clear();
|
2016-12-01 20:45:13 -05:00
|
|
|
|
foreach(Tuple<int, int, string> searchResult in this.ctrlCodeViewer.FindAllOccurrences(text, matchWholeWord, matchCase)) {
|
2016-11-27 10:56:37 -05:00
|
|
|
|
var item = this.lstSearchResult.Items.Add(searchResult.Item1.ToString("X4"));
|
|
|
|
|
item.Tag = searchResult.Item2;
|
|
|
|
|
item.SubItems.Add(searchResult.Item3);
|
2016-12-01 20:45:13 -05:00
|
|
|
|
item.SubItems.Add("");
|
2016-11-27 10:56:37 -05:00
|
|
|
|
}
|
|
|
|
|
this.lblSearchResult.Text = $"Search results for: {text} ({this.lstSearchResult.Items.Count} results)";
|
|
|
|
|
this.lstSearchResult.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
|
|
|
|
|
this.lstSearchResult.Columns[0].Width += 20;
|
2016-12-03 09:57:58 -05:00
|
|
|
|
this.lstSearchResult.Columns[1].Width = Math.Max(this.lstSearchResult.Columns[1].Width, this.lstSearchResult.Width - this.lstSearchResult.Columns[0].Width - 24);
|
2016-11-27 10:56:37 -05:00
|
|
|
|
this.splitContainer.Panel2Collapsed = false;
|
|
|
|
|
}
|
2016-12-01 20:45:13 -05:00
|
|
|
|
|
|
|
|
|
private void lstSearchResult_SizeChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
2016-12-03 09:57:58 -05:00
|
|
|
|
this.lstSearchResult.SizeChanged -= lstSearchResult_SizeChanged;
|
2016-12-01 20:45:13 -05:00
|
|
|
|
this.lstSearchResult.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
|
2016-12-03 09:57:58 -05:00
|
|
|
|
this.lstSearchResult.Columns[1].Width = Math.Max(this.lstSearchResult.Columns[1].Width, this.lstSearchResult.Width - this.lstSearchResult.Columns[0].Width - 24);
|
|
|
|
|
this.lstSearchResult.SizeChanged += lstSearchResult_SizeChanged;
|
2016-12-01 20:45:13 -05:00
|
|
|
|
}
|
2016-11-27 10:56:37 -05:00
|
|
|
|
|
|
|
|
|
private void picCloseOccurrenceList_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.splitContainer.Panel2Collapsed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void lstSearchResult_DoubleClick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(lstSearchResult.SelectedItems.Count > 0) {
|
|
|
|
|
int lineIndex = (int)lstSearchResult.SelectedItems[0].Tag;
|
|
|
|
|
this.ctrlCodeViewer.ScrollToLineIndex(lineIndex);
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuAddToWatch_Click(object sender, EventArgs e)
|
2016-11-24 19:47:59 -05:00
|
|
|
|
{
|
|
|
|
|
AddWatch();
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 10:56:37 -05:00
|
|
|
|
private void GoToLocation()
|
|
|
|
|
{
|
|
|
|
|
this.ctrlCodeViewer.ScrollToLineNumber((int)_lastClickedAddress);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-02 14:44:28 -05:00
|
|
|
|
private void mnuShowInSplitView_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ShowInSplitView();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ShowInSplitView()
|
|
|
|
|
{
|
|
|
|
|
this.OnScrollToAddress?.Invoke(this, new AddressEventArgs() { Address = (UInt32)_lastClickedAddress });
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 19:47:59 -05:00
|
|
|
|
private void AddWatch()
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
2017-03-02 20:33:25 -05:00
|
|
|
|
WatchManager.AddWatch(_newWatchValue);
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
2015-08-17 21:59:22 -04:00
|
|
|
|
|
|
|
|
|
private void mnuSetNextStatement_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-01-02 14:44:28 -05:00
|
|
|
|
this.OnSetNextStatement?.Invoke(this, new AddressEventArgs() { Address = (UInt32)this.ctrlCodeViewer.CurrentLine });
|
2015-08-17 21:59:22 -04:00
|
|
|
|
}
|
|
|
|
|
|
2016-06-04 14:43:13 -04:00
|
|
|
|
private void ctrlCodeViewer_FontSizeChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-01-03 19:12:02 -05:00
|
|
|
|
if(_config.FontSize != this.FontSize) {
|
|
|
|
|
_config.FontSize = this.FontSize;
|
|
|
|
|
UpdateConfig();
|
|
|
|
|
}
|
2016-06-04 14:43:13 -04:00
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 20:30:19 -05:00
|
|
|
|
private void mnuEditLabel_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2016-12-03 09:57:58 -05:00
|
|
|
|
if(UpdateContextMenu(_previousLocation)) {
|
|
|
|
|
AddressTypeInfo info = new AddressTypeInfo();
|
|
|
|
|
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)_lastClickedAddress, ref info);
|
|
|
|
|
if(info.Address >= 0) {
|
|
|
|
|
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
|
|
|
|
}
|
2016-11-27 20:30:19 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-27 12:14:32 -05:00
|
|
|
|
private void mnuNavigateForward_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.ctrlCodeViewer.NavigateForward();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuNavigateBackward_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.ctrlCodeViewer.NavigateBackward();
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-04 12:16:12 -05:00
|
|
|
|
private void mnuToggleBreakpoint_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-02-10 21:23:22 -05:00
|
|
|
|
this.ToggleBreakpoint(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ToggleBreakpoint(bool toggleEnabledFlag)
|
|
|
|
|
{
|
|
|
|
|
int relativeAddress = ctrlCodeViewer.CurrentLine;
|
|
|
|
|
AddressTypeInfo info = GetLineAddressTypeInfo(ctrlCodeViewer.SelectedLine);
|
|
|
|
|
|
|
|
|
|
BreakpointManager.ToggleBreakpoint(relativeAddress, info, toggleEnabledFlag);
|
2016-12-04 12:16:12 -05:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#endregion
|
2016-12-04 14:02:22 -05:00
|
|
|
|
|
|
|
|
|
private void mnuShowByteCodeOnLeft_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_config.ByteCodePosition = ByteCodePosition.Left;
|
|
|
|
|
this.UpdateConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuShowByteCodeBelow_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_config.ByteCodePosition = ByteCodePosition.Below;
|
|
|
|
|
this.UpdateConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuHideByteCode_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_config.ByteCodePosition = ByteCodePosition.Hidden;
|
|
|
|
|
this.UpdateConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuReplaceCpuAddress_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_config.PrgAddressPosition = PrgAddressPosition.Replace;
|
|
|
|
|
this.UpdateConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuBelowCpuAddress_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_config.PrgAddressPosition = PrgAddressPosition.Below;
|
|
|
|
|
this.UpdateConfig();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuHidePrgAddresses_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_config.PrgAddressPosition = PrgAddressPosition.Hidden;
|
|
|
|
|
this.UpdateConfig();
|
|
|
|
|
}
|
2017-03-07 17:51:14 -05:00
|
|
|
|
|
|
|
|
|
private void mnuEditSubroutine_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
int currentLine = this.GetCurrentLine();
|
|
|
|
|
if(currentLine != -1 && InteropEmu.DebugIsExecutionStopped()) {
|
|
|
|
|
int byteLength;
|
2017-03-09 20:42:53 -05:00
|
|
|
|
List<string> code = this.GetCode(out byteLength, ref currentLine);
|
2017-03-07 17:51:14 -05:00
|
|
|
|
this.OnEditCode?.Invoke(new AssemblerEventArgs() { Code = string.Join(Environment.NewLine, code), StartAddress = (UInt16)currentLine, BlockLength = (UInt16)byteLength });
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-09 20:42:53 -05:00
|
|
|
|
|
|
|
|
|
private void mnuEditSelectedCode_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
int startAddress = this.GetCurrentLine();
|
|
|
|
|
int endAddress = this.ctrlCodeViewer.LastSelectedLine;
|
|
|
|
|
if(startAddress != -1 && InteropEmu.DebugIsExecutionStopped()) {
|
|
|
|
|
int byteLength;
|
|
|
|
|
List<string> code = this.GetCode(out byteLength, ref startAddress, endAddress);
|
|
|
|
|
this.OnEditCode?.Invoke(new AssemblerEventArgs() { Code = string.Join(Environment.NewLine, code), StartAddress = (UInt16)startAddress, BlockLength = (UInt16)byteLength });
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-09 23:50:20 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LineStyleProvider : ctrlTextbox.ILineStyleProvider
|
|
|
|
|
{
|
2017-08-03 21:30:44 -04:00
|
|
|
|
private ctrlDebuggerCode _code;
|
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
public LineStyleProvider(ctrlDebuggerCode code)
|
|
|
|
|
{
|
|
|
|
|
_code = code;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-03 18:48:16 -05:00
|
|
|
|
public LineProperties GetLineStyle(int cpuAddress, int lineNumber)
|
2017-03-09 23:50:20 -05:00
|
|
|
|
{
|
2018-01-03 18:48:16 -05:00
|
|
|
|
DebugInfo info = ConfigManager.Config.DebugInfo;
|
2018-02-10 21:23:22 -05:00
|
|
|
|
LineProperties props = new LineProperties();
|
|
|
|
|
bool isActiveStatement = _code._currentActiveAddress.HasValue && _code.ctrlCodeViewer.GetLineIndex((int)_code._currentActiveAddress.Value) == lineNumber;
|
|
|
|
|
if(isActiveStatement) {
|
|
|
|
|
props.TextBgColor = info.CodeActiveStatementColor;
|
|
|
|
|
props.Symbol = LineSymbol.Arrow;
|
2018-01-03 18:48:16 -05:00
|
|
|
|
} else if(_code._unexecutedAddresses.Contains(lineNumber)) {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
props.LineBgColor = info.CodeUnexecutedCodeColor;
|
2018-01-03 18:48:16 -05:00
|
|
|
|
} else if(_code._speculativeCodeAddreses.Contains(lineNumber)) {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
props.LineBgColor = info.CodeUnidentifiedDataColor;
|
2018-01-03 18:48:16 -05:00
|
|
|
|
} else if(_code._verifiedDataAddresses.Contains(lineNumber)) {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
props.LineBgColor = info.CodeVerifiedDataColor;
|
2018-01-03 18:48:16 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
AddressTypeInfo addressInfo = _code.GetLineAddressTypeInfo(lineNumber);
|
|
|
|
|
|
2017-03-09 23:50:20 -05:00
|
|
|
|
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
if(breakpoint.Matches(cpuAddress, addressInfo)) {
|
2017-03-09 23:50:20 -05:00
|
|
|
|
Color? fgColor = Color.White;
|
|
|
|
|
Color? bgColor = null;
|
2018-01-03 18:48:16 -05:00
|
|
|
|
Color bpColor = breakpoint.BreakOnExec ? info.CodeExecBreakpointColor : (breakpoint.BreakOnWrite ? info.CodeWriteBreakpointColor : info.CodeReadBreakpointColor);
|
2017-08-03 21:30:44 -04:00
|
|
|
|
Color? outlineColor = bpColor;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
LineSymbol symbol;
|
|
|
|
|
if(breakpoint.Enabled) {
|
2017-08-03 21:30:44 -04:00
|
|
|
|
bgColor = bpColor;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
symbol = LineSymbol.Circle;
|
|
|
|
|
} else {
|
|
|
|
|
fgColor = Color.Black;
|
|
|
|
|
symbol = LineSymbol.CircleOutline;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
|
|
|
|
|
if(isActiveStatement) {
|
2017-03-09 23:50:20 -05:00
|
|
|
|
fgColor = Color.Black;
|
|
|
|
|
bgColor = Color.Yellow;
|
|
|
|
|
symbol |= LineSymbol.Arrow;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-03 18:48:16 -05:00
|
|
|
|
if(props == null) {
|
|
|
|
|
props = new LineProperties();
|
|
|
|
|
}
|
|
|
|
|
props.FgColor = fgColor;
|
|
|
|
|
props.TextBgColor = bgColor;
|
|
|
|
|
props.OutlineColor = outlineColor;
|
|
|
|
|
props.Symbol = symbol;
|
|
|
|
|
break;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-10 21:23:22 -05:00
|
|
|
|
switch(_code._lineMemoryType[lineNumber]) {
|
|
|
|
|
case 'P': props.AddressColor = Color.Gray; break;
|
|
|
|
|
case 'W': props.AddressColor = Color.DarkBlue; break;
|
|
|
|
|
case 'S': props.AddressColor = Color.DarkRed; break;
|
|
|
|
|
case 'N': props.AddressColor = Color.DarkGreen; break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-03 18:48:16 -05:00
|
|
|
|
return props;
|
2017-03-09 23:50:20 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-03-11 10:59:26 -05:00
|
|
|
|
|
|
|
|
|
private void copySelectionToolStripMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.ctrlCodeViewer.CopySelection();
|
|
|
|
|
}
|
2017-12-26 15:59:58 -05:00
|
|
|
|
|
|
|
|
|
private void mnuEditInMemoryViewer_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(UpdateContextMenu(_previousLocation)) {
|
|
|
|
|
DebugWindowManager.OpenMemoryViewer(_lastClickedAddress);
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
|
2018-01-03 18:48:16 -05:00
|
|
|
|
private void GetSelectedAddressRange(out int start, out int end, out string range)
|
|
|
|
|
{
|
|
|
|
|
int firstLineOfSelection = this.ctrlCodeViewer.SelectionStart;
|
|
|
|
|
while(this.ctrlCodeViewer.GetLineNumber(firstLineOfSelection) < 0) {
|
|
|
|
|
firstLineOfSelection++;
|
|
|
|
|
}
|
|
|
|
|
int firstLineAfterSelection = this.ctrlCodeViewer.SelectionStart + this.ctrlCodeViewer.SelectionLength + 1;
|
|
|
|
|
while(this.ctrlCodeViewer.GetLineNumber(firstLineAfterSelection) < 0) {
|
|
|
|
|
firstLineAfterSelection++;
|
|
|
|
|
}
|
|
|
|
|
start = this.ctrlCodeViewer.GetLineNumber(firstLineOfSelection);
|
|
|
|
|
end = this.ctrlCodeViewer.GetLineNumber(firstLineAfterSelection) - 1;
|
|
|
|
|
|
|
|
|
|
range = "";
|
|
|
|
|
if(start >= 0 && end >= 0) {
|
|
|
|
|
range = $"${start.ToString("X4")} - ${end.ToString("X4")}";
|
|
|
|
|
start = InteropEmu.DebugGetAbsoluteAddress((UInt32)start);
|
|
|
|
|
end = InteropEmu.DebugGetAbsoluteAddress((UInt32)end);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void MarkSelectionAs(CdlPrgFlags type)
|
|
|
|
|
{
|
|
|
|
|
int startAddress, endAddress;
|
|
|
|
|
string range;
|
|
|
|
|
GetSelectedAddressRange(out startAddress, out endAddress, out range);
|
|
|
|
|
|
|
|
|
|
if(startAddress >= 0 && endAddress >= 0 && startAddress <= endAddress) {
|
|
|
|
|
InteropEmu.DebugMarkPrgBytesAs((UInt32)startAddress, (UInt32)endAddress, type);
|
|
|
|
|
|
|
|
|
|
frmDebugger debugger = DebugWindowManager.GetDebugger();
|
|
|
|
|
if(debugger != null) {
|
|
|
|
|
debugger.UpdateDebugger(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuMarkAsCode_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.MarkSelectionAs(CdlPrgFlags.Code);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuMarkAsData_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.MarkSelectionAs(CdlPrgFlags.Data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuMarkAsUnidentifiedData_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.MarkSelectionAs(CdlPrgFlags.None);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-24 19:47:59 -05:00
|
|
|
|
public class WatchEventArgs : EventArgs
|
|
|
|
|
{
|
|
|
|
|
public string WatchValue { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-17 21:59:22 -04:00
|
|
|
|
public class AddressEventArgs : EventArgs
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
|
|
|
|
public UInt32 Address { get; set; }
|
|
|
|
|
}
|
2017-03-07 17:51:14 -05:00
|
|
|
|
|
|
|
|
|
public class AssemblerEventArgs : EventArgs
|
|
|
|
|
{
|
|
|
|
|
public string Code { get; set; }
|
|
|
|
|
public UInt16 StartAddress { get; set; }
|
|
|
|
|
public UInt16 BlockLength { get; set; }
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|