summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rwxr-xr-xcpu_dsl.py2
-rw-r--r--m68k.cpu108
-rw-r--r--m68k_core_x86.c33
-rw-r--r--trans.c24
5 files changed, 146 insertions, 23 deletions
diff --git a/Makefile b/Makefile
index ee295a6..730deab 100644
--- a/Makefile
+++ b/Makefile
@@ -297,7 +297,7 @@ libemu68k.a : $(M68KOBJS) $(TRANSOBJS)
ar rcs libemu68k.a $(M68KOBJS) $(TRANSOBJS)
trans : trans.o serialize.o $(M68KOBJS) $(TRANSOBJS) util.o
- $(CC) -o trans trans.o $(M68KOBJS) $(TRANSOBJS) util.o $(OPT)
+ $(CC) -o $@ $^ $(OPT)
transz80 : transz80.o $(Z80OBJS) $(TRANSOBJS)
$(CC) -o transz80 transz80.o $(Z80OBJS) $(TRANSOBJS)
diff --git a/cpu_dsl.py b/cpu_dsl.py
index f58749c..44e08fe 100755
--- a/cpu_dsl.py
+++ b/cpu_dsl.py
@@ -899,7 +899,7 @@ class NormalOp:
else:
param = parent.resolveLocal(param) or param
if param in fieldVals:
- param = fieldVals[index]
+ param = fieldVals[param]
prog.meta[self.params[0]] = param
elif self.op == 'dis':
#TODO: Disassembler
diff --git a/m68k.cpu b/m68k.cpu
index f601d47..30cafad 100644
--- a/m68k.cpu
+++ b/m68k.cpu
@@ -861,6 +861,114 @@ m68k_save_dst
end
m68k_save_dst Z
m68k_prefetch
+
+1110CCC0ZZ001RRR lsri
+ invalid Z 3
+ switch C
+ case 0
+ meta shift 8
+ default
+ meta shift C
+ end
+ lsr dregs.R shift dregs.R Z
+ update_flags XNZV0C
+ add shift shift shift
+ switch Z
+ case 2
+ add 4 shift shift
+ default
+ add 2 shift shift
+ end
+ cycles shift
+ #TODO: should this happen before or after the majority of the shift?
+ m68k_prefetch
+
+1110CCC0ZZ101RRR lsr_dn
+ invalid Z 3
+ local shift 8
+ and dregs.C 63 shift
+ lsr dregs.R shift dregs.R Z
+ update_flags XNZV0C
+ add shift shift shift
+ switch Z
+ case 2
+ add 4 shift shift
+ default
+ add 2 shift shift
+ end
+ cycles shift
+ #TODO: should this happen before or after the majority of the shift?
+ m68k_prefetch
+
+1110001011MMMRRR lsr_ea
+ invalid M 0
+ invalid M 1
+ invalid M 7 R 2
+ invalid M 7 R 3
+ invalid M 7 R 4
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+
+ m68k_fetch_dst_ea M R 0
+ lsr dst 1 dst
+ update_flags XNZV0C
+ m68k_save_dst 0
+ m68k_prefetch
+
+1110CCC1ZZ001RRR lsli
+ invalid Z 3
+ switch C
+ case 0
+ meta shift 8
+ default
+ meta shift C
+ end
+ lsl dregs.R shift dregs.R Z
+ update_flags XNZV0C
+ add shift shift shift
+ switch Z
+ case 2
+ add 4 shift shift
+ default
+ add 2 shift shift
+ end
+ cycles shift
+ #TODO: should this happen before or after the majority of the shift?
+ m68k_prefetch
+
+1110CCC1ZZ101RRR lsl_dn
+ invalid Z 3
+ local shift 8
+ and dregs.C 63 shift
+ lsl dregs.R shift dregs.R Z
+ update_flags XNZV0C
+ add shift shift shift
+ switch Z
+ case 2
+ add 4 shift shift
+ default
+ add 2 shift shift
+ end
+ cycles shift
+ #TODO: should this happen before or after the majority of the shift?
+ m68k_prefetch
+
+1110001111MMMRRR lsl_ea
+ invalid M 0
+ invalid M 1
+ invalid M 7 R 2
+ invalid M 7 R 3
+ invalid M 7 R 4
+ invalid M 7 R 5
+ invalid M 7 R 6
+ invalid M 7 R 7
+
+ m68k_fetch_dst_ea M R 0
+ lsl dst 1 dst
+ update_flags XNZV0C
+ m68k_save_dst 0
+ m68k_prefetch
00ZZRRRMMMEEESSS move
invalid Z 0
diff --git a/m68k_core_x86.c b/m68k_core_x86.c
index e88e219..3dd91b5 100644
--- a/m68k_core_x86.c
+++ b/m68k_core_x86.c
@@ -421,7 +421,11 @@ uint8_t translate_m68k_op(m68kinst * inst, host_ea * ea, m68k_options * opts, ui
push_r(code, opts->gen.scratch1);
}
dec_amount = inst->extra.size == OPSIZE_WORD ? 2 : (inst->extra.size == OPSIZE_LONG ? 4 : (op->params.regs.pri == 7 ? 2 :1));
- if (!dst) {
+ if (!dst || (
+ inst->op != M68K_MOVE && inst->op != M68K_MOVEM
+ && inst->op != M68K_SUBX && inst->op != M68K_ADDX
+ && inst->op != M68K_ABCD && inst->op != M68K_SBCD
+ )) {
cycles(&opts->gen, PREDEC_PENALTY);
}
subi_areg(opts, dec_amount, op->params.regs.pri);
@@ -874,7 +878,7 @@ void translate_m68k_scc(m68k_options * opts, m68kinst * inst)
code_ptr end_off = code->cur+1;
jmp(code, code->cur+2);
*true_off = code->cur - (true_off+1);
- cycles(&opts->gen, 6);
+ cycles(&opts->gen, inst->dst.addr_mode == MODE_REG ? 6 : 4);
if (dst_op.mode == MODE_REG_DIRECT) {
mov_ir(code, 0xFF, dst_op.base, SZ_B);
} else {
@@ -1190,8 +1194,6 @@ void translate_shift(m68k_options * opts, m68kinst * inst, host_ea *src_op, host
void translate_m68k_reset(m68k_options *opts, m68kinst *inst)
{
code_info *code = &opts->gen.code;
- //RESET instructions take a long time to give peripherals time to reset themselves
- cycles(&opts->gen, 132);
mov_rdispr(code, opts->gen.context_reg, offsetof(m68k_context, reset_handler), opts->gen.scratch1, SZ_PTR);
cmp_ir(code, 0, opts->gen.scratch1, SZ_PTR);
code_ptr no_reset_handler = code->cur + 1;
@@ -1201,6 +1203,8 @@ void translate_m68k_reset(m68k_options *opts, m68kinst *inst)
mov_rr(code, RAX, opts->gen.context_reg, SZ_PTR);
call(code, opts->gen.load_context);
*no_reset_handler = code->cur - (no_reset_handler + 1);
+ //RESET instructions take a long time to give peripherals time to reset themselves
+ cycles(&opts->gen, 132);
}
void op_ir(code_info *code, m68kinst *inst, int32_t val, uint8_t dst, uint8_t size)
@@ -1309,14 +1313,17 @@ void translate_m68k_arith(m68k_options *opts, m68kinst * inst, uint32_t flag_mas
uint32_t numcycles;
if ((inst->op == M68K_ADDX || inst->op == M68K_SUBX) && inst->src.addr_mode != MODE_REG) {
- numcycles = 6;
+ numcycles = 4;
} else if (size == OPSIZE_LONG) {
if (inst->op == M68K_CMP) {
+ numcycles = inst->src.addr_mode > MODE_AREG && inst->dst.addr_mode > MODE_AREG ? 4 : 6;
+ } else if (inst->op == M68K_AND && inst->variant == VAR_IMMEDIATE && inst->dst.addr_mode == MODE_REG) {
numcycles = 6;
- } else if (inst->op == M68K_AND && inst->variant == VAR_IMMEDIATE) {
- numcycles = 6;
- } else if (inst->dst.addr_mode <= MODE_AREG) {
+ } else if (inst->dst.addr_mode == MODE_REG) {
numcycles = inst->src.addr_mode <= MODE_AREG || inst->src.addr_mode == MODE_IMMEDIATE ? 8 : 6;
+ } else if (inst->dst.addr_mode == MODE_AREG) {
+ numcycles = numcycles = inst->src.addr_mode <= MODE_AREG || inst->src.addr_mode == MODE_IMMEDIATE
+ || inst->extra.size == OPSIZE_WORD ? 8 : 6;
} else {
numcycles = 4;
}
@@ -1493,8 +1500,9 @@ void translate_m68k_abcd_sbcd(m68k_options *opts, m68kinst *inst, host_ea *src_o
//destination is in memory so we need to preserve scratch2 for the write at the end
push_r(code, opts->gen.scratch2);
}
- //MC68000 User's Manual suggests NBCD hides the 2 cycle penalty during the write cycle somehow
- cycles(&opts->gen, inst->op == M68K_NBCD && inst->dst.addr_mode != MODE_REG_DIRECT ? BUS : BUS + 2);
+
+ //reg to reg takes 6 cycles, mem to mem is 4 cycles + all the operand fetch/writing (including 2 cycle predec penalty for first operand)
+ cycles(&opts->gen, inst->dst.addr_mode != MODE_REG ? BUS : BUS + 2);
uint8_t other_reg;
//WARNING: This may need adjustment if register assignments change
if (opts->gen.scratch2 > RBX) {
@@ -2068,7 +2076,7 @@ void translate_m68k_mul(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos
void translate_m68k_negx(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
{
code_info *code = &opts->gen.code;
- cycles(&opts->gen, BUS);
+ cycles(&opts->gen, inst->extra.size == OPSIZE_LONG && inst->dst.addr_mode == MODE_REG ? BUS+2 : BUS);
if (dst_op->mode == MODE_REG_DIRECT) {
if (dst_op->base == opts->gen.scratch1) {
push_r(code, opts->gen.scratch2);
@@ -2134,6 +2142,7 @@ void translate_m68k_rot(m68k_options *opts, m68kinst *inst, host_ea *src_op, hos
}
update_flags(opts, init_flags);
} else {
+ cycles(&opts->gen, inst->extra.size == OPSIZE_LONG ? 8 : 6);
if (src_op->mode == MODE_REG_DIRECT) {
if (src_op->base != opts->gen.scratch1) {
mov_rr(code, src_op->base, opts->gen.scratch1, SZ_B);
@@ -2441,7 +2450,7 @@ void translate_m68k_odd(m68k_options *opts, m68kinst *inst)
void translate_m68k_move_from_sr(m68k_options *opts, m68kinst *inst, host_ea *src_op, host_ea *dst_op)
{
code_info *code = &opts->gen.code;
- cycles(&opts->gen, inst->dst.addr_mode == MODE_REG_DIRECT ? BUS+2 : BUS);
+ cycles(&opts->gen, inst->dst.addr_mode == MODE_REG ? BUS+2 : BUS);
call(code, opts->get_sr);
if (dst_op->mode == MODE_REG_DIRECT) {
mov_rr(code, opts->gen.scratch1, dst_op->base, SZ_W);
diff --git a/trans.c b/trans.c
index 1992e88..a3a4839 100644
--- a/trans.c
+++ b/trans.c
@@ -26,8 +26,9 @@ void render_infobox(char * title, char * buf)
#ifndef NEW_CORE
m68k_context * sync_components(m68k_context * context, uint32_t address)
{
- if (context->current_cycle > 0x80000000) {
- context->current_cycle -= 0x80000000;
+ if (context->current_cycle >= context->target_cycle) {
+ puts("hit cycle limit");
+ exit(0);
}
if (context->status & M68K_STATUS_TRACE || context->trace_pending) {
context->target_cycle = context->current_cycle;
@@ -39,6 +40,11 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
m68k_context *reset_handler(m68k_context *context)
{
m68k_print_regs(context);
+#ifdef NEW_CORE
+ printf("cycles: %d\n", context->cycles);
+#else
+ printf("cycles: %d\n", context->current_cycle);
+#endif
exit(0);
//unreachable
return context;
@@ -80,16 +86,16 @@ int main(int argc, char ** argv)
m68k_context * context = init_68k_context(&opts, reset_handler);
context->mem_pointers[0] = memmap[0].buffer;
context->mem_pointers[1] = memmap[1].buffer;
-#ifndef NEW_CORE
- context->target_cycle = context->sync_cycle = 0x80000000;
+#ifdef NEW_CORE
+ context->cycles = 40;
+#else
+ context->current_cycle = 40;
+ context->target_cycle = context->sync_cycle = 8000;
#endif
m68k_reset(context);
#ifdef NEW_CORE
- for (;;)
- {
- m68k_execute(context, 0x80000000);
- context->cycles = 0;
- }
+ m68k_execute(context, 8000);
+ puts("hit cycle limit");
#endif
return 0;
}