mirror of
https://github.com/SourMesen/Mesen.git
synced 2025-04-02 10:52:48 -04:00
Debugger - Added callstack
This commit is contained in:
parent
955fd88a36
commit
cb8ec83408
12 changed files with 414 additions and 48 deletions
|
@ -474,14 +474,15 @@ class BaseMapper : public IMemoryHandler, public Snapshotable, public INotificat
|
|||
|
||||
int32_t FromAbsoluteAddress(uint32_t addr)
|
||||
{
|
||||
/*uint32_t page = addr / GetPRGPageSize();
|
||||
for(int i = 0, len = GetPRGSlotCount(); i < len; i++) {
|
||||
if((_prgSlotPages[i] % GetPRGPageCount()) == page) {
|
||||
uint32_t offset = addr - (page * GetPRGPageSize());
|
||||
return GetPRGPageSize() * i + offset + 0x8000;
|
||||
uint8_t* ptrAddress = _prgRom + addr;
|
||||
|
||||
for(int i = 0; i < 256; i++) {
|
||||
uint8_t* pageAddress = _prgPages[i];
|
||||
if(pageAddress != nullptr && ptrAddress >= pageAddress && ptrAddress <= pageAddress + 0xFF) {
|
||||
return (i << 8) + (ptrAddress - pageAddress);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//Address is currently not mapped
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -112,6 +112,24 @@ void Debugger::PrivateCheckBreakpoint(BreakpointType type, uint32_t addr)
|
|||
bool breakDone = false;
|
||||
if(type == BreakpointType::Execute) {
|
||||
_lastInstruction = _memoryManager->DebugRead(addr);
|
||||
|
||||
//Update callstack
|
||||
if(_lastInstruction == 0x60 && !_callstackRelative.empty()) {
|
||||
//RTS
|
||||
_callstackRelative.pop_back();
|
||||
_callstackRelative.pop_back();
|
||||
_callstackAbsolute.pop_back();
|
||||
_callstackAbsolute.pop_back();
|
||||
} else if(_lastInstruction == 0x20 && _callstackRelative.size() < 1022) {
|
||||
//JSR
|
||||
uint16_t targetAddr = _memoryManager->DebugRead(addr + 1) | (_memoryManager->DebugRead(addr + 2) << 8);
|
||||
_callstackRelative.push_back(addr);
|
||||
_callstackRelative.push_back(targetAddr);
|
||||
|
||||
_callstackAbsolute.push_back(_mapper->ToAbsoluteAddress(addr));
|
||||
_callstackAbsolute.push_back(_mapper->ToAbsoluteAddress(targetAddr));
|
||||
}
|
||||
|
||||
if(_stepOut && _lastInstruction == 0x60) {
|
||||
//RTS found, set StepCount to 2 to break on the following instruction
|
||||
Step(2);
|
||||
|
@ -435,4 +453,20 @@ void Debugger::GetPalette(uint32_t* frameBuffer)
|
|||
}
|
||||
VideoDecoder::GetInstance()->DebugDecodeFrame(screenBuffer, frameBuffer, 4*8);
|
||||
delete[] screenBuffer;
|
||||
}
|
||||
|
||||
void Debugger::GetCallstack(int32_t* callstackAbsolute, int32_t* callstackRelative)
|
||||
{
|
||||
for(size_t i = 0, len = _callstackRelative.size(); i < len; i++) {
|
||||
callstackAbsolute[i] = _callstackAbsolute[i];
|
||||
|
||||
int32_t relativeAddr = _callstackRelative[i];
|
||||
if(_mapper->FromAbsoluteAddress(_callstackAbsolute[i]) == -1) {
|
||||
//Mark address as an unmapped memory addr
|
||||
relativeAddr |= 0x10000;
|
||||
}
|
||||
callstackRelative[i] = relativeAddr;
|
||||
}
|
||||
callstackAbsolute[_callstackRelative.size()] = -2;
|
||||
callstackRelative[_callstackRelative.size()] = -2;
|
||||
}
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include <atomic>
|
||||
#include <deque>
|
||||
using std::atomic;
|
||||
using std::deque;
|
||||
|
||||
#include "CPU.h"
|
||||
#include "PPU.h"
|
||||
|
@ -44,6 +46,8 @@ private:
|
|||
vector<shared_ptr<Breakpoint>> _readBreakpoints;
|
||||
vector<shared_ptr<Breakpoint>> _writeBreakpoints;
|
||||
vector<shared_ptr<Breakpoint>> _execBreakpoints;
|
||||
deque<uint32_t> _callstackAbsolute;
|
||||
deque<uint32_t> _callstackRelative;
|
||||
|
||||
SimpleLock _bpLock;
|
||||
SimpleLock _breakLock;
|
||||
|
@ -75,6 +79,8 @@ public:
|
|||
void GetSprites(uint32_t* frameBuffer);
|
||||
void GetPalette(uint32_t* frameBuffer);
|
||||
|
||||
void GetCallstack(int32_t* callstackAbsolute, int32_t* callstackRelative);
|
||||
|
||||
void GetState(DebugState *state);
|
||||
|
||||
void Step(uint32_t count = 1);
|
||||
|
|
|
@ -43,6 +43,11 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
this.ScrollableTextbox.GoToAddress();
|
||||
}
|
||||
|
||||
public void ScrollToLineNumber(int lineNumber)
|
||||
{
|
||||
this.ScrollableTextbox.ScrollToLineNumber(lineNumber);
|
||||
}
|
||||
|
||||
public int GetCurrentLine()
|
||||
{
|
||||
return this.ScrollableTextbox.CurrentLine;
|
||||
|
|
71
GUI.NET/Debugger/Controls/ctrlCallstack.Designer.cs
generated
Normal file
71
GUI.NET/Debugger/Controls/ctrlCallstack.Designer.cs
generated
Normal file
|
@ -0,0 +1,71 @@
|
|||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class ctrlCallstack
|
||||
{
|
||||
/// <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.lstCallstack = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// lstCallstack
|
||||
//
|
||||
this.lstCallstack.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1});
|
||||
this.lstCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lstCallstack.Font = new System.Drawing.Font("Consolas", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.lstCallstack.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
||||
this.lstCallstack.Location = new System.Drawing.Point(0, 0);
|
||||
this.lstCallstack.MultiSelect = false;
|
||||
this.lstCallstack.Name = "lstCallstack";
|
||||
this.lstCallstack.Size = new System.Drawing.Size(324, 125);
|
||||
this.lstCallstack.TabIndex = 1;
|
||||
this.lstCallstack.UseCompatibleStateImageBehavior = false;
|
||||
this.lstCallstack.View = System.Windows.Forms.View.Details;
|
||||
this.lstCallstack.DoubleClick += new System.EventHandler(this.lstCallstack_DoubleClick);
|
||||
//
|
||||
// columnHeader1
|
||||
//
|
||||
this.columnHeader1.Width = 256;
|
||||
//
|
||||
// ctrlCallstack
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.lstCallstack);
|
||||
this.Name = "ctrlCallstack";
|
||||
this.Size = new System.Drawing.Size(324, 125);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ListView lstCallstack;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||
|
||||
}
|
||||
}
|
74
GUI.NET/Debugger/Controls/ctrlCallstack.cs
Normal file
74
GUI.NET/Debugger/Controls/ctrlCallstack.cs
Normal file
|
@ -0,0 +1,74 @@
|
|||
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;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class ctrlCallstack : UserControl
|
||||
{
|
||||
public event EventHandler FunctionSelected;
|
||||
|
||||
private Int32[] _absoluteCallstack;
|
||||
private Int32[] _relativeCallstack;
|
||||
private Int32 _programCounter;
|
||||
|
||||
public ctrlCallstack()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void UpdateCallstack()
|
||||
{
|
||||
InteropEmu.DebugGetCallstack(out _absoluteCallstack, out _relativeCallstack);
|
||||
DebugState state = new DebugState();
|
||||
InteropEmu.DebugGetState(ref state);
|
||||
_programCounter = state.CPU.DebugPC;
|
||||
|
||||
this.lstCallstack.Items.Clear();
|
||||
int subStartAddr = -1;
|
||||
for(int i = 0, len = _relativeCallstack.Length; i < len; i+=2) {
|
||||
int jsrAddr = _relativeCallstack[i];
|
||||
bool unmappedAddress = false;
|
||||
if(subStartAddr >= 0) {
|
||||
unmappedAddress = ((subStartAddr & 0x10000) == 0x10000);
|
||||
if(unmappedAddress) {
|
||||
subStartAddr &= 0xFFFF;
|
||||
jsrAddr &= 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
string startAddr = subStartAddr >= 0 ? subStartAddr.ToString("X4") : "----";
|
||||
if(_relativeCallstack[i] == -2) {
|
||||
break;
|
||||
}
|
||||
subStartAddr = _relativeCallstack[i+1];
|
||||
ListViewItem item = this.lstCallstack.Items.Insert(0, "$" + startAddr + " @ $" + jsrAddr.ToString("X4") + " [$" + _absoluteCallstack[i].ToString("X4") + "]");
|
||||
if(unmappedAddress) {
|
||||
item.ForeColor = Color.Gray;
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
}
|
||||
this.lstCallstack.Items.Insert(0, "$" + subStartAddr.ToString("X4") + " @ $" + _programCounter.ToString("X4"));
|
||||
}
|
||||
|
||||
private void lstCallstack_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(this.lstCallstack.SelectedIndices.Count > 0) {
|
||||
if(this.lstCallstack.SelectedIndices[0] == 0) {
|
||||
this.FunctionSelected(_programCounter, null);
|
||||
} else {
|
||||
Int32 address = _relativeCallstack[(this.lstCallstack.Items.Count - 1 - this.lstCallstack.SelectedIndices[0]) * 2];
|
||||
if(this.FunctionSelected != null) {
|
||||
this.FunctionSelected(address, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
GUI.NET/Debugger/Controls/ctrlCallstack.resx
Normal file
120
GUI.NET/Debugger/Controls/ctrlCallstack.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?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>
|
||||
</root>
|
96
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
96
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
|
@ -41,10 +41,11 @@
|
|||
this.ctrlConsoleStatus = new Mesen.GUI.Debugger.ctrlConsoleStatus();
|
||||
this.ctrlDebuggerCodeSplit = new Mesen.GUI.Debugger.ctrlDebuggerCode();
|
||||
this.tableLayoutPanel10 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.grpBreakpoints = new System.Windows.Forms.GroupBox();
|
||||
this.ctrlBreakpoints = new Mesen.GUI.Debugger.Controls.ctrlBreakpoints();
|
||||
this.grpWatch = new System.Windows.Forms.GroupBox();
|
||||
this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
|
||||
this.grpBreakpoints = new System.Windows.Forms.GroupBox();
|
||||
this.ctrlBreakpoints = new Mesen.GUI.Debugger.Controls.ctrlBreakpoints();
|
||||
this.grpCallstack = new System.Windows.Forms.GroupBox();
|
||||
this.menuStrip = new System.Windows.Forms.MenuStrip();
|
||||
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -72,6 +73,7 @@
|
|||
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.ctrlCallstack = new Mesen.GUI.Debugger.Controls.ctrlCallstack();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
|
@ -79,8 +81,9 @@
|
|||
this.tlpTop.SuspendLayout();
|
||||
this.contextMenuCode.SuspendLayout();
|
||||
this.tableLayoutPanel10.SuspendLayout();
|
||||
this.grpBreakpoints.SuspendLayout();
|
||||
this.grpWatch.SuspendLayout();
|
||||
this.grpBreakpoints.SuspendLayout();
|
||||
this.grpCallstack.SuspendLayout();
|
||||
this.menuStrip.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
|
@ -181,52 +184,28 @@
|
|||
//
|
||||
// tableLayoutPanel10
|
||||
//
|
||||
this.tableLayoutPanel10.ColumnCount = 2;
|
||||
this.tableLayoutPanel10.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel10.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tableLayoutPanel10.Controls.Add(this.grpBreakpoints, 0, 0);
|
||||
this.tableLayoutPanel10.ColumnCount = 3;
|
||||
this.tableLayoutPanel10.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel10.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel10.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33.33333F));
|
||||
this.tableLayoutPanel10.Controls.Add(this.grpWatch, 0, 0);
|
||||
this.tableLayoutPanel10.Controls.Add(this.grpBreakpoints, 1, 0);
|
||||
this.tableLayoutPanel10.Controls.Add(this.grpCallstack, 2, 0);
|
||||
this.tableLayoutPanel10.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel10.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel10.Name = "tableLayoutPanel10";
|
||||
this.tableLayoutPanel10.RowCount = 1;
|
||||
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 162F));
|
||||
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 162F));
|
||||
this.tableLayoutPanel10.Size = new System.Drawing.Size(984, 162);
|
||||
this.tableLayoutPanel10.TabIndex = 0;
|
||||
//
|
||||
// grpBreakpoints
|
||||
//
|
||||
this.grpBreakpoints.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.grpBreakpoints.Controls.Add(this.ctrlBreakpoints);
|
||||
this.grpBreakpoints.Location = new System.Drawing.Point(495, 3);
|
||||
this.grpBreakpoints.Name = "grpBreakpoints";
|
||||
this.grpBreakpoints.Size = new System.Drawing.Size(486, 156);
|
||||
this.grpBreakpoints.TabIndex = 3;
|
||||
this.grpBreakpoints.TabStop = false;
|
||||
this.grpBreakpoints.Text = "Breakpoints";
|
||||
//
|
||||
// ctrlBreakpoints
|
||||
//
|
||||
this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlBreakpoints.Name = "ctrlBreakpoints";
|
||||
this.ctrlBreakpoints.Size = new System.Drawing.Size(480, 137);
|
||||
this.ctrlBreakpoints.TabIndex = 0;
|
||||
this.ctrlBreakpoints.BreakpointChanged += new System.EventHandler(this.ctrlBreakpoints_BreakpointChanged);
|
||||
//
|
||||
// grpWatch
|
||||
//
|
||||
this.grpWatch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.grpWatch.Controls.Add(this.ctrlWatch);
|
||||
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpWatch.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpWatch.Name = "grpWatch";
|
||||
this.grpWatch.Size = new System.Drawing.Size(486, 156);
|
||||
this.grpWatch.Size = new System.Drawing.Size(322, 156);
|
||||
this.grpWatch.TabIndex = 2;
|
||||
this.grpWatch.TabStop = false;
|
||||
this.grpWatch.Text = "Watch";
|
||||
|
@ -236,9 +215,40 @@
|
|||
this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlWatch.Name = "ctrlWatch";
|
||||
this.ctrlWatch.Size = new System.Drawing.Size(480, 137);
|
||||
this.ctrlWatch.Size = new System.Drawing.Size(316, 137);
|
||||
this.ctrlWatch.TabIndex = 0;
|
||||
//
|
||||
// grpBreakpoints
|
||||
//
|
||||
this.grpBreakpoints.Controls.Add(this.ctrlBreakpoints);
|
||||
this.grpBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpBreakpoints.Location = new System.Drawing.Point(331, 3);
|
||||
this.grpBreakpoints.Name = "grpBreakpoints";
|
||||
this.grpBreakpoints.Size = new System.Drawing.Size(322, 156);
|
||||
this.grpBreakpoints.TabIndex = 3;
|
||||
this.grpBreakpoints.TabStop = false;
|
||||
this.grpBreakpoints.Text = "Breakpoints";
|
||||
//
|
||||
// ctrlBreakpoints
|
||||
//
|
||||
this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlBreakpoints.Name = "ctrlBreakpoints";
|
||||
this.ctrlBreakpoints.Size = new System.Drawing.Size(316, 137);
|
||||
this.ctrlBreakpoints.TabIndex = 0;
|
||||
this.ctrlBreakpoints.BreakpointChanged += new System.EventHandler(this.ctrlBreakpoints_BreakpointChanged);
|
||||
//
|
||||
// grpCallstack
|
||||
//
|
||||
this.grpCallstack.Controls.Add(this.ctrlCallstack);
|
||||
this.grpCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpCallstack.Location = new System.Drawing.Point(659, 3);
|
||||
this.grpCallstack.Name = "grpCallstack";
|
||||
this.grpCallstack.Size = new System.Drawing.Size(322, 156);
|
||||
this.grpCallstack.TabIndex = 4;
|
||||
this.grpCallstack.TabStop = false;
|
||||
this.grpCallstack.Text = "Callstack";
|
||||
//
|
||||
// menuStrip
|
||||
//
|
||||
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
|
@ -472,6 +482,15 @@
|
|||
this.mnuMemoryViewer.Text = "Memory Viewer";
|
||||
this.mnuMemoryViewer.Click += new System.EventHandler(this.mnuMemoryViewer_Click);
|
||||
//
|
||||
// ctrlCallstack
|
||||
//
|
||||
this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlCallstack.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlCallstack.Name = "ctrlCallstack";
|
||||
this.ctrlCallstack.Size = new System.Drawing.Size(316, 137);
|
||||
this.ctrlCallstack.TabIndex = 0;
|
||||
this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected);
|
||||
//
|
||||
// frmDebugger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -491,8 +510,9 @@
|
|||
this.tlpTop.ResumeLayout(false);
|
||||
this.contextMenuCode.ResumeLayout(false);
|
||||
this.tableLayoutPanel10.ResumeLayout(false);
|
||||
this.grpBreakpoints.ResumeLayout(false);
|
||||
this.grpWatch.ResumeLayout(false);
|
||||
this.grpBreakpoints.ResumeLayout(false);
|
||||
this.grpCallstack.ResumeLayout(false);
|
||||
this.menuStrip.ResumeLayout(false);
|
||||
this.menuStrip.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
@ -542,5 +562,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuIncreaseFontSize;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuDecreaseFontSize;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuResetFontSize;
|
||||
private System.Windows.Forms.GroupBox grpCallstack;
|
||||
private Controls.ctrlCallstack ctrlCallstack;
|
||||
}
|
||||
}
|
|
@ -91,6 +91,7 @@ namespace Mesen.GUI.Debugger
|
|||
|
||||
ctrlConsoleStatus.UpdateStatus(ref state);
|
||||
ctrlWatch.UpdateWatch();
|
||||
ctrlCallstack.UpdateCallstack();
|
||||
}
|
||||
|
||||
private void ClearActiveStatement()
|
||||
|
@ -242,5 +243,10 @@ namespace Mesen.GUI.Debugger
|
|||
{
|
||||
OpenChildForm(new frmPpuViewer());
|
||||
}
|
||||
|
||||
private void ctrlCallstack_FunctionSelected(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.ScrollToLineNumber((int)sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,6 +109,12 @@
|
|||
<Compile Include="Debugger\Controls\ctrlBreakpoints.Designer.cs">
|
||||
<DependentUpon>ctrlBreakpoints.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlCallstack.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlCallstack.Designer.cs">
|
||||
<DependentUpon>ctrlCallstack.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlPaletteViewer.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -289,6 +295,9 @@
|
|||
<EmbeddedResource Include="Debugger\Controls\ctrlBreakpoints.resx">
|
||||
<DependentUpon>ctrlBreakpoints.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlCallstack.resx">
|
||||
<DependentUpon>ctrlCallstack.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlPaletteViewer.resx">
|
||||
<DependentUpon>ctrlPaletteViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -82,12 +82,8 @@ namespace Mesen.GUI
|
|||
[DllImport(DLLPath)] public static extern IntPtr DebugGetCode();
|
||||
[DllImport(DLLPath)] public static extern Byte DebugGetMemoryValue(UInt32 addr);
|
||||
[DllImport(DLLPath)] public static extern UInt32 DebugGetRelativeAddress(UInt32 addr);
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetMemoryState")] private static extern UInt32 DebugGetMemoryStateWrapper(DebugMemoryType type, IntPtr buffer);
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetNametable")] private static extern void DebugGetNametableWrapper(UInt32 nametableIndex, IntPtr frameBuffer, IntPtr tileData, IntPtr attributeData);
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetChrBank")] private static extern void DebugGetChrBankWrapper(UInt32 bankIndex, IntPtr frameBuffer, Byte palette);
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetSprites")] private static extern void DebugGetSpritesWrapper(IntPtr frameBuffer);
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetPalette")] private static extern void DebugGetPaletteWrapper(IntPtr frameBuffer);
|
||||
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetMemoryState")] private static extern UInt32 DebugGetMemoryStateWrapper(DebugMemoryType type, IntPtr buffer);
|
||||
public static byte[] DebugGetMemoryState(DebugMemoryType type)
|
||||
{
|
||||
byte[] buffer = new byte[10485760]; //10mb buffer
|
||||
|
@ -101,6 +97,7 @@ namespace Mesen.GUI
|
|||
return buffer;
|
||||
}
|
||||
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetNametable")] private static extern void DebugGetNametableWrapper(UInt32 nametableIndex, IntPtr frameBuffer, IntPtr tileData, IntPtr attributeData);
|
||||
public static void DebugGetNametable(int nametableIndex, out byte[] frameData, out byte[] tileData, out byte[] attributeData)
|
||||
{
|
||||
frameData = new byte[256*240*4];
|
||||
|
@ -119,6 +116,7 @@ namespace Mesen.GUI
|
|||
}
|
||||
}
|
||||
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetChrBank")] private static extern void DebugGetChrBankWrapper(UInt32 bankIndex, IntPtr frameBuffer, Byte palette);
|
||||
public static byte[] DebugGetChrBank(int bankIndex, int palette)
|
||||
{
|
||||
byte[] frameData = new byte[128*128*4];
|
||||
|
@ -133,6 +131,7 @@ namespace Mesen.GUI
|
|||
return frameData;
|
||||
}
|
||||
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetSprites")] private static extern void DebugGetSpritesWrapper(IntPtr frameBuffer);
|
||||
public static byte[] DebugGetSprites()
|
||||
{
|
||||
byte[] frameData = new byte[64*128*4];
|
||||
|
@ -147,6 +146,7 @@ namespace Mesen.GUI
|
|||
return frameData;
|
||||
}
|
||||
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetPalette")] private static extern void DebugGetPaletteWrapper(IntPtr frameBuffer);
|
||||
public static byte[] DebugGetPalette()
|
||||
{
|
||||
byte[] frameData = new byte[4*8*4];
|
||||
|
@ -161,6 +161,22 @@ namespace Mesen.GUI
|
|||
return frameData;
|
||||
}
|
||||
|
||||
[DllImport(DLLPath, EntryPoint="DebugGetCallstack")] private static extern void DebugGetCallstackWrapper(IntPtr callstackAbsolute, IntPtr callstackRelative);
|
||||
public static void DebugGetCallstack(out Int32[] callstackAbsolute, out Int32[] callstackRelative)
|
||||
{
|
||||
callstackAbsolute = new Int32[1024];
|
||||
callstackRelative = new Int32[1024];
|
||||
|
||||
GCHandle hAbsolute = GCHandle.Alloc(callstackAbsolute, GCHandleType.Pinned);
|
||||
GCHandle hRelative = GCHandle.Alloc(callstackRelative, GCHandleType.Pinned);
|
||||
try {
|
||||
InteropEmu.DebugGetCallstackWrapper(hAbsolute.AddrOfPinnedObject(), hRelative.AddrOfPinnedObject());
|
||||
} finally {
|
||||
hAbsolute.Free();
|
||||
hRelative.Free();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetROMPath() { return PtrToStringUtf8(InteropEmu.GetROMPathWrapper()); }
|
||||
public static string GetKeyName(UInt32 key) { return PtrToStringUtf8(InteropEmu.GetKeyNameWrapper(key)); }
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ extern "C"
|
|||
DllExport void __stdcall DebugGetSprites(uint32_t *frameBuffer) { _debugger->GetSprites(frameBuffer); }
|
||||
DllExport void __stdcall DebugGetPalette(uint32_t *frameBuffer) { _debugger->GetPalette(frameBuffer); }
|
||||
|
||||
DllExport void __stdcall DebugGetCallstack(int32_t *callstackAbsolute, int32_t *callstackRelative) { _debugger->GetCallstack(callstackAbsolute, callstackRelative); }
|
||||
|
||||
DllExport uint8_t __stdcall DebugGetMemoryValue(uint32_t addr) { return _debugger->GetMemoryValue(addr); }
|
||||
DllExport uint32_t __stdcall DebugGetRelativeAddress(uint32_t addr) { return _debugger->GetRelativeAddress(addr); }
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue