Debugger: Added access counters tab to memory tools

This commit is contained in:
Sour 2020-02-15 10:49:11 -05:00
parent b82b087b4e
commit 93cccd34dc
13 changed files with 796 additions and 97 deletions

View file

@ -19,7 +19,10 @@ MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger, Console *console)
for(int i = (int)SnesMemoryType::PrgRom; i < (int)SnesMemoryType::Register; i++) {
uint32_t memSize = _debugger->GetMemoryDumper()->GetMemorySize((SnesMemoryType)i);
_counters[i].insert(_counters[i].end(), memSize, {});
_counters[i].reserve(memSize);
for(uint32_t j = 0; j < memSize; j++) {
_counters[i].push_back({ j });
}
}
}
@ -74,7 +77,9 @@ void MemoryAccessCounter::ResetCounts()
{
DebugBreakHelper helper(_debugger);
for(int i = 0; i < (int)SnesMemoryType::Register; i++) {
memset(_counters[i].data(), 0, _counters[i].size() * sizeof(AddressCounters));
for(uint32_t j = 0; j < _counters[i].size(); j++) {
_counters[i][j] = { j };
}
}
}
@ -118,7 +123,7 @@ void MemoryAccessCounter::GetAccessCounts(uint32_t offset, uint32_t length, Snes
break;
default:
memcpy(counts, &_counters[(int)memoryType] + offset, length * sizeof(AddressCounters));
memcpy(counts, _counters[(int)memoryType].data() + offset, length * sizeof(AddressCounters));
break;
}
}

View file

@ -11,11 +11,14 @@ class Gsu;
struct AddressCounters
{
uint32_t Address;
uint32_t ReadCount;
uint64_t ReadStamp;
uint32_t WriteCount;
bool UninitRead;
uint32_t WriteCount;
uint64_t WriteStamp;
uint32_t ExecCount;
uint64_t ExecStamp;
};

View file

@ -1,7 +1,5 @@
#pragma once
#include "stdafx.h"
#include <unordered_map>
#include <stack>
#include "DebugTypes.h"
class Debugger;

View file

@ -79,6 +79,7 @@ extern "C"
DllExport void __stdcall SetLabel(uint32_t address, SnesMemoryType memType, char* label, char* comment) { GetDebugger()->GetLabelManager()->SetLabel(address, memType, label, comment); }
DllExport void __stdcall ClearLabels() { GetDebugger()->GetLabelManager()->ClearLabels(); }
DllExport void __stdcall ResetMemoryAccessCounts() { GetDebugger()->GetMemoryAccessCounter()->ResetCounts(); }
DllExport void __stdcall GetMemoryAccessCounts(uint32_t offset, uint32_t length, SnesMemoryType memoryType, AddressCounters* counts) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(offset, length, memoryType, counts); }
DllExport void __stdcall GetCdlData(uint32_t offset, uint32_t length, SnesMemoryType memoryType, uint8_t* cdlData) { GetDebugger()->GetCodeDataLogger()->GetCdlData(offset, length, memoryType, cdlData); }

View file

@ -0,0 +1,77 @@
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mesen.GUI.Debugger.Controls
{
class ctrlMemoryType : ComboBoxWithSeparator
{
private bool _disableEvent = false;
protected override void OnSelectedIndexChanged(EventArgs e)
{
if(!_disableEvent) {
base.OnSelectedIndexChanged(e);
}
}
public void InitMemoryTypeDropdown(SnesMemoryType? newType = null, bool excludeCpuMemory = false)
{
this._disableEvent = true;
SnesMemoryType originalValue = newType.HasValue ? newType.Value : this.GetEnumValue<SnesMemoryType>();
this.BeginUpdate();
this.Items.Clear();
if(!excludeCpuMemory) {
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CpuMemory));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SpcMemory));
this.Items.Add("-");
}
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
if(DebugApi.GetMemorySize(SnesMemoryType.SaveRam) > 0) {
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SaveRam));
}
this.Items.Add("-");
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.VideoRam));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CGRam));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SpriteRam));
if(DebugApi.GetMemorySize(SnesMemoryType.DspProgramRom) > 0) {
this.Items.Add("-");
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.DspProgramRom));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.DspDataRom));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.DspDataRam));
}
if(DebugApi.GetMemorySize(SnesMemoryType.Sa1InternalRam) > 0) {
this.Items.Add("-");
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Sa1Memory));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Sa1InternalRam));
}
if(DebugApi.GetMemorySize(SnesMemoryType.GsuWorkRam) > 0) {
this.Items.Add("-");
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuMemory));
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuWorkRam));
}
if(DebugApi.GetMemorySize(SnesMemoryType.Cx4DataRam) > 0) {
this.Items.Add("-");
this.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Cx4DataRam));
}
this.SelectedIndex = 0;
this.SetEnumValue(originalValue);
this._disableEvent = false;
this.EndUpdate();
}
}
}

View file

@ -0,0 +1,283 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlMemoryAccessCounters
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.lblViewMemoryType = new System.Windows.Forms.Label();
this.cboMemoryType = new Mesen.GUI.Debugger.Controls.ctrlMemoryType();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.btnReset = new System.Windows.Forms.Button();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.picWatchHelp = new System.Windows.Forms.PictureBox();
this.lblHint = new System.Windows.Forms.Label();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.lstCounters = new Mesen.GUI.Controls.DoubleBufferedListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader9 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader6 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader7 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader8 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader5 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).BeginInit();
this.tableLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// lblViewMemoryType
//
this.lblViewMemoryType.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblViewMemoryType.AutoSize = true;
this.lblViewMemoryType.Location = new System.Drawing.Point(3, 7);
this.lblViewMemoryType.Name = "lblViewMemoryType";
this.lblViewMemoryType.Size = new System.Drawing.Size(33, 13);
this.lblViewMemoryType.TabIndex = 0;
this.lblViewMemoryType.Text = "View:";
//
// cboMemoryType
//
this.cboMemoryType.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
this.cboMemoryType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboMemoryType.FormattingEnabled = true;
this.cboMemoryType.Location = new System.Drawing.Point(42, 3);
this.cboMemoryType.Name = "cboMemoryType";
this.cboMemoryType.Size = new System.Drawing.Size(162, 21);
this.cboMemoryType.TabIndex = 1;
this.cboMemoryType.SelectedIndexChanged += new System.EventHandler(this.cboMemoryType_SelectedIndexChanged);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.Controls.Add(this.btnReset, 1, 2);
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.lstCounters, 0, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(641, 343);
this.tableLayoutPanel1.TabIndex = 3;
//
// btnReset
//
this.btnReset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnReset.Location = new System.Drawing.Point(566, 320);
this.btnReset.Margin = new System.Windows.Forms.Padding(0);
this.btnReset.Name = "btnReset";
this.btnReset.Size = new System.Drawing.Size(75, 23);
this.btnReset.TabIndex = 5;
this.btnReset.Text = "Reset";
this.btnReset.UseVisualStyleBackColor = true;
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 2;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.picWatchHelp, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.lblHint, 1, 0);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 320);
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 2;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(566, 23);
this.tableLayoutPanel3.TabIndex = 2;
//
// picWatchHelp
//
this.picWatchHelp.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.picWatchHelp.Image = global::Mesen.GUI.Properties.Resources.Warning;
this.picWatchHelp.Location = new System.Drawing.Point(3, 3);
this.picWatchHelp.Name = "picWatchHelp";
this.picWatchHelp.Size = new System.Drawing.Size(16, 16);
this.picWatchHelp.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.picWatchHelp.TabIndex = 2;
this.picWatchHelp.TabStop = false;
//
// lblHint
//
this.lblHint.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblHint.AutoSize = true;
this.lblHint.Location = new System.Drawing.Point(25, 4);
this.lblHint.Name = "lblHint";
this.lblHint.Size = new System.Drawing.Size(530, 13);
this.lblHint.TabIndex = 0;
this.lblHint.Text = "Uninitialized read column is only accurate if the debugger was active when the ga" +
"me was loaded/power cycled";
this.lblHint.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel1.SetColumnSpan(this.tableLayoutPanel2, 2);
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.cboMemoryType, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.lblViewMemoryType, 0, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(641, 27);
this.tableLayoutPanel2.TabIndex = 6;
//
// lstCounters
//
this.lstCounters.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader9,
this.columnHeader2,
this.columnHeader6,
this.columnHeader3,
this.columnHeader7,
this.columnHeader4,
this.columnHeader8,
this.columnHeader5});
this.tableLayoutPanel1.SetColumnSpan(this.lstCounters, 2);
this.lstCounters.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstCounters.FullRowSelect = true;
this.lstCounters.Location = new System.Drawing.Point(0, 27);
this.lstCounters.Margin = new System.Windows.Forms.Padding(0);
this.lstCounters.Name = "lstCounters";
this.lstCounters.Size = new System.Drawing.Size(641, 293);
this.lstCounters.TabIndex = 7;
this.lstCounters.UseCompatibleStateImageBehavior = false;
this.lstCounters.View = System.Windows.Forms.View.Details;
this.lstCounters.VirtualMode = true;
this.lstCounters.ColumnClick += new System.Windows.Forms.ColumnClickEventHandler(this.lstCounters_ColumnClick);
this.lstCounters.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.lstCounters_RetrieveVirtualItem);
//
// columnHeader1
//
this.columnHeader1.Text = "Address";
//
// columnHeader9
//
this.columnHeader9.Text = "Value";
this.columnHeader9.Width = 40;
//
// columnHeader2
//
this.columnHeader2.Text = "Reads";
this.columnHeader2.Width = 70;
//
// columnHeader6
//
this.columnHeader6.Text = "Last Read";
this.columnHeader6.Width = 70;
//
// columnHeader3
//
this.columnHeader3.Text = "Writes";
this.columnHeader3.Width = 70;
//
// columnHeader7
//
this.columnHeader7.Text = "Last Write";
this.columnHeader7.Width = 70;
//
// columnHeader4
//
this.columnHeader4.Text = "Executes";
this.columnHeader4.Width = 70;
//
// columnHeader8
//
this.columnHeader8.Text = "Last Exec";
this.columnHeader8.Width = 70;
//
// columnHeader5
//
this.columnHeader5.Text = "Uninit Read";
this.columnHeader5.Width = 70;
//
// toolTip
//
this.toolTip.AutomaticDelay = 0;
this.toolTip.AutoPopDelay = 32700;
this.toolTip.InitialDelay = 10;
this.toolTip.ReshowDelay = 10;
//
// ctrlMemoryAccessCounters
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel1);
this.Margin = new System.Windows.Forms.Padding(0);
this.Name = "ctrlMemoryAccessCounters";
this.Size = new System.Drawing.Size(641, 343);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picWatchHelp)).EndInit();
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label lblViewMemoryType;
private ctrlMemoryType cboMemoryType;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Button btnReset;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.ToolTip toolTip;
private Mesen.GUI.Controls.DoubleBufferedListView lstCounters;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader3;
private System.Windows.Forms.ColumnHeader columnHeader4;
private System.Windows.Forms.ColumnHeader columnHeader5;
private System.Windows.Forms.ColumnHeader columnHeader6;
private System.Windows.Forms.ColumnHeader columnHeader7;
private System.Windows.Forms.ColumnHeader columnHeader8;
private System.Windows.Forms.Label lblHint;
private System.Windows.Forms.PictureBox picWatchHelp;
private System.Windows.Forms.ColumnHeader columnHeader9;
}
}

View file

@ -0,0 +1,190 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Controls;
using Mesen.GUI.Forms;
using Mesen.GUI.Config;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlMemoryAccessCounters : BaseControl
{
private bool _sorting = false;
private UInt64 _masterClock = 0;
private AddressCounters[] _counts = new AddressCounters[0];
private AddressCounters[] _newCounts = new AddressCounters[0];
private SnesMemoryType _memoryType = SnesMemoryType.PrgRom;
private SortType _sortType = SortType.Address;
public ctrlMemoryAccessCounters()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!IsDesignMode) {
InitMemoryTypeDropdown();
}
}
public void InitMemoryTypeDropdown()
{
cboMemoryType.InitMemoryTypeDropdown(excludeCpuMemory: true);
UpdateMemoryType();
}
public void RefreshData()
{
if(_sorting) {
return;
}
DebugApi.GetMemoryAccessCounts(_memoryType, ref _newCounts);
DebugState state = DebugApi.GetState();
_masterClock = state.MasterClock;
_sorting = true;
Task.Run(() => {
switch(_sortType) {
case SortType.Address: break;
case SortType.Value: break;
case SortType.Read: Array.Sort(_newCounts, new SortReadComparer()); break;
case SortType.ReadStamp: Array.Sort(_newCounts, new SortReadStampComparer()); break;
case SortType.Write: Array.Sort(_newCounts, new SortWriteComparer()); break;
case SortType.WriteStamp: Array.Sort(_newCounts, new SortWriteStampComparer()); break;
case SortType.Exec: Array.Sort(_newCounts, new SortExecComparer()); break;
case SortType.ExecStamp: Array.Sort(_newCounts, new SortExecStampComparer()); break;
case SortType.UninitRead: Array.Sort(_newCounts, new SortUninitComparer()); break;
}
AddressCounters[] counts = _counts;
_counts = _newCounts;
_newCounts = counts;
this.BeginInvoke((Action)(() => {
_sorting = false;
lstCounters.BeginUpdate();
lstCounters.VirtualListSize = _counts.Length;
lstCounters.EndUpdate();
}));
});
}
private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMemoryType();
}
private void UpdateMemoryType()
{
_memoryType = cboMemoryType.GetEnumValue<SnesMemoryType>();
RefreshData();
}
private void btnReset_Click(object sender, EventArgs e)
{
DebugApi.ResetMemoryAccessCounts();
RefreshData();
}
private string FormatNumber(UInt64 value)
{
if(value >= 1000000000000) {
return ((double)value / 1000000000000).ToString("0.00") + " T";
} else if(value >= 1000000000) {
return ((double)value / 1000000000).ToString("0.00") + " G";
} else if(value >= 1000000) {
return ((double)value / 1000000).ToString("0.00") + " M";
} else if(value >= 1000) {
return ((double)value / 1000).ToString("0.00") + " K";
}
return value.ToString();
}
private void lstCounters_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
{
AddressCounters counts = _counts[e.ItemIndex];
ListViewItem item = new ListViewItem("$" + counts.Address.ToString("X4"));
item.Selected = false;
item.Focused = false;
item.SubItems.Add("$" + DebugApi.GetMemoryValue(_memoryType, counts.Address).ToString("X2"));
item.SubItems.Add(FormatNumber(counts.ReadCount));
item.SubItems.Add(counts.ReadStamp > 0 ? FormatNumber(_masterClock - counts.ReadStamp) : "n/a");
item.SubItems.Add(FormatNumber(counts.WriteCount));
item.SubItems.Add(counts.WriteStamp > 0 ? FormatNumber(_masterClock - counts.WriteStamp) : "n/a");
item.SubItems.Add(FormatNumber(counts.ExecCount));
item.SubItems.Add(counts.ExecStamp > 0 ? FormatNumber(_masterClock - counts.ExecStamp) : "n/a");
item.SubItems.Add(counts.UninitRead != 0 ? "☑" : "☐");
if(counts.ReadCount == 0 && counts.WriteCount == 0 && counts.ExecCount == 0) {
item.ForeColor = Color.Gray;
}
e.Item = item;
}
public void GoToAddress()
{
GoToAddress address = new GoToAddress();
address.Address = 0;
using(frmGoToLine frm = new frmGoToLine(address, 8)) {
frm.StartPosition = FormStartPosition.Manual;
Point topLeft = this.PointToScreen(new Point(0, 0));
frm.Location = new Point(topLeft.X + (this.Width - frm.Width) / 2, topLeft.Y + (this.Height - frm.Height) / 2);
if(frm.ShowDialog() == DialogResult.OK) {
int index = -1;
for(int i = 0; i < _counts.Length; i++) {
if(_counts[i].Address == address.Address) {
index = i;
break;
}
}
if(index >= 0) {
lstCounters.EnsureVisible(index);
lstCounters.SelectedIndices.Clear();
lstCounters.SelectedIndices.Add(index);
}
}
}
}
private void lstCounters_ColumnClick(object sender, ColumnClickEventArgs e)
{
_sortType = (SortType)e.Column;
RefreshData();
}
private class SortReadComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.ReadCount.CompareTo(b.ReadCount) * -2 + a.Address.CompareTo(b.Address); } }
private class SortReadStampComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.ReadStamp.CompareTo(b.ReadStamp) * -2 + a.Address.CompareTo(b.Address); } }
private class SortWriteComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.WriteCount.CompareTo(b.WriteCount) * -2 + a.Address.CompareTo(b.Address); } }
private class SortWriteStampComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.WriteStamp.CompareTo(b.WriteStamp) * -2 + a.Address.CompareTo(b.Address); } }
private class SortExecComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.ExecCount.CompareTo(b.ExecCount) * -2 + a.Address.CompareTo(b.Address); } }
private class SortExecStampComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.ExecStamp.CompareTo(b.ExecStamp) * -2 + a.Address.CompareTo(b.Address); } }
private class SortUninitComparer : IComparer<AddressCounters> { public int Compare(AddressCounters a, AddressCounters b) { return a.UninitRead.CompareTo(b.UninitRead) * -2 + a.Address.CompareTo(b.Address); } }
private enum SortType
{
Address = 0,
Value,
Read,
ReadStamp,
Write,
WriteStamp,
Exec,
ExecStamp,
UninitRead,
}
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -34,7 +34,7 @@
this.ctrlHexViewer = new Mesen.GUI.Debugger.Controls.ctrlHexViewer();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.lblViewMemoryType = new System.Windows.Forms.Label();
this.cboMemoryType = new Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator();
this.cboMemoryType = new Mesen.GUI.Debugger.Controls.ctrlMemoryType();
this.menuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuImport = new System.Windows.Forms.ToolStripMenuItem();
@ -101,9 +101,16 @@
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFindPrev = new System.Windows.Forms.ToolStripMenuItem();
this.pnlMain = new System.Windows.Forms.Panel();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgMemoryViewer = new System.Windows.Forms.TabPage();
this.tpgAccessCounters = new System.Windows.Forms.TabPage();
this.ctrlMemoryAccessCounters = new Mesen.GUI.Debugger.Controls.ctrlMemoryAccessCounters();
this.flowLayoutPanel1.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.pnlMain.SuspendLayout();
this.tabMain.SuspendLayout();
this.tpgMemoryViewer.SuspendLayout();
this.tpgAccessCounters.SuspendLayout();
this.SuspendLayout();
//
// ctrlHexViewer
@ -113,7 +120,7 @@
this.ctrlHexViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlHexViewer.Margin = new System.Windows.Forms.Padding(0);
this.ctrlHexViewer.Name = "ctrlHexViewer";
this.ctrlHexViewer.Size = new System.Drawing.Size(614, 369);
this.ctrlHexViewer.Size = new System.Drawing.Size(606, 343);
this.ctrlHexViewer.TabIndex = 0;
this.ctrlHexViewer.TextZoom = 100;
this.ctrlHexViewer.RequiredWidthChanged += new System.EventHandler(this.ctrlHexViewer_RequiredWidthChanged);
@ -645,27 +652,27 @@
//
this.mnuGoToAll.Image = global::Mesen.GUI.Properties.Resources.Find;
this.mnuGoToAll.Name = "mnuGoToAll";
this.mnuGoToAll.Size = new System.Drawing.Size(180, 22);
this.mnuGoToAll.Size = new System.Drawing.Size(145, 22);
this.mnuGoToAll.Text = "Go to All";
this.mnuGoToAll.Click += new System.EventHandler(this.mnuGoToAll_Click);
//
// mnuGoTo
//
this.mnuGoTo.Name = "mnuGoTo";
this.mnuGoTo.Size = new System.Drawing.Size(180, 22);
this.mnuGoTo.Size = new System.Drawing.Size(145, 22);
this.mnuGoTo.Text = "Go To...";
this.mnuGoTo.Click += new System.EventHandler(this.mnuGoTo_Click);
//
// toolStripMenuItem14
//
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
this.toolStripMenuItem14.Size = new System.Drawing.Size(177, 6);
this.toolStripMenuItem14.Size = new System.Drawing.Size(142, 6);
//
// mnuFind
//
this.mnuFind.Image = global::Mesen.GUI.Properties.Resources.Find;
this.mnuFind.Name = "mnuFind";
this.mnuFind.Size = new System.Drawing.Size(180, 22);
this.mnuFind.Size = new System.Drawing.Size(145, 22);
this.mnuFind.Text = "Find...";
this.mnuFind.Click += new System.EventHandler(this.mnuFind_Click);
//
@ -673,7 +680,7 @@
//
this.mnuFindNext.Image = global::Mesen.GUI.Properties.Resources.NextArrow;
this.mnuFindNext.Name = "mnuFindNext";
this.mnuFindNext.Size = new System.Drawing.Size(180, 22);
this.mnuFindNext.Size = new System.Drawing.Size(145, 22);
this.mnuFindNext.Text = "Find Next";
this.mnuFindNext.Click += new System.EventHandler(this.mnuFindNext_Click);
//
@ -681,7 +688,7 @@
//
this.mnuFindPrev.Image = global::Mesen.GUI.Properties.Resources.PreviousArrow;
this.mnuFindPrev.Name = "mnuFindPrev";
this.mnuFindPrev.Size = new System.Drawing.Size(180, 22);
this.mnuFindPrev.Size = new System.Drawing.Size(145, 22);
this.mnuFindPrev.Text = "Find Previous";
this.mnuFindPrev.Click += new System.EventHandler(this.mnuFindPrev_Click);
//
@ -690,31 +697,75 @@
this.pnlMain.Controls.Add(this.flowLayoutPanel1);
this.pnlMain.Controls.Add(this.ctrlHexViewer);
this.pnlMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlMain.Location = new System.Drawing.Point(0, 24);
this.pnlMain.Location = new System.Drawing.Point(0, 0);
this.pnlMain.Margin = new System.Windows.Forms.Padding(0);
this.pnlMain.Name = "pnlMain";
this.pnlMain.Size = new System.Drawing.Size(614, 369);
this.pnlMain.Size = new System.Drawing.Size(606, 343);
this.pnlMain.TabIndex = 4;
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgMemoryViewer);
this.tabMain.Controls.Add(this.tpgAccessCounters);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 24);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(614, 369);
this.tabMain.TabIndex = 5;
this.tabMain.SelectedIndexChanged += new System.EventHandler(this.tabMain_SelectedIndexChanged);
//
// tpgMemoryViewer
//
this.tpgMemoryViewer.Controls.Add(this.pnlMain);
this.tpgMemoryViewer.Location = new System.Drawing.Point(4, 22);
this.tpgMemoryViewer.Name = "tpgMemoryViewer";
this.tpgMemoryViewer.Size = new System.Drawing.Size(606, 343);
this.tpgMemoryViewer.TabIndex = 0;
this.tpgMemoryViewer.Text = "Memory Viewer";
this.tpgMemoryViewer.UseVisualStyleBackColor = true;
//
// tpgAccessCounters
//
this.tpgAccessCounters.Controls.Add(this.ctrlMemoryAccessCounters);
this.tpgAccessCounters.Location = new System.Drawing.Point(4, 22);
this.tpgAccessCounters.Name = "tpgAccessCounters";
this.tpgAccessCounters.Size = new System.Drawing.Size(606, 343);
this.tpgAccessCounters.TabIndex = 1;
this.tpgAccessCounters.Text = "Access Counters";
this.tpgAccessCounters.UseVisualStyleBackColor = true;
//
// ctrlMemoryAccessCounters
//
this.ctrlMemoryAccessCounters.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlMemoryAccessCounters.Location = new System.Drawing.Point(0, 0);
this.ctrlMemoryAccessCounters.Margin = new System.Windows.Forms.Padding(0);
this.ctrlMemoryAccessCounters.Name = "ctrlMemoryAccessCounters";
this.ctrlMemoryAccessCounters.Size = new System.Drawing.Size(606, 343);
this.ctrlMemoryAccessCounters.TabIndex = 0;
//
// frmMemoryTools
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(614, 393);
this.Controls.Add(this.pnlMain);
this.Controls.Add(this.tabMain);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.MinimumSize = new System.Drawing.Size(429, 337);
this.Name = "frmMemoryTools";
this.Text = "Memory Tools";
this.Controls.SetChildIndex(this.menuStrip1, 0);
this.Controls.SetChildIndex(this.pnlMain, 0);
this.Controls.SetChildIndex(this.tabMain, 0);
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.pnlMain.ResumeLayout(false);
this.pnlMain.PerformLayout();
this.tabMain.ResumeLayout(false);
this.tpgMemoryViewer.ResumeLayout(false);
this.tpgAccessCounters.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@ -725,7 +776,7 @@
private Controls.ctrlHexViewer ctrlHexViewer;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Label lblViewMemoryType;
private Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator cboMemoryType;
private Mesen.GUI.Debugger.Controls.ctrlMemoryType cboMemoryType;
private Mesen.GUI.Controls.ctrlMesenMenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuFind;
@ -792,5 +843,9 @@
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem14;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightBreakpoints;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightCurrentRowColumn;
private System.Windows.Forms.TabControl tabMain;
private System.Windows.Forms.TabPage tpgMemoryViewer;
private System.Windows.Forms.TabPage tpgAccessCounters;
private Controls.ctrlMemoryAccessCounters ctrlMemoryAccessCounters;
}
}

View file

@ -62,16 +62,11 @@ namespace Mesen.GUI.Debugger
this.ctrlHexViewer.TextZoom = config.TextZoom;
this.ctrlHexViewer.BaseFont = new Font(config.FontFamily, config.FontSize, config.FontStyle);
//TODO this.ctrlMemoryAccessCounters.BaseFont = new Font(config.FontFamily, config.FontSize, config.FontStyle);
//TODO this.ctrlMemoryAccessCounters.TextZoom = config.TextZoom;
this.UpdateFadeOptions();
this.InitTblMappings();
this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked;
//TODO
//this.ctrlHexViewer.MemoryViewer = this;
UpdateImportButton();
InitMemoryTypeDropdown(true);
@ -136,55 +131,7 @@ namespace Mesen.GUI.Debugger
private void InitMemoryTypeDropdown(bool forStartup)
{
cboMemoryType.SelectedIndexChanged -= this.cboMemoryType_SelectedIndexChanged;
SnesMemoryType originalValue = forStartup ? ConfigManager.Config.Debug.HexEditor.MemoryType : cboMemoryType.GetEnumValue<SnesMemoryType>();
cboMemoryType.BeginUpdate();
cboMemoryType.Items.Clear();
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CpuMemory));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SpcMemory));
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
if(DebugApi.GetMemorySize(SnesMemoryType.SaveRam) > 0) {
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SaveRam));
}
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.VideoRam));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CGRam));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SpriteRam));
if(DebugApi.GetMemorySize(SnesMemoryType.DspProgramRom) > 0) {
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.DspProgramRom));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.DspDataRom));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.DspDataRam));
}
if(DebugApi.GetMemorySize(SnesMemoryType.Sa1InternalRam) > 0) {
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Sa1Memory));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Sa1InternalRam));
}
if(DebugApi.GetMemorySize(SnesMemoryType.GsuWorkRam) > 0) {
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuMemory));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.GsuWorkRam));
}
if(DebugApi.GetMemorySize(SnesMemoryType.Cx4DataRam) > 0) {
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.Cx4DataRam));
}
cboMemoryType.SelectedIndex = 0;
cboMemoryType.SetEnumValue(originalValue);
cboMemoryType.SelectedIndexChanged += this.cboMemoryType_SelectedIndexChanged;
cboMemoryType.EndUpdate();
cboMemoryType.InitMemoryTypeDropdown(forStartup ? (SnesMemoryType?)ConfigManager.Config.Debug.HexEditor.MemoryType : null);
UpdateMemoryType();
}
@ -209,6 +156,7 @@ namespace Mesen.GUI.Debugger
{
cboMemoryType.SetEnumValue(memoryType);
ctrlHexViewer.GoToAddress(address);
tabMain.SelectedTab = tpgMemoryViewer;
}
public void GoToDestination(GoToDestination dest)
@ -273,7 +221,7 @@ namespace Mesen.GUI.Debugger
}
this.InitTblMappings();
this.InitMemoryTypeDropdown(false);
//TODO ctrlMemoryAccessCounters.InitMemoryTypeDropdown();
ctrlMemoryAccessCounters.InitMemoryTypeDropdown();
}));
this.UpdateFlags();
break;
@ -287,7 +235,7 @@ namespace Mesen.GUI.Debugger
}
DateTime now = DateTime.Now;
if(!_updating && ConfigManager.Config.Debug.HexEditor.AutoRefresh && (now - _lastUpdate).Milliseconds >= refreshDelay) {
if(!_updating && ConfigManager.Config.Debug.HexEditor.AutoRefresh && (now - _lastUpdate).Milliseconds >= refreshDelay*3) {
_lastUpdate = now;
_updating = true;
this.BeginInvoke((Action)(() => {
@ -341,8 +289,12 @@ namespace Mesen.GUI.Debugger
return;
}
this.UpdateByteColorProvider();
this.ctrlHexViewer.RefreshData(_memoryType);
if(tabMain.SelectedTab == tpgAccessCounters) {
ctrlMemoryAccessCounters.RefreshData();
} else if(tabMain.SelectedTab == tpgMemoryViewer) {
UpdateByteColorProvider();
ctrlHexViewer.RefreshData(_memoryType);
}
}
private void mnuFind_Click(object sender, EventArgs e)
@ -362,7 +314,11 @@ namespace Mesen.GUI.Debugger
private void mnuGoTo_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.GoToAddress();
if(tabMain.SelectedTab == tpgMemoryViewer) {
ctrlHexViewer.GoToAddress();
} else if(tabMain.SelectedTab == tpgAccessCounters) {
ctrlMemoryAccessCounters.GoToAddress();
}
}
private void mnuGoToAll_Click(object sender, EventArgs e)
@ -373,19 +329,16 @@ namespace Mesen.GUI.Debugger
private void mnuIncreaseFontSize_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.TextZoom += 10;
//TODO this.ctrlMemoryAccessCounters.TextZoom += 10;
}
private void mnuDecreaseFontSize_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.TextZoom -= 10;
//TODO this.ctrlMemoryAccessCounters.TextZoom -= 10;
}
private void mnuResetFontSize_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.TextZoom = 100;
//TODO this.ctrlMemoryAccessCounters.TextZoom = 100;
}
private void mnuClose_Click(object sender, EventArgs e)
@ -438,7 +391,7 @@ namespace Mesen.GUI.Debugger
private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
{
this.RefreshData();
RefreshData();
}
private void ctrlHexViewer_RequiredWidthChanged(object sender, EventArgs e)
@ -634,7 +587,6 @@ namespace Mesen.GUI.Debugger
private void mnuSelectFont_Click(object sender, EventArgs e)
{
ctrlHexViewer.BaseFont = FontDialogHelper.SelectFont(ctrlHexViewer.BaseFont);
//TODO ctrlMemoryAccessCounters.BaseFont = ctrlHexViewer.BaseFont;
}
private void mnuByteEditingMode_CheckedChanged(object sender, EventArgs e)

View file

@ -48,9 +48,6 @@ namespace Mesen.GUI.Debugger.Controls
public void RefreshList()
{
int? topItemIndex = lstFunctions.TopItem?.Index;
int selectedIndex = lstFunctions.SelectedIndices.Count > 0 ? lstFunctions.SelectedIndices[0] : -1;
lstFunctions.BeginUpdate();
_functions = _newData;
@ -62,15 +59,6 @@ namespace Mesen.GUI.Debugger.Controls
Array.Sort(_functions, new ListComparer(this, _sortColumn, _sortOrder));
lstFunctions.VirtualListSize = _functions.Length;
if(topItemIndex.HasValue && _functions.Length > topItemIndex.Value) {
lstFunctions.TopItem = lstFunctions.Items[topItemIndex.Value];
}
if(selectedIndex >= 0 && _functions.Length > selectedIndex) {
lstFunctions.Items[selectedIndex].Selected = true;
lstFunctions.Items[selectedIndex].Focused = true;
}
lstFunctions.EndUpdate();
}

View file

@ -145,6 +145,14 @@ namespace Mesen.GUI
return profilerData;
}
[DllImport(DllPath)] public static extern void ResetMemoryAccessCounts();
public static void GetMemoryAccessCounts(SnesMemoryType type, ref AddressCounters[] counters)
{
int size = DebugApi.GetMemorySize(type);
Array.Resize(ref counters, size);
DebugApi.GetMemoryAccessCountsWrapper(0, (uint)size, type, counters);
}
[DllImport(DllPath, EntryPoint = "GetMemoryAccessCounts")] private static extern void GetMemoryAccessCountsWrapper(UInt32 offset, UInt32 length, SnesMemoryType type, [In,Out]AddressCounters[] counts);
public static AddressCounters[] GetMemoryAccessCounts(UInt32 offset, UInt32 length, SnesMemoryType type)
{
@ -268,13 +276,17 @@ namespace Mesen.GUI
}
}
[StructLayout(LayoutKind.Sequential)]
public struct AddressCounters
{
public UInt32 Address;
public UInt32 ReadCount;
public UInt64 ReadStamp;
public byte UninitRead;
public UInt32 WriteCount;
public bool UninitRead;
public UInt64 WriteStamp;
public UInt32 ExecCount;
public UInt64 ExecStamp;
}
@ -578,5 +590,5 @@ namespace Mesen.GUI
public UInt64 MinCycles;
public UInt64 MaxCycles;
public AddressInfo Address;
};
}
}

View file

@ -279,6 +279,15 @@
<Compile Include="Debugger\Config\RegisterViewerConfig.cs" />
<Compile Include="Debugger\Config\TileViewerConfig.cs" />
<Compile Include="Debugger\Config\TilemapViewerConfig.cs" />
<Compile Include="Debugger\Controls\ctrlMemoryType.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\MemoryTools\ctrlMemoryAccessCounters.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\MemoryTools\ctrlMemoryAccessCounters.Designer.cs">
<DependentUpon>ctrlMemoryAccessCounters.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlPanel.cs">
<SubType>Component</SubType>
</Compile>
@ -1014,6 +1023,9 @@
<EmbeddedResource Include="Debugger\Controls\ctrlCallstack.resx">
<DependentUpon>ctrlCallstack.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\MemoryTools\ctrlMemoryAccessCounters.resx">
<DependentUpon>ctrlMemoryAccessCounters.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlPpuStatus.resx">
<DependentUpon>ctrlPpuStatus.cs</DependentUpon>
</EmbeddedResource>