trace for quicknes

This commit is contained in:
nattthebear 2016-01-30 13:47:14 -05:00
parent b6406fe523
commit 6f8bcc2be3
9 changed files with 112 additions and 0 deletions

View File

@ -737,6 +737,7 @@
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.IStatable.cs">
<DependentUpon>QuickNES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.ITraceable.cs" />
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.IVideoProvider.cs">
<DependentUpon>QuickNES.cs</DependentUpon>
</Compile>

View File

@ -215,6 +215,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr qn_get_mapper(IntPtr e, ref int number);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TraceCallback(IntPtr data);
/// <summary>
/// set a trace callback to be run on each cycle
/// </summary>
/// <param name="e">Context</param>
/// <param name="cb"></param>
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
public static extern void qn_set_tracecb(IntPtr e, TraceCallback cb);
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]

View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BizHawk.Common.BufferExtensions;
using BizHawk.Emulation.Common;
using BizHawk.Common;
using BizHawk.Common.CollectionExtensions;
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
{
partial class QuickNES
{
public TraceBuffer Tracer { get; private set; }
private LibQuickNES.TraceCallback _tracecb;
private void MakeTrace(IntPtr data)
{
int[] s = new int[7];
System.Runtime.InteropServices.Marshal.Copy(data, s, 0, 7);
byte a = (byte)s[0];
byte x = (byte)s[1];
byte y = (byte)s[2];
ushort sp = (ushort)s[3];
ushort pc = (ushort)s[4];
byte p = (byte)s[5];
byte opcode = (byte)s[6];
Tracer.Put(string.Format("{0:X2} {1:X2} {2:X2} {3:X4} {4:X4} {5:X2} {6:X2}",
a, x, y, sp, pc, p, opcode));
}
private const string TraceHeader = "_A _X _Y _SP_ _PC_ _P OP";
private void ConnectTracer()
{
Tracer = new TraceBuffer
{
Header = TraceHeader
};
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);
_tracecb = new LibQuickNES.TraceCallback(MakeTrace);
}
}
}

View File

@ -64,6 +64,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
SetControllerDefinition();
ComputeBootGod();
ConnectTracer();
}
catch
{
@ -190,6 +192,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
int j1, j2;
SetPads(out j1, out j2);
if (Tracer.Enabled)
LibQuickNES.qn_set_tracecb(Context, _tracecb);
else
LibQuickNES.qn_set_tracecb(Context, null);
Frame++;
LibQuickNES.ThrowStringError(LibQuickNES.qn_emulate_frame(Context, j1, j2));
IsLagFrame = LibQuickNES.qn_get_joypad_read_count(Context) == 0;

Binary file not shown.

View File

@ -16,6 +16,20 @@ public:
long size() const { return size_; }
};
// 0 filled new just for kicks
void *operator new(std::size_t n)
{
if (!n)
n = 1;
void *p = std::malloc(n);
std::memset(p, 0, n);
return p;
}
void operator delete(void *p)
{
std::free(p);
}
#define EXPORT extern "C" __declspec(dllexport)
@ -314,3 +328,8 @@ EXPORT void qn_peek_ppubus(Nes_Emu *e, byte *dest)
for (int i = 0; i < 0x3000; i++)
dest[i] = e->peek_ppu(i);
}
EXPORT void qn_set_tracecb(Nes_Emu *e, void (*cb)(unsigned int *dest))
{
e->set_tracecb(cb);
}

View File

@ -113,6 +113,11 @@ void Nes_Cpu::write( nes_addr_t addr, int value )
WRITE( addr, value );
}
void Nes_Cpu::set_tracecb(void (*cb)(unsigned int *data))
{
tracecb = cb;
}
#ifndef NES_CPU_GLUE_ONLY
static const unsigned char clock_table [256] = {
@ -206,6 +211,19 @@ loop:
if ( clock_count >= clock_limit )
goto stop;
if (tracecb)
{
unsigned int scratch[7];
scratch[0] = a;
scratch[1] = x;
scratch[2] = y;
scratch[3] = sp;
scratch[4] = pc;
scratch[5] = status;
scratch[6] = opcode;
tracecb(scratch);
}
clock_count += clock_table [opcode];
unsigned data;

View File

@ -65,6 +65,8 @@ public:
// One of the many opcodes that are undefined and stop CPU emulation.
enum { bad_opcode = 0xD2 };
void set_tracecb(void (*cb)(unsigned int *dest));
private:
uint8_t const* code_map [page_count + 1];
@ -77,6 +79,8 @@ private:
enum { irq_inhibit = 0x04 };
void set_code_page( int, uint8_t const* );
void update_clock_limit();
void (*tracecb)(unsigned int *dest);
public:
registers_t r;

View File

@ -214,6 +214,8 @@ public:
byte* pal_mem() { return emu.ppu.palette; }
byte* oam_mem() { return emu.ppu.spr_ram; }
void set_tracecb(void (*cb)(unsigned int *dest)) { emu.set_tracecb(cb); }
// End of public interface
public:
blargg_err_t set_sample_rate( long rate, class Nes_Buffer* );