2014-12-06 00:03:36 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
2014-12-06 00:18:51 +00:00
|
|
|
|
using BizHawk.Emulation.Common;
|
|
|
|
|
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
2014-12-06 00:03:36 +00:00
|
|
|
|
using BizHawk.Client.Common;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
|
|
|
{
|
2014-12-22 23:57:03 +00:00
|
|
|
|
public partial class GenericDebugger : Form, IToolFormAutoConfig, IControlMainform
|
2014-12-06 00:03:36 +00:00
|
|
|
|
{
|
|
|
|
|
public GenericDebugger()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2014-12-06 00:18:51 +00:00
|
|
|
|
Closing += (o, e) => DisengageDebugger();
|
2014-12-13 21:41:39 +00:00
|
|
|
|
|
|
|
|
|
DisassemblerView.QueryItemText += DisassemblerView_QueryItemText;
|
|
|
|
|
DisassemblerView.QueryItemBkColor += DisassemblerView_QueryItemBkColor;
|
|
|
|
|
DisassemblerView.VirtualMode = true;
|
2014-12-06 00:03:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void GenericDebugger_Load(object sender, EventArgs e)
|
|
|
|
|
{
|
2014-12-24 03:14:58 +00:00
|
|
|
|
|
2014-12-06 00:03:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-06 00:18:51 +00:00
|
|
|
|
private void EngageDebugger()
|
|
|
|
|
{
|
2014-12-23 17:44:59 +00:00
|
|
|
|
DisassemblyLines.Clear();
|
2015-01-24 03:10:21 +00:00
|
|
|
|
GlobalWin.MainForm.OnPauseChanged += OnPauseChanged;
|
2015-01-21 23:04:47 +00:00
|
|
|
|
CancelSeekBtn.Enabled = false;
|
2014-12-20 13:12:03 +00:00
|
|
|
|
if (CanDisassemble)
|
2014-12-13 21:41:39 +00:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2014-12-20 13:12:03 +00:00
|
|
|
|
if (CanSetCpu && Disassembler.AvailableCpus.Count() > 1)
|
2014-12-13 21:41:39 +00:00
|
|
|
|
{
|
|
|
|
|
var c = new ComboBox
|
|
|
|
|
{
|
2014-12-28 21:59:53 +00:00
|
|
|
|
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(17)),
|
|
|
|
|
Width = UIHelper.ScaleX(121),
|
2014-12-13 21:41:39 +00:00
|
|
|
|
DropDownStyle = ComboBoxStyle.DropDownList
|
|
|
|
|
};
|
|
|
|
|
|
2014-12-15 22:25:06 +00:00
|
|
|
|
c.Items.AddRange(Disassembler.AvailableCpus.ToArray());
|
|
|
|
|
c.SelectedItem = Disassembler.Cpu;
|
2014-12-13 22:10:39 +00:00
|
|
|
|
c.SelectedIndexChanged += OnCpuDropDownIndexChanged;
|
2014-12-13 21:41:39 +00:00
|
|
|
|
|
2014-12-13 22:10:39 +00:00
|
|
|
|
DisassemblerBox.Controls.Add(c);
|
2014-12-13 21:41:39 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DisassemblerBox.Controls.Add(new Label
|
|
|
|
|
{
|
2014-12-28 21:59:53 +00:00
|
|
|
|
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(23)),
|
|
|
|
|
Size = new Size(UIHelper.ScaleX(100), UIHelper.ScaleY(15)),
|
2014-12-13 21:41:39 +00:00
|
|
|
|
Text = Disassembler.Cpu
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (NotImplementedException)
|
|
|
|
|
{
|
|
|
|
|
DisassemblerBox.Controls.Add(new Label
|
|
|
|
|
{
|
2014-12-28 21:59:53 +00:00
|
|
|
|
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(23)),
|
|
|
|
|
Size = new Size(UIHelper.ScaleX(100), UIHelper.ScaleY(15)),
|
2014-12-13 21:41:39 +00:00
|
|
|
|
Text = Disassembler.Cpu
|
|
|
|
|
});
|
|
|
|
|
}
|
2014-12-23 17:44:59 +00:00
|
|
|
|
|
2016-02-22 16:16:05 +00:00
|
|
|
|
PCRegisterSize = Debuggable.GetCpuFlagsAndRegisters()[Disassembler.PCRegisterName].BitSize / 4;
|
2014-12-23 17:44:59 +00:00
|
|
|
|
SetDisassemblerItemCount();
|
|
|
|
|
UpdateDisassembler();
|
2014-12-13 21:41:39 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DisassemblerBox.Enabled = false;
|
2014-12-23 17:44:59 +00:00
|
|
|
|
DisassemblerView.ItemCount = 0;
|
2014-12-13 21:41:39 +00:00
|
|
|
|
DisassemblerBox.Controls.Add(new Label
|
|
|
|
|
{
|
2014-12-28 21:59:53 +00:00
|
|
|
|
Location = new Point(UIHelper.ScaleX(35), UIHelper.ScaleY(23)),
|
|
|
|
|
Size = new Size(UIHelper.ScaleX(100), UIHelper.ScaleY(15)),
|
2014-12-13 21:41:39 +00:00
|
|
|
|
Text = "Unknown"
|
|
|
|
|
});
|
2014-12-20 14:45:06 +00:00
|
|
|
|
|
|
|
|
|
toolTip1.SetToolTip(DisassemblerBox, "This core does not currently support disassembling");
|
2014-12-13 21:41:39 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:36:22 +00:00
|
|
|
|
RegisterPanel.Core = Debuggable;
|
2014-12-07 14:52:09 +00:00
|
|
|
|
RegisterPanel.ParentDebugger = this;
|
|
|
|
|
RegisterPanel.GenerateUI();
|
|
|
|
|
|
2014-12-23 18:24:01 +00:00
|
|
|
|
if (CanUseMemoryCallbacks)
|
|
|
|
|
{
|
|
|
|
|
BreakPointControl1.Core = Debuggable;
|
|
|
|
|
BreakPointControl1.MCS = MemoryCallbacks;
|
|
|
|
|
BreakPointControl1.ParentDebugger = this;
|
|
|
|
|
BreakPointControl1.MemoryDomains = MemoryDomains;
|
|
|
|
|
BreakPointControl1.GenerateUI();
|
2015-01-21 00:46:13 +00:00
|
|
|
|
EnabledBreakpointBox();
|
2014-12-23 18:24:01 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DisableBreakpointBox();
|
|
|
|
|
}
|
2014-12-20 13:36:22 +00:00
|
|
|
|
|
2015-01-21 00:46:13 +00:00
|
|
|
|
SeekToBox.Enabled = SeekToBtn.Enabled = CanUseMemoryCallbacks && RegisterPanel.CanGetCpuRegisters;
|
|
|
|
|
|
2015-02-06 01:01:34 +00:00
|
|
|
|
if (RegisterPanel.CanGetCpuRegisters && CanDisassemble)
|
2015-01-21 00:46:13 +00:00
|
|
|
|
{
|
2015-01-31 23:34:28 +00:00
|
|
|
|
var pc = PCRegister;
|
2015-01-21 00:46:13 +00:00
|
|
|
|
SeekToBox.Nullable = false;
|
|
|
|
|
SeekToBox.SetHexProperties((long)Math.Pow(2, pc.BitSize));
|
|
|
|
|
SeekToBox.SetFromRawInt(0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SeekToBox.Nullable = true;
|
|
|
|
|
SeekToBox.Text = string.Empty;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 13:36:22 +00:00
|
|
|
|
StepIntoMenuItem.Enabled = StepIntoBtn.Enabled = CanStepInto;
|
|
|
|
|
StepOutMenuItem.Enabled = StepOutBtn.Enabled = CanStepOut;
|
|
|
|
|
StepOverMenuItem.Enabled = StepOverBtn.Enabled = CanStepOver;
|
2014-12-20 14:45:06 +00:00
|
|
|
|
|
|
|
|
|
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 00:03:36 +00:00
|
|
|
|
{
|
2014-12-06 15:07:01 +00:00
|
|
|
|
BreakPointControl1.Shutdown();
|
2015-01-24 03:10:21 +00:00
|
|
|
|
GlobalWin.MainForm.OnPauseChanged -= OnPauseChanged;
|
2014-12-06 00:03:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 17:34:12 +00:00
|
|
|
|
public void DisableRegisterBox()
|
2014-12-06 00:03:36 +00:00
|
|
|
|
{
|
2014-12-23 17:34:12 +00:00
|
|
|
|
RegistersGroupBox.Enabled = false;
|
|
|
|
|
toolTip1.SetToolTip(RegistersGroupBox, "This core does not currently support reading registers");
|
2014-12-06 00:03:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 17:34:12 +00:00
|
|
|
|
public void DisableBreakpointBox()
|
2014-12-06 00:03:36 +00:00
|
|
|
|
{
|
2014-12-23 17:34:12 +00:00
|
|
|
|
BreakpointsGroupBox.Enabled = false;
|
|
|
|
|
toolTip1.SetToolTip(BreakpointsGroupBox, "This core does not currently support breakpoints");
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-21 00:46:13 +00:00
|
|
|
|
public void EnabledBreakpointBox()
|
|
|
|
|
{
|
|
|
|
|
BreakpointsGroupBox.Enabled = true;
|
|
|
|
|
toolTip1.SetToolTip(BreakpointsGroupBox, "");
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 17:34:12 +00:00
|
|
|
|
private void OnCpuDropDownIndexChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Disassembler.Cpu = (sender as ComboBox).SelectedItem.ToString();
|
2014-12-06 00:03:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-12-14 16:40:31 +00:00
|
|
|
|
#region File
|
|
|
|
|
|
2014-12-06 00:03:36 +00:00
|
|
|
|
private void ExitMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
Close();
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-14 16:40:31 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Debug
|
|
|
|
|
|
|
|
|
|
private void DebugSubMenu_DropDownOpened(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-24 19:17:48 +00:00
|
|
|
|
private void RunBtn_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
GlobalWin.MainForm.UnpauseEmulator();
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-14 16:40:31 +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();
|
|
|
|
|
}
|
2014-12-14 16:40:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StepOverMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2014-12-20 13:48:56 +00:00
|
|
|
|
if (CanStepOver)
|
|
|
|
|
{
|
|
|
|
|
Debuggable.Step(StepType.Over);
|
|
|
|
|
FullUpdate();
|
|
|
|
|
}
|
2014-12-14 16:40:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void StepOutMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2014-12-20 13:48:56 +00:00
|
|
|
|
if (CanStepOut)
|
|
|
|
|
{
|
|
|
|
|
Debuggable.Step(StepType.Out);
|
|
|
|
|
FullUpdate();
|
|
|
|
|
}
|
2014-12-14 16:40:31 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
|
|
|
|
{
|
2014-12-20 13:48:56 +00:00
|
|
|
|
if (keyData == Keys.F11)
|
2014-12-14 16:40:31 +00:00
|
|
|
|
{
|
|
|
|
|
StepIntoMenuItem_Click(null, null);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else if (keyData == (Keys.F11 | Keys.Shift))
|
|
|
|
|
{
|
2014-12-20 13:48:56 +00:00
|
|
|
|
StepOutMenuItem_Click(null, null);
|
2014-12-14 16:40:31 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2014-12-20 13:48:56 +00:00
|
|
|
|
else if (keyData == Keys.F10)
|
2014-12-14 16:40:31 +00:00
|
|
|
|
{
|
2014-12-20 13:48:56 +00:00
|
|
|
|
StepOverMenuItem_Click(null, null);
|
2014-12-14 16:40:31 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return base.ProcessCmdKey(ref msg, keyData);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-20 14:45:06 +00:00
|
|
|
|
|
|
|
|
|
private Control _currentToolTipControl = null;
|
|
|
|
|
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 02:12:59 +00:00
|
|
|
|
|
2015-01-21 23:04:47 +00:00
|
|
|
|
public void DisableCancelSeekBtn()
|
|
|
|
|
{
|
|
|
|
|
CancelSeekBtn.Enabled = false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-21 02:12:59 +00:00
|
|
|
|
private void SeekToBtn_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-01-21 23:04:47 +00:00
|
|
|
|
CancelSeekBtn.Enabled = true;
|
2015-01-21 02:12:59 +00:00
|
|
|
|
var pcVal = (uint)(SeekToBox.ToRawInt() ?? 0);
|
2016-02-21 12:49:22 +00:00
|
|
|
|
var pcBitSize = PCRegister.BitSize;
|
|
|
|
|
|
2015-01-21 23:04:47 +00:00
|
|
|
|
BreakPointControl1.RemoveCurrentSeek();
|
2015-01-21 02:12:59 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
2015-01-24 03:10:21 +00:00
|
|
|
|
|
|
|
|
|
private void RefreshMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
FullUpdate();
|
|
|
|
|
}
|
2015-02-08 17:39:59 +00:00
|
|
|
|
|
2016-08-08 11:37:39 +00:00
|
|
|
|
public void AddBreakpoint(uint address, uint mask, MemoryCallbackType type)
|
2015-02-08 17:39:59 +00:00
|
|
|
|
{
|
2016-08-08 11:37:39 +00:00
|
|
|
|
this.BreakPointControl1.AddBreakpoint(address, mask, type);
|
2015-02-08 17:39:59 +00:00
|
|
|
|
}
|
2014-12-06 00:03:36 +00:00
|
|
|
|
}
|
|
|
|
|
}
|