-// SSP1601 to ARM recompiler
-
-// (c) Copyright 2008, Grazvydas "notaz" Ignotas
-// Free for non-commercial use.
+/*
+ * SSP1601 to ARM recompiler
+ * (C) notaz, 2008,2009,2010
+ *
+ * This work is licensed under the terms of MAME license.
+ * See COPYING file in the top-level directory.
+ */
#include "../../pico_int.h"
#include "../../../cpu/drc/cmn.h"
#define SSP_FLAG_Z (1<<0xd)
#define SSP_FLAG_N (1<<0xf)
-#ifndef ARM
+#ifndef __arm__
//#define DUMP_BLOCK 0x0c9a
void ssp_drc_next(void){}
void ssp_drc_next_patch(void){}
return 0;
}
+#ifdef __MACH__
+/* spacial version of call for calling C needed on ios, since we use r9.. */
+static void emith_call_c_func(void *target)
+{
+ EOP_STMFD_SP(A_R7M|A_R9M);
+ emith_call(target);
+ EOP_LDMFD_SP(A_R7M|A_R9M);
+}
+#else
+#define emith_call_c_func emith_call
+#endif
+
// -----------------------------------------------------
//@ r4: XXYY
tr_flush_dirty_ST();
//tr_flush_dirty_pmcrs();
tr_mov16(0, reg);
- emith_call(ssp_pm_read);
+ emith_call_c_func(ssp_pm_read);
hostreg_clear();
}
tr_flush_dirty_ST();
//tr_flush_dirty_pmcrs();
tr_mov16(1, reg);
- emith_call(ssp_pm_write);
+ emith_call_c_func(ssp_pm_write);
hostreg_clear();
}
* >0: direct (un)conditional jump
* <0: indirect jump
*/
-static void emit_block_epilogue(int cycles, int cond, int pc, int end_pc)
+static void *emit_block_epilogue(int cycles, int cond, int pc, int end_pc)
{
- if (cycles > 0xff) { elprintf(EL_ANOMALY, "large cycle count: %i\n", cycles); cycles = 0xff; }
+ void *end_ptr = NULL;
+
+ if (cycles > 0xff) {
+ elprintf(EL_ANOMALY, "large cycle count: %i\n", cycles);
+ cycles = 0xff;
+ }
EOP_SUB_IMM(11,11,0,cycles); // sub r11, r11, #cycles
if (cond < 0 || (end_pc >= 0x400 && pc < 0x400)) {
emith_jump(target);
else {
int ops = emith_jump(ssp_drc_next);
+ end_ptr = tcache_ptr;
// cause the next block to be emitted over jump instruction
tcache_ptr -= ops;
}
emith_jump(ssp_drc_next);
#endif
}
+
+ if (end_ptr == NULL)
+ end_ptr = tcache_ptr;
+
+ return end_ptr;
}
void *ssp_translate_block(int pc)
{
unsigned int op, op1, imm, ccount = 0;
- unsigned int *block_start;
+ unsigned int *block_start, *block_end;
int ret, end_cond = A_COND_AL, jump_pc = -1;
//printf("translate %04x -> %04x\n", pc<<1, (tcache_ptr-tcache)<<2);
tr_flush_dirty_prs();
tr_flush_dirty_ST();
tr_flush_dirty_pmcrs();
- emit_block_epilogue(ccount, end_cond, jump_pc, pc);
+ block_end = emit_block_epilogue(ccount, end_cond, jump_pc, pc);
if (tcache_ptr - (u32 *)tcache > DRC_TCACHE_SIZE/4) {
elprintf(EL_ANOMALY|EL_STATUS|EL_SVP, "tcache overflow!\n");
exit(0);
#endif
-#ifdef ARM
- cache_flush_d_inval_i(tcache, tcache_ptr);
+#ifdef __arm__
+ cache_flush_d_inval_i(block_start, block_end);
#endif
return block_start;
PicoLoadStateHook = ssp1601_state_load;
n_in_ops = 0;
-#ifdef ARM
+#ifdef __arm__
// hle'd blocks
ssp_block_table[0x800/2] = (void *) ssp_hle_800;
ssp_block_table[0x902/2] = (void *) ssp_hle_902;
#ifdef DUMP_BLOCK
ssp_translate_block(DUMP_BLOCK >> 1);
#endif
-#ifdef ARM
- ssp_drc_entry(cycles);
+#ifdef __arm__
+ ssp_drc_entry(ssp, cycles);
#endif
}