BizHawk/BizHawk.Client.EmuHawk/tools/NES/NESDebugger.cs

172 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using BizHawk.Emulation.Cores.Nintendo.NES;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
public partial class NESDebugger : Form, IToolForm
{
private const int ADDR_MAX = 0xFFFF;
private const int DISASM_LINE_COUNT = 100;
private int defaultWidth; //For saving the default size of the dialog, so the user can restore if desired
private int defaultHeight;
private NES _nes;
private int pc;
private int addr;
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; }
}
public bool AskSave() { return true; }
public bool UpdateBefore { get { return true; } }
public NESDebugger()
{
InitializeComponent();
DebugView.QueryItemText += DebugView_QueryItemText;
DebugView.QueryItemBkColor += DebugView_QueryItemBkColor;
DebugView.VirtualMode = true;
DebugView.ItemCount = ADDR_MAX + 1;
Activated += (o, e) => UpdateValues();
Closing += (o, e) => SaveConfigSettings();
}
public void Restart()
{
if (Global.Emulator is NES)
{
_nes = Global.Emulator as NES;
}
else
{
Close();
}
}
public void UpdateValues()
{
if (Global.Emulator is NES)
{
addr = pc = _nes.cpu.PC;
UpdateDebugView();
}
else
{
Close();
}
}
private void UpdateDebugView()
{
DebugView.BlazingFast = true;
Disasm(DISASM_LINE_COUNT);
DebugView.ensureVisible(0xFFFF);
DebugView.ensureVisible(pc);
DebugView.Refresh();
DebugView.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 = _nes.cpu.Disassemble((ushort)a, out advance);
lines.Add(new DisasmOp(advance, line));
a += advance;
if (a > ADDR_MAX) break;
}
}
private void NESDebugger_Load(object sender, EventArgs e)
{
LoadConfigSettings();
_nes = Global.Emulator as NES;
}
private void LoadConfigSettings()
{
defaultWidth = Size.Width; //Save these first so that the user can restore to its original size
defaultHeight = Size.Height;
if (Global.Config.NESDebuggerSaveWindowPosition && Global.Config.NESDebuggerWndx >= 0 && Global.Config.NESDebuggerWndy >= 0)
Location = new Point(Global.Config.NESDebuggerWndx, Global.Config.NESDebuggerWndy);
if (Global.Config.NESDebuggerWidth >= 0 && Global.Config.NESDebuggerHeight >= 0)
{
Size = new Size(Global.Config.NESDebuggerWidth, Global.Config.NESDebuggerHeight);
}
}
public void SaveConfigSettings()
{
Global.Config.NESDebuggerWndx = Location.X;
Global.Config.NESDebuggerWndy = Location.Y;
Global.Config.NESDebuggerWidth = Right - Left;
Global.Config.NESDebuggerHeight = Bottom - Top;
}
private void DebugView_QueryItemBkColor(int index, int column, ref Color color)
{
}
void DebugView_QueryItemText(int index, int column, out string text)
{
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 exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Close();
}
private void autoloadToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.AutoLoadNESDebugger ^= true;
}
private void saveWindowPositionToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.NESDebuggerSaveWindowPosition ^= true;
}
private void optionsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
autoloadToolStripMenuItem.Checked = Global.Config.AutoLoadNESDebugger;
saveWindowPositionToolStripMenuItem.Checked = Global.Config.NESDebuggerSaveWindowPosition;
}
private void restoreOriginalSizeToolStripMenuItem_Click(object sender, EventArgs e)
{
Size = new Size(defaultWidth, defaultHeight);
}
}
}