changeset 342:13f994c88c34

Get frame time correct and frame rate sort of correct for EUR region
author Mike Pavone <pavone@retrodev.com>
date Thu, 16 May 2013 09:37:53 -0700
parents 6ad8e36de685
children 467bfa17004a
files blastem.c render.h render_sdl.c
diffstat 3 files changed, 41 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Wed May 15 23:51:22 2013 -0700
+++ b/blastem.c	Thu May 16 09:37:53 2013 -0700
@@ -15,8 +15,11 @@
 #define MCLKS_PER_68K 7
 #define MCLKS_PER_Z80 15
 //TODO: Figure out the exact value for this
-#define MCLKS_PER_FRAME (MCLKS_LINE*262)
 #define CYCLE_NEVER 0xFFFFFFFF
+#define LINES_NTSC 262
+#define LINES_PAL 312
+
+uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC;
 
 uint16_t cart[CARTRIDGE_WORDS];
 uint16_t ram[RAM_WORDS];
@@ -192,22 +195,22 @@
 	z80_context * z_context = gen->z80;
 	uint32_t mclks = context->current_cycle * MCLKS_PER_68K;
 	sync_z80(z_context, mclks);
-	if (mclks >= MCLKS_PER_FRAME) {
+	if (mclks >= mclks_per_frame) {
 		ym_run(gen->ym, context->current_cycle);
-		gen->ym->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_68K;
+		gen->ym->current_cycle -= mclks_per_frame/MCLKS_PER_68K;
 		//printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
-		vdp_run_context(v_context, MCLKS_PER_FRAME);
+		vdp_run_context(v_context, mclks_per_frame);
 		if (!headless) {
 			break_on_sync |= wait_render_frame(v_context, frame_limit);
 		}
 		frame++;
-		mclks -= MCLKS_PER_FRAME;
-		vdp_adjust_cycles(v_context, MCLKS_PER_FRAME);
-		io_adjust_cycles(&gamepad_1, context->current_cycle, MCLKS_PER_FRAME/MCLKS_PER_68K);
-		io_adjust_cycles(&gamepad_2, context->current_cycle, MCLKS_PER_FRAME/MCLKS_PER_68K);
-		context->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_68K;
-		if (z_context->current_cycle >= MCLKS_PER_FRAME/MCLKS_PER_Z80) {
-			z_context->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_Z80;
+		mclks -= mclks_per_frame;
+		vdp_adjust_cycles(v_context, mclks_per_frame);
+		io_adjust_cycles(&gamepad_1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K);
+		io_adjust_cycles(&gamepad_2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K);
+		context->current_cycle -= mclks_per_frame/MCLKS_PER_68K;
+		if (z_context->current_cycle >= mclks_per_frame/MCLKS_PER_Z80) {
+			z_context->current_cycle -= mclks_per_frame/MCLKS_PER_Z80;
 		} else {
 			z_context->current_cycle = 0;
 		}
@@ -240,14 +243,14 @@
 		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, MCLKS_PER_FRAME);
-					if (v_context->cycles >= MCLKS_PER_FRAME) {
+					vdp_run_dma_done(v_context, mclks_per_frame);
+					if (v_context->cycles >= mclks_per_frame) {
 						if (!headless) {
 							wait_render_frame(v_context, frame_limit);
 						}
-						vdp_adjust_cycles(v_context, MCLKS_PER_FRAME);
-						io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K);
-						io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K);
+						vdp_adjust_cycles(v_context, mclks_per_frame);
+						io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
+						io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
 					}
 				}
 				context->current_cycle = v_context->cycles / MCLKS_PER_68K;
@@ -257,14 +260,14 @@
 			if (blocked) {
 				while (blocked) {
 					while(v_context->flags & FLAG_DMA_RUN) {
-						vdp_run_dma_done(v_context, MCLKS_PER_FRAME);
-						if (v_context->cycles >= MCLKS_PER_FRAME) {
+						vdp_run_dma_done(v_context, mclks_per_frame);
+						if (v_context->cycles >= mclks_per_frame) {
 							if (!headless) {
 								wait_render_frame(v_context, frame_limit);
 							}
-							vdp_adjust_cycles(v_context, MCLKS_PER_FRAME);
-							io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K);
-							io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K);
+							vdp_adjust_cycles(v_context, mclks_per_frame);
+							io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
+							io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
 						}
 					}
 					if (blocked < 0) {
@@ -1005,7 +1008,7 @@
 	context.system = gen;
 	//cartridge ROM
 	context.mem_pointers[0] = cart;
-	context.target_cycle = context.sync_cycle = MCLKS_PER_FRAME/MCLKS_PER_68K;
+	context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K;
 	//work RAM
 	context.mem_pointers[1] = ram;
 	uint32_t address;
@@ -1148,6 +1151,10 @@
 	if (!headless) {
 		render_init(width, height, title);
 	}
+	if (version_reg & 0x40) {
+		mclks_per_frame = MCLKS_LINE * LINES_PAL;
+		render_fps(50);
+	}
 	vdp_context v_context;
 	
 	init_vdp_context(&v_context);
@@ -1164,7 +1171,7 @@
 
 	z_context.system = &gen;
 	z_context.mem_pointers[0] = z80_ram;
-	z_context.sync_cycle = z_context.target_cycle = MCLKS_PER_FRAME/MCLKS_PER_Z80;
+	z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80;
 	z_context.int_cycle = CYCLE_NEVER;
 	z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
 	
--- a/render.h	Wed May 15 23:51:22 2013 -0700
+++ b/render.h	Thu May 16 09:37:53 2013 -0700
@@ -6,6 +6,7 @@
 void render_context(vdp_context * context);
 void render_wait_quit(vdp_context * context);
 int wait_render_frame(vdp_context * context, int frame_limit);
+void render_fps(uint32_t fps);
 
 #endif //RENDER_SDL_H_
 
--- a/render_sdl.c	Wed May 15 23:51:22 2013 -0700
+++ b/render_sdl.c	Thu May 16 09:37:53 2013 -0700
@@ -14,6 +14,7 @@
 uint8_t levels[] = {0, 27, 49, 71, 87, 103, 119, 130, 146, 157, 174, 190, 206, 228, 255};
 
 uint32_t min_delay;
+uint32_t frame_delay = 1000/60;
 
 void render_init(int width, int height, char * title)
 {
@@ -229,8 +230,6 @@
 #define BUTTON_START 0x20
 #define BUTTON_C     0x20
 
-#define FRAME_DELAY 16
-#define MIN_DELAY 5
 uint32_t frame_counter = 0;
 uint32_t start = 0;
 int wait_render_frame(vdp_context * context, int frame_limit)
@@ -362,12 +361,11 @@
 	if (frame_limit) {
 		//TODO: Adjust frame delay so we actually get 60 FPS rather than 62.5 FPS
 		uint32_t current = SDL_GetTicks();
-		uint32_t desired = last_frame + FRAME_DELAY;
+		uint32_t desired = last_frame + frame_delay;
 		if (current < desired) {
-			uint32_t delay = last_frame + FRAME_DELAY - current;
-			//TODO: Calculate MIN_DELAY at runtime
-			if (delay > MIN_DELAY) {
-				SDL_Delay((delay/MIN_DELAY)*MIN_DELAY);
+			uint32_t delay = last_frame + frame_delay - current;
+			if (delay > min_delay) {
+				SDL_Delay((delay/min_delay)*min_delay);
 			}
 			while ((desired) >= SDL_GetTicks()) {
 			}
@@ -389,4 +387,9 @@
 	return ret;
 }
 
+void render_fps(uint32_t fps)
+{
+	frame_delay = 1000/fps;
+}
 
+