changeset 697:7f96bd1cb1be

Sync fixes and logging to fix more sync issues
author Michael Pavone <pavone@retrodev.com>
date Mon, 11 May 2015 00:28:47 -0700
parents 0b2242bbc84a
children 0a86e81fa87d
files backend.h backend_x86.c blastem.c m68k_core.c vdp.c vdp.h z80_to_x86.c
diffstat 7 files changed, 66 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/backend.h	Tue May 05 08:42:27 2015 -0700
+++ b/backend.h	Mon May 11 00:28:47 2015 -0700
@@ -113,6 +113,7 @@
 void check_cycles_int(cpu_options *opts, uint32_t address);
 void check_cycles(cpu_options * opts);
 void check_code_prologue(code_info *code);
+void log_address(cpu_options *opts, uint32_t address, char * format);
 
 code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc);
 void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
--- a/backend_x86.c	Tue May 05 08:42:27 2015 -0700
+++ b/backend_x86.c	Mon May 11 00:28:47 2015 -0700
@@ -11,7 +11,7 @@
 	code_info *code = &opts->code;
 	cmp_rr(code, opts->cycles, opts->limit, SZ_D);
 	code_ptr jmp_off = code->cur+1;
-	jcc(code, CC_NC, jmp_off+1);
+	jcc(code, CC_A, jmp_off+1);
 	mov_ir(code, address, opts->scratch1, SZ_D);
 	call(code, opts->handle_cycle_limit_int);
 	*jmp_off = code->cur - (jmp_off+1);
@@ -23,11 +23,24 @@
 	cmp_rr(code, opts->cycles, opts->limit, SZ_D);
 	check_alloc_code(code, MAX_INST_LEN*2);
 	code_ptr jmp_off = code->cur+1;
-	jcc(code, CC_NC, jmp_off+1);
+	jcc(code, CC_A, jmp_off+1);
 	call(code, opts->handle_cycle_limit);
 	*jmp_off = code->cur - (jmp_off+1);
 }
 
+void log_address(cpu_options *opts, uint32_t address, char * format)
+{
+	code_info *code = &opts->code;
+	call(code, opts->save_context);
+	push_r(code, opts->context_reg);
+	mov_rr(code, opts->cycles, RDX, SZ_D);
+	mov_ir(code, (int64_t)format, RDI, SZ_PTR);
+	mov_ir(code, address, RSI, SZ_D);
+	call_args_abi(code, (code_ptr)printf, 3, RDI, RSI, RDX);
+	pop_r(code, opts->context_reg);
+	call(code, opts->load_context);
+}
+
 void check_code_prologue(code_info *code)
 {
 	check_alloc_code(code, MAX_INST_LEN*4);
--- a/blastem.c	Tue May 05 08:42:27 2015 -0700
+++ b/blastem.c	Mon May 11 00:28:47 2015 -0700
@@ -203,7 +203,7 @@
 	//printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
 }
 
-uint32_t frame=0;
+uint32_t last_frame_num;
 m68k_context * sync_components(m68k_context * context, uint32_t address)
 {
 	genesis_context * gen = context->system;
@@ -212,45 +212,37 @@
 	uint32_t mclks = context->current_cycle;
 	sync_z80(z_context, mclks);
 	sync_sound(gen, mclks);
-	if (mclks >= gen->frame_end) {
-		vdp_run_context(v_context, gen->frame_end);
-		if (vdp_is_frame_over(v_context)) {
-			//printf("reached frame end | MCLK Cycles: %d, Target: %d, VDP cycles: %d\n", mclks, gen->frame_end, v_context->cycles);
+	vdp_run_context(v_context, mclks);
+	if (v_context->frame != last_frame_num) {
+		//printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot);
+		last_frame_num = v_context->frame;
 
-			if (!headless) {
-				break_on_sync |= wait_render_frame(v_context, frame_limit);
-			} else if(exit_after){
-				--exit_after;
-				if (!exit_after) {
-					exit(0);
-				}
+		if (!headless) {
+			break_on_sync |= wait_render_frame(v_context, frame_limit);
+		} else if(exit_after){
+			--exit_after;
+			if (!exit_after) {
+				exit(0);
 			}
-			frame++;
-			mclks -= gen->frame_end;
-			vdp_adjust_cycles(v_context, gen->frame_end);
-			io_adjust_cycles(gen->ports, context->current_cycle, gen->frame_end);
-			io_adjust_cycles(gen->ports+1, context->current_cycle, gen->frame_end);
-			io_adjust_cycles(gen->ports+2, context->current_cycle, gen->frame_end);
-			context->current_cycle -= gen->frame_end;
-			z80_adjust_cycles(z_context, gen->frame_end);
-			gen->ym->current_cycle -= gen->frame_end;
-			gen->psg->cycles -= gen->frame_end;
-			if (gen->ym->write_cycle != CYCLE_NEVER) {
-				gen->ym->write_cycle = gen->ym->write_cycle >= gen->frame_end ? gen->ym->write_cycle - gen->frame_end : 0;
-			}
-			if (mclks) {
-				vdp_run_context(v_context, mclks);
-			}
-			gen->frame_end = vdp_cycles_to_frame_end(v_context);
-		} else {
-			vdp_run_context(v_context, mclks);
-			gen->frame_end = vdp_cycles_to_frame_end(v_context);
 		}
-		context->sync_cycle = gen->frame_end;
+		
+		vdp_adjust_cycles(v_context, mclks);
+		io_adjust_cycles(gen->ports, context->current_cycle, mclks);
+		io_adjust_cycles(gen->ports+1, context->current_cycle, mclks);
+		io_adjust_cycles(gen->ports+2, context->current_cycle, mclks);
+		context->current_cycle -= mclks;
+		z80_adjust_cycles(z_context, mclks);
+		gen->ym->current_cycle -= mclks;
+		gen->psg->cycles -= mclks;
+		if (gen->ym->write_cycle != CYCLE_NEVER) {
+			gen->ym->write_cycle = gen->ym->write_cycle >= mclks ? gen->ym->write_cycle - mclks : 0;
+		}
+		gen->frame_end = vdp_cycles_to_frame_end(v_context);
 	} else {
-		//printf("running VDP for %d cycles\n", mclks - v_context->cycles);
-		vdp_run_context(v_context, mclks);
+		gen->frame_end = vdp_cycles_to_frame_end(v_context);
 	}
+	context->sync_cycle = gen->frame_end;
+	//printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
 	if (context->int_ack) {
 		vdp_int_ack(v_context, context->int_ack);
 		context->int_ack = 0;
@@ -289,12 +281,15 @@
 		int blocked;
 		uint32_t before_cycle = v_context->cycles;
 		if (vdp_port < 4) {
+			
 			while (vdp_data_port_write(v_context, value) < 0) {
 				while(v_context->flags & FLAG_DMA_RUN) {
 					vdp_run_dma_done(v_context, gen->frame_end);
 					if (v_context->cycles >= gen->frame_end) {
 						context->current_cycle = v_context->cycles;
+						gen->bus_busy = 1;
 						sync_components(context, 0);
+						gen->bus_busy = 0;
 					}
 				}
 				//context->current_cycle = v_context->cycles;
@@ -307,7 +302,9 @@
 						vdp_run_dma_done(v_context, gen->frame_end);
 						if (v_context->cycles >= gen->frame_end) {
 							context->current_cycle = v_context->cycles;
+							gen->bus_busy = 1;
 							sync_components(context, 0);
+							gen->bus_busy = 0;
 						}
 					}
 					if (blocked < 0) {
@@ -317,6 +314,8 @@
 					}
 				}
 			} else {
+				context->sync_cycle = gen->frame_end = vdp_cycles_to_frame_end(v_context);
+				//printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
 				adjust_int_cycle(context, v_context);
 			}
 		} else {
--- a/m68k_core.c	Tue May 05 08:42:27 2015 -0700
+++ b/m68k_core.c	Mon May 11 00:28:47 2015 -0700
@@ -801,6 +801,7 @@
 void translate_m68k(m68k_options * opts, m68kinst * inst)
 {
 	check_cycles_int(&opts->gen, inst->address);
+	log_address(&opts->gen, inst->address, "M68K: %X @ %d\n");
 	impl_info * info = m68k_impls + inst->op;
 	if (info->itype == RAW_FUNC) {
 		info->impl.raw(opts, inst);
--- a/vdp.c	Tue May 05 08:42:27 2015 -0700
+++ b/vdp.c	Mon May 11 00:28:47 2015 -0700
@@ -24,8 +24,8 @@
 #define MCLKS_SLOT_H32  20
 #define VINT_SLOT_H40  4 //21 slots before HSYNC, 16 during, 10 after
 #define VINT_SLOT_H32  23  //33 slots before HSYNC, 20 during, 7 after  TODO: confirm final number
-#define HSYNC_SLOT_H40  240
-#define HSYNC_END_H40  (240+17)
+#define HSYNC_SLOT_H40  234
+#define HSYNC_END_H40  (HSYNC_SLOT_H40+17)
 #define HSYNC_END_H32   (33 * MCLKS_SLOT_H32)
 #define HBLANK_START_H40 178 //should be 179 according to Nemesis, but 178 seems to fit slightly better with my test ROM results
 #define HBLANK_END_H40  0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results
@@ -1420,7 +1420,7 @@
 	}
 }
 
-uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 19, 20, 20, 20, 19, 20, 20, 20, 19, 20, 20, 20, 19};
+uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19};
 
 void vdp_run_context(vdp_context * context, uint32_t target_cycles)
 {
@@ -1428,12 +1428,13 @@
 	{
 		context->flags &= ~FLAG_UNUSED_SLOT;
 		uint32_t line = context->vcounter;
-		uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START;
 		uint32_t slot = context->hslot;
-		//TODO: Figure out when this actually happens
+		
 		if (!line && !slot) {
+			//TODO: Figure out when this actually happens
 			latch_mode(context);
 		}
+		uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START;
 
 		uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40;
 		if (is_h40) {
@@ -1455,6 +1456,9 @@
 		}
 		if (is_h40 && slot == LINE_CHANGE_H40 || !is_h40 && slot == LINE_CHANGE_H32) {
 			if (line >= inactive_start) {
+				if (line == (inactive_start + 8)) {
+					context->frame++;
+				}
 				context->hint_counter = context->regs[REG_HINT];
 			} else if (context->hint_counter) {
 				context->hint_counter--;
@@ -1824,7 +1828,7 @@
 {
 	if (context->regs[REG_MODE_4] & BIT_H40) {
 		if (context->hslot < LINE_CHANGE_H40) {
-			return (HBLANK_START_H40 - context->hslot) * MCLKS_SLOT_H40;
+			return (LINE_CHANGE_H40 - context->hslot) * MCLKS_SLOT_H40;
 		} else if (context->hslot < 183) {
 			return MCLKS_LINE - (context->hslot - LINE_CHANGE_H40) * MCLKS_SLOT_H40;
 		} else if (context->hslot < HSYNC_END_H40){
@@ -1916,12 +1920,6 @@
 	return context->cycles + vdp_cycles_to_line(context, vdp_frame_end_line(context));
 }
 
-uint8_t vdp_is_frame_over(vdp_context * context)
-{
-	uint32_t frame_end = vdp_frame_end_line(context);
-	return context->vcounter >= frame_end && context->vcounter < (frame_end + 8);
-}
-
 uint32_t vdp_next_hint(vdp_context * context)
 {
 	if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) {
--- a/vdp.h	Tue May 05 08:42:27 2015 -0700
+++ b/vdp.h	Mon May 11 00:28:47 2015 -0700
@@ -143,6 +143,7 @@
 	uint32_t    colors[CRAM_SIZE*3];
 	uint32_t    debugcolors[1 << (3 + 1 + 1 + 1)];//3 bits for source, 1 bit for priority, 1 bit for shadow, 1 bit for hilight
 	uint16_t    vsram[VSRAM_SIZE];
+	uint32_t    frame;
 	uint16_t    vcounter;
 	uint16_t    hslot; //hcounter/2
 	uint16_t    hscroll_a;
@@ -194,7 +195,7 @@
 void vdp_print_reg_explain(vdp_context * context);
 void latch_mode(vdp_context * context);
 uint32_t vdp_cycles_to_frame_end(vdp_context * context);
-uint8_t vdp_is_frame_over(vdp_context * context);
+uint32_t vdp_frame_end_line(vdp_context *context);
 
 extern int32_t color_map[1 << 12];
 
--- a/z80_to_x86.c	Tue May 05 08:42:27 2015 -0700
+++ b/z80_to_x86.c	Mon May 11 00:28:47 2015 -0700
@@ -309,6 +309,7 @@
 		if (context->breakpoint_flags[address / sizeof(uint8_t)] & (1 << (address % sizeof(uint8_t)))) {
 			zbreakpoint_patch(context, address, start);
 		}
+		//log_address(&opts->gen, address, "Z80: %X @ %d\n");
 	}
 	switch(inst->op)
 	{
@@ -2293,7 +2294,9 @@
 
 void z80_assert_busreq(z80_context * context, uint32_t cycle)
 {
+	printf("bus requested at %d\n", cycle);
 	z80_run(context, cycle);
+	printf("asserted busreq at %d\n", context->current_cycle);
 	context->busreq = 1;
 		}