# HG changeset patch # User Mike Pavone # Date 1368722273 25200 # Node ID 13f994c88c343f39de5d9869b3f702c63599d35c # Parent 6ad8e36de685264e3e8c051f3125b930db20069e Get frame time correct and frame rate sort of correct for EUR region diff -r 6ad8e36de685 -r 13f994c88c34 blastem.c --- 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; diff -r 6ad8e36de685 -r 13f994c88c34 render.h --- 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_ diff -r 6ad8e36de685 -r 13f994c88c34 render_sdl.c --- 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; +} +