Refactor ITraceable to work on TraceInfo objects that separate Disassembly and Register information. Make Tracelogger two columns.

This commit is contained in:
adelikat 2016-02-21 17:34:14 -05:00
parent 01dc05375d
commit f5e679fa0d
21 changed files with 340 additions and 183 deletions

View File

@ -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;
}
}

View File

@ -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());
}

View File

@ -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);
}
}

View File

@ -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; }
}
}

View File

@ -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)
{

View File

@ -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 =

View File

@ -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;

View File

@ -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);

View File

@ -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" : ""
)
};
}
}
}

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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()

View File

@ -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
)
});
}
}
}

View File

@ -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 ";

View File

@ -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; }

View File

@ -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
{

View File

@ -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);
}
}

View File

@ -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();

View File

@ -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.