changeset 1992:8ad431312aa7

Merge
author Michael Pavone <pavone@retrodev.com>
date Sat, 13 Jun 2020 00:38:52 -0700
parents 7d4df6b74263 (diff) 0cbc456972c9 (current diff)
children a9449608d0b0 00873afe1fe9
files
diffstat 5 files changed, 146 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Tue Jun 02 00:06:02 2020 -0700
+++ b/Makefile	Sat Jun 13 00:38:52 2020 -0700
@@ -297,7 +297,7 @@
 	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)
--- a/cpu_dsl.py	Tue Jun 02 00:06:02 2020 -0700
+++ b/cpu_dsl.py	Sat Jun 13 00:38:52 2020 -0700
@@ -899,7 +899,7 @@
 			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
--- a/m68k.cpu	Tue Jun 02 00:06:02 2020 -0700
+++ b/m68k.cpu	Sat Jun 13 00:38:52 2020 -0700
@@ -861,6 +861,114 @@
 	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
--- a/m68k_core_x86.c	Tue Jun 02 00:06:02 2020 -0700
+++ b/m68k_core_x86.c	Sat Jun 13 00:38:52 2020 -0700
@@ -421,7 +421,11 @@
 			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 @@
 		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_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 @@
 	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 @@
 	
 	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 = 6;
-		} else if (inst->op == M68K_AND && inst->variant == VAR_IMMEDIATE) {
+			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->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 @@
 		//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_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 @@
 			}
 			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_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);
--- a/trans.c	Tue Jun 02 00:06:02 2020 -0700
+++ b/trans.c	Sat Jun 13 00:38:52 2020 -0700
@@ -26,8 +26,9 @@
 #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 *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 @@
 	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;
 }