yabause tracer

This commit is contained in:
feos 2016-08-24 00:04:44 +03:00
parent cac0f533db
commit 6e0b8e2784
12 changed files with 206 additions and 171 deletions

View File

@ -942,6 +942,9 @@
<Compile Include="Consoles\Sega\Saturn\Yabause.IStatable.cs">
<DependentUpon>Yabause.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\Saturn\Yabause.ITraceable.cs">
<DependentUpon>Yabause.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Sega\SMS\SMS.cs" />
<Compile Include="Consoles\Sega\SMS\SMS.ICodeDataLogger.cs">
<DependentUpon>SMS.cs</DependentUpon>

View File

@ -85,6 +85,17 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn
public static extern void libyabause_setinputcallback(InputCallback cb);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void TraceCallback(string dis, string regs);
/// <summary>
/// set a fcn to call every time input is read
/// </summary>
/// <param name="cb">execxutes right before the input read. null to clear</param>
[DllImport("libyabause.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void libyabause_settracecallback(TraceCallback cb);
/// <summary>
///
/// </summary>

View File

@ -79,6 +79,7 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn
InputCallbackH = new LibYabause.InputCallback(() => InputCallbacks.Call());
LibYabause.libyabause_setinputcallback(InputCallbackH);
ConnectTracer();
DriveLightEnabled = true;
DeactivateGL();
@ -277,6 +278,11 @@ namespace BizHawk.Emulation.Cores.Sega.Saturn
DriveLightOn = false;
if (Tracer.Enabled)
LibYabause.libyabause_settracecallback(trace_cb);
else
LibYabause.libyabause_settracecallback(null);
IsLagFrame = LibYabause.libyabause_frameadvance(out w, out h, out nsamp);
BufferWidth = w;
BufferHeight = h;

View File

@ -39,6 +39,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
private void ConnectTracer()
{
trace_cb = new OctoshockDll.ShockCallback_Trace(ShockTraceCallback);
Tracer = new TraceBuffer() { Header = TraceHeader };
ServiceProvider = new BasicServiceProvider(this);
(ServiceProvider as BasicServiceProvider).Register<ITraceable>(Tracer);

View File

@ -323,8 +323,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
SetMemoryDomains();
InitMemCallbacks();
trace_cb = new OctoshockDll.ShockCallback_Trace(ShockTraceCallback);
//set a default framebuffer based on the first frame of emulation, to cut down on flickering or whatever
//this is probably quixotic, but we have to pick something
{

Binary file not shown.

View File

@ -24,6 +24,13 @@ extern "C" __declspec(dllexport) void libyabause_setinputcallback(void (*cb)(voi
inputcallback = cb;
}
void (*tracecallback)(const char* dis, const char* regs) = NULL;
extern "C" __declspec(dllexport) void libyabause_settracecallback(void (*cb)(const char* dis, const char* regs))
{
tracecallback = cb;
}
CDInterface FECD =
{
2,

View File

@ -149,8 +149,8 @@ i_descr tab[] = {
{ MD_F, "mov.w @(0x%03X, r%d), r0", 0xff00, 0x8500, 0, 0 },
{ ND4_F, "mov.b r0, @(0x%03X, r%d)", 0xff00, 0x8000, 0, 0 },
{ ND4_F, "mov.w r0, @(0x%03X, r%d)", 0xff00, 0x8100, 0, 0 },
{ NMD_F, "mov.l r%d, @(0x%03X, r%d)", 0xf000, 0x1000, 0,0 },
{ NMD_F, "mov.l @(0x%03X, r%d), r%d", 0xf000, 0x5000, 0,0 },
{ NMD_F, "mov.l r%d, @(0x%03X, r%d)", 0xf000, 0x1000, 0, 0 },
{ NMD_F, "mov.l @(0x%03X, r%d), r%d", 0xf000, 0x5000, 0, 0 },
{ D_F, "mov.b r0, @(0x%03X, gbr)", 0xff00, 0xc000, 1, 0 },
{ D_F, "mov.w r0, @(0x%03X, gbr)", 0xff00, 0xc100, 2, 0 },
{ D_F, "mov.l r0, @(0x%03X, gbr)", 0xff00, 0xc200, 4, 0 },
@ -166,10 +166,10 @@ i_descr tab[] = {
{ D12_F, "bsr 0x%08X", 0xf000, 0xb000, 0, 0 },
{ ND8_F, "mov.w @(0x%03X, pc), r%d", 0xf000, 0x9000, 2, 0 },
{ ND8_F, "mov.l @(0x%03X, pc), r%d", 0xf000, 0xd000, 4, 0 },
{ I_F, "and.b #0x%02X, @(r0, gbr)", 0xff00, 0xcd00, 0,0 },
{ I_F, "or.b #0x%02X, @(r0, gbr)", 0xff00, 0xcf00, 0,0 },
{ I_F, "tst.b #0x%02X, @(r0, gbr)", 0xff00, 0xcc00, 0,0 },
{ I_F, "xor.b #0x%02X, @(r0, gbr)", 0xff00, 0xce00, 0,0 },
{ I_F, "and.b #0x%02X, @(r0, gbr)", 0xff00, 0xcd00, 0, 0 },
{ I_F, "or.b #0x%02X, @(r0, gbr)", 0xff00, 0xcf00, 0, 0 },
{ I_F, "tst.b #0x%02X, @(r0, gbr)", 0xff00, 0xcc00, 0, 0 },
{ I_F, "xor.b #0x%02X, @(r0, gbr)", 0xff00, 0xce00, 0, 0 },
{ I_F, "and #0x%02X, r0", 0xff00, 0xc900, 0, 0 },
{ I_F, "cmp/eq #0x%02X, r0", 0xff00, 0x8800, 0, 0 },
{ I_F, "or #0x%02X, r0", 0xff00, 0xcb00, 0, 0 },

View File

@ -31,23 +31,23 @@
#include "bios.h"
#include "yabause.h"
// #define SH2_TRACE // Uncomment to enable tracing
#define SH2_TRACE // Uncomment to enable tracing
#ifdef SH2_TRACE
# include "sh2trace.h"
# define MappedMemoryWriteByte(a,v) do { \
uint32_t __a = (a), __v = (v); \
sh2_trace_writeb(__a, __v); \
u32 __a = (a), __v = (v); \
/*sh2_trace_writeb(__a, __v);*/ \
MappedMemoryWriteByte(__a, __v); \
} while (0)
# define MappedMemoryWriteWord(a,v) do { \
uint32_t __a = (a), __v = (v); \
sh2_trace_writew(__a, __v); \
u32 __a = (a), __v = (v); \
/*sh2_trace_writew(__a, __v);*/ \
MappedMemoryWriteWord(__a, __v); \
} while (0)
# define MappedMemoryWriteLong(a,v) do { \
uint32_t __a = (a), __v = (v); \
sh2_trace_writel(__a, __v); \
u32 __a = (a), __v = (v); \
/*sh2_trace_writel(__a, __v);*/ \
MappedMemoryWriteLong(__a, __v); \
} while (0)
#endif

View File

@ -48,6 +48,8 @@ static FILE *logfile; // Trace log file
static u64 cycle_accum = 0; // Global cycle accumulator
static u64 current_cycles = 0; // Cycle count on last call to sh2_trace()
char disasmbuf[128];
/*************************************************************************/
FASTCALL u64 sh2_cycle_count(void)
@ -163,6 +165,9 @@ static INLINE void HEXIT(char * const ptr, u32 val, int ndigits)
FASTCALL void sh2_trace(SH2_struct *state, u32 address)
{
if (!tracecallback)
return;
current_cycles = cycle_accum + state->cycles;
if (current_cycles < trace_start) {
@ -171,7 +176,7 @@ FASTCALL void sh2_trace(SH2_struct *state, u32 address)
} else if (current_cycles >= trace_stop) {
/* After last instruction: close log file if it's open */
/* After last instruction: close log file if it's open
if (logfile) {
#ifdef GZIP_LOG
pclose(logfile);
@ -179,7 +184,7 @@ FASTCALL void sh2_trace(SH2_struct *state, u32 address)
fclose(logfile);
#endif
logfile = NULL;
}
}*/
} else {
u16 opcode;
@ -194,10 +199,10 @@ FASTCALL void sh2_trace(SH2_struct *state, u32 address)
#else
char buf[100];
/* This looks ugly, but it's faster than fprintf() in this case */
static char regbuf[] = " R0: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX\n R8: XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX\n PR: XXXXXXXX SR: XXX MAC: XXXXXXXX/XXXXXXXX GBR: XXXXXXXX VBR: XXXXXXXX\n";
static char regbuf[] = "r0:XXXXXXXX r1:XXXXXXXX r2:XXXXXXXX r3:XXXXXXXX r4:XXXXXXXX r5:XXXXXXXX r6:XXXXXXXX r7:XXXXXXXX r8:XXXXXXXX r9:XXXXXXXX r10:XXXXXXXX r11:XXXXXXXX r12:XXXXXXXX r13:XXXXXXXX r14:XXXXXXXX r15:XXXXXXXX PR:XXXXXXXX SR:XXX MAC:XXXXXXXX XXXXXXXX GBR:XXXXXXXX VBR:XXXXXXXX";
int i;
#endif
/*
if (!logfile) {
const char *filename = "sh2.log";
#ifdef GZIP_LOG
@ -211,7 +216,7 @@ FASTCALL void sh2_trace(SH2_struct *state, u32 address)
return;
}
setvbuf(logfile, NULL, _IOFBF, 65536);
}
}*/
opcode = MappedMemoryReadWord(address);
@ -233,9 +238,8 @@ FASTCALL void sh2_trace(SH2_struct *state, u32 address)
SH2GetRegisters(state, &state->regs);
SH2Disasm(address, opcode, 0, buf);
fprintf(logfile, "[%c] %08X: %04X %-44s [%12llu]\n",
state==SSH2 ? 'S' : 'M', (int)address, (int)opcode, buf+12,
(unsigned long long)current_cycles);
sprintf(disasmbuf, "[%c] %08X: %04X %-26s",
state==SSH2 ? 'S' : 'M', (int)address, (int)opcode, buf+12);
#ifdef ECHO_TO_STDERR
fprintf(stderr, "[%c] %08X: %04X %-44s [%12llu]\n",
state==SSH2 ? 'S' : 'M', (int)address, (int)opcode, buf+12,
@ -243,21 +247,23 @@ FASTCALL void sh2_trace(SH2_struct *state, u32 address)
#endif
for (i = 0; i < 16; i++) {
HEXIT(i>=8 ? &regbuf[12+i*9] : &regbuf[6+i*9], state->regs.R[i], 8);
HEXIT(&regbuf[i>9 ? i*13-6 : i*12+3], state->regs.R[i], 8);
}
HEXIT(&regbuf[162], state->regs.PR, 8);
HEXIT(&regbuf[176], state->regs.SR.all, 3);
HEXIT(&regbuf[186], state->regs.MACH, 8);
HEXIT(&regbuf[195], state->regs.MACL, 8);
HEXIT(&regbuf[210], state->regs.GBR, 8);
HEXIT(&regbuf[225], state->regs.VBR, 8);
fwrite(regbuf, sizeof(regbuf)-1, 1, logfile);
HEXIT(&regbuf[201], state->regs.PR, 8);
HEXIT(&regbuf[213], state->regs.SR.all, 3);
HEXIT(&regbuf[221], state->regs.MACH, 8);
HEXIT(&regbuf[230], state->regs.MACL, 8);
HEXIT(&regbuf[243], state->regs.GBR, 8);
HEXIT(&regbuf[256], state->regs.VBR, 8);
//fwrite(regbuf, sizeof(regbuf)-1, 1, logfile);
#ifdef ECHO_TO_STDERR
fwrite(regbuf, sizeof(regbuf)-1, 1, stderr);
#endif
#endif // BINARY_LOG
tracecallback(disasmbuf, regbuf);
} // current_cycles >= trace_start && current_cycles < trace_stop
}

View File

@ -22,6 +22,7 @@
#define SH2TRACE_H
#include "core.h"
#include "yui.h"
extern FASTCALL u64 sh2_cycle_count(void);
extern FASTCALL void sh2_trace_add_cycles(s32 cycles);

View File

@ -56,6 +56,8 @@ void YuiSwapBuffers(void);
extern void (*inputcallback)(void);
extern void (*tracecallback)(const char* dis, const char* regs);