trace for quicknes
This commit is contained in:
parent
b6406fe523
commit
6f8bcc2be3
|
@ -737,6 +737,7 @@
|
||||||
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.IStatable.cs">
|
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.IStatable.cs">
|
||||||
<DependentUpon>QuickNES.cs</DependentUpon>
|
<DependentUpon>QuickNES.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.ITraceable.cs" />
|
||||||
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.IVideoProvider.cs">
|
<Compile Include="Consoles\Nintendo\QuickNES\QuickNES.IVideoProvider.cs">
|
||||||
<DependentUpon>QuickNES.cs</DependentUpon>
|
<DependentUpon>QuickNES.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
|
|
@ -215,6 +215,17 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
||||||
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern IntPtr qn_get_mapper(IntPtr e, ref int number);
|
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)]
|
[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
||||||
|
|
||||||
SetControllerDefinition();
|
SetControllerDefinition();
|
||||||
ComputeBootGod();
|
ComputeBootGod();
|
||||||
|
|
||||||
|
ConnectTracer();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -190,6 +192,11 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
||||||
int j1, j2;
|
int j1, j2;
|
||||||
SetPads(out j1, out j2);
|
SetPads(out j1, out j2);
|
||||||
|
|
||||||
|
if (Tracer.Enabled)
|
||||||
|
LibQuickNES.qn_set_tracecb(Context, _tracecb);
|
||||||
|
else
|
||||||
|
LibQuickNES.qn_set_tracecb(Context, null);
|
||||||
|
|
||||||
Frame++;
|
Frame++;
|
||||||
LibQuickNES.ThrowStringError(LibQuickNES.qn_emulate_frame(Context, j1, j2));
|
LibQuickNES.ThrowStringError(LibQuickNES.qn_emulate_frame(Context, j1, j2));
|
||||||
IsLagFrame = LibQuickNES.qn_get_joypad_read_count(Context) == 0;
|
IsLagFrame = LibQuickNES.qn_get_joypad_read_count(Context) == 0;
|
||||||
|
|
Binary file not shown.
|
@ -16,6 +16,20 @@ public:
|
||||||
long size() const { return size_; }
|
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)
|
#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++)
|
for (int i = 0; i < 0x3000; i++)
|
||||||
dest[i] = e->peek_ppu(i);
|
dest[i] = e->peek_ppu(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT void qn_set_tracecb(Nes_Emu *e, void (*cb)(unsigned int *dest))
|
||||||
|
{
|
||||||
|
e->set_tracecb(cb);
|
||||||
|
}
|
||||||
|
|
|
@ -113,6 +113,11 @@ void Nes_Cpu::write( nes_addr_t addr, int value )
|
||||||
WRITE( addr, value );
|
WRITE( addr, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Nes_Cpu::set_tracecb(void (*cb)(unsigned int *data))
|
||||||
|
{
|
||||||
|
tracecb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NES_CPU_GLUE_ONLY
|
#ifndef NES_CPU_GLUE_ONLY
|
||||||
|
|
||||||
static const unsigned char clock_table [256] = {
|
static const unsigned char clock_table [256] = {
|
||||||
|
@ -207,6 +212,19 @@ loop:
|
||||||
if ( clock_count >= clock_limit )
|
if ( clock_count >= clock_limit )
|
||||||
goto stop;
|
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];
|
clock_count += clock_table [opcode];
|
||||||
unsigned data;
|
unsigned data;
|
||||||
data = page [pc];
|
data = page [pc];
|
||||||
|
|
|
@ -66,6 +66,8 @@ public:
|
||||||
// One of the many opcodes that are undefined and stop CPU emulation.
|
// One of the many opcodes that are undefined and stop CPU emulation.
|
||||||
enum { bad_opcode = 0xD2 };
|
enum { bad_opcode = 0xD2 };
|
||||||
|
|
||||||
|
void set_tracecb(void (*cb)(unsigned int *dest));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t const* code_map [page_count + 1];
|
uint8_t const* code_map [page_count + 1];
|
||||||
nes_time_t clock_limit;
|
nes_time_t clock_limit;
|
||||||
|
@ -78,6 +80,8 @@ private:
|
||||||
void set_code_page( int, uint8_t const* );
|
void set_code_page( int, uint8_t const* );
|
||||||
void update_clock_limit();
|
void update_clock_limit();
|
||||||
|
|
||||||
|
void (*tracecb)(unsigned int *dest);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
registers_t r;
|
registers_t r;
|
||||||
|
|
||||||
|
|
|
@ -214,6 +214,8 @@ public:
|
||||||
byte* pal_mem() { return emu.ppu.palette; }
|
byte* pal_mem() { return emu.ppu.palette; }
|
||||||
byte* oam_mem() { return emu.ppu.spr_ram; }
|
byte* oam_mem() { return emu.ppu.spr_ram; }
|
||||||
|
|
||||||
|
void set_tracecb(void (*cb)(unsigned int *dest)) { emu.set_tracecb(cb); }
|
||||||
|
|
||||||
// End of public interface
|
// End of public interface
|
||||||
public:
|
public:
|
||||||
blargg_err_t set_sample_rate( long rate, class Nes_Buffer* );
|
blargg_err_t set_sample_rate( long rate, class Nes_Buffer* );
|
||||||
|
|
Loading…
Reference in New Issue