2017-04-15 19:53:02 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
|
|
using BizHawk.Emulation.Common.IEmulatorExtensions;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.Emulation.Common
|
2016-12-14 15:11:07 +00:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
2017-04-27 13:24:21 +00:00
|
|
|
|
/// An implementation of <seealso cref="ITraceable"/> that is implementation using only methods
|
|
|
|
|
/// from <seealso cref="IDebuggable"/>, <seealso cref="IMemoryDomains"/>, and <seealso cref="IDisassemblable"/>
|
2016-12-14 15:11:07 +00:00
|
|
|
|
/// Useful for ported cores that have these hooks but no trace logging hook,
|
|
|
|
|
/// This allows for a traceable implementation without the need for additional API
|
|
|
|
|
/// Note that this technique will always be significantly slower than a direct implementation
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <seealso cref="ITraceable"/>
|
|
|
|
|
/// <seealso cref="IDebuggable"/>
|
|
|
|
|
/// <seealso cref="IMemoryDomains"/>
|
2017-04-14 17:28:23 +00:00
|
|
|
|
/// <seealso cref="IDisassemblable"/>
|
2017-04-15 19:53:02 +00:00
|
|
|
|
public abstract class CallbackBasedTraceBuffer : ITraceable
|
|
|
|
|
{
|
2017-04-27 13:24:21 +00:00
|
|
|
|
protected CallbackBasedTraceBuffer(IDebuggable debuggableCore, IMemoryDomains memoryDomains, IDisassemblable disassembler)
|
2017-04-15 19:53:02 +00:00
|
|
|
|
{
|
|
|
|
|
if (!debuggableCore.MemoryCallbacksAvailable())
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException("Memory callbacks are required");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
debuggableCore.GetCpuFlagsAndRegisters();
|
|
|
|
|
}
|
|
|
|
|
catch (NotImplementedException)
|
|
|
|
|
{
|
2019-03-28 03:17:14 +00:00
|
|
|
|
throw new InvalidOperationException($"{nameof(IDebuggable.GetCpuFlagsAndRegisters)} is required");
|
2017-04-15 19:53:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Header = "Instructions";
|
|
|
|
|
DebuggableCore = debuggableCore;
|
|
|
|
|
MemoryDomains = memoryDomains;
|
|
|
|
|
Disassembler = disassembler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected readonly IMemoryDomains MemoryDomains;
|
|
|
|
|
protected readonly IDisassemblable Disassembler;
|
|
|
|
|
protected readonly IDebuggable DebuggableCore;
|
|
|
|
|
|
|
|
|
|
protected readonly List<TraceInfo> Buffer = new List<TraceInfo>();
|
|
|
|
|
|
2019-06-06 09:04:47 +00:00
|
|
|
|
protected abstract void TraceFromCallback(uint addr, uint value, uint flags);
|
2016-08-13 20:31:04 +00:00
|
|
|
|
|
2016-12-14 20:30:43 +00:00
|
|
|
|
private ITraceSink _sink;
|
2016-08-13 20:31:04 +00:00
|
|
|
|
|
2017-04-15 19:53:02 +00:00
|
|
|
|
public bool Enabled => Sink != null;
|
|
|
|
|
|
2017-04-15 20:37:30 +00:00
|
|
|
|
public void Put(TraceInfo info)
|
2016-12-14 20:30:43 +00:00
|
|
|
|
{
|
|
|
|
|
Sink.Put(info);
|
|
|
|
|
}
|
2016-08-13 20:31:04 +00:00
|
|
|
|
|
|
|
|
|
public ITraceSink Sink
|
|
|
|
|
{
|
2017-04-27 13:24:21 +00:00
|
|
|
|
private get
|
2016-08-13 20:31:04 +00:00
|
|
|
|
{
|
|
|
|
|
return _sink;
|
|
|
|
|
}
|
2017-04-24 12:41:55 +00:00
|
|
|
|
|
2016-08-13 20:31:04 +00:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
_sink = value;
|
|
|
|
|
DebuggableCore.MemoryCallbacks.Remove(TraceFromCallback);
|
|
|
|
|
|
|
|
|
|
if (_sink != null)
|
|
|
|
|
{
|
|
|
|
|
DebuggableCore.MemoryCallbacks.Add(new TracingMemoryCallback(TraceFromCallback));
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-15 19:53:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-27 13:24:21 +00:00
|
|
|
|
public string Header { get; protected set; }
|
2017-04-15 19:53:02 +00:00
|
|
|
|
|
|
|
|
|
public class TracingMemoryCallback : IMemoryCallback
|
|
|
|
|
{
|
2019-06-06 09:04:47 +00:00
|
|
|
|
public TracingMemoryCallback(MemoryCallbackDelegate callback)
|
2017-04-15 19:53:02 +00:00
|
|
|
|
{
|
|
|
|
|
Callback = callback;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MemoryCallbackType Type => MemoryCallbackType.Execute;
|
|
|
|
|
|
2017-04-15 20:37:30 +00:00
|
|
|
|
public string Name => "Trace Logging";
|
2017-04-15 19:53:02 +00:00
|
|
|
|
|
2019-06-06 09:04:47 +00:00
|
|
|
|
public MemoryCallbackDelegate Callback { get; }
|
2017-04-15 19:53:02 +00:00
|
|
|
|
|
|
|
|
|
public uint? Address => null;
|
|
|
|
|
|
|
|
|
|
public uint? AddressMask => null;
|
2017-08-02 03:05:17 +00:00
|
|
|
|
|
2017-08-04 01:03:40 +00:00
|
|
|
|
public string Scope => ""; // This will be relevant if/when the trace logger can trace anything other than the system bus
|
2017-04-15 19:53:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|