Refactor ITraceable to work on TraceInfo objects that separate Disassembly and Register information. Make Tracelogger two columns.
This commit is contained in:
parent
01dc05375d
commit
f5e679fa0d
|
@ -31,7 +31,7 @@
|
|||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TraceLogger));
|
||||
this.TracerBox = new System.Windows.Forms.GroupBox();
|
||||
this.TraceView = new BizHawk.Client.EmuHawk.VirtualListView();
|
||||
this.Script = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.Disasm = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.menuStrip1 = new MenuStripEx();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.FileSubMenu = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -50,6 +50,7 @@
|
|||
this.ToWindowRadio = new System.Windows.Forms.RadioButton();
|
||||
this.ClearButton = new System.Windows.Forms.Button();
|
||||
this.LoggingEnabled = new System.Windows.Forms.CheckBox();
|
||||
this.Registers = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.TracerBox.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
|
@ -76,7 +77,8 @@
|
|||
this.TraceView.BlazingFast = false;
|
||||
this.TraceView.CheckBoxes = true;
|
||||
this.TraceView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.Script});
|
||||
this.Disasm,
|
||||
this.Registers});
|
||||
this.TraceView.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.TraceView.FullRowSelect = true;
|
||||
this.TraceView.GridLines = true;
|
||||
|
@ -93,10 +95,10 @@
|
|||
this.TraceView.UseCustomBackground = true;
|
||||
this.TraceView.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// Script
|
||||
// Disasm
|
||||
//
|
||||
this.Script.Text = "Instructions";
|
||||
this.Script.Width = 599;
|
||||
this.Disasm.Text = "Disasm";
|
||||
this.Disasm.Width = 239;
|
||||
//
|
||||
// menuStrip1
|
||||
//
|
||||
|
@ -124,27 +126,27 @@
|
|||
this.toolStripSeparator1,
|
||||
this.ExitMenuItem});
|
||||
this.FileSubMenu.Name = "FileSubMenu";
|
||||
this.FileSubMenu.Size = new System.Drawing.Size(35, 20);
|
||||
this.FileSubMenu.Size = new System.Drawing.Size(37, 20);
|
||||
this.FileSubMenu.Text = "&File";
|
||||
//
|
||||
// SaveLogMenuItem
|
||||
//
|
||||
this.SaveLogMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.SaveAs;
|
||||
this.SaveLogMenuItem.Name = "SaveLogMenuItem";
|
||||
this.SaveLogMenuItem.Size = new System.Drawing.Size(132, 22);
|
||||
this.SaveLogMenuItem.Size = new System.Drawing.Size(134, 22);
|
||||
this.SaveLogMenuItem.Text = "&Save Log";
|
||||
this.SaveLogMenuItem.Click += new System.EventHandler(this.SaveLogMenuItem_Click);
|
||||
//
|
||||
// toolStripSeparator1
|
||||
//
|
||||
this.toolStripSeparator1.Name = "toolStripSeparator1";
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(129, 6);
|
||||
this.toolStripSeparator1.Size = new System.Drawing.Size(131, 6);
|
||||
//
|
||||
// ExitMenuItem
|
||||
//
|
||||
this.ExitMenuItem.Name = "ExitMenuItem";
|
||||
this.ExitMenuItem.ShortcutKeyDisplayString = "Alt+F4";
|
||||
this.ExitMenuItem.Size = new System.Drawing.Size(132, 22);
|
||||
this.ExitMenuItem.Size = new System.Drawing.Size(134, 22);
|
||||
this.ExitMenuItem.Text = "E&xit";
|
||||
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
|
||||
//
|
||||
|
@ -154,7 +156,7 @@
|
|||
this.CopyMenuItem,
|
||||
this.SelectAllMenuItem});
|
||||
this.EditSubMenu.Name = "EditSubMenu";
|
||||
this.EditSubMenu.Size = new System.Drawing.Size(37, 20);
|
||||
this.EditSubMenu.Size = new System.Drawing.Size(39, 20);
|
||||
this.EditSubMenu.Text = "Edit";
|
||||
//
|
||||
// CopyMenuItem
|
||||
|
@ -162,7 +164,7 @@
|
|||
this.CopyMenuItem.Name = "CopyMenuItem";
|
||||
this.CopyMenuItem.ShortcutKeyDisplayString = "";
|
||||
this.CopyMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
|
||||
this.CopyMenuItem.Size = new System.Drawing.Size(156, 22);
|
||||
this.CopyMenuItem.Size = new System.Drawing.Size(164, 22);
|
||||
this.CopyMenuItem.Text = "&Copy";
|
||||
this.CopyMenuItem.Click += new System.EventHandler(this.CopyMenuItem_Click);
|
||||
//
|
||||
|
@ -171,7 +173,7 @@
|
|||
this.SelectAllMenuItem.Name = "SelectAllMenuItem";
|
||||
this.SelectAllMenuItem.ShortcutKeyDisplayString = "";
|
||||
this.SelectAllMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
|
||||
this.SelectAllMenuItem.Size = new System.Drawing.Size(156, 22);
|
||||
this.SelectAllMenuItem.Size = new System.Drawing.Size(164, 22);
|
||||
this.SelectAllMenuItem.Text = "Select &All";
|
||||
this.SelectAllMenuItem.Click += new System.EventHandler(this.SelectAllMenuItem_Click);
|
||||
//
|
||||
|
@ -180,13 +182,13 @@
|
|||
this.OptionsSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.MaxLinesMenuItem});
|
||||
this.OptionsSubMenu.Name = "OptionsSubMenu";
|
||||
this.OptionsSubMenu.Size = new System.Drawing.Size(58, 20);
|
||||
this.OptionsSubMenu.Size = new System.Drawing.Size(61, 20);
|
||||
this.OptionsSubMenu.Text = "&Settings";
|
||||
//
|
||||
// MaxLinesMenuItem
|
||||
//
|
||||
this.MaxLinesMenuItem.Name = "MaxLinesMenuItem";
|
||||
this.MaxLinesMenuItem.Size = new System.Drawing.Size(152, 22);
|
||||
this.MaxLinesMenuItem.Size = new System.Drawing.Size(154, 22);
|
||||
this.MaxLinesMenuItem.Text = "&Set Max Lines...";
|
||||
this.MaxLinesMenuItem.Click += new System.EventHandler(this.MaxLinesMenuItem_Click);
|
||||
//
|
||||
|
@ -277,6 +279,11 @@
|
|||
this.LoggingEnabled.UseVisualStyleBackColor = true;
|
||||
this.LoggingEnabled.CheckedChanged += new System.EventHandler(this.LoggingEnabled_CheckedChanged);
|
||||
//
|
||||
// Registers
|
||||
//
|
||||
this.Registers.Text = "Registers";
|
||||
this.Registers.Width = 357;
|
||||
//
|
||||
// TraceLogger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -317,7 +324,7 @@
|
|||
private System.Windows.Forms.Button ClearButton;
|
||||
private System.Windows.Forms.ToolStripMenuItem OptionsSubMenu;
|
||||
private VirtualListView TraceView;
|
||||
public System.Windows.Forms.ColumnHeader Script;
|
||||
public System.Windows.Forms.ColumnHeader Disasm;
|
||||
private System.Windows.Forms.ToolStripMenuItem MaxLinesMenuItem;
|
||||
private System.Windows.Forms.RadioButton ToFileRadio;
|
||||
private System.Windows.Forms.RadioButton ToWindowRadio;
|
||||
|
@ -326,5 +333,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem EditSubMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem CopyMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SelectAllMenuItem;
|
||||
private System.Windows.Forms.ColumnHeader Registers;
|
||||
}
|
||||
}
|
|
@ -1,17 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Client.Common;
|
||||
using BizHawk.Client.EmuHawk.WinFormExtensions;
|
||||
|
||||
|
||||
namespace BizHawk.Client.EmuHawk
|
||||
{
|
||||
public partial class TraceLogger : Form, IToolFormAutoConfig
|
||||
|
@ -22,7 +19,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
[ConfigPersist]
|
||||
private int MaxLines { get; set; }
|
||||
|
||||
private readonly List<string> _instructions = new List<string>();
|
||||
private readonly List<TraceInfo> _instructions = new List<TraceInfo>();
|
||||
|
||||
private FileInfo _logFile;
|
||||
|
||||
|
@ -55,7 +52,20 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void TraceView_QueryItemText(int index, int column, out string text)
|
||||
{
|
||||
text = index < _instructions.Count ? _instructions[index] : string.Empty;
|
||||
text = string.Empty;
|
||||
if (index < _instructions.Count)
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case 0:
|
||||
text = _instructions[index].Disassembly;
|
||||
break;
|
||||
case 1:
|
||||
text = _instructions[index].RegisterInfo;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TraceLogger_Load(object sender, EventArgs e)
|
||||
|
@ -80,11 +90,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
public void FastUpdate()
|
||||
{
|
||||
// never skip instructions when tracelogging!
|
||||
// TODO: get instructions, but don't draw on screen
|
||||
UpdateValues();
|
||||
}
|
||||
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
ClearList();
|
||||
|
@ -99,21 +108,47 @@ namespace BizHawk.Client.EmuHawk
|
|||
SetTracerBoxTitle();
|
||||
}
|
||||
|
||||
// TODO: LogToFile and DumpListTODisk have a lot of repeated code
|
||||
private void LogToFile()
|
||||
{
|
||||
using (var sw = new StreamWriter(_logFile.FullName, true))
|
||||
var todo = Tracer.TakeContents();
|
||||
if (todo.Any())
|
||||
{
|
||||
sw.Write(Tracer.TakeContents());
|
||||
using (var sw = new StreamWriter(_logFile.FullName, true))
|
||||
{
|
||||
int pad = todo.Max(i => i.Disassembly.Length) + 4;
|
||||
|
||||
foreach (var instruction in todo)
|
||||
{
|
||||
sw.WriteLine(instruction.Disassembly.PadRight(pad)
|
||||
+ instruction.RegisterInfo
|
||||
);
|
||||
}
|
||||
|
||||
sw.Write(Tracer.TakeContents());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DumpListToDisk(FileSystemInfo file)
|
||||
{
|
||||
using (var sw = new StreamWriter(file.FullName))
|
||||
{
|
||||
int pad = _instructions.Max(i => i.Disassembly.Length) + 4;
|
||||
|
||||
foreach (var instruction in _instructions)
|
||||
{
|
||||
sw.WriteLine(instruction.Disassembly.PadRight(pad)
|
||||
+ instruction.RegisterInfo
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LogToWindow()
|
||||
{
|
||||
var instructions = Tracer.TakeContents().Split('\n');
|
||||
if (!string.IsNullOrWhiteSpace(instructions[0]))
|
||||
{
|
||||
_instructions.AddRange(instructions);
|
||||
}
|
||||
_instructions.AddRange(Tracer.TakeContents());
|
||||
|
||||
|
||||
if (_instructions.Count >= MaxLines)
|
||||
{
|
||||
|
@ -190,19 +225,6 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
private void DumpListToDisk(FileSystemInfo file)
|
||||
{
|
||||
using (var sw = new StreamWriter(file.FullName))
|
||||
{
|
||||
foreach (var instruction in _instructions)
|
||||
{
|
||||
sw.WriteLine(instruction
|
||||
.Replace("\r", string.Empty)
|
||||
.Replace("\n", string.Empty));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Events
|
||||
|
||||
#region Menu Items
|
||||
|
@ -231,10 +253,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
var blob = new StringBuilder();
|
||||
foreach (int index in indices)
|
||||
{
|
||||
if (blob.Length != 0) blob.AppendLine();
|
||||
blob.Append(_instructions[index]
|
||||
.Replace("\r", string.Empty)
|
||||
.Replace("\n", string.Empty) );
|
||||
int pad = _instructions.Max(m => m.Disassembly.Length) + 4;
|
||||
blob.Append(_instructions[index].Disassembly.PadRight(pad))
|
||||
.Append(_instructions[index].RegisterInfo)
|
||||
.AppendLine();
|
||||
}
|
||||
Clipboard.SetDataObject(blob.ToString());
|
||||
}
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace BizHawk.Emulation.Common
|
||||
{
|
||||
public class TraceBuffer : ITraceable
|
||||
{
|
||||
private readonly StringBuilder buffer;
|
||||
private readonly List<TraceInfo> Buffer = new List<TraceInfo>();
|
||||
|
||||
public TraceBuffer()
|
||||
{
|
||||
buffer = new StringBuilder();
|
||||
Header = "Instructions";
|
||||
}
|
||||
|
||||
public string TakeContents()
|
||||
public IEnumerable<TraceInfo> TakeContents()
|
||||
{
|
||||
string s = buffer.ToString();
|
||||
buffer.Clear();
|
||||
return s;
|
||||
var contents = Buffer.ToList();
|
||||
Buffer.Clear();
|
||||
return contents;
|
||||
}
|
||||
|
||||
public string Contents
|
||||
public IEnumerable<TraceInfo> Contents
|
||||
{
|
||||
get { return buffer.ToString(); }
|
||||
get { return Buffer; }
|
||||
}
|
||||
|
||||
public void Put(string content)
|
||||
public void Put(TraceInfo content)
|
||||
{
|
||||
if (Enabled)
|
||||
{
|
||||
buffer.AppendLine(content);
|
||||
Buffer.Add(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
namespace BizHawk.Emulation.Common
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Emulation.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// Allows the cpu to dump trace info to a trace stream
|
||||
|
@ -17,16 +19,19 @@
|
|||
/// <summary>
|
||||
/// The current log of cpu instructions
|
||||
/// </summary>
|
||||
string Contents { get; }
|
||||
IEnumerable<TraceInfo> Contents { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Takes the current log of cpu instructions, when doing so, it will clear the contents from the buffer
|
||||
/// </summary>
|
||||
string TakeContents();
|
||||
IEnumerable<TraceInfo> TakeContents();
|
||||
|
||||
/// <summary>
|
||||
/// Adds contents to the log of cpu instructions
|
||||
/// </summary>
|
||||
void Put(string content);
|
||||
void Put(TraceInfo content);
|
||||
}
|
||||
|
||||
public class TraceInfo
|
||||
{
|
||||
public string Disassembly { get; set; }
|
||||
public string RegisterInfo { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
// Do not modify this file directly! This is GENERATED code.
|
||||
// Please open the CpuCoreGenerator solution and make your modifications there.
|
||||
|
@ -8,7 +9,7 @@ namespace BizHawk.Emulation.Cores.Components.H6280
|
|||
public partial class HuC6280
|
||||
{
|
||||
public bool Debug;
|
||||
public Action<string> Logger;
|
||||
public Action<TraceInfo> Logger;
|
||||
|
||||
public void Execute(int cycles)
|
||||
{
|
||||
|
|
|
@ -262,21 +262,35 @@ namespace BizHawk.Emulation.Cores.Components.H6280
|
|||
return (ushort)(ReadMemory(address) | (ReadMemory(highAddress) << 8));
|
||||
}
|
||||
|
||||
public string State()
|
||||
public TraceInfo State()
|
||||
{
|
||||
int notused;
|
||||
string a = string.Format("{3:X2}:{0:X4} {1:X2} {2} ", PC, ReadMemory(PC), Disassemble(PC, out notused), MPR[PC>>13]).PadRight(41);
|
||||
string b = string.Format("A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}", A, X, Y, P, S, TotalExecutedCycles);
|
||||
string val = a + b + " ";
|
||||
if (FlagN) val = val + "N";
|
||||
if (FlagV) val = val + "V";
|
||||
if (FlagT) val = val + "T";
|
||||
if (FlagB) val = val + "B";
|
||||
if (FlagD) val = val + "D";
|
||||
if (FlagI) val = val + "I";
|
||||
if (FlagZ) val = val + "Z";
|
||||
if (FlagC) val = val + "C";
|
||||
return val;
|
||||
|
||||
return new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format(
|
||||
"{3:X2}:{0:X4} {1:X2} {2} ",
|
||||
PC,
|
||||
ReadMemory(PC),
|
||||
Disassemble(PC, out notused), MPR[PC >> 13]),
|
||||
RegisterInfo = string.Format(
|
||||
"A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5} {6}{7}{8}{9}{10}{11}{12}{13}",
|
||||
A,
|
||||
X,
|
||||
Y,
|
||||
P,
|
||||
S,
|
||||
TotalExecutedCycles,
|
||||
FlagN ? "N" : "",
|
||||
FlagV ? "V" : "",
|
||||
FlagT ? "T" : "",
|
||||
FlagB ? "B" : "",
|
||||
FlagD ? "D" : "",
|
||||
FlagI ? "I" : "",
|
||||
FlagZ ? "Z" : "",
|
||||
FlagC ? "C" : ""
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly byte[] TableNZ =
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
using System;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.M6502
|
||||
{
|
||||
|
@ -551,7 +552,7 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
bool booltemp;
|
||||
int tempint;
|
||||
int lo, hi;
|
||||
public Action<string> TraceCallback;
|
||||
public Action<TraceInfo> TraceCallback;
|
||||
|
||||
void Fetch1()
|
||||
{
|
||||
|
@ -563,7 +564,14 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
if (NMI)
|
||||
{
|
||||
if (TraceCallback != null)
|
||||
TraceCallback("====NMI====");
|
||||
{
|
||||
TraceCallback(new TraceInfo
|
||||
{
|
||||
Disassembly = "====NMI====",
|
||||
RegisterInfo = ""
|
||||
});
|
||||
}
|
||||
|
||||
ea = NMIVector;
|
||||
opcode = VOP_NMI;
|
||||
NMI = false;
|
||||
|
@ -574,7 +582,13 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
else if (IRQ && !my_iflag)
|
||||
{
|
||||
if (TraceCallback != null)
|
||||
TraceCallback("====IRQ====");
|
||||
{
|
||||
TraceCallback(new TraceInfo
|
||||
{
|
||||
Disassembly = "====IRQ====",
|
||||
RegisterInfo = ""
|
||||
});
|
||||
}
|
||||
ea = IRQVector;
|
||||
opcode = VOP_IRQ;
|
||||
mi = 0;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.M6502
|
||||
{
|
||||
|
@ -40,27 +41,40 @@ namespace BizHawk.Emulation.Cores.Components.M6502
|
|||
FlagI = true;
|
||||
}
|
||||
|
||||
public string State(bool disassemble = true)
|
||||
public TraceInfo State(bool disassemble = true)
|
||||
{
|
||||
int notused;
|
||||
string a = string.Format("{0:X4} {1:X2} {2} ", PC, PeekMemory(PC), disassemble ? Disassemble(PC, out notused) : "---").PadRight(30);
|
||||
string b = string.Format("A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}", A, X, Y, P, S, TotalExecutedCycles);
|
||||
string val = a + b + " ";
|
||||
if (FlagN) val = val + "N";
|
||||
if (FlagV) val = val + "V";
|
||||
if (FlagT) val = val + "T";
|
||||
if (FlagB) val = val + "B";
|
||||
if (FlagD) val = val + "D";
|
||||
if (FlagI) val = val + "I";
|
||||
if (FlagZ) val = val + "Z";
|
||||
if (FlagC) val = val + "C";
|
||||
if (!RDY) val = val + "R";
|
||||
return val;
|
||||
|
||||
return new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format(
|
||||
"{0:X4} {1:X2} {2} ",
|
||||
PC,
|
||||
PeekMemory(PC),
|
||||
disassemble ? Disassemble(PC, out notused) : "---"),
|
||||
RegisterInfo = string.Format(
|
||||
"A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5} {6}{7}{8}{9}{10}{11}{12}{13}",
|
||||
A,
|
||||
X,
|
||||
Y,
|
||||
P,
|
||||
S,
|
||||
TotalExecutedCycles,
|
||||
FlagN ? "N" : "",
|
||||
FlagV ? "V" : "",
|
||||
FlagT ? "T" : "",
|
||||
FlagB ? "B" : "",
|
||||
FlagD ? "D" : "",
|
||||
FlagI ? "I" : "",
|
||||
FlagZ ? "Z" : "",
|
||||
FlagC ? "C" : "",
|
||||
!RDY ? "R" : "")
|
||||
};
|
||||
}
|
||||
|
||||
public bool AtStart { get { return opcode == VOP_Fetch1 || Microcode[opcode][mi] >= Uop.End; } }
|
||||
|
||||
public string TraceState()
|
||||
public TraceInfo TraceState()
|
||||
{
|
||||
// only disassemble when we're at the beginning of an opcode
|
||||
return State(AtStart);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Components.Z80
|
||||
|
@ -14,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Components.Z80
|
|||
public int PendingCycles { get { return pendingCycles; } set { pendingCycles = value; } }
|
||||
|
||||
public bool Debug;
|
||||
public Action<string> Logger;
|
||||
public Action<TraceInfo> Logger;
|
||||
|
||||
/// <summary>
|
||||
/// Runs the CPU for a particular number of clock cycles.
|
||||
|
@ -11949,22 +11950,37 @@ namespace BizHawk.Emulation.Cores.Components.Z80
|
|||
// TODO, not super thrilled with the existing Z80 disassembler, lets see if we can find something decent to replace it with
|
||||
Disassembler Disassembler = new Disassembler();
|
||||
|
||||
public string State()
|
||||
public TraceInfo State()
|
||||
{
|
||||
ushort tempPC = RegPC.Word;
|
||||
string a = string.Format("{0:X4} {1:X2} {2} ", RegPC.Word, FetchMemoryWrapper(RegPC.Word), Disassembler.Disassemble(() => ReadMemoryWrapper(tempPC++)).PadRight(41));
|
||||
string b = string.Format("AF:{0:X4} BC:{1:X4} DE:{2:X4} HL:{3:X4} IX:{4:X4} IY:{5:X4} SP:{6:X4} Cy:{7}", RegAF.Word, RegBC.Word, RegDE.Word, RegHL.Word, RegIX.Word, RegIY.Word, RegSP.Word, TotalExecutedCycles);
|
||||
string val = a + b + " ";
|
||||
|
||||
if (RegFlagC) val = val + "C";
|
||||
if (RegFlagN) val = val + "N";
|
||||
if (RegFlagP) val = val + "P";
|
||||
if (RegFlag3) val = val + "3";
|
||||
if (RegFlagH) val = val + "H";
|
||||
if (RegFlag5) val = val + "5";
|
||||
if (RegFlagZ) val = val + "Z";
|
||||
if (RegFlagS) val = val + "S";
|
||||
return val;
|
||||
return new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format(
|
||||
"{0:X4} {1:X2} {2}",
|
||||
RegPC.Word,
|
||||
FetchMemoryWrapper(RegPC.Word),
|
||||
Disassembler.Disassemble(() => ReadMemoryWrapper(tempPC++))),
|
||||
RegisterInfo = string.Format(
|
||||
"AF:{0:X4} BC:{1:X4} DE:{2:X4} HL:{3:X4} IX:{4:X4} IY:{5:X4} SP:{6:X4} Cy:{7} {8}{9}{10}{11}{12}{13}{14}{15}",
|
||||
RegAF.Word,
|
||||
RegBC.Word,
|
||||
RegDE.Word,
|
||||
RegHL.Word,
|
||||
RegIX.Word,
|
||||
RegIY.Word,
|
||||
RegSP.Word,
|
||||
TotalExecutedCycles,
|
||||
RegFlagC ? "C" : "",
|
||||
RegFlagN ? "N" : "",
|
||||
RegFlagP ? "P" : "",
|
||||
RegFlag3 ? "3" : "",
|
||||
RegFlagH ? "H" : "",
|
||||
RegFlag5 ? "5" : "",
|
||||
RegFlagZ ? "Z" : "",
|
||||
RegFlagS ? "S" : ""
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -123,7 +123,7 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
private void StepInto()
|
||||
{
|
||||
if (Tracer.Enabled)
|
||||
_machine.Cpu.TraceCallback = (s) => Tracer.Put(s);
|
||||
_machine.Cpu.TraceCallback = (s) => TracerWrapper(s);
|
||||
else
|
||||
_machine.Cpu.TraceCallback = null;
|
||||
|
||||
|
|
|
@ -140,12 +140,25 @@ namespace BizHawk.Emulation.Cores.Computers.AppleII
|
|||
private bool _nextPressed = false;
|
||||
private bool _prevPressed = false;
|
||||
|
||||
private void TracerWrapper(string[] content)
|
||||
{
|
||||
Tracer.Put(new TraceInfo
|
||||
{
|
||||
Disassembly = content[0],
|
||||
RegisterInfo = content[1]
|
||||
});
|
||||
}
|
||||
|
||||
private void FrameAdv(bool render, bool rendersound)
|
||||
{
|
||||
if (Tracer.Enabled)
|
||||
_machine.Cpu.TraceCallback = (s) => Tracer.Put(s);
|
||||
{
|
||||
_machine.Cpu.TraceCallback = (s) => TracerWrapper(s);
|
||||
}
|
||||
else
|
||||
{
|
||||
_machine.Cpu.TraceCallback = null;
|
||||
}
|
||||
|
||||
if (Controller["Next Disk"] && !_nextPressed)
|
||||
{
|
||||
|
|
|
@ -235,10 +235,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
|
||||
#endregion
|
||||
|
||||
void Trace(string msg)
|
||||
{
|
||||
Tracer.Put(msg);
|
||||
}
|
||||
// Tracer refactor TODO - rehook up meteor, if it is worth it
|
||||
//void Trace(string msg)
|
||||
//{
|
||||
// Tracer.Put(msg);
|
||||
//}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
|
@ -247,7 +248,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
|
||||
messagecallback = PrintMessage;
|
||||
inputcallback = GetInput;
|
||||
tracecallback = Trace; // don't set this callback now, only set if enabled
|
||||
|
||||
// Tracer refactor TODO - rehook up meteor, if it is worth it
|
||||
//tracecallback = Trace; // don't set this callback now, only set if enabled
|
||||
LibMeteor.libmeteor_setmessagecallback(messagecallback);
|
||||
LibMeteor.libmeteor_setkeycallback(inputcallback);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ using BizHawk.Emulation.Common;
|
|||
using Newtonsoft.Json;
|
||||
using System.ComponentModel;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Cores.Components.ARM;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
||||
{
|
||||
|
@ -159,13 +160,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
|
|||
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
|
||||
public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } }
|
||||
|
||||
string Trace(uint addr, uint opcode)
|
||||
TraceInfo Trace(uint addr, uint opcode)
|
||||
{
|
||||
return
|
||||
string.Format("{0:x8} {1} {2}",
|
||||
opcode,
|
||||
(Emulation.Cores.Components.ARM.Darm.DisassembleStuff(addr, opcode) ?? "").PadRight(30),
|
||||
regs.TraceString());
|
||||
return new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format("{0:X8} {1}", opcode, Darm.DisassembleStuff(addr, opcode)),
|
||||
RegisterInfo = regs.TraceString()
|
||||
};
|
||||
}
|
||||
|
||||
void InitCallbacks()
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Common.Components.Z80GB;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
||||
{
|
||||
|
@ -17,24 +16,30 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
|
|||
System.Runtime.InteropServices.Marshal.Copy(_s, s, 0, 14);
|
||||
ushort unused;
|
||||
|
||||
Tracer.Put(string.Format(
|
||||
"{13} SP:{2:x2} A:{3:x2} B:{4:x2} C:{5:x2} D:{6:x2} E:{7:x2} F:{8:x2} H:{9:x2} L:{10:x2} LY:{14:x2} {11} Cy:{0}",
|
||||
s[0],
|
||||
s[1] & 0xffff,
|
||||
s[2] & 0xffff,
|
||||
s[3] & 0xff,
|
||||
s[4] & 0xff,
|
||||
s[5] & 0xff,
|
||||
s[6] & 0xff,
|
||||
s[7] & 0xff,
|
||||
s[8] & 0xff,
|
||||
s[9] & 0xff,
|
||||
s[10] & 0xff,
|
||||
s[11] != 0 ? "skip" : "",
|
||||
s[12] & 0xff,
|
||||
Common.Components.Z80GB.NewDisassembler.Disassemble((ushort)s[1], (addr) => LibGambatte.gambatte_cpuread(GambatteState, addr), out unused).PadRight(30),
|
||||
s[13] & 0xff
|
||||
));
|
||||
Tracer.Put(new TraceInfo
|
||||
{
|
||||
Disassembly =
|
||||
NewDisassembler
|
||||
.Disassemble((ushort)s[1], (addr) => LibGambatte.gambatte_cpuread(GambatteState, addr), out unused)
|
||||
.PadRight(30),
|
||||
RegisterInfo =
|
||||
string.Format(
|
||||
"SP:{2:x2} A:{3:x2} B:{4:x2} C:{5:x2} D:{6:x2} E:{7:x2} F:{8:x2} H:{9:x2} L:{10:x2} LY:{14:x2} {11} Cy:{0}",
|
||||
s[0],
|
||||
s[1] & 0xffff,
|
||||
s[2] & 0xffff,
|
||||
s[3] & 0xff,
|
||||
s[4] & 0xff,
|
||||
s[5] & 0xff,
|
||||
s[6] & 0xff,
|
||||
s[7] & 0xff,
|
||||
s[8] & 0xff,
|
||||
s[9] & 0xff,
|
||||
s[10] & 0xff,
|
||||
s[11] != 0 ? "skip" : "",
|
||||
s[12] & 0xff
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,16 +27,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|||
int notused = 0;
|
||||
string opcodeStr = MOS6502X.Disassemble(pc, out notused, (address) => _memoryDomains.SystemBus.PeekByte(address));
|
||||
|
||||
Tracer.Put(string.Format(
|
||||
"{0:X4}: {1} SP:{2:X2} A:{3:X2} P:{4:X2} X:{5:X2} Y:{6:X2} ",
|
||||
pc,
|
||||
opcodeStr.PadRight(26),
|
||||
sp,
|
||||
a,
|
||||
p,
|
||||
x,
|
||||
y));
|
||||
|
||||
Tracer.Put(new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format("{0:X4} {1}", pc, opcodeStr).PadRight(26),
|
||||
RegisterInfo = string.Format(
|
||||
"SP:{0:X2} A:{1:X2} P:{2:X2} X:{3:X2} Y:{4:X2}",
|
||||
sp,
|
||||
a,
|
||||
p,
|
||||
x,
|
||||
y)
|
||||
});
|
||||
}
|
||||
|
||||
private const string TraceHeader = "PC: OP SP_A_P_X_Y ";
|
||||
|
|
|
@ -393,7 +393,20 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
|
|||
|
||||
void snes_trace(string msg)
|
||||
{
|
||||
Tracer.Put(msg);
|
||||
// TODO: get them out of the core split up and remove this hackery
|
||||
string splitStr = "[";
|
||||
if (!msg.Contains('['))
|
||||
{
|
||||
splitStr = "A:";
|
||||
}
|
||||
|
||||
var split = msg.Split(new[] {splitStr }, StringSplitOptions.None);
|
||||
|
||||
Tracer.Put(new TraceInfo
|
||||
{
|
||||
Disassembly = split[0],
|
||||
RegisterInfo = splitStr + split[1]
|
||||
});
|
||||
}
|
||||
|
||||
public SnesColors.ColorType CurrPalette { get; private set; }
|
||||
|
|
|
@ -224,7 +224,11 @@ namespace BizHawk.Emulation.Cores.PCEngine
|
|||
RomData = rom;
|
||||
RomLength = RomData.Length;
|
||||
// user request: current value of the SF2MapperLatch on the tracelogger
|
||||
Cpu.Logger = (s) => Tracer.Put(string.Format("{0:X1}:{1}", SF2MapperLatch, s));
|
||||
Cpu.Logger = (s) => Tracer.Put(new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format("{0:X1}:{1}", SF2MapperLatch, s),
|
||||
RegisterInfo = ""
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
|
@ -29,7 +31,6 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
throw new InvalidOperationException("GetCpuFlagsAndRegisters is required");
|
||||
}
|
||||
|
||||
Buffer = new StringBuilder();
|
||||
Header = "Instructions";
|
||||
DebuggableCore = debuggableCore;
|
||||
|
||||
|
@ -42,7 +43,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
private readonly IMemoryDomains MemoryDomains;
|
||||
private readonly IDisassemblable Disassembler;
|
||||
private readonly IDebuggable DebuggableCore;
|
||||
private readonly StringBuilder Buffer;
|
||||
|
||||
private readonly List<TraceInfo> Buffer = new List<TraceInfo>();
|
||||
|
||||
private bool _enabled;
|
||||
|
||||
|
@ -55,20 +57,28 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
// feos: we shouldn't append up to 64, but movem.l prints all the regs affected
|
||||
// so use 32 and deal with registers shifting every now and then
|
||||
Buffer.Append(string.Format("{0:X6}: {1,-32}", pc, disasm));
|
||||
|
||||
var traceInfo = new TraceInfo
|
||||
{
|
||||
Disassembly = string.Format("{0:X6}: {1,-32}", pc, disasm)
|
||||
};
|
||||
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var r in regs)
|
||||
{
|
||||
if (r.Key.StartsWith("M68K"))
|
||||
{
|
||||
Buffer.Append(
|
||||
sb.Append(
|
||||
string.Format("{0}:{1} ",
|
||||
r.Key.Replace("M68K", string.Empty).Trim(),
|
||||
r.Value.Value.ToHexString(r.Value.BitSize / 4)));
|
||||
}
|
||||
}
|
||||
|
||||
Buffer.AppendLine();
|
||||
traceInfo.RegisterInfo = sb.ToString();
|
||||
|
||||
Buffer.Add(traceInfo);
|
||||
}
|
||||
|
||||
public bool Enabled
|
||||
|
@ -92,23 +102,23 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.gpgx
|
|||
|
||||
public string Header { get; set; }
|
||||
|
||||
public string Contents
|
||||
public IEnumerable<TraceInfo> Contents
|
||||
{
|
||||
get { return Buffer.ToString(); }
|
||||
get { return Buffer; }
|
||||
}
|
||||
|
||||
public string TakeContents()
|
||||
public IEnumerable<TraceInfo> TakeContents()
|
||||
{
|
||||
string s = Buffer.ToString();
|
||||
var contents = Buffer.ToList();
|
||||
Buffer.Clear();
|
||||
return s;
|
||||
return contents;
|
||||
}
|
||||
|
||||
public void Put(string content)
|
||||
public void Put(TraceInfo content)
|
||||
{
|
||||
if (_enabled)
|
||||
if (Enabled)
|
||||
{
|
||||
Buffer.AppendLine(content);
|
||||
Buffer.Add(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1325,7 +1325,12 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
|
||||
public void ShockTraceCallback(IntPtr opaque, uint PC, uint inst, string dis)
|
||||
{
|
||||
Tracer.Put(dis);
|
||||
// Tracer refactor TODO: fix this
|
||||
Tracer.Put(new TraceInfo
|
||||
{
|
||||
Disassembly = dis,
|
||||
RegisterInfo = "TODO"
|
||||
});
|
||||
}
|
||||
|
||||
private readonly MemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem();
|
||||
|
|
|
@ -177,20 +177,28 @@ namespace Jellyfish.Virtu
|
|||
RA, RX, RY, RP, RS, RPC, EA, CC);
|
||||
}
|
||||
|
||||
public string TraceState()
|
||||
public string[] TraceState()
|
||||
{
|
||||
string a = string.Format("{0:X4} {1:X2} {2} ", RPC, _memory.Read(RPC), ReadOpcode(RPC)).PadRight(30);
|
||||
string b = string.Format("A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}", RA, RX, RY, RP, RS, Cycles);
|
||||
string state = a + b + " ";
|
||||
if (FlagN) state = state + "N";
|
||||
if (FlagV) state = state + "V";
|
||||
if (FlagT) state = state + "T";
|
||||
if (FlagB) state = state + "B";
|
||||
if (FlagD) state = state + "D";
|
||||
if (FlagI) state = state + "I";
|
||||
if (FlagZ) state = state + "Z";
|
||||
if (FlagC) state = state + "C";
|
||||
return state;
|
||||
string[] parts = new string[2];
|
||||
parts[0] = string.Format("{0:X4} {1:X2} {2} ", RPC, _memory.Read(RPC), ReadOpcode(RPC));
|
||||
parts[1] = string.Format(
|
||||
"A:{0:X2} X:{1:X2} Y:{2:X2} P:{3:X2} SP:{4:X2} Cy:{5}",
|
||||
RA,
|
||||
RX,
|
||||
RY,
|
||||
RP,
|
||||
RS,
|
||||
Cycles,
|
||||
FlagN ? "N" : "",
|
||||
FlagV ? "V" : "",
|
||||
FlagT ? "T" : "",
|
||||
FlagB ? "B" : "",
|
||||
FlagD ? "D" : "",
|
||||
FlagI ? "I" : "",
|
||||
FlagZ ? "Z" : "",
|
||||
FlagC ? "C" : "");
|
||||
|
||||
return parts;
|
||||
}
|
||||
|
||||
private string ReadOpcode(int pc)
|
||||
|
@ -3448,7 +3456,7 @@ namespace Jellyfish.Virtu
|
|||
private Action[] _executeOpCode;
|
||||
|
||||
[JsonIgnore]
|
||||
public Action<string> TraceCallback;
|
||||
public Action<string[]> TraceCallback;
|
||||
|
||||
/// <summary>Carry Flag</summary>
|
||||
[JsonIgnore]
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue