diff --git a/BizHawk.Client.EmuHawk/tools/TraceLogger.Designer.cs b/BizHawk.Client.EmuHawk/tools/TraceLogger.Designer.cs index 998d7e1255..1e45f46883 100644 --- a/BizHawk.Client.EmuHawk/tools/TraceLogger.Designer.cs +++ b/BizHawk.Client.EmuHawk/tools/TraceLogger.Designer.cs @@ -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; } } \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/TraceLogger.cs b/BizHawk.Client.EmuHawk/tools/TraceLogger.cs index 4846d7346a..94460a1097 100644 --- a/BizHawk.Client.EmuHawk/tools/TraceLogger.cs +++ b/BizHawk.Client.EmuHawk/tools/TraceLogger.cs @@ -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 _instructions = new List(); + private readonly List _instructions = new List(); 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()); } diff --git a/BizHawk.Emulation.Common/Base Implementations/TraceBuffer.cs b/BizHawk.Emulation.Common/Base Implementations/TraceBuffer.cs index 4aa781befd..1dfbc4271c 100644 --- a/BizHawk.Emulation.Common/Base Implementations/TraceBuffer.cs +++ b/BizHawk.Emulation.Common/Base Implementations/TraceBuffer.cs @@ -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 Buffer = new List(); public TraceBuffer() { - buffer = new StringBuilder(); Header = "Instructions"; } - public string TakeContents() + public IEnumerable TakeContents() { - string s = buffer.ToString(); - buffer.Clear(); - return s; + var contents = Buffer.ToList(); + Buffer.Clear(); + return contents; } - public string Contents + public IEnumerable 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); } } diff --git a/BizHawk.Emulation.Common/Interfaces/ITraceable.cs b/BizHawk.Emulation.Common/Interfaces/ITraceable.cs index d3cd24c78b..1d750a97ee 100644 --- a/BizHawk.Emulation.Common/Interfaces/ITraceable.cs +++ b/BizHawk.Emulation.Common/Interfaces/ITraceable.cs @@ -1,4 +1,6 @@ -namespace BizHawk.Emulation.Common +using System.Collections.Generic; + +namespace BizHawk.Emulation.Common { /// /// Allows the cpu to dump trace info to a trace stream @@ -17,16 +19,19 @@ /// /// The current log of cpu instructions /// - string Contents { get; } + IEnumerable Contents { get; } /// /// Takes the current log of cpu instructions, when doing so, it will clear the contents from the buffer /// - string TakeContents(); + IEnumerable TakeContents(); - /// - /// Adds contents to the log of cpu instructions - /// - void Put(string content); + void Put(TraceInfo content); + } + + public class TraceInfo + { + public string Disassembly { get; set; } + public string RegisterInfo { get; set; } } } diff --git a/BizHawk.Emulation.Cores/CPUs/HuC6280/Execute.cs b/BizHawk.Emulation.Cores/CPUs/HuC6280/Execute.cs index be74c7c740..d151dd15a8 100644 --- a/BizHawk.Emulation.Cores/CPUs/HuC6280/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/HuC6280/Execute.cs @@ -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 Logger; + public Action Logger; public void Execute(int cycles) { diff --git a/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs b/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs index 5f99ee53ef..db4b8e66d0 100644 --- a/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs +++ b/BizHawk.Emulation.Cores/CPUs/HuC6280/HuC6280.cs @@ -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 = diff --git a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs index 1fd4e0b784..acb5f97f3b 100644 --- a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/Execute.cs @@ -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 TraceCallback; + public Action 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; diff --git a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/MOS6502X.cs b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/MOS6502X.cs index be6043a861..684be9377d 100644 --- a/BizHawk.Emulation.Cores/CPUs/MOS 6502X/MOS6502X.cs +++ b/BizHawk.Emulation.Cores/CPUs/MOS 6502X/MOS6502X.cs @@ -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); diff --git a/BizHawk.Emulation.Cores/CPUs/Z80/Execute.cs b/BizHawk.Emulation.Cores/CPUs/Z80/Execute.cs index c6b32d737e..133c2916b7 100644 --- a/BizHawk.Emulation.Cores/CPUs/Z80/Execute.cs +++ b/BizHawk.Emulation.Cores/CPUs/Z80/Execute.cs @@ -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 Logger; + public Action Logger; /// /// 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" : "" + ) + }; } } } \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IDebuggable.cs b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IDebuggable.cs index de7bba788d..7ad45f73ea 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IDebuggable.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.IDebuggable.cs @@ -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; diff --git a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs index 9f43877262..d51dcb7161 100644 --- a/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs +++ b/BizHawk.Emulation.Cores/Computers/AppleII/AppleII.cs @@ -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) { diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs index 3e918a1258..50c9a62f4c 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/Meteor.cs @@ -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); diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs index 3678b24584..d497fd0a62 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/VBANext.cs @@ -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() diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ITraceable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ITraceable.cs index 20855e1988..c236930b35 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ITraceable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.ITraceable.cs @@ -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 + ) + }); } } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.ITraceable.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.ITraceable.cs index 87556b4db3..4065dacfc4 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.ITraceable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/QuickNES/QuickNES.ITraceable.cs @@ -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 "; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs index 0d1d3e5657..2f2837c733 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -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; } diff --git a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs index c39273e240..8d4df61234 100644 --- a/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation.Cores/Consoles/PC Engine/PCEngine.cs @@ -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 { diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ITraceable.cs b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ITraceable.cs index 97e0002fa3..6cd409d262 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ITraceable.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/gpgx/GPGX.ITraceable.cs @@ -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 Buffer = new List(); 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 Contents { - get { return Buffer.ToString(); } + get { return Buffer; } } - public string TakeContents() + public IEnumerable 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); } } diff --git a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs index 1ae0a88609..abe3b051c0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sony/PSX/Octoshock.cs @@ -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(); diff --git a/ExternalCoreProjects/Virtu/Cpu.cs b/ExternalCoreProjects/Virtu/Cpu.cs index 71ea78caf3..6443522422 100644 --- a/ExternalCoreProjects/Virtu/Cpu.cs +++ b/ExternalCoreProjects/Virtu/Cpu.cs @@ -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 TraceCallback; + public Action TraceCallback; /// Carry Flag [JsonIgnore] diff --git a/References/Virtu.dll b/References/Virtu.dll index 77c0260f55..2e66b2f851 100644 Binary files a/References/Virtu.dll and b/References/Virtu.dll differ