rcache_clean();
+#ifndef DCR_SR_REG
// must writeback cycles for poll detection stuff
- // FIXME: rm
if (reg_map_g2h[SHR_SR] != -1)
emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
-
+#endif
arg1 = rcache_get_tmp_arg(1);
emith_move_r_r_ptr(arg1, CONTEXT_REG);
switch (size) {
case 2: emith_call(sh2_drc_read32); break; // 32
}
rcache_invalidate();
-
+#ifndef DCR_SR_REG
if (reg_map_g2h[SHR_SR] != -1)
emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
-
+#endif
return rcache_get_tmp_ret();
}
static void emit_memhandler_write(int size)
{
int arg2;
-
+#ifndef DCR_SR_REG
if (reg_map_g2h[SHR_SR] != -1)
emith_ctx_write(reg_map_g2h[SHR_SR], SHR_SR * 4);
-
+#endif
rcache_clean();
arg2 = rcache_get_tmp_arg(2);
}
rcache_invalidate();
+#ifndef DCR_SR_REG
if (reg_map_g2h[SHR_SR] != -1)
emith_ctx_read(reg_map_g2h[SHR_SR], SHR_SR * 4);
+#endif
}
// rd = @(Rs,#offs)
#define sh2_drc_frame()
#endif
-#define BLOCK_INSN_LIMIT 128
+#define BLOCK_INSN_LIMIT 1024
/* op_flags */
#define OF_DELAY_OP (1 << 0)
void scan_block(unsigned int base_pc, int is_slave,
unsigned char *op_flags, unsigned int *end_pc,
unsigned int *end_literals);
+
+#if defined(DRC_SH2)
+// direct access to some host CPU registers used by the DRC
+// XXX MUST match definitions in cpu/sh2/compiler.c
+#if defined(_arm__)
+#define DRC_SR_REG r10
+#elif defined(__i386__)
+#define DRC_SR_REG edi
+#else
+#warning "direct DRC register access not available for this host"
+#endif
+
+#ifdef DCR_SR_REG
+#define DRC_DECLARE_SR register int sh2_sr asm(#DCR_SR_REG)
+#define DRC_SAVE_SR(sh2) \
+ if ((sh2->state & (SH2_STATE_RUN|SH2_STATE_BUSY)) == SH2_STATE_RUN) \
+ sh2->sr = sh2_sr;
+#define DRC_RESTORE_SR(sh2) \
+ if ((sh2->state & (SH2_STATE_RUN|SH2_STATE_BUSY)) == SH2_STATE_RUN) \
+ sh2_sr = sh2->sr;
+#else
+#define DRC_DECLARE_SR
+#define DRC_SAVE_SR(sh2)
+#define DRC_RESTORE_SR(sh2)
+#endif
+#endif
*/
#include "../pico_int.h"
#include "../memory.h"
+
#include "../../cpu/sh2/compiler.h"
+DRC_DECLARE_SR;
static const char str_mars[] = "MARS";
static u32 sh2_read8_cs0(u32 a, SH2 *sh2)
{
u32 d = 0;
+ DRC_SAVE_SR(sh2);
sh2_burn_cycles(sh2, 1*2);
goto out_16to8;
}
- // TODO: mirroring?
- if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
- return Pico32xMem->sh2_rom_m.b[a ^ 1];
- if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
- return Pico32xMem->sh2_rom_s.b[a ^ 1];
-
if ((a & 0x3fe00) == 0x4200) {
d = Pico32xMem->pal[(a & 0x1ff) / 2];
goto out_16to8;
}
- return sh2_read8_unmapped(a, sh2);
+ // TODO: mirroring?
+ if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
+ d = Pico32xMem->sh2_rom_m.b[a ^ 1];
+ else if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
+ d = Pico32xMem->sh2_rom_s.b[a ^ 1];
+ else
+ d = sh2_read8_unmapped(a, sh2);
+ goto out;
out_16to8:
if (a & 1)
else
d >>= 8;
+out:
elprintf_sh2(sh2, EL_32X, "r8 [%08x] %02x @%06x",
a, d, sh2_pc(sh2));
+ DRC_RESTORE_SR(sh2);
return d;
}
static u32 sh2_read16_cs0(u32 a, SH2 *sh2)
{
u32 d = 0;
+ DRC_SAVE_SR(sh2);
sh2_burn_cycles(sh2, 1*2);
if ((a & 0x3ffc0) == 0x4000) {
d = p32x_sh2reg_read16(a, sh2);
if (!(EL_LOGMASK & EL_PWM) && (a & 0x30) == 0x30) // hide PWM
- return d;
+ goto out_noprint;
goto out;
}
goto out;
}
- if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
- return Pico32xMem->sh2_rom_m.w[a / 2];
- if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
- return Pico32xMem->sh2_rom_s.w[a / 2];
-
if ((a & 0x3fe00) == 0x4200) {
d = Pico32xMem->pal[(a & 0x1ff) / 2];
goto out;
}
- return sh2_read16_unmapped(a, sh2);
+ if (!sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_m))
+ d = Pico32xMem->sh2_rom_m.w[a / 2];
+ else if (sh2->is_slave && a < sizeof(Pico32xMem->sh2_rom_s))
+ d = Pico32xMem->sh2_rom_s.w[a / 2];
+ else
+ d = sh2_read16_unmapped(a, sh2);
out:
elprintf_sh2(sh2, EL_32X, "r16 [%08x] %04x @%06x",
a, d, sh2_pc(sh2));
+out_noprint:
+ DRC_RESTORE_SR(sh2);
return d;
}
static void REGPARM(3) sh2_write8_cs0(u32 a, u32 d, SH2 *sh2)
{
+ DRC_SAVE_SR(sh2);
elprintf_sh2(sh2, EL_32X, "w8 [%08x] %02x @%06x",
a, d & 0xff, sh2_pc(sh2));
if ((a & 0x3fff0) == 0x4100) {
sh2->poll_addr = 0;
p32x_vdp_write8(a, d);
- return;
+ goto out;
+ }
+
+ if ((a & 0x3fe00) == 0x4200) {
+ ((u8 *)Pico32xMem->pal)[(a & 0x1ff) ^ 1] = d;
+ Pico32x.dirty_pal = 1;
+ goto out;
}
}
if ((a & 0x3ffc0) == 0x4000) {
p32x_sh2reg_write8(a, d, sh2);
- return;
+ goto out;
}
sh2_write8_unmapped(a, d, sh2);
+out:
+ DRC_RESTORE_SR(sh2);
}
static void REGPARM(3) sh2_write8_dram0(u32 a, u32 d, SH2 *sh2)
static void REGPARM(3) sh2_write8_sdram_wt(u32 a, u32 d, SH2 *sh2)
{
// xmen sync hack..
- if (a < 0x26000200)
+ if (a < 0x26000200) {
+ DRC_SAVE_SR(sh2);
sh2_end_run(sh2, 32);
+ DRC_RESTORE_SR(sh2);
+ }
sh2_write8_sdram(a, d, sh2);
}
static void REGPARM(3) sh2_write16_cs0(u32 a, u32 d, SH2 *sh2)
{
+ DRC_SAVE_SR(sh2);
if (((EL_LOGMASK & EL_PWM) || (a & 0x30) != 0x30)) // hide PWM
elprintf_sh2(sh2, EL_32X, "w16 [%08x] %04x @%06x",
a, d & 0xffff, sh2_pc(sh2));
if ((a & 0x3fff0) == 0x4100) {
sh2->poll_addr = 0;
p32x_vdp_write16(a, d, sh2);
- return;
+ goto out;
}
if ((a & 0x3fe00) == 0x4200) {
Pico32xMem->pal[(a & 0x1ff) / 2] = d;
Pico32x.dirty_pal = 1;
- return;
+ goto out;
}
}
if ((a & 0x3ffc0) == 0x4000) {
p32x_sh2reg_write16(a, d, sh2);
- return;
+ goto out;
}
sh2_write16_unmapped(a, d, sh2);
+out:
+ DRC_RESTORE_SR(sh2);
}
static void REGPARM(3) sh2_write16_dram0(u32 a, u32 d, SH2 *sh2)