2014-12-20 15:56:01 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2014-12-20 16:01:11 +00:00
|
|
|
|
using System.Drawing;
|
2014-12-20 15:56:01 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2014-12-20 20:33:54 +00:00
|
|
|
|
using System.Windows.Forms;
|
2014-12-20 15:56:01 +00:00
|
|
|
|
|
|
|
|
|
namespace BizHawk.Client.EmuHawk
|
|
|
|
|
{
|
|
|
|
|
public partial class GenericDebugger
|
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
private readonly List<DisasmOp> DisassemblyLines = new List<DisasmOp>();
|
|
|
|
|
|
2014-12-20 15:56:01 +00:00
|
|
|
|
private class DisasmOp
|
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
public DisasmOp(uint address, int s, string m)
|
2014-12-20 15:56:01 +00:00
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
Address = address;
|
2014-12-20 15:56:01 +00:00
|
|
|
|
Size = s;
|
|
|
|
|
Mnemonic = m;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-23 02:34:08 +00:00
|
|
|
|
public uint Address { get; private set; }
|
2014-12-20 15:56:01 +00:00
|
|
|
|
public int Size { get; private set; }
|
|
|
|
|
public string Mnemonic { get; private set; }
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-18 15:25:47 +00:00
|
|
|
|
private long BusMaxValue
|
2014-12-20 18:11:42 +00:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2015-01-24 15:49:02 +00:00
|
|
|
|
return MemoryDomains.SystemBus.Size;
|
2014-12-20 18:11:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 15:56:01 +00:00
|
|
|
|
private void UpdateDisassembler()
|
|
|
|
|
{
|
|
|
|
|
if (CanDisassemble)
|
|
|
|
|
{
|
|
|
|
|
DisassemblerView.BlazingFast = true;
|
2015-01-24 02:50:22 +00:00
|
|
|
|
DisassemblerView.ItemCount = 0;
|
2015-02-06 00:56:54 +00:00
|
|
|
|
currentDisassemblerAddress = (uint)PCRegister.Value;
|
2014-12-23 02:34:08 +00:00
|
|
|
|
Disassemble();
|
2014-12-20 15:56:01 +00:00
|
|
|
|
DisassemblerView.Refresh();
|
|
|
|
|
DisassemblerView.BlazingFast = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 20:33:54 +00:00
|
|
|
|
uint currentDisassemblerAddress = 0;
|
|
|
|
|
|
2014-12-23 02:34:08 +00:00
|
|
|
|
private void Disassemble()
|
2014-12-20 15:56:01 +00:00
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
int line_count = DisassemblerView.NumberOfVisibleRows;
|
|
|
|
|
|
2014-12-20 15:56:01 +00:00
|
|
|
|
DisassemblyLines.Clear();
|
2014-12-20 20:33:54 +00:00
|
|
|
|
uint a = currentDisassemblerAddress;
|
2014-12-20 15:56:01 +00:00
|
|
|
|
for (int i = 0; i < line_count; ++i)
|
|
|
|
|
{
|
|
|
|
|
int advance;
|
2015-01-24 15:49:02 +00:00
|
|
|
|
string line = Disassembler.Disassemble(MemoryDomains.SystemBus, a, out advance);
|
2014-12-23 02:34:08 +00:00
|
|
|
|
DisassemblyLines.Add(new DisasmOp(a, advance, line));
|
2014-12-20 20:33:54 +00:00
|
|
|
|
a += (uint)advance;
|
2014-12-20 18:11:42 +00:00
|
|
|
|
if (a > BusMaxValue)
|
2014-12-20 15:56:01 +00:00
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-20 16:01:11 +00:00
|
|
|
|
|
|
|
|
|
private void DisassemblerView_QueryItemText(int index, int column, out string text)
|
|
|
|
|
{
|
|
|
|
|
text = "";
|
2014-12-23 02:34:08 +00:00
|
|
|
|
|
|
|
|
|
if (index < DisassemblyLines.Count)
|
2014-12-20 16:01:11 +00:00
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
if (column == 0)
|
2014-12-20 16:01:11 +00:00
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
text = string.Format("{0:X4}", DisassemblyLines[index].Address);
|
2014-12-20 16:01:11 +00:00
|
|
|
|
}
|
2014-12-23 02:34:08 +00:00
|
|
|
|
else if (column == 1)
|
2014-12-20 16:01:11 +00:00
|
|
|
|
{
|
2014-12-23 02:34:08 +00:00
|
|
|
|
text = DisassemblyLines[index].Mnemonic;
|
2014-12-20 16:01:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DisassemblerView_QueryItemBkColor(int index, int column, ref Color color)
|
|
|
|
|
{
|
2014-12-23 03:13:13 +00:00
|
|
|
|
if (DisassemblyLines.Any() && index < DisassemblyLines.Count)
|
2014-12-20 16:01:11 +00:00
|
|
|
|
{
|
2015-02-06 00:56:54 +00:00
|
|
|
|
if (DisassemblyLines[index].Address == (uint)PCRegister.Value)
|
2014-12-23 03:13:13 +00:00
|
|
|
|
{
|
|
|
|
|
color = Color.LightCyan;
|
|
|
|
|
}
|
2014-12-20 16:01:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-20 20:33:54 +00:00
|
|
|
|
|
|
|
|
|
private void DecrementCurrentAddress()
|
|
|
|
|
{
|
|
|
|
|
uint newaddress = currentDisassemblerAddress;
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
int bytestoadvance;
|
2015-01-24 15:49:02 +00:00
|
|
|
|
Disassembler.Disassemble(MemoryDomains.SystemBus, newaddress, out bytestoadvance);
|
2014-12-20 20:33:54 +00:00
|
|
|
|
if (newaddress + bytestoadvance == currentDisassemblerAddress)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
newaddress--;
|
|
|
|
|
|
2014-12-23 02:34:08 +00:00
|
|
|
|
if (newaddress < 0)
|
|
|
|
|
{
|
|
|
|
|
newaddress = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-20 20:33:54 +00:00
|
|
|
|
// Just in case
|
|
|
|
|
if (currentDisassemblerAddress - newaddress > 5)
|
|
|
|
|
{
|
|
|
|
|
newaddress = currentDisassemblerAddress - 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentDisassemblerAddress = newaddress;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void IncrementCurrentAddress()
|
|
|
|
|
{
|
2014-12-23 02:13:26 +00:00
|
|
|
|
currentDisassemblerAddress += (uint)DisassemblyLines.First().Size;
|
2014-12-23 02:34:08 +00:00
|
|
|
|
if (currentDisassemblerAddress >= BusMaxValue)
|
|
|
|
|
{
|
|
|
|
|
currentDisassemblerAddress = (uint)(BusMaxValue - 1);
|
|
|
|
|
}
|
2014-12-20 20:33:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DisassemblerView_Scroll(object sender, ScrollEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.Type == ScrollEventType.SmallIncrement)
|
|
|
|
|
{
|
|
|
|
|
IncrementCurrentAddress();
|
2014-12-23 02:34:08 +00:00
|
|
|
|
Disassemble();
|
2014-12-23 02:13:26 +00:00
|
|
|
|
DisassemblerView.Refresh();
|
2014-12-20 20:33:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (e.Type == ScrollEventType.SmallDecrement)
|
|
|
|
|
{
|
|
|
|
|
DecrementCurrentAddress();
|
2014-12-23 02:34:08 +00:00
|
|
|
|
Disassemble();
|
2014-12-23 02:13:26 +00:00
|
|
|
|
DisassemblerView.Refresh();
|
2014-12-20 20:33:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-23 02:34:08 +00:00
|
|
|
|
|
|
|
|
|
private void SetDisassemblerItemCount()
|
|
|
|
|
{
|
|
|
|
|
DisassemblerView.ItemCount = DisassemblerView.NumberOfVisibleRows + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void DisassemblerView_SizeChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SetDisassemblerItemCount();
|
2015-02-08 15:16:28 +00:00
|
|
|
|
if (CanDisassemble)
|
|
|
|
|
{
|
|
|
|
|
Disassemble();
|
|
|
|
|
}
|
2014-12-23 02:34:08 +00:00
|
|
|
|
}
|
2015-01-24 00:02:22 +00:00
|
|
|
|
|
|
|
|
|
private void DisassemblerView_KeyDown(object sender, KeyEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (e.Control && !e.Shift && !e.Alt && e.KeyCode == Keys.C) // Ctrl + C
|
|
|
|
|
{
|
|
|
|
|
CopySelectedDisassembler();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CopySelectedDisassembler()
|
|
|
|
|
{
|
|
|
|
|
var indices = DisassemblerView.SelectedIndices;
|
|
|
|
|
|
|
|
|
|
if (indices.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var blob = new StringBuilder();
|
|
|
|
|
foreach (int index in indices)
|
|
|
|
|
{
|
2015-02-08 15:32:56 +00:00
|
|
|
|
if (blob.Length != 0) blob.AppendLine();
|
2015-01-24 00:02:22 +00:00
|
|
|
|
blob.Append(DisassemblyLines[index].Address)
|
|
|
|
|
.Append(" ")
|
2015-02-08 15:32:56 +00:00
|
|
|
|
.Append(DisassemblyLines[index].Mnemonic);
|
2015-01-24 00:02:22 +00:00
|
|
|
|
}
|
|
|
|
|
Clipboard.SetDataObject(blob.ToString());
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-01-24 03:10:21 +00:00
|
|
|
|
|
|
|
|
|
private void OnPauseChanged(object sender, MainForm.PauseChangedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
FullUpdate();
|
|
|
|
|
}
|
2015-02-06 00:41:50 +00:00
|
|
|
|
|
|
|
|
|
private void DisassemblerContextMenu_Opening(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
AddBreakpointContextMenuItem.Enabled = DisassemblerView.SelectedIndices.Count > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AddBreakpointContextMenuItem_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var indices = DisassemblerView.SelectedIndices;
|
|
|
|
|
|
|
|
|
|
if (indices.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var line = DisassemblyLines[indices[0]];
|
|
|
|
|
BreakPointControl1.AddBreakpoint(line.Address, Emulation.Common.MemoryCallbackType.Execute);
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-12-20 15:56:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|