Debugger - a rough basic disassembler (if the necessary pieces are provided by the core), still a lot of details to work out
This commit is contained in:
parent
2d56514fde
commit
227fd64e60
|
@ -12,10 +12,32 @@ namespace BizHawk.Client.EmuHawk
|
||||||
public IDictionary<Type, object> EmulatorServices { private get; set; }
|
public IDictionary<Type, object> EmulatorServices { private get; set; }
|
||||||
private IDebuggable Core { get { return (IDebuggable)EmulatorServices[typeof(IDebuggable)]; } }
|
private IDebuggable Core { get { return (IDebuggable)EmulatorServices[typeof(IDebuggable)]; } }
|
||||||
private IDisassemblable Disassembler { get { return (IDisassemblable)EmulatorServices[typeof(IDisassemblable)]; } }
|
private IDisassemblable Disassembler { get { return (IDisassemblable)EmulatorServices[typeof(IDisassemblable)]; } }
|
||||||
|
private MemoryDomainList MemoryDomains { get { return (EmulatorServices[typeof(IMemoryDomains)] as IMemoryDomains).MemoryDomains; } }
|
||||||
|
|
||||||
|
private int? PC
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var flags = Core.GetCpuFlagsAndRegisters();
|
||||||
|
|
||||||
|
if (flags.ContainsKey("PC"))
|
||||||
|
{
|
||||||
|
return flags["PC"];
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (flags.ContainsKey("R15"))
|
||||||
|
{
|
||||||
|
return flags["R15"];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateValues()
|
public void UpdateValues()
|
||||||
{
|
{
|
||||||
RegisterPanel.UpdateValues();
|
RegisterPanel.UpdateValues();
|
||||||
|
UpdateDisassembler();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FastUpdate()
|
public void FastUpdate()
|
||||||
|
|
|
@ -14,7 +14,7 @@ using BizHawk.Client.Common;
|
||||||
namespace BizHawk.Client.EmuHawk
|
namespace BizHawk.Client.EmuHawk
|
||||||
{
|
{
|
||||||
[RequiredServices(typeof(IDebuggable))]
|
[RequiredServices(typeof(IDebuggable))]
|
||||||
[OptionalServices(typeof(IDisassemblable))]
|
[OptionalServices(typeof(IDisassemblable), typeof(IMemoryDomains))]
|
||||||
public partial class GenericDebugger : Form, IToolForm, IControlMainform
|
public partial class GenericDebugger : Form, IToolForm, IControlMainform
|
||||||
{
|
{
|
||||||
private int _defaultWidth;
|
private int _defaultWidth;
|
||||||
|
@ -29,6 +29,7 @@ namespace BizHawk.Client.EmuHawk
|
||||||
DisassemblerView.QueryItemText += DisassemblerView_QueryItemText;
|
DisassemblerView.QueryItemText += DisassemblerView_QueryItemText;
|
||||||
DisassemblerView.QueryItemBkColor += DisassemblerView_QueryItemBkColor;
|
DisassemblerView.QueryItemBkColor += DisassemblerView_QueryItemBkColor;
|
||||||
DisassemblerView.VirtualMode = true;
|
DisassemblerView.VirtualMode = true;
|
||||||
|
DisassemblerView.ItemCount = ADDR_MAX + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GenericDebugger_Load(object sender, EventArgs e)
|
private void GenericDebugger_Load(object sender, EventArgs e)
|
||||||
|
@ -51,7 +52,22 @@ namespace BizHawk.Client.EmuHawk
|
||||||
|
|
||||||
private void DisassemblerView_QueryItemText(int index, int column, out string text)
|
private void DisassemblerView_QueryItemText(int index, int column, out string text)
|
||||||
{
|
{
|
||||||
text = string.Empty;
|
text = "";
|
||||||
|
if (column == 0)
|
||||||
|
{
|
||||||
|
if (addr <= index && index < addr + lines.Count)
|
||||||
|
{
|
||||||
|
int a = addr;
|
||||||
|
for (int i = 0; i < index - addr; ++i)
|
||||||
|
a += lines[i].size;
|
||||||
|
text = string.Format("{0:X4}", a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (column == 1)
|
||||||
|
{
|
||||||
|
if (addr <= index && index < addr + lines.Count)
|
||||||
|
text = lines[index - addr].mnemonic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisassemblerView_QueryItemBkColor(int index, int column, ref Color color)
|
private void DisassemblerView_QueryItemBkColor(int index, int column, ref Color color)
|
||||||
|
@ -164,6 +180,59 @@ namespace BizHawk.Client.EmuHawk
|
||||||
Owner = Global.Config.RamSearchSettings.FloatingWindow ? null : GlobalWin.MainForm;
|
Owner = Global.Config.RamSearchSettings.FloatingWindow ? null : GlobalWin.MainForm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private readonly List<DisasmOp> lines = new List<DisasmOp>();
|
||||||
|
|
||||||
|
private struct DisasmOp
|
||||||
|
{
|
||||||
|
public readonly int size;
|
||||||
|
public readonly string mnemonic;
|
||||||
|
public DisasmOp(int s, string m) { size = s; mnemonic = m; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int addr;
|
||||||
|
private const int ADDR_MAX = 0xFFFF; // TODO: this isn't a constant, calculate it off bus size
|
||||||
|
private const int DISASM_LINE_COUNT = 100;
|
||||||
|
|
||||||
|
private void UpdateDisassembler()
|
||||||
|
{
|
||||||
|
// Always show a window's worth of instructions (if possible)
|
||||||
|
if (CanDisassemble)
|
||||||
|
{
|
||||||
|
addr = PC.Value;
|
||||||
|
|
||||||
|
DisassemblerView.BlazingFast = true;
|
||||||
|
Disasm(DISASM_LINE_COUNT);
|
||||||
|
DisassemblerView.ensureVisible(0xFFFF);
|
||||||
|
DisassemblerView.ensureVisible(PC.Value);
|
||||||
|
|
||||||
|
DisassemblerView.Refresh();
|
||||||
|
DisassemblerView.BlazingFast = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Disasm(int line_count)
|
||||||
|
{
|
||||||
|
lines.Clear();
|
||||||
|
int a = addr;
|
||||||
|
for (int i = 0; i < line_count; ++i)
|
||||||
|
{
|
||||||
|
int advance;
|
||||||
|
string line = Disassembler.Disassemble(MemoryDomains.SystemBus, (ushort)a, out advance);
|
||||||
|
lines.Add(new DisasmOp(advance, line));
|
||||||
|
a += advance;
|
||||||
|
if (a > ADDR_MAX) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool CanDisassemble
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return Disassembler != null && PC.HasValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Menu Items
|
#region Menu Items
|
||||||
|
|
||||||
private void ExitMenuItem_Click(object sender, EventArgs e)
|
private void ExitMenuItem_Click(object sender, EventArgs e)
|
||||||
|
|
Loading…
Reference in New Issue