Merge pull request #678 from parasyte/feature/breakpoint-address-mask

Add address mask setting for breakpoints
This commit is contained in:
Paul Kratt 2016-08-09 20:58:18 -05:00 committed by GitHub
commit 8fd273bdf3
12 changed files with 120 additions and 52 deletions

View File

@ -225,7 +225,7 @@ namespace BizHawk.Client.Common
_luaFunctions.Add(nlf);
DebuggableCore.MemoryCallbacks.Add(
new MemoryCallback(MemoryCallbackType.Execute, "Lua Hook", nlf.Callback, address));
new MemoryCallback(MemoryCallbackType.Execute, "Lua Hook", nlf.Callback, address, null));
return nlf.Guid.ToString();
}
}
@ -253,7 +253,7 @@ namespace BizHawk.Client.Common
_luaFunctions.Add(nlf);
DebuggableCore.MemoryCallbacks.Add(
new MemoryCallback(MemoryCallbackType.Read, "Lua Hook", nlf.Callback, address));
new MemoryCallback(MemoryCallbackType.Read, "Lua Hook", nlf.Callback, address, null));
return nlf.Guid.ToString();
}
}
@ -281,7 +281,7 @@ namespace BizHawk.Client.Common
_luaFunctions.Add(nlf);
DebuggableCore.MemoryCallbacks.Add(
new MemoryCallback(MemoryCallbackType.Write, "Lua Hook", nlf.Callback, address));
new MemoryCallback(MemoryCallbackType.Write, "Lua Hook", nlf.Callback, address, null));
return nlf.Guid.ToString();
}
}

View File

@ -38,13 +38,15 @@
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.CancelBtn = new System.Windows.Forms.Button();
this.AddressBox = new BizHawk.Client.EmuHawk.HexTextBox();
this.label2 = new System.Windows.Forms.Label();
this.AddressMaskBox = new BizHawk.Client.EmuHawk.HexTextBox();
this.BreakpointTypeGroupbox.SuspendLayout();
this.SuspendLayout();
//
// AddBtn
//
this.AddBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.AddBtn.Location = new System.Drawing.Point(152, 92);
this.AddBtn.Location = new System.Drawing.Point(152, 115);
this.AddBtn.Name = "AddBtn";
this.AddBtn.Size = new System.Drawing.Size(60, 23);
this.AddBtn.TabIndex = 100;
@ -57,10 +59,10 @@
this.BreakpointTypeGroupbox.Controls.Add(this.ExecuteRadio);
this.BreakpointTypeGroupbox.Controls.Add(this.WriteRadio);
this.BreakpointTypeGroupbox.Controls.Add(this.ReadRadio);
this.BreakpointTypeGroupbox.Location = new System.Drawing.Point(15, 31);
this.BreakpointTypeGroupbox.Location = new System.Drawing.Point(16, 57);
this.BreakpointTypeGroupbox.Name = "BreakpointTypeGroupbox";
this.BreakpointTypeGroupbox.Size = new System.Drawing.Size(196, 52);
this.BreakpointTypeGroupbox.TabIndex = 1;
this.BreakpointTypeGroupbox.TabIndex = 3;
this.BreakpointTypeGroupbox.TabStop = false;
//
// ExecuteRadio
@ -101,13 +103,14 @@
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(59, 13);
this.label1.TabIndex = 3;
this.label1.TabIndex = 4;
this.label1.Text = "Address 0x";
//
// CancelBtn
//
this.CancelBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.CancelBtn.Location = new System.Drawing.Point(83, 92);
this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.CancelBtn.Location = new System.Drawing.Point(83, 115);
this.CancelBtn.Name = "CancelBtn";
this.CancelBtn.Size = new System.Drawing.Size(60, 23);
this.CancelBtn.TabIndex = 101;
@ -125,13 +128,34 @@
this.AddressBox.TabIndex = 1;
this.AddressBox.Text = "0";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(13, 32);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(47, 13);
this.label2.TabIndex = 5;
this.label2.Text = "Mask 0x";
//
// AddressMaskBox
//
this.AddressMaskBox.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
this.AddressMaskBox.Location = new System.Drawing.Point(77, 31);
this.AddressMaskBox.Name = "AddressMaskBox";
this.AddressMaskBox.Nullable = false;
this.AddressMaskBox.Size = new System.Drawing.Size(135, 20);
this.AddressMaskBox.TabIndex = 2;
this.AddressMaskBox.Text = "FFFFFFFF";
//
// AddBreakpointDialog
//
this.AcceptButton = this.AddBtn;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.CancelBtn;
this.ClientSize = new System.Drawing.Size(224, 123);
this.ClientSize = new System.Drawing.Size(224, 146);
this.Controls.Add(this.AddressMaskBox);
this.Controls.Add(this.label2);
this.Controls.Add(this.CancelBtn);
this.Controls.Add(this.label1);
this.Controls.Add(this.AddressBox);
@ -163,5 +187,7 @@
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.Button CancelBtn;
private System.Windows.Forms.Label label2;
private HexTextBox AddressMaskBox;
}
}
}

View File

@ -17,11 +17,15 @@ namespace BizHawk.Client.EmuHawk
{
InitializeComponent();
Operation = op;
AddressMaskBox.SetHexProperties(0xFFFFFFFF);
AddressMask = 0xFFFFFFFF;
}
public AddBreakpointDialog(BreakpointOperation op, uint address, MemoryCallbackType type):this(op)
public AddBreakpointDialog(BreakpointOperation op, uint address, uint mask, MemoryCallbackType type):this(op)
{
AddressMaskBox.SetHexProperties(0xFFFFFFFF);
Address = address;
AddressMask = mask;
BreakType = type;
}
@ -29,9 +33,9 @@ namespace BizHawk.Client.EmuHawk
private BreakpointOperation Operation
{
get
{
return _operation;
get
{
return _operation;
}
set
{
@ -59,10 +63,10 @@ namespace BizHawk.Client.EmuHawk
}
ExecuteRadio.Enabled = false;
}
public MemoryCallbackType BreakType
public MemoryCallbackType BreakType
{
get
{
@ -104,8 +108,14 @@ namespace BizHawk.Client.EmuHawk
public uint Address
{
get { return (uint)AddressBox.ToRawInt().Value; }
set { AddressBox.SetFromLong(value); }
get { return (uint)AddressBox.ToRawInt().Value & AddressMask; }
set { AddressBox.SetFromLong(value & AddressMask); }
}
public uint AddressMask
{
get { return (uint)AddressMaskBox.ToRawInt().Value; }
set { AddressMaskBox.SetFromLong(value); }
}
public long MaxAddressSize
@ -117,6 +127,7 @@ namespace BizHawk.Client.EmuHawk
set
{
AddressBox.SetHexProperties(value);
AddressMaskBox.SetHexProperties(value);
}
}

View File

@ -10,9 +10,9 @@ namespace BizHawk.Client.EmuHawk
{
public Action Callback { get; set; }
public void Add(IDebuggable core, uint address, MemoryCallbackType type)
public void Add(IDebuggable core, uint address, uint mask, MemoryCallbackType type)
{
Add(new Breakpoint(core, Callback, address, type));
Add(new Breakpoint(core, Callback, address, mask, type));
}
public new void Clear()
@ -68,35 +68,38 @@ namespace BizHawk.Client.EmuHawk
private bool _active;
private readonly IDebuggable _core;
public Breakpoint(bool readOnly, IDebuggable core, Action callBack, uint address, MemoryCallbackType type, bool enabled = true)
public Breakpoint(bool readOnly, IDebuggable core, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
{
_core = core;
Type = type;
Callback = callBack;
Address = address;
AddressMask = mask;
Name = "Pause";
Active = enabled;
ReadOnly = readOnly;
}
public Breakpoint(IDebuggable core, Action callBack, uint address, MemoryCallbackType type, bool enabled = true)
public Breakpoint(IDebuggable core, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
{
_core = core;
Type = type;
Callback = callBack;
Address = address;
AddressMask = mask;
Name = "Pause";
Active = enabled;
}
public Breakpoint(string name, bool readOnly, IDebuggable core, Action callBack, uint address, MemoryCallbackType type, bool enabled = true)
public Breakpoint(string name, bool readOnly, IDebuggable core, Action callBack, uint address, uint mask, MemoryCallbackType type, bool enabled = true)
{
_core = core;
Type = type;
Callback = callBack;
Address = address;
AddressMask = mask;
Name = name;
Active = enabled;
@ -105,6 +108,7 @@ namespace BizHawk.Client.EmuHawk
public Action Callback { get; set; }
public uint? Address { get; set; }
public uint? AddressMask { get; set; }
public MemoryCallbackType Type { get; set; }
public string Name { get; set; }
@ -117,6 +121,7 @@ namespace BizHawk.Client.EmuHawk
_active = true;
Callback = callback.Callback;
Address = callback.Address;
AddressMask = callback.AddressMask;
Type = callback.Type;
Name = callback.Name;
@ -153,14 +158,14 @@ namespace BizHawk.Client.EmuHawk
private void AddCallback()
{
_core.MemoryCallbacks.Add(new MemoryCallback(Type, Name, Callback, Address));
_core.MemoryCallbacks.Add(new MemoryCallback(Type, Name, Callback, Address, AddressMask));
}
private void RemoveCallback()
{
_core.MemoryCallbacks.Remove(Callback);
}
public void ResetCallback()
{
if (Active)

View File

@ -40,6 +40,7 @@
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.SuspendLayout();
//
// AddBreakpointButton
@ -67,7 +68,7 @@
//
this.ToggleButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.ToggleButton.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Refresh;
this.ToggleButton.Location = new System.Drawing.Point(138, 387);
this.ToggleButton.Location = new System.Drawing.Point(311, 387);
this.ToggleButton.Name = "ToggleButton";
this.ToggleButton.Size = new System.Drawing.Size(23, 23);
this.ToggleButton.TabIndex = 9;
@ -79,7 +80,7 @@
//
this.RemoveBreakpointButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.RemoveBreakpointButton.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Delete;
this.RemoveBreakpointButton.Location = new System.Drawing.Point(167, 387);
this.RemoveBreakpointButton.Location = new System.Drawing.Point(340, 387);
this.RemoveBreakpointButton.Name = "RemoveBreakpointButton";
this.RemoveBreakpointButton.Size = new System.Drawing.Size(23, 23);
this.RemoveBreakpointButton.TabIndex = 7;
@ -91,7 +92,7 @@
//
this.DuplicateBreakpointButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.DuplicateBreakpointButton.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Duplicate;
this.DuplicateBreakpointButton.Location = new System.Drawing.Point(109, 387);
this.DuplicateBreakpointButton.Location = new System.Drawing.Point(282, 387);
this.DuplicateBreakpointButton.Name = "DuplicateBreakpointButton";
this.DuplicateBreakpointButton.Size = new System.Drawing.Size(23, 23);
this.DuplicateBreakpointButton.TabIndex = 10;
@ -104,7 +105,7 @@
this.EditBreakpointButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.EditBreakpointButton.BackgroundImage = global::BizHawk.Client.EmuHawk.Properties.Resources.pencil;
this.EditBreakpointButton.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.EditBreakpointButton.Location = new System.Drawing.Point(80, 387);
this.EditBreakpointButton.Location = new System.Drawing.Point(253, 387);
this.EditBreakpointButton.Name = "EditBreakpointButton";
this.EditBreakpointButton.Size = new System.Drawing.Size(23, 23);
this.EditBreakpointButton.TabIndex = 11;
@ -115,14 +116,15 @@
// BreakpointView
//
this.BreakpointView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.BreakpointView.BlazingFast = false;
this.BreakpointView.CheckBoxes = true;
this.BreakpointView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2,
this.columnHeader3});
this.columnHeader1,
this.columnHeader4,
this.columnHeader2,
this.columnHeader3});
this.BreakpointView.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.BreakpointView.FullRowSelect = true;
this.BreakpointView.GridLines = true;
@ -132,7 +134,7 @@
this.BreakpointView.Name = "BreakpointView";
this.BreakpointView.SelectAllInProgress = false;
this.BreakpointView.selectedItem = -1;
this.BreakpointView.Size = new System.Drawing.Size(193, 365);
this.BreakpointView.Size = new System.Drawing.Size(366, 365);
this.BreakpointView.TabIndex = 5;
this.BreakpointView.TabStop = false;
this.BreakpointView.UseCompatibleStateImageBehavior = false;
@ -157,6 +159,11 @@
this.columnHeader3.Text = "Name";
this.columnHeader3.Width = 80;
//
// columnHeader4
//
this.columnHeader4.Text = "Mask";
this.columnHeader4.Width = 91;
//
// BreakpointControl
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
@ -168,7 +175,7 @@
this.Controls.Add(this.AddBreakpointButton);
this.Controls.Add(this.BreakpointView);
this.Name = "BreakpointControl";
this.Size = new System.Drawing.Size(193, 413);
this.Size = new System.Drawing.Size(366, 413);
this.Load += new System.EventHandler(this.BreakpointControl_Load);
this.ResumeLayout(false);
this.PerformLayout();
@ -188,5 +195,6 @@
private System.Windows.Forms.Button ToggleButton;
private System.Windows.Forms.Button DuplicateBreakpointButton;
private System.Windows.Forms.Button EditBreakpointButton;
private System.Windows.Forms.ColumnHeader columnHeader4;
}
}

View File

@ -46,9 +46,12 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
text = string.Format("{0:X}", Breakpoints[index].Address);
break;
case 1:
text = Breakpoints[index].Type.ToString();
text = string.Format("{0:X}", Breakpoints[index].AddressMask);
break;
case 2:
text = Breakpoints[index].Type.ToString();
break;
case 3:
text = Breakpoints[index].Name;
break;
}
@ -106,6 +109,7 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
if (!Breakpoints.Any(b =>
b.Type == callback.Type &&
b.Address == callback.Address &&
b.AddressMask == callback.AddressMask &&
b.Name == callback.Name &&
b.Callback == callback.Callback
))
@ -143,9 +147,9 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
UpdateStatsLabel();
}
public void AddBreakpoint(uint address, MemoryCallbackType type)
public void AddBreakpoint(uint address, uint mask, MemoryCallbackType type)
{
Breakpoints.Add(Core, address, type);
Breakpoints.Add(Core, address, mask, type);
BreakpointView.ItemCount = Breakpoints.Count;
UpdateBreakpointRemoveButton();
@ -158,7 +162,7 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
if (b.ShowHawkDialog() == DialogResult.OK)
{
Breakpoints.Add(Core, b.Address, b.BreakType);
Breakpoints.Add(Core, b.Address, b.AddressMask, b.BreakType);
}
BreakpointView.ItemCount = Breakpoints.Count;
@ -171,7 +175,7 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
public void AddSeekBreakpoint(uint pcVal, int pcBitSize)
{
var Name = SeekName + pcVal.ToHexString(pcBitSize / 4);
Breakpoints.Add(new Breakpoint(Name, true, Core, SeekCallback, pcVal, MemoryCallbackType.Execute));
Breakpoints.Add(new Breakpoint(Name, true, Core, SeekCallback, pcVal, 0xFFFFFFFF, MemoryCallbackType.Execute));
}
public void RemoveCurrentSeek()
@ -284,11 +288,11 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
if (breakpoint != null && !breakpoint.ReadOnly)
{
var b = CreateAddBreakpointDialog(BreakpointOperation.Duplicate, breakpoint.Type, breakpoint.Address);
var b = CreateAddBreakpointDialog(BreakpointOperation.Duplicate, breakpoint.Type, breakpoint.Address, breakpoint.AddressMask);
if (b.ShowHawkDialog() == DialogResult.OK)
{
Breakpoints.Add(new Breakpoint(Core, breakpoint.Callback, b.Address, b.BreakType, breakpoint.Active));
Breakpoints.Add(new Breakpoint(Core, breakpoint.Callback, b.Address, b.AddressMask, b.BreakType, breakpoint.Active));
}
}
@ -303,12 +307,13 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
if (breakpoint != null && !breakpoint.ReadOnly)
{
var b = CreateAddBreakpointDialog(BreakpointOperation.Edit, breakpoint.Type, breakpoint.Address);
var b = CreateAddBreakpointDialog(BreakpointOperation.Edit, breakpoint.Type, breakpoint.Address, breakpoint.AddressMask);
if (b.ShowHawkDialog() == DialogResult.OK)
{
breakpoint.Type = b.BreakType;
breakpoint.Address = b.Address;
breakpoint.AddressMask = b.AddressMask;
breakpoint.ResetCallback();
}
}
@ -318,7 +323,7 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
UpdateStatsLabel();
}
private AddBreakpointDialog CreateAddBreakpointDialog(BreakpointOperation op, MemoryCallbackType? type = null, uint? address = null)
private AddBreakpointDialog CreateAddBreakpointDialog(BreakpointOperation op, MemoryCallbackType? type = null, uint? address = null, uint? mask = null)
{
var operation = (AddBreakpointDialog.BreakpointOperation)op;
@ -338,6 +343,11 @@ namespace BizHawk.Client.EmuHawk.tools.Debugger
b.Address = (uint)address;
}
if (mask != null)
{
b.AddressMask = (uint)mask;
}
if (!MCS.ExecuteCallbacksAvailable)
{
b.DisableExecuteOption();

View File

@ -213,7 +213,7 @@ namespace BizHawk.Client.EmuHawk
if (indices.Count > 0)
{
var line = DisassemblyLines[indices[0]];
BreakPointControl1.AddBreakpoint(line.Address, Emulation.Common.MemoryCallbackType.Execute);
BreakPointControl1.AddBreakpoint(line.Address, 0xFFFFFFFF, Emulation.Common.MemoryCallbackType.Execute);
}
}
}

View File

@ -303,9 +303,9 @@ namespace BizHawk.Client.EmuHawk
FullUpdate();
}
public void AddBreakpoint(uint address, MemoryCallbackType type)
public void AddBreakpoint(uint address, uint mask, MemoryCallbackType type)
{
this.BreakPointControl1.AddBreakpoint(address, type);
this.BreakPointControl1.AddBreakpoint(address, mask, type);
}
}
}

View File

@ -1096,7 +1096,7 @@ namespace BizHawk.Client.EmuHawk
foreach (var watch in selected)
{
debugger.AddBreakpoint((uint)watch.Address, MemoryCallbackType.Read);
debugger.AddBreakpoint((uint)watch.Address, 0xFFFFFFFF, MemoryCallbackType.Read);
}
}
}
@ -1111,7 +1111,7 @@ namespace BizHawk.Client.EmuHawk
foreach (var watch in selected)
{
debugger.AddBreakpoint((uint)watch.Address, MemoryCallbackType.Write);
debugger.AddBreakpoint((uint)watch.Address, 0xFFFFFFFF, MemoryCallbackType.Write);
}
}
}

View File

@ -104,6 +104,11 @@ namespace BizHawk.Emulation.Common
{
get { return null; }
}
public uint? AddressMask
{
get { return null; }
}
}
}
}

View File

@ -53,7 +53,7 @@ namespace BizHawk.Emulation.Common
{
for (int i = 0; i < cbs.Count; i++)
{
if (!cbs[i].Address.HasValue || cbs[i].Address == addr)
if (!cbs[i].Address.HasValue || cbs[i].Address == (addr & cbs[i].AddressMask))
cbs[i].Callback();
}
}
@ -207,7 +207,7 @@ namespace BizHawk.Emulation.Common
public class MemoryCallback : IMemoryCallback
{
public MemoryCallback(MemoryCallbackType type, string name, Action callback, uint? address)
public MemoryCallback(MemoryCallbackType type, string name, Action callback, uint? address, uint? mask)
{
if (type == MemoryCallbackType.Execute && !address.HasValue)
{
@ -218,11 +218,13 @@ namespace BizHawk.Emulation.Common
Name = name;
Callback = callback;
Address = address;
AddressMask = (mask.HasValue ? mask : 0xFFFFFFFF);
}
public MemoryCallbackType Type { get; private set; }
public string Name { get; private set; }
public Action Callback { get; private set; }
public uint? Address { get; private set; }
public uint? AddressMask { get; private set; }
}
}

View File

@ -75,6 +75,7 @@ namespace BizHawk.Emulation.Common
string Name { get; }
Action Callback { get; }
uint? Address { get; }
uint? AddressMask { get; }
}
public enum MemoryCallbackType { Read, Write, Execute }