# HG changeset patch # User Michael Pavone # Date 1446086724 25200 # Node ID f2cd380adebe3ea4f8c01e965f48a171dce4221d # Parent 124a58fdcf3a3d202bbbb5df09a123ce37d3dbd6 Implement TAS diff -r 124a58fdcf3a -r f2cd380adebe blastem.c --- a/blastem.c Wed Oct 28 19:40:01 2015 -0700 +++ b/blastem.c Wed Oct 28 19:45:24 2015 -0700 @@ -821,6 +821,7 @@ 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 -r 124a58fdcf3a -r f2cd380adebe m68k_core.c --- a/m68k_core.c Wed Oct 28 19:40:01 2015 -0700 +++ b/m68k_core.c Wed Oct 28 19:45:24 2015 -0700 @@ -796,10 +796,9 @@ //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 -r 124a58fdcf3a -r f2cd380adebe m68k_core.h --- a/m68k_core.h Wed Oct 28 19:40:01 2015 -0700 +++ b/m68k_core.h Wed Oct 28 19:45:24 2015 -0700 @@ -16,6 +16,8 @@ #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 -r 124a58fdcf3a -r f2cd380adebe m68k_core_x86.c --- a/m68k_core_x86.c Wed Oct 28 19:40:01 2015 -0700 +++ b/m68k_core_x86.c Wed Oct 28 19:45:24 2015 -0700 @@ -1312,6 +1312,39 @@ 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 -r 124a58fdcf3a -r f2cd380adebe m68k_internal.h --- a/m68k_internal.h Wed Oct 28 19:40:01 2015 -0700 +++ b/m68k_internal.h Wed Oct 28 19:45:24 2015 -0700 @@ -66,6 +66,7 @@ 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);