gbhawk: tracelogger
This commit is contained in:
parent
24d3bb76e2
commit
3eda4a90a6
|
@ -139,6 +139,11 @@ namespace BizHawk.Emulation.Consoles.GB
|
|||
LibGambatte.gambatte_reset(GambatteState);
|
||||
|
||||
RefreshMemoryCallbacks();
|
||||
if (CoreInputComm.Tracer.Enabled)
|
||||
tracecb = MakeTrace;
|
||||
else
|
||||
tracecb = null;
|
||||
LibGambatte.gambatte_settracecallback(GambatteState, tracecb);
|
||||
|
||||
LibGambatte.gambatte_runfor(GambatteState, VideoBuffer, 160, soundbuff, ref nsamp);
|
||||
|
||||
|
@ -410,6 +415,7 @@ namespace BizHawk.Emulation.Consoles.GB
|
|||
VsyncDen = 4389,
|
||||
RomStatusAnnotation = null, //"Bizwhackin it up",
|
||||
RomStatusDetails = null, //"LEVAR BURTON",
|
||||
CpuTraceAvailable = true
|
||||
};
|
||||
|
||||
public CoreOutputComm CoreOutputComm
|
||||
|
@ -417,6 +423,31 @@ namespace BizHawk.Emulation.Consoles.GB
|
|||
get { return GbOutputComm; }
|
||||
}
|
||||
|
||||
LibGambatte.TraceCallback tracecb;
|
||||
|
||||
void MakeTrace(IntPtr _s)
|
||||
{
|
||||
int[] s = new int[13];
|
||||
System.Runtime.InteropServices.Marshal.Copy(_s, s, 0, 13);
|
||||
|
||||
CoreInputComm.Tracer.Put(string.Format(
|
||||
"{1:x4} {12:x2} 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} {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
|
||||
));
|
||||
}
|
||||
|
||||
#region MemoryDomains
|
||||
|
||||
class MemoryRefresher
|
||||
|
|
|
@ -152,6 +152,21 @@ namespace BizHawk.Emulation.Consoles.GB
|
|||
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void gambatte_setwritecallback(IntPtr core, MemoryCallback callback);
|
||||
|
||||
/// <summary>
|
||||
/// type of the cpu trace callback
|
||||
/// </summary>
|
||||
/// <param name="data">cpu state</param>
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void TraceCallback(IntPtr state);
|
||||
|
||||
/// <summary>
|
||||
/// set a callback to occur immediately BEFORE each opcode is executed
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="callback">null to clear</param>
|
||||
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void gambatte_settracecallback(IntPtr core, TraceCallback callback);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the directory used for storing save data. The default is the same directory as the ROM Image file.
|
||||
/// </summary>
|
||||
|
|
Binary file not shown.
|
@ -85,6 +85,7 @@ public:
|
|||
|
||||
void setReadCallback(void (*callback)(unsigned));
|
||||
void setWriteCallback(void (*callback)(unsigned));
|
||||
void setTraceCallback(void (*callback)(void *));
|
||||
|
||||
/** Sets the directory used for storing save data. The default is the same directory as the ROM Image file. */
|
||||
void setSaveDir(const std::string &sdir);
|
||||
|
|
|
@ -77,6 +77,12 @@ __declspec(dllexport) void gambatte_setwritecallback(void *core, void (*callback
|
|||
g->setWriteCallback(callback);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void gambatte_settracecallback(void *core, void (*callback)(void *))
|
||||
{
|
||||
GB *g = (GB *) core;
|
||||
g->setTraceCallback(callback);
|
||||
}
|
||||
|
||||
__declspec(dllexport) void gambatte_setsavedir(void *core, const char *sdir)
|
||||
{
|
||||
GB *g = (GB *) core;
|
||||
|
|
|
@ -22,6 +22,8 @@ extern "C"
|
|||
|
||||
__declspec(dllexport) void gambatte_setwritecallback(void *core, void (*callback)(unsigned));
|
||||
|
||||
__declspec(dllexport) void gambatte_settracecallback(void *core, void (*callback)(void *));
|
||||
|
||||
__declspec(dllexport) void gambatte_setsavedir(void *core, const char *sdir);
|
||||
|
||||
__declspec(dllexport) int gambatte_iscgb(void *core);
|
||||
|
|
|
@ -38,7 +38,8 @@ CPU::CPU()
|
|||
E(0xD8),
|
||||
H(0x01),
|
||||
L(0x4D),
|
||||
skip(false)
|
||||
skip(false),
|
||||
tracecallback(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -520,7 +521,27 @@ void CPU::process(const unsigned long cycles) {
|
|||
} else while (cycleCounter < memory.nextEventTime()) {
|
||||
unsigned char opcode;
|
||||
|
||||
PC_READ(opcode);
|
||||
if (tracecallback) {
|
||||
int result[13];
|
||||
result[0] = cycleCounter;
|
||||
result[1] = PC;
|
||||
result[2] = SP;
|
||||
result[3] = A;
|
||||
result[4] = B;
|
||||
result[5] = C;
|
||||
result[6] = D;
|
||||
result[7] = E;
|
||||
result[8] = F();
|
||||
result[9] = H;
|
||||
result[10] = L;
|
||||
result[11] = skip;
|
||||
PC_READ(opcode);
|
||||
result[12] = opcode;
|
||||
tracecallback((void *)result);
|
||||
}
|
||||
else {
|
||||
PC_READ(opcode);
|
||||
}
|
||||
|
||||
if (skip) {
|
||||
PC = (PC - 1) & 0xFFFF;
|
||||
|
|
|
@ -39,6 +39,8 @@ class CPU {
|
|||
|
||||
void process(unsigned long cycles);
|
||||
|
||||
void (*tracecallback)(void *);
|
||||
|
||||
public:
|
||||
|
||||
CPU();
|
||||
|
@ -72,6 +74,10 @@ public:
|
|||
void setWriteCallback(void (*callback)(unsigned)) {
|
||||
memory.setWriteCallback(callback);
|
||||
}
|
||||
|
||||
void setTraceCallback(void (*callback)(void *)) {
|
||||
tracecallback = callback;
|
||||
}
|
||||
|
||||
void setSaveDir(const std::string &sdir) {
|
||||
memory.setSaveDir(sdir);
|
||||
|
|
|
@ -103,6 +103,10 @@ void GB::setWriteCallback(void (*callback)(unsigned)) {
|
|||
p_->cpu.setWriteCallback(callback);
|
||||
}
|
||||
|
||||
void GB::setTraceCallback(void (*callback)(void *)) {
|
||||
p_->cpu.setTraceCallback(callback);
|
||||
}
|
||||
|
||||
void GB::setSaveDir(const std::string &sdir) {
|
||||
p_->cpu.setSaveDir(sdir);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue