2015-07-01 23:17:14 -04:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Text;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace Mesen.GUI.Debugger
|
|
|
|
|
{
|
|
|
|
|
public partial class frmDebugger : Form
|
|
|
|
|
{
|
2015-08-08 22:36:39 -04:00
|
|
|
|
private List<Form> _childForms = new List<Form>();
|
2015-08-05 20:40:10 -04:00
|
|
|
|
private InteropEmu.NotificationListener _notifListener;
|
|
|
|
|
private ctrlDebuggerCode _lastCodeWindow;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
|
|
|
|
|
public frmDebugger()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2015-08-02 19:27:02 -04:00
|
|
|
|
|
|
|
|
|
_lastCodeWindow = ctrlDebuggerCode;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnLoad(e);
|
|
|
|
|
|
2015-07-05 19:03:57 -04:00
|
|
|
|
if(!DesignMode) {
|
|
|
|
|
Icon = Properties.Resources.MesenIcon;
|
|
|
|
|
}
|
2015-07-03 00:12:02 -04:00
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
_notifListener = new InteropEmu.NotificationListener();
|
|
|
|
|
_notifListener.OnNotification += _notifListener_OnNotification;
|
|
|
|
|
|
|
|
|
|
InteropEmu.DebugInitialize();
|
2015-08-02 22:19:12 -04:00
|
|
|
|
|
|
|
|
|
//Pause a few frames later to give the debugger a chance to disassemble some code
|
|
|
|
|
InteropEmu.DebugStep(100000);
|
2015-08-17 19:32:10 -04:00
|
|
|
|
|
|
|
|
|
UpdateCdlRatios();
|
|
|
|
|
tmrCdlRatios.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateCdlRatios()
|
|
|
|
|
{
|
|
|
|
|
CdlRatios ratios = new CdlRatios();
|
|
|
|
|
InteropEmu.DebugGetCdlRatios(ref ratios);
|
|
|
|
|
|
|
|
|
|
lblPrgAnalysisResult.Text = string.Format("{0:0.00}% (Code: {1:0.00}%, Data: {2:0.00}%, Unknown: {3:0.00}%)", ratios.PrgRatio * 100, ratios.CodeRatio * 100, ratios.DataRatio * 100, (1 - ratios.PrgRatio) * 100);
|
|
|
|
|
if(ratios.ChrRatio >= 0) {
|
|
|
|
|
lblChrAnalysisResult.Text = string.Format("{0:0.00}% (Drawn: {1:0.00}%, Read: {2:0.00}%, Unknown: {3:0.00}%)", ratios.ChrRatio * 100, ratios.ChrDrawnRatio * 100, ratios.ChrReadRatio * 100, (1 - ratios.ChrRatio) * 100);
|
|
|
|
|
} else {
|
|
|
|
|
lblChrAnalysisResult.Text = "N/A (CHR RAM)";
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-08 22:36:39 -04:00
|
|
|
|
private void _notifListener_OnNotification(InteropEmu.NotificationEventArgs e)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
|
|
|
|
if(e.NotificationType == InteropEmu.ConsoleNotificationType.CodeBreak) {
|
|
|
|
|
this.BeginInvoke((MethodInvoker)(() => UpdateDebugger()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool UpdateSplitView()
|
|
|
|
|
{
|
|
|
|
|
if(mnuSplitView.Checked) {
|
|
|
|
|
tlpTop.ColumnStyles[1].SizeType = SizeType.Percent;
|
2015-08-04 19:50:57 -04:00
|
|
|
|
tlpTop.ColumnStyles[0].Width = 50f;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
tlpTop.ColumnStyles[1].Width = 50f;
|
|
|
|
|
this.MinimumSize = new Size(1250, 650);
|
|
|
|
|
} else {
|
|
|
|
|
tlpTop.ColumnStyles[1].SizeType = SizeType.Absolute;
|
|
|
|
|
tlpTop.ColumnStyles[1].Width = 0f;
|
|
|
|
|
this.MinimumSize = new Size(1000, 650);
|
|
|
|
|
}
|
2015-08-03 21:53:46 -04:00
|
|
|
|
ctrlDebuggerCodeSplit.Visible = mnuSplitView.Checked;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
return mnuSplitView.Checked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void UpdateDebugger()
|
|
|
|
|
{
|
|
|
|
|
if(InteropEmu.DebugIsCodeChanged()) {
|
|
|
|
|
string code = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(InteropEmu.DebugGetCode());
|
|
|
|
|
ctrlDebuggerCode.Code = code;
|
|
|
|
|
ctrlDebuggerCodeSplit.Code = code;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DebugState state = new DebugState();
|
|
|
|
|
InteropEmu.DebugGetState(ref state);
|
|
|
|
|
|
|
|
|
|
if(UpdateSplitView()) {
|
|
|
|
|
ctrlDebuggerCodeSplit.UpdateCode(true);
|
2015-08-02 19:27:02 -04:00
|
|
|
|
} else {
|
|
|
|
|
_lastCodeWindow = ctrlDebuggerCode;
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-02 19:27:02 -04:00
|
|
|
|
ctrlDebuggerCode.SelectActiveAddress(state.CPU.DebugPC);
|
|
|
|
|
ctrlDebuggerCodeSplit.SetActiveAddress(state.CPU.DebugPC);
|
|
|
|
|
RefreshBreakpoints();
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
ctrlConsoleStatus.UpdateStatus(ref state);
|
|
|
|
|
ctrlWatch.UpdateWatch();
|
2015-08-09 14:47:27 -04:00
|
|
|
|
ctrlCallstack.UpdateCallstack();
|
2015-08-21 22:42:44 -04:00
|
|
|
|
|
|
|
|
|
this.BringToFront();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-02 19:27:02 -04:00
|
|
|
|
private void ClearActiveStatement()
|
|
|
|
|
{
|
|
|
|
|
ctrlDebuggerCode.ClearActiveAddress();
|
2015-08-09 20:47:50 -04:00
|
|
|
|
ctrlDebuggerCodeSplit.ClearActiveAddress();
|
2015-08-02 19:27:02 -04:00
|
|
|
|
RefreshBreakpoints();
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
private void ToggleBreakpoint()
|
|
|
|
|
{
|
2015-08-02 19:27:02 -04:00
|
|
|
|
ctrlBreakpoints.ToggleBreakpoint(_lastCodeWindow.GetCurrentLine());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void RefreshBreakpoints()
|
|
|
|
|
{
|
|
|
|
|
ctrlDebuggerCodeSplit.HighlightBreakpoints(ctrlBreakpoints.GetBreakpoints());
|
|
|
|
|
ctrlDebuggerCode.HighlightBreakpoints(ctrlBreakpoints.GetBreakpoints());
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-08 22:36:39 -04:00
|
|
|
|
private void OpenChildForm(Form frm)
|
|
|
|
|
{
|
|
|
|
|
this._childForms.Add(frm);
|
|
|
|
|
frm.FormClosed += (obj, args) => {
|
|
|
|
|
this._childForms.Remove((Form)obj);
|
|
|
|
|
};
|
|
|
|
|
frm.Show();
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
private void mnuContinue_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-08-02 19:27:02 -04:00
|
|
|
|
ClearActiveStatement();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
InteropEmu.DebugRun();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void frmDebugger_FormClosed(object sender, FormClosedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugRelease();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuToggleBreakpoint_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
ToggleBreakpoint();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuBreak_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugStep(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuStepInto_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugStep(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuStepOut_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugStepOut();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuStepOver_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugStepOver();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuRunOneFrame_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugStepCycles(29780);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-17 21:59:22 -04:00
|
|
|
|
private void ctrlDebuggerCode_OnWatchAdded(AddressEventArgs args)
|
2015-07-01 23:17:14 -04:00
|
|
|
|
{
|
|
|
|
|
this.ctrlWatch.AddWatch(args.Address);
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-17 21:59:22 -04:00
|
|
|
|
private void ctrlDebuggerCode_OnSetNextStatement(AddressEventArgs args)
|
|
|
|
|
{
|
|
|
|
|
UInt16 addr = (UInt16)args.Address;
|
|
|
|
|
InteropEmu.DebugSetNextStatement(addr);
|
|
|
|
|
this.UpdateDebugger();
|
|
|
|
|
}
|
|
|
|
|
|
2015-07-01 23:17:14 -04:00
|
|
|
|
private void mnuFind_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-08-03 21:53:46 -04:00
|
|
|
|
_lastCodeWindow.OpenSearchBox();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuFindNext_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.FindNext();
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
|
2015-08-03 21:53:46 -04:00
|
|
|
|
private void mnuFindPrev_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.FindPrevious();
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuSplitView_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
UpdateDebugger();
|
|
|
|
|
}
|
2015-08-02 19:27:02 -04:00
|
|
|
|
|
|
|
|
|
private void mnuMemoryViewer_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2015-08-08 22:36:39 -04:00
|
|
|
|
OpenChildForm(new frmMemoryViewer());
|
2015-08-02 19:27:02 -04:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ctrlBreakpoints_BreakpointChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
RefreshBreakpoints();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ctrlDebuggerCode_Enter(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow = ctrlDebuggerCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ctrlDebuggerCodeSplit_Enter(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow = ctrlDebuggerCodeSplit;
|
|
|
|
|
}
|
2015-08-02 22:19:12 -04:00
|
|
|
|
|
|
|
|
|
private void mnuGoTo_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.GoToAddress();
|
|
|
|
|
}
|
2015-08-04 19:50:57 -04:00
|
|
|
|
|
|
|
|
|
private void mnuIncreaseFontSize_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.FontSize++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuDecreaseFontSize_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.FontSize--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuResetFontSize_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.FontSize = 13;
|
|
|
|
|
}
|
2015-08-05 20:40:10 -04:00
|
|
|
|
|
|
|
|
|
private void mnuClose_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void OnFormClosed(FormClosedEventArgs e)
|
|
|
|
|
{
|
2015-08-08 22:36:39 -04:00
|
|
|
|
foreach(Form frm in this._childForms.ToArray()) {
|
2015-08-05 20:40:10 -04:00
|
|
|
|
frm.Close();
|
|
|
|
|
}
|
|
|
|
|
base.OnFormClosed(e);
|
|
|
|
|
}
|
2015-08-08 22:36:39 -04:00
|
|
|
|
|
|
|
|
|
private void mnuNametableViewer_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
OpenChildForm(new frmPpuViewer());
|
|
|
|
|
}
|
2015-08-09 14:47:27 -04:00
|
|
|
|
|
|
|
|
|
private void ctrlCallstack_FunctionSelected(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
_lastCodeWindow.ScrollToLineNumber((int)sender);
|
|
|
|
|
}
|
2015-08-17 19:32:10 -04:00
|
|
|
|
|
|
|
|
|
private void tmrCdlRatios_Tick(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
this.UpdateCdlRatios();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuLoadCdlFile_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
OpenFileDialog ofd = new OpenFileDialog();
|
|
|
|
|
ofd.Filter = "CDL files (*.cdl)|*.cdl";
|
|
|
|
|
if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
|
|
|
|
|
if(!InteropEmu.DebugLoadCdlFile(ofd.FileName)) {
|
|
|
|
|
MessageBox.Show("Could not load CDL file. The file selected file is invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuSaveAsCdlFile_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
SaveFileDialog sfd = new SaveFileDialog();
|
|
|
|
|
sfd.Filter = "CDL files (*.cdl)|*.cdl";
|
|
|
|
|
sfd.AddExtension = true;
|
|
|
|
|
if(sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
|
|
|
|
|
if(!InteropEmu.DebugSaveCdlFile(sfd.FileName)) {
|
|
|
|
|
MessageBox.Show("Error while trying to save CDL file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuResetCdlLog_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
InteropEmu.DebugResetCdlLog();
|
|
|
|
|
}
|
2015-07-01 23:17:14 -04:00
|
|
|
|
}
|
|
|
|
|
}
|