BizHawk/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs

317 lines
7.8 KiB
C#
Raw Normal View History

using System;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
2014-12-06 00:18:51 +00:00
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
2019-12-22 17:45:28 +00:00
public partial class GenericDebugger : ToolFormBase, IToolFormAutoConfig, IControlMainform
{
private const string AddressColumnName = "Address";
private const string InstructionColumnName = "Instruction";
public GenericDebugger()
{
InitializeComponent();
2014-12-06 00:18:51 +00:00
Closing += (o, e) => DisengageDebugger();
DisassemblerView.QueryItemText += DisassemblerView_QueryItemText;
DisassemblerView.QueryItemBkColor += DisassemblerView_QueryItemBkColor;
DisassemblerView.AllColumns.Clear();
DisassemblerView.AllColumns.AddRange(new[]
{
new RollColumn
{
Name = AddressColumnName,
Text = AddressColumnName,
Width = 94,
Type = ColumnType.Text
},
new RollColumn
{
Name = InstructionColumnName,
Text = InstructionColumnName,
Width = 291,
Type = ColumnType.Text
}
});
}
2014-12-06 00:18:51 +00:00
private void EngageDebugger()
{
2017-05-24 14:06:31 +00:00
_disassemblyLines.Clear();
2019-12-22 17:45:28 +00:00
MainForm.OnPauseChanged += OnPauseChanged;
2015-01-21 23:04:47 +00:00
CancelSeekBtn.Enabled = false;
if (CanDisassemble)
{
try
{
if (CanSetCpu && Disassembler.AvailableCpus.Count() > 1)
{
var c = new ComboBox
{
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(17)),
Width = UIHelper.ScaleX(121),
DropDownStyle = ComboBoxStyle.DropDownList
};
c.Items.AddRange(Disassembler.AvailableCpus.ToArray());
c.SelectedItem = Disassembler.Cpu;
2014-12-13 22:10:39 +00:00
c.SelectedIndexChanged += OnCpuDropDownIndexChanged;
2014-12-13 22:10:39 +00:00
DisassemblerBox.Controls.Add(c);
}
else
{
DisassemblerBox.Controls.Add(new Label
{
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(23)),
Size = new Size(UIHelper.ScaleX(100), UIHelper.ScaleY(15)),
Text = Disassembler.Cpu
});
}
}
catch (NotImplementedException)
{
DisassemblerBox.Controls.Add(new Label
{
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(23)),
Size = new Size(UIHelper.ScaleX(100), UIHelper.ScaleY(15)),
Text = Disassembler.Cpu
});
}
2014-12-23 17:44:59 +00:00
2017-05-24 14:06:31 +00:00
_pcRegisterSize = Debuggable.GetCpuFlagsAndRegisters()[Disassembler.PCRegisterName].BitSize / 4;
2014-12-23 17:44:59 +00:00
SetDisassemblerItemCount();
UpdateDisassembler();
}
else
{
DisassemblerBox.Enabled = false;
DisassemblerView.RowCount = 0;
DisassemblerBox.Controls.Add(new Label
{
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(23)),
Size = new Size(UIHelper.ScaleX(100), UIHelper.ScaleY(15)),
Text = "Unknown"
});
toolTip1.SetToolTip(DisassemblerBox, "This core does not currently support disassembling");
}
RegisterPanel.Core = Debuggable;
RegisterPanel.ParentDebugger = this;
RegisterPanel.GenerateUI();
if (CanUseMemoryCallbacks)
{
BreakPointControl1.Core = Debuggable;
BreakPointControl1.MCS = MemoryCallbacks;
BreakPointControl1.ParentDebugger = this;
BreakPointControl1.MemoryDomains = MemoryDomains;
BreakPointControl1.GenerateUI();
EnabledBreakpointBox();
}
else
{
DisableBreakpointBox();
}
SeekToBox.Enabled = SeekToBtn.Enabled = CanUseMemoryCallbacks && RegisterPanel.CanGetCpuRegisters;
if (RegisterPanel.CanGetCpuRegisters && CanDisassemble)
{
var pc = PCRegister;
SeekToBox.Nullable = false;
SeekToBox.SetHexProperties((long)Math.Pow(2, pc.BitSize));
SeekToBox.SetFromRawInt(0);
}
else
{
SeekToBox.Nullable = true;
2017-05-10 11:45:23 +00:00
SeekToBox.Text = "";
}
StepIntoMenuItem.Enabled = StepIntoBtn.Enabled = CanStepInto;
StepOutMenuItem.Enabled = StepOutBtn.Enabled = CanStepOut;
StepOverMenuItem.Enabled = StepOverBtn.Enabled = CanStepOver;
if (!StepIntoMenuItem.Enabled)
{
toolTip1.SetToolTip(StepIntoBtn, "This core does not currently implement this feature");
}
if (!StepOutMenuItem.Enabled)
{
toolTip1.SetToolTip(StepOutBtn, "This core does not currently implement this feature");
}
if (!StepOverMenuItem.Enabled)
{
toolTip1.SetToolTip(StepOverBtn, "This core does not currently implement this feature");
}
2014-12-06 00:18:51 +00:00
}
private void DisengageDebugger()
{
2014-12-06 15:07:01 +00:00
BreakPointControl1.Shutdown();
2019-12-22 17:45:28 +00:00
MainForm.OnPauseChanged -= OnPauseChanged;
}
2014-12-23 17:34:12 +00:00
public void DisableRegisterBox()
{
2014-12-23 17:34:12 +00:00
RegistersGroupBox.Enabled = false;
toolTip1.SetToolTip(RegistersGroupBox, "This core does not currently support reading registers");
}
2014-12-23 17:34:12 +00:00
public void DisableBreakpointBox()
{
2014-12-23 17:34:12 +00:00
BreakpointsGroupBox.Enabled = false;
toolTip1.SetToolTip(BreakpointsGroupBox, "This core does not currently support breakpoints");
}
public void EnabledBreakpointBox()
{
BreakpointsGroupBox.Enabled = true;
toolTip1.SetToolTip(BreakpointsGroupBox, "");
}
2014-12-23 17:34:12 +00:00
private void OnCpuDropDownIndexChanged(object sender, EventArgs e)
{
2019-12-22 17:13:53 +00:00
Disassembler.Cpu = ((ComboBox) sender).SelectedItem.ToString();
}
#region File
private void ExitMenuItem_Click(object sender, EventArgs e)
{
Close();
}
#endregion
#region Debug
2016-02-24 19:17:48 +00:00
private void RunBtn_Click(object sender, EventArgs e)
{
2019-12-22 17:45:28 +00:00
MainForm.UnpauseEmulator();
2016-02-24 19:17:48 +00:00
}
private void StepIntoMenuItem_Click(object sender, EventArgs e)
{
2014-12-20 13:48:56 +00:00
if (CanStepInto)
{
Debuggable.Step(StepType.Into);
FullUpdate();
}
}
private void StepOverMenuItem_Click(object sender, EventArgs e)
{
2014-12-20 13:48:56 +00:00
if (CanStepOver)
{
Debuggable.Step(StepType.Over);
FullUpdate();
}
}
private void StepOutMenuItem_Click(object sender, EventArgs e)
{
2014-12-20 13:48:56 +00:00
if (CanStepOut)
{
Debuggable.Step(StepType.Out);
FullUpdate();
}
}
#endregion
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
2014-12-20 13:48:56 +00:00
if (keyData == Keys.F11)
{
StepIntoMenuItem_Click(null, null);
return true;
}
2017-05-24 14:06:31 +00:00
if (keyData == (Keys.F11 | Keys.Shift))
{
2014-12-20 13:48:56 +00:00
StepOutMenuItem_Click(null, null);
return true;
}
2017-05-24 14:06:31 +00:00
if (keyData == Keys.F10)
{
2014-12-20 13:48:56 +00:00
StepOverMenuItem_Click(null, null);
return true;
}
2017-05-24 14:06:31 +00:00
return base.ProcessCmdKey(ref msg, keyData);
}
private Control _currentToolTipControl = null;
2017-05-24 14:06:31 +00:00
private void GenericDebugger_MouseMove(object sender, MouseEventArgs e)
{
var control = GetChildAtPoint(e.Location);
if (control != null)
{
if (!control.Enabled && _currentToolTipControl == null)
{
string toolTipString = toolTip1.GetToolTip(control);
toolTip1.Show(toolTipString, control, control.Width / 2, control.Height / 2);
_currentToolTipControl = control;
}
}
else
{
if (_currentToolTipControl != null)
{
toolTip1.Hide(_currentToolTipControl);
}
_currentToolTipControl = null;
}
}
2015-01-21 23:04:47 +00:00
public void DisableCancelSeekBtn()
{
CancelSeekBtn.Enabled = false;
}
private void SeekToBtn_Click(object sender, EventArgs e)
{
2015-01-21 23:04:47 +00:00
CancelSeekBtn.Enabled = true;
var pcVal = (uint)(SeekToBox.ToRawInt() ?? 0);
var pcBitSize = PCRegister.BitSize;
2015-01-21 23:04:47 +00:00
BreakPointControl1.RemoveCurrentSeek();
BreakPointControl1.AddSeekBreakpoint(pcVal, pcBitSize);
BreakPointControl1.UpdateValues();
}
2015-01-21 23:04:47 +00:00
private void CancelSeekBtn_Click(object sender, EventArgs e)
{
BreakPointControl1.RemoveCurrentSeek();
CancelSeekBtn.Enabled = false;
}
2015-01-24 02:50:22 +00:00
private void ToPCBtn_Click(object sender, EventArgs e)
{
UpdateDisassembler();
}
private void RefreshMenuItem_Click(object sender, EventArgs e)
{
FullUpdate();
}
public void AddBreakpoint(uint address, uint mask, MemoryCallbackType type)
{
this.BreakPointControl1.AddBreakpoint(address, mask, type);
}
}
}