summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blastem.c1
-rw-r--r--m68k_core.c3
-rw-r--r--m68k_core.h2
-rw-r--r--m68k_core_x86.c33
-rw-r--r--m68k_internal.h1
5 files changed, 38 insertions, 2 deletions
diff --git a/blastem.c b/blastem.c
index 2528ecb..e4645eb 100644
--- a/blastem.c
+++ b/blastem.c
@@ -821,6 +821,7 @@ void init_run_cpu(genesis_context * gen, rom_info *rom, FILE * address_log, char
init_m68k_opts(&opts, rom->map, rom->map_chunks, MCLKS_PER_68K);
opts.address_log = address_log;
+ opts.gen.flags |= M68K_OPT_BROKEN_READ_MODIFY;
m68k_context *context = init_68k_context(&opts);
gen->m68k = context;
diff --git a/m68k_core.c b/m68k_core.c
index 09e2662..490fcec 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -796,10 +796,9 @@ impl_info m68k_impls[] = {
//misc
RAW_IMPL(M68K_NOP, translate_m68k_nop),
RAW_IMPL(M68K_RESET, translate_m68k_reset),
+ RAW_IMPL(M68K_TAS, translate_m68k_tas),
//currently unimplemented
- //M68K_NBCD
- //M68K_TAS
//M68K_TRAPV
};
diff --git a/m68k_core.h b/m68k_core.h
index 421302f..7135000 100644
--- a/m68k_core.h
+++ b/m68k_core.h
@@ -16,6 +16,8 @@ struct m68kinst;
#define NATIVE_CHUNK_SIZE ((16 * 1024 * 1024 / NATIVE_MAP_CHUNKS)/2)
#define MAX_NATIVE_SIZE 255
+#define M68K_OPT_BROKEN_READ_MODIFY 1
+
typedef void (*start_fun)(uint8_t * addr, void * context);
typedef struct {
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index bb3c702..f23c51d 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -1312,6 +1312,39 @@ void translate_m68k_cmp(m68k_options * opts, m68kinst * inst)
translate_m68k_arith(opts, inst, N|Z|V|C, &src_op, &dst_op);
}
+void translate_m68k_tas(m68k_options *opts, m68kinst *inst)
+{
+ code_info *code = &opts->gen.code;
+ host_ea op;
+ translate_m68k_op(inst, &op, opts, 1);
+ if (op.mode == MODE_REG_DIRECT) {
+ cmp_ir(code, 0, op.base, SZ_B);
+ } else {
+ cmp_irdisp(code, 0, op.base, op.disp, SZ_B);
+ }
+ update_flags(opts, N|Z|V0|C0);
+ if (inst->dst.addr_mode == MODE_REG) {
+ cycles(&opts->gen, BUS);
+ if (op.mode == MODE_REG_DIRECT) {
+ bts_ir(code, 7, op.base, SZ_B);
+ } else {
+ bts_irdisp(code, 7, op.base, op.disp, SZ_B);
+ }
+ } else {
+ if (opts->gen.flags & M68K_OPT_BROKEN_READ_MODIFY) {
+ //2 cycles for processing
+ //4 for failed writeback
+ //4 for prefetch
+ cycles(&opts->gen, BUS * 2 + 2);
+ } else {
+ cycles(&opts->gen, 2);
+ bts_ir(code, 7, op.base, SZ_B);
+ m68k_save_result(inst, opts);
+ cycles(&opts->gen, BUS);
+ }
+ }
+}
+
void op_r(code_info *code, m68kinst *inst, uint8_t dst, uint8_t size)
{
switch(inst->op)
diff --git a/m68k_internal.h b/m68k_internal.h
index 13b7c15..b0c162e 100644
--- a/m68k_internal.h
+++ b/m68k_internal.h
@@ -66,6 +66,7 @@ void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mas
void translate_m68k_unary(m68k_options *opts, m68kinst *inst, uint32_t flag_mask, host_ea *dst_op);
void translate_m68k_invalid(m68k_options *opts, m68kinst *inst);
void translate_m68k_cmp(m68k_options * opts, m68kinst * inst);
+void translate_m68k_tas(m68k_options * opts, m68kinst * inst);
void translate_m68k_clr(m68k_options * opts, m68kinst * inst);
void translate_m68k_ext(m68k_options * opts, m68kinst * inst);
void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op);