n64: switch to regular tracer method

todo: same for gpgx
This commit is contained in:
feos 2016-08-14 20:35:05 +03:00
parent 45a83322a7
commit 799afc6b0a
8 changed files with 98 additions and 60 deletions

View File

@ -2,72 +2,74 @@
using System.Runtime.InteropServices;
using System.Text;
using BizHawk.Emulation.Common;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.N64.NativeApi;
namespace BizHawk.Emulation.Cores.Nintendo.N64
{
public partial class N64
partial class N64
{
private readonly ITraceable Tracer;
public TraceBuffer Tracer { get; private set; }
public class m64pTraceBuffer : CallbackBasedTraceBuffer
private mupen64plusApi.TraceCallback _tracecb;
public void MakeTrace()
{
public m64pTraceBuffer(IDebuggable debuggableCore, IMemoryDomains memoryDomains, IDisassemblable disassembler)
: base(debuggableCore, memoryDomains, disassembler)
var regs = GetCpuFlagsAndRegisters();
uint pc = (uint)regs["PC"].Value;
var length = 0;
var disasm = Disassemble(MemoryDomains.SystemBus, pc, out length);
var traceInfo = new TraceInfo
{
Header = "r3400: PC, mnemonic, arguments, registers (GPRs, Load/Link Bit, MultHI, MultLO, Implementation/Revision, Control/Status)";
}
public override void TraceFromCallback()
{
var regs = DebuggableCore.GetCpuFlagsAndRegisters();
uint pc = (uint)regs["PC"].Value;
var length = 0;
var disasm = Disassembler.Disassemble(MemoryDomains.SystemBus, pc, out length);
var traceInfo = new TraceInfo
{
Disassembly = string.Format("{0:X}: {1}", pc, disasm.PadRight(32))
};
var sb = new StringBuilder();
for (int i = 1; i < 32; i++) // r0 is always zero
{
UInt64 val = (regs["REG" + i + "_hi"].Value << 32) | regs["REG" + i + "_lo"].Value;
string name = GPRnames[i];
sb.Append(string.Format("{0}:{1:X16} ", name, val));
}
sb.Append(string.Format("LL:{0:X8} ", regs["LL"].Value));
sb.Append(string.Format("LO:{0:X8}{1:X8} ", regs["LO_hi"].Value, regs["LO_lo"].Value));
sb.Append(string.Format("HI:{0:X8}{1:X8} ", regs["HI_hi"].Value, regs["HI_lo"].Value));
sb.Append(string.Format("FCR0:{0:X8} ", regs["FCR0"].Value));
sb.Append(string.Format("FCR31:{0:X8} ", regs["FCR31"].Value));
// drop co-processor regs for now
traceInfo.RegisterInfo = sb.ToString().Trim();
Put(traceInfo);
}
private string[] GPRnames = new string[32]
{
"r0",
"at",
"v0", "v1",
"a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
"t8", "t9",
"k0", "k1",
"gp",
"sp",
"s8",
"ra"
Disassembly = string.Format("{0:X}: {1}", pc, disasm.PadRight(32))
};
var sb = new StringBuilder();
for (int i = 1; i < 32; i++) // r0 is always zero
{
UInt64 val = (regs["REG" + i + "_hi"].Value << 32) | regs["REG" + i + "_lo"].Value;
string name = GPRnames[i];
sb.Append(string.Format("{0}:{1:X16} ", name, val));
}
sb.Append(string.Format("LL:{0:X8} ", regs["LL"].Value));
sb.Append(string.Format("LO:{0:X8}{1:X8} ", regs["LO_hi"].Value, regs["LO_lo"].Value));
sb.Append(string.Format("HI:{0:X8}{1:X8} ", regs["HI_hi"].Value, regs["HI_lo"].Value));
sb.Append(string.Format("FCR0:{0:X8} ", regs["FCR0"].Value));
sb.Append(string.Format("FCR31:{0:X8} ", regs["FCR31"].Value));
// drop co-processor regs for now
traceInfo.RegisterInfo = sb.ToString().Trim();
Tracer.Put(traceInfo);
}
private const string TraceHeader = "r3400: PC, mnemonic, arguments, registers (GPRs, Load/Link Bit, MultHI, MultLO, Implementation/Revision, Control/Status)";
private void ConnectTracer()
{
Tracer = new TraceBuffer { Header = TraceHeader };
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
_tracecb = new mupen64plusApi.TraceCallback(MakeTrace);
}
private string[] GPRnames = new string[32]
{
"r0",
"at",
"v0", "v1",
"a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
"t8", "t9",
"k0", "k1",
"gp",
"sp",
"s8",
"ra"
};
}
}

View File

@ -138,11 +138,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
api.AttachPlugin(mupen64plusApi.m64p_plugin_type.M64PLUGIN_RSP, rsp);
InitMemoryDomains();
ConnectTracer();
RefreshMemoryCallbacks();
Tracer = new m64pTraceBuffer(this, MemoryDomains, this);
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
api.AsyncExecuteEmulator();
// Hack: Saving a state on frame 0 has been shown to not be sync stable. Advance past that frame to avoid the problem.
@ -215,9 +213,18 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64
public void FrameAdvance(bool render, bool rendersound)
{
IsVIFrame = false;
RefreshMemoryCallbacks();
if (Tracer.Enabled)
{
api.setTraceCallback(_tracecb);
}
else
{
api.setTraceCallback(null);
}
_audioProvider.RenderSound = rendersound;
if (Controller["Reset"])

View File

@ -377,6 +377,19 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
public delegate void SetExecuteCallback(MemoryCallback callback);
SetExecuteCallback m64pSetExecuteCallback;
/// <summary>
/// Type of the trace callback
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TraceCallback();
/// <summary>
/// Sets the trace callback
/// </summary>
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SetTraceCallback(TraceCallback callback);
SetTraceCallback m64pSetTraceCallback;
/// <summary>
/// Gets the CPU registers
/// </summary>
@ -511,6 +524,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
m64pSetReadCallback = (SetReadCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetReadCallback"), typeof(SetReadCallback));
m64pSetWriteCallback = (SetWriteCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetWriteCallback"), typeof(SetWriteCallback));
m64pSetExecuteCallback = (SetExecuteCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetExecuteCallback"), typeof(SetExecuteCallback));
m64pSetTraceCallback = (SetTraceCallback)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "SetTraceCallback"), typeof(SetTraceCallback));
m64pGetRegisters = (GetRegisters)Marshal.GetDelegateForFunctionPointer(GetProcAddress(CoreDll, "GetRegisters"), typeof(GetRegisters));
@ -713,6 +727,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.N64.NativeApi
m64pSetExecuteCallback(callback);
}
public void setTraceCallback(TraceCallback callback)
{
m64pSetTraceCallback(callback);
}
public void getRegisters(byte[] dest)
{
m64pGetRegisters(dest);

View File

@ -136,6 +136,7 @@ static int firstFrameBufferSetting;
void (*readCB)(unsigned int) = NULL;
void (*writeCB)(unsigned int) = NULL;
void (*executeCB)(unsigned int) = NULL;
void (*traceCB)(void) = NULL;
// uncomment to output count of calls to write_rdram():
//#define COUNT_WRITE_RDRAM_CALLS 1
@ -4049,4 +4050,9 @@ EXPORT void CALL SetWriteCallback(void (*CB)(unsigned int))
EXPORT void CALL SetExecuteCallback(void (*CB)(unsigned int))
{
executeCB = CB;
}
EXPORT void CALL SetTraceCallback(void (*CB)(unsigned int))
{
traceCB = CB;
}

View File

@ -27,6 +27,7 @@
#define READCB() if (readCB) readCB(address)
#define WRITECB() if (writeCB) writeCB(address)
#define EXECUTECB() if (executeCB) executeCB(PC->addr)
#define TRACECB() if (traceCB) traceCB()
#define READCBADDR(addr) if (readCB) readCB(addr)
#define WRITECBADDR(addr) if (writeCB) writeCB(addr)
@ -56,6 +57,7 @@ extern unsigned short hword;
extern unsigned long long dword, *rdword;
extern void (*executeCB)(unsigned int);
extern void (*traceCB)(void);
extern void (*readmem[0x10000])(void);
extern void (*readmemb[0x10000])(void);

View File

@ -420,6 +420,7 @@ void pure_interpreter(void)
if (g_DebuggerActive) update_debugger(PC->addr);
#endif
EXECUTECB();
TRACECB();
PC->ops();
}
}

View File

@ -1069,6 +1069,7 @@ void r4300_execute(void (*startcb)(void))
if (g_DebuggerActive) update_debugger(PC->addr);
#endif
EXECUTECB();
TRACECB();
PC->ops();
}

Binary file not shown.