Debugger: Break and open trace logger on BRK instruction
This commit is contained in:
parent
fa36f36314
commit
4bea25ecc7
7 changed files with 165 additions and 10 deletions
|
@ -57,6 +57,12 @@ void Console::Run()
|
|||
void Console::Stop()
|
||||
{
|
||||
_stopFlag = true;
|
||||
|
||||
shared_ptr<Debugger> debugger = _debugger;
|
||||
if(debugger) {
|
||||
debugger->Run();
|
||||
}
|
||||
|
||||
_runLock.WaitForRelease();
|
||||
|
||||
_cpu.reset();
|
||||
|
@ -78,12 +84,12 @@ void Console::LoadRom(VirtualFile romFile, VirtualFile patchFile)
|
|||
|
||||
_cpu.reset(new Cpu(_memoryManager));
|
||||
|
||||
if(_debugger) {
|
||||
//if(_debugger) {
|
||||
//Reset debugger if it was running before
|
||||
auto lock = _debuggerLock.AcquireSafe();
|
||||
_debugger.reset();
|
||||
GetDebugger();
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Console.h"
|
||||
#include "Cpu.h"
|
||||
#include "Ppu.h"
|
||||
#include "NotificationManager.h"
|
||||
#include "CpuTypes.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
#include "TraceLogger.h"
|
||||
|
@ -11,6 +12,7 @@
|
|||
|
||||
Debugger::Debugger(shared_ptr<Console> console)
|
||||
{
|
||||
_console = console;
|
||||
_cpu = console->GetCpu();
|
||||
_ppu = console->GetPpu();
|
||||
_memoryManager = console->GetMemoryManager();
|
||||
|
@ -35,10 +37,18 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_traceLogger->LogEffectiveAddress(_cpu->GetLastOperand());
|
||||
_traceLogger->Log(debugState, disassemblyInfo);
|
||||
|
||||
if(value == 0x00) {
|
||||
//break on BRK
|
||||
_cpuStepCount = 1;
|
||||
}
|
||||
|
||||
if(_cpuStepCount > 0) {
|
||||
_cpuStepCount--;
|
||||
while(_cpuStepCount == 0) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
if(_cpuStepCount == 0) {
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::CodeBreak);
|
||||
while(_cpuStepCount == 0) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ struct DebugState
|
|||
class Debugger
|
||||
{
|
||||
private:
|
||||
shared_ptr<Console> _console;
|
||||
shared_ptr<Cpu> _cpu;
|
||||
shared_ptr<Ppu> _ppu;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
|
|
117
UI/Debugger/DebugWindowManager.cs
Normal file
117
UI/Debugger/DebugWindowManager.cs
Normal file
|
@ -0,0 +1,117 @@
|
|||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public class DebugWindowManager
|
||||
{
|
||||
private static HashSet<Form> _openedWindows = new HashSet<Form>();
|
||||
|
||||
public static List<Form> GetWindows()
|
||||
{
|
||||
return new List<Form>(_openedWindows);
|
||||
}
|
||||
|
||||
public static Form OpenDebugWindow(DebugWindow window)
|
||||
{
|
||||
Form existingWindow = GetExistingSingleInstanceWindow(window);
|
||||
if(existingWindow != null) {
|
||||
existingWindow.BringToFront();
|
||||
if(existingWindow.WindowState == FormWindowState.Minimized) {
|
||||
//Unminimize window if it was minimized
|
||||
existingWindow.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
existingWindow.Focus();
|
||||
return existingWindow;
|
||||
} else {
|
||||
BaseForm frm = null;
|
||||
switch(window) {
|
||||
case DebugWindow.TraceLogger: frm = new frmTraceLogger(); frm.Icon = Properties.Resources.LogWindow; break;
|
||||
case DebugWindow.MemoryTools: frm = new frmMemoryTools(); frm.Icon = Properties.Resources.CheatCode; break;
|
||||
}
|
||||
_openedWindows.Add(frm);
|
||||
frm.FormClosed += Debugger_FormClosed;
|
||||
frm.Show();
|
||||
return frm;
|
||||
}
|
||||
}
|
||||
|
||||
private static frmMemoryTools OpenMemoryViewer()
|
||||
{
|
||||
frmMemoryTools frm = GetMemoryViewer();
|
||||
if(frm == null) {
|
||||
frm = new frmMemoryTools();
|
||||
frm.Icon = Properties.Resources.CheatCode;
|
||||
frm.FormClosed += Debugger_FormClosed;
|
||||
_openedWindows.Add(frm);
|
||||
} else {
|
||||
if(frm.WindowState == FormWindowState.Minimized) {
|
||||
//Unminimize window if it was minimized
|
||||
frm.WindowState = FormWindowState.Normal;
|
||||
}
|
||||
frm.BringToFront();
|
||||
}
|
||||
frm.Show();
|
||||
return frm;
|
||||
}
|
||||
|
||||
public static frmMemoryTools GetMemoryViewer()
|
||||
{
|
||||
return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmMemoryTools)) as frmMemoryTools;
|
||||
}
|
||||
|
||||
public static bool HasOpenedWindow
|
||||
{
|
||||
get
|
||||
{
|
||||
return _openedWindows.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CloseAll()
|
||||
{
|
||||
List<Form> openedWindows = new List<Form>(_openedWindows);
|
||||
foreach(Form frm in openedWindows) {
|
||||
frm.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private static Form GetExistingSingleInstanceWindow(DebugWindow window)
|
||||
{
|
||||
//Only one of each of these windows can be opened at once, check if one is already opened
|
||||
switch(window) {
|
||||
case DebugWindow.TraceLogger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmTraceLogger));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void CleanupDebugger()
|
||||
{
|
||||
if(_openedWindows.Count == 0) {
|
||||
//All windows have been closed, disable debugger
|
||||
//TODO
|
||||
//DebugWorkspaceManager.SaveWorkspace();
|
||||
//DebugWorkspaceManager.Clear();
|
||||
//DebugApi.ReleaseDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
private static void Debugger_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
_openedWindows.Remove((Form)sender);
|
||||
CleanupDebugger();
|
||||
}
|
||||
}
|
||||
|
||||
public enum DebugWindow
|
||||
{
|
||||
MemoryTools,
|
||||
TraceLogger
|
||||
}
|
||||
}
|
|
@ -78,7 +78,7 @@ namespace Mesen.GUI.Debugger
|
|||
InitMemoryTypeDropdown(true);
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += _notifListener_OnNotification;
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
this.mnuShowCharacters.CheckedChanged += this.mnuShowCharacters_CheckedChanged;
|
||||
this.mnuIgnoreRedundantWrites.CheckedChanged += mnuIgnoreRedundantWrites_CheckedChanged;
|
||||
|
@ -230,7 +230,7 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
}*/
|
||||
|
||||
private void _notifListener_OnNotification(NotificationEventArgs e)
|
||||
private void OnNotificationReceived(NotificationEventArgs e)
|
||||
{
|
||||
switch(e.NotificationType) {
|
||||
case ConsoleNotificationType.CodeBreak:
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace Mesen.GUI.Forms
|
|||
{
|
||||
public partial class frmMain : BaseForm
|
||||
{
|
||||
private NotificationListener _notifListener;
|
||||
|
||||
public frmMain(string[] args)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
@ -27,26 +29,44 @@ namespace Mesen.GUI.Forms
|
|||
|
||||
EmuApi.InitDll();
|
||||
EmuApi.InitializeEmu(ConfigManager.HomeFolder, Handle, ctrlRenderer.Handle, false, false, false);
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
}
|
||||
|
||||
protected override void OnFormClosing(FormClosingEventArgs e)
|
||||
{
|
||||
base.OnFormClosing(e);
|
||||
|
||||
if(_notifListener != null) {
|
||||
_notifListener.Dispose();
|
||||
_notifListener = null;
|
||||
}
|
||||
|
||||
DebugApi.ResumeExecution();
|
||||
EmuApi.Stop();
|
||||
EmuApi.Release();
|
||||
}
|
||||
|
||||
private void OnNotificationReceived(NotificationEventArgs e)
|
||||
{
|
||||
switch(e.NotificationType) {
|
||||
case ConsoleNotificationType.CodeBreak:
|
||||
this.BeginInvoke((Action)(() => {
|
||||
DebugWindowManager.OpenDebugWindow(DebugWindow.TraceLogger);
|
||||
}));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuTraceLogger_Click(object sender, EventArgs e)
|
||||
{
|
||||
frmTraceLogger frm = new frmTraceLogger();
|
||||
frm.Show();
|
||||
DebugWindowManager.OpenDebugWindow(DebugWindow.TraceLogger);
|
||||
}
|
||||
|
||||
private void mnuMemoryTools_Click(object sender, EventArgs e)
|
||||
{
|
||||
frmMemoryTools frm = new frmMemoryTools();
|
||||
frm.Show();
|
||||
DebugWindowManager.OpenDebugWindow(DebugWindow.MemoryTools);
|
||||
}
|
||||
|
||||
private void mnuStep_Click(object sender, EventArgs e)
|
||||
|
|
|
@ -371,6 +371,7 @@
|
|||
<Compile Include="Debugger\HexBox\TblByteCharConverter.cs" />
|
||||
<Compile Include="Debugger\HexBox\Util.cs" />
|
||||
<Compile Include="Debugger\TblLoader.cs" />
|
||||
<Compile Include="Debugger\DebugWindowManager.cs" />
|
||||
<Compile Include="Forms\BaseConfigForm.Designer.cs">
|
||||
<DependentUpon>BaseConfigForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
|
Loading…
Add table
Reference in a new issue