gbhawk: tracelogger
This commit is contained in:
parent
24d3bb76e2
commit
3eda4a90a6
|
@ -139,6 +139,11 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
LibGambatte.gambatte_reset(GambatteState);
|
LibGambatte.gambatte_reset(GambatteState);
|
||||||
|
|
||||||
RefreshMemoryCallbacks();
|
RefreshMemoryCallbacks();
|
||||||
|
if (CoreInputComm.Tracer.Enabled)
|
||||||
|
tracecb = MakeTrace;
|
||||||
|
else
|
||||||
|
tracecb = null;
|
||||||
|
LibGambatte.gambatte_settracecallback(GambatteState, tracecb);
|
||||||
|
|
||||||
LibGambatte.gambatte_runfor(GambatteState, VideoBuffer, 160, soundbuff, ref nsamp);
|
LibGambatte.gambatte_runfor(GambatteState, VideoBuffer, 160, soundbuff, ref nsamp);
|
||||||
|
|
||||||
|
@ -410,6 +415,7 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
VsyncDen = 4389,
|
VsyncDen = 4389,
|
||||||
RomStatusAnnotation = null, //"Bizwhackin it up",
|
RomStatusAnnotation = null, //"Bizwhackin it up",
|
||||||
RomStatusDetails = null, //"LEVAR BURTON",
|
RomStatusDetails = null, //"LEVAR BURTON",
|
||||||
|
CpuTraceAvailable = true
|
||||||
};
|
};
|
||||||
|
|
||||||
public CoreOutputComm CoreOutputComm
|
public CoreOutputComm CoreOutputComm
|
||||||
|
@ -417,6 +423,31 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
get { return GbOutputComm; }
|
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
|
#region MemoryDomains
|
||||||
|
|
||||||
class MemoryRefresher
|
class MemoryRefresher
|
||||||
|
|
|
@ -152,6 +152,21 @@ namespace BizHawk.Emulation.Consoles.GB
|
||||||
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static extern void gambatte_setwritecallback(IntPtr core, MemoryCallback callback);
|
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>
|
/// <summary>
|
||||||
/// Sets the directory used for storing save data. The default is the same directory as the ROM Image file.
|
/// Sets the directory used for storing save data. The default is the same directory as the ROM Image file.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Binary file not shown.
|
@ -85,6 +85,7 @@ public:
|
||||||
|
|
||||||
void setReadCallback(void (*callback)(unsigned));
|
void setReadCallback(void (*callback)(unsigned));
|
||||||
void setWriteCallback(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. */
|
/** 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);
|
void setSaveDir(const std::string &sdir);
|
||||||
|
|
|
@ -77,6 +77,12 @@ __declspec(dllexport) void gambatte_setwritecallback(void *core, void (*callback
|
||||||
g->setWriteCallback(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)
|
__declspec(dllexport) void gambatte_setsavedir(void *core, const char *sdir)
|
||||||
{
|
{
|
||||||
GB *g = (GB *) core;
|
GB *g = (GB *) core;
|
||||||
|
|
|
@ -22,6 +22,8 @@ extern "C"
|
||||||
|
|
||||||
__declspec(dllexport) void gambatte_setwritecallback(void *core, void (*callback)(unsigned));
|
__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) void gambatte_setsavedir(void *core, const char *sdir);
|
||||||
|
|
||||||
__declspec(dllexport) int gambatte_iscgb(void *core);
|
__declspec(dllexport) int gambatte_iscgb(void *core);
|
||||||
|
|
|
@ -38,7 +38,8 @@ CPU::CPU()
|
||||||
E(0xD8),
|
E(0xD8),
|
||||||
H(0x01),
|
H(0x01),
|
||||||
L(0x4D),
|
L(0x4D),
|
||||||
skip(false)
|
skip(false),
|
||||||
|
tracecallback(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +521,27 @@ void CPU::process(const unsigned long cycles) {
|
||||||
} else while (cycleCounter < memory.nextEventTime()) {
|
} else while (cycleCounter < memory.nextEventTime()) {
|
||||||
unsigned char opcode;
|
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) {
|
if (skip) {
|
||||||
PC = (PC - 1) & 0xFFFF;
|
PC = (PC - 1) & 0xFFFF;
|
||||||
|
|
|
@ -39,6 +39,8 @@ class CPU {
|
||||||
|
|
||||||
void process(unsigned long cycles);
|
void process(unsigned long cycles);
|
||||||
|
|
||||||
|
void (*tracecallback)(void *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
CPU();
|
CPU();
|
||||||
|
@ -73,6 +75,10 @@ public:
|
||||||
memory.setWriteCallback(callback);
|
memory.setWriteCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setTraceCallback(void (*callback)(void *)) {
|
||||||
|
tracecallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
void setSaveDir(const std::string &sdir) {
|
void setSaveDir(const std::string &sdir) {
|
||||||
memory.setSaveDir(sdir);
|
memory.setSaveDir(sdir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,10 @@ void GB::setWriteCallback(void (*callback)(unsigned)) {
|
||||||
p_->cpu.setWriteCallback(callback);
|
p_->cpu.setWriteCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GB::setTraceCallback(void (*callback)(void *)) {
|
||||||
|
p_->cpu.setTraceCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void GB::setSaveDir(const std::string &sdir) {
|
void GB::setSaveDir(const std::string &sdir) {
|
||||||
p_->cpu.setSaveDir(sdir);
|
p_->cpu.setSaveDir(sdir);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue