1 + cpuid, SH2_DRCBLK_DA_SHIFT, 0xfff);
}
-int sh2_execute(SH2 *sh2c, int cycles)
+int sh2_execute_drc(SH2 *sh2c, int cycles)
{
int ret_cycles;
- sh2c->cycles_timeslice = cycles;
-
// cycles are kept in SHR_SR unused bits (upper 20)
// bit11 contains T saved for delay slot
// others are usual SH2 flags
dbg(1, "warning: drc returned with cycles: %d", ret_cycles);
sh2c->sr &= 0x3f3;
- return sh2c->cycles_timeslice - ret_cycles;
+ return ret_cycles;
}
#if (DRC_DEBUG & 2)
typedef unsigned char UINT8;
#endif
-#define RB(sh2, a) p32x_sh2_read8(a,sh2)
-#define RW(sh2, a) p32x_sh2_read16(a,sh2)
-#define RL(sh2, a) p32x_sh2_read32(a,sh2)
-#define WB(sh2, a, d) p32x_sh2_write8(a,d,sh2)
-#define WW(sh2, a, d) p32x_sh2_write16(a,d,sh2)
-#define WL(sh2, a, d) p32x_sh2_write32(a,d,sh2)
+#ifdef DRC_SH2
+
+// this nasty conversion is needed for drc-expecting memhandlers
+#define MAKE_READFUNC(name, cname) \
+static inline unsigned int name(SH2 *sh2, unsigned int a) \
+{ \
+ unsigned int ret; \
+ sh2->sr |= sh2->icount << 12; \
+ ret = cname(a, sh2); \
+ sh2->icount = (signed int)sh2->sr >> 12; \
+ sh2->sr &= 0x3f3; \
+ return ret; \
+}
+
+#define MAKE_WRITEFUNC(name, cname) \
+static inline void name(SH2 *sh2, unsigned int a, unsigned int d) \
+{ \
+ sh2->sr |= sh2->icount << 12; \
+ cname(a, d, sh2); \
+ sh2->icount = (signed int)sh2->sr >> 12; \
+ sh2->sr &= 0x3f3; \
+}
+
+MAKE_READFUNC(RB, p32x_sh2_read8)
+MAKE_READFUNC(RW, p32x_sh2_read16)
+MAKE_READFUNC(RL, p32x_sh2_read32)
+MAKE_WRITEFUNC(WB, p32x_sh2_write8)
+MAKE_WRITEFUNC(WW, p32x_sh2_write16)
+MAKE_WRITEFUNC(WL, p32x_sh2_write32)
+
+#else
+
+#define RB(sh2, a) p32x_sh2_read8(a, sh2)
+#define RW(sh2, a) p32x_sh2_read16(a, sh2)
+#define RL(sh2, a) p32x_sh2_read32(a, sh2)
+#define WB(sh2, a, d) p32x_sh2_write8(a, d, sh2)
+#define WW(sh2, a, d) p32x_sh2_write16(a, d, sh2)
+#define WL(sh2, a, d) p32x_sh2_write32(a, d, sh2)
+
+#endif
// some stuff from sh2comn.h
#define T 0x00000001
#include "sh2.c"
-#ifndef DRC_SH2
#ifndef DRC_CMP
-int sh2_execute(SH2 *sh2, int cycles)
+int sh2_execute_interpreter(SH2 *sh2, int cycles)
{
UINT32 opcode;
- sh2->icount = sh2->cycles_timeslice = cycles;
+ sh2->icount = cycles;
if (sh2->icount <= 0)
goto out;
while (sh2->icount > 0 || sh2->delay); /* can't interrupt before delay */
out:
- return sh2->cycles_timeslice - sh2->icount;
+ return sh2->icount;
}
#else // if DRC_CMP
-int sh2_execute(SH2 *sh2, int cycles)
+int sh2_execute_interpreter(SH2 *sh2, int cycles)
{
static unsigned int base_pc_[2] = { 0, 0 };
static unsigned int end_pc_[2] = { 0, 0 };
while (1);
out:
- return sh2->cycles_timeslice - sh2->icount;
+ return sh2->icount;
}
#endif // DRC_CMP
-#endif // DRC_SH2
#ifdef SH2_STATS
#include <stdio.h>
void sh2_pack(const SH2 *sh2, unsigned char *buff);\r
void sh2_unpack(SH2 *sh2, const unsigned char *buff);\r
\r
-int sh2_execute(SH2 *sh2, int cycles);\r
+int sh2_execute_drc(SH2 *sh2c, int cycles);\r
+int sh2_execute_interpreter(SH2 *sh2c, int cycles);\r
+\r
+static inline int sh2_execute(SH2 *sh2, int cycles, int use_drc)\r
+{\r
+ int ret;\r
+\r
+ sh2->cycles_timeslice = cycles;\r
+#ifdef DRC_SH2\r
+ if (use_drc)\r
+ ret = sh2_execute_drc(sh2, cycles);\r
+ else\r
+#endif\r
+ ret = sh2_execute_interpreter(sh2, cycles);\r
+\r
+ return sh2->cycles_timeslice - ret;\r
+}\r
\r
// regs, pending_int*, cycles, reserved\r
#define SH2_STATE_SIZE ((24 + 2 + 2 + 12) * 4)\r
//{ "region", "Region; Auto|NTSC|PAL" },
{ "picodrive_input1", "Input device 1; 3 button pad|6 button pad|None" },
{ "picodrive_input2", "Input device 2; 3 button pad|6 button pad|None" },
+#ifdef DRC_SH2
+ { "picodrive_drc", "Dynamic recompilers; enabled|disabled" },
+#endif
{ NULL, NULL },
};
var.key = "picodrive_input2";
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
PicoSetInputDevice(1, input_name_to_val(var.value));
+
+#ifdef DRC_SH2
+ var.value = NULL;
+ var.key = "picodrive_drc";
+ if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) {
+ if (strcmp(var.value, "enabled") == 0)
+ PicoOpt |= POPT_EN_DRC;
+ else
+ PicoOpt &= ~POPT_EN_DRC;
+ }
+#endif
}
void retro_run(void)