comparison blastem.c @ 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
comparison
equal deleted inserted replaced
341:6ad8e36de685 342:13f994c88c34
13 #define RAM_WORDS 32 * 1024 13 #define RAM_WORDS 32 * 1024
14 #define Z80_RAM_BYTES 8 * 1024 14 #define Z80_RAM_BYTES 8 * 1024
15 #define MCLKS_PER_68K 7 15 #define MCLKS_PER_68K 7
16 #define MCLKS_PER_Z80 15 16 #define MCLKS_PER_Z80 15
17 //TODO: Figure out the exact value for this 17 //TODO: Figure out the exact value for this
18 #define MCLKS_PER_FRAME (MCLKS_LINE*262)
19 #define CYCLE_NEVER 0xFFFFFFFF 18 #define CYCLE_NEVER 0xFFFFFFFF
19 #define LINES_NTSC 262
20 #define LINES_PAL 312
21
22 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC;
20 23
21 uint16_t cart[CARTRIDGE_WORDS]; 24 uint16_t cart[CARTRIDGE_WORDS];
22 uint16_t ram[RAM_WORDS]; 25 uint16_t ram[RAM_WORDS];
23 uint8_t z80_ram[Z80_RAM_BYTES]; 26 uint8_t z80_ram[Z80_RAM_BYTES];
24 27
190 genesis_context * gen = context->system; 193 genesis_context * gen = context->system;
191 vdp_context * v_context = gen->vdp; 194 vdp_context * v_context = gen->vdp;
192 z80_context * z_context = gen->z80; 195 z80_context * z_context = gen->z80;
193 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; 196 uint32_t mclks = context->current_cycle * MCLKS_PER_68K;
194 sync_z80(z_context, mclks); 197 sync_z80(z_context, mclks);
195 if (mclks >= MCLKS_PER_FRAME) { 198 if (mclks >= mclks_per_frame) {
196 ym_run(gen->ym, context->current_cycle); 199 ym_run(gen->ym, context->current_cycle);
197 gen->ym->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_68K; 200 gen->ym->current_cycle -= mclks_per_frame/MCLKS_PER_68K;
198 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); 201 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
199 vdp_run_context(v_context, MCLKS_PER_FRAME); 202 vdp_run_context(v_context, mclks_per_frame);
200 if (!headless) { 203 if (!headless) {
201 break_on_sync |= wait_render_frame(v_context, frame_limit); 204 break_on_sync |= wait_render_frame(v_context, frame_limit);
202 } 205 }
203 frame++; 206 frame++;
204 mclks -= MCLKS_PER_FRAME; 207 mclks -= mclks_per_frame;
205 vdp_adjust_cycles(v_context, MCLKS_PER_FRAME); 208 vdp_adjust_cycles(v_context, mclks_per_frame);
206 io_adjust_cycles(&gamepad_1, context->current_cycle, MCLKS_PER_FRAME/MCLKS_PER_68K); 209 io_adjust_cycles(&gamepad_1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K);
207 io_adjust_cycles(&gamepad_2, context->current_cycle, MCLKS_PER_FRAME/MCLKS_PER_68K); 210 io_adjust_cycles(&gamepad_2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K);
208 context->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_68K; 211 context->current_cycle -= mclks_per_frame/MCLKS_PER_68K;
209 if (z_context->current_cycle >= MCLKS_PER_FRAME/MCLKS_PER_Z80) { 212 if (z_context->current_cycle >= mclks_per_frame/MCLKS_PER_Z80) {
210 z_context->current_cycle -= MCLKS_PER_FRAME/MCLKS_PER_Z80; 213 z_context->current_cycle -= mclks_per_frame/MCLKS_PER_Z80;
211 } else { 214 } else {
212 z_context->current_cycle = 0; 215 z_context->current_cycle = 0;
213 } 216 }
214 if (mclks) { 217 if (mclks) {
215 vdp_run_context(v_context, mclks); 218 vdp_run_context(v_context, mclks);
238 if (vdp_port < 0x10) { 241 if (vdp_port < 0x10) {
239 int blocked; 242 int blocked;
240 if (vdp_port < 4) { 243 if (vdp_port < 4) {
241 while (vdp_data_port_write(v_context, value) < 0) { 244 while (vdp_data_port_write(v_context, value) < 0) {
242 while(v_context->flags & FLAG_DMA_RUN) { 245 while(v_context->flags & FLAG_DMA_RUN) {
243 vdp_run_dma_done(v_context, MCLKS_PER_FRAME); 246 vdp_run_dma_done(v_context, mclks_per_frame);
244 if (v_context->cycles >= MCLKS_PER_FRAME) { 247 if (v_context->cycles >= mclks_per_frame) {
245 if (!headless) { 248 if (!headless) {
246 wait_render_frame(v_context, frame_limit); 249 wait_render_frame(v_context, frame_limit);
247 } 250 }
248 vdp_adjust_cycles(v_context, MCLKS_PER_FRAME); 251 vdp_adjust_cycles(v_context, mclks_per_frame);
249 io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K); 252 io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
250 io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K); 253 io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
251 } 254 }
252 } 255 }
253 context->current_cycle = v_context->cycles / MCLKS_PER_68K; 256 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
254 } 257 }
255 } else if(vdp_port < 8) { 258 } else if(vdp_port < 8) {
256 blocked = vdp_control_port_write(v_context, value); 259 blocked = vdp_control_port_write(v_context, value);
257 if (blocked) { 260 if (blocked) {
258 while (blocked) { 261 while (blocked) {
259 while(v_context->flags & FLAG_DMA_RUN) { 262 while(v_context->flags & FLAG_DMA_RUN) {
260 vdp_run_dma_done(v_context, MCLKS_PER_FRAME); 263 vdp_run_dma_done(v_context, mclks_per_frame);
261 if (v_context->cycles >= MCLKS_PER_FRAME) { 264 if (v_context->cycles >= mclks_per_frame) {
262 if (!headless) { 265 if (!headless) {
263 wait_render_frame(v_context, frame_limit); 266 wait_render_frame(v_context, frame_limit);
264 } 267 }
265 vdp_adjust_cycles(v_context, MCLKS_PER_FRAME); 268 vdp_adjust_cycles(v_context, mclks_per_frame);
266 io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K); 269 io_adjust_cycles(&gamepad_1, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
267 io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, MCLKS_PER_FRAME/MCLKS_PER_68K); 270 io_adjust_cycles(&gamepad_2, v_context->cycles/MCLKS_PER_68K, mclks_per_frame/MCLKS_PER_68K);
268 } 271 }
269 } 272 }
270 if (blocked < 0) { 273 if (blocked < 0) {
271 blocked = vdp_control_port_write(v_context, value); 274 blocked = vdp_control_port_write(v_context, value);
272 } else { 275 } else {
1003 1006
1004 context.video_context = gen->vdp; 1007 context.video_context = gen->vdp;
1005 context.system = gen; 1008 context.system = gen;
1006 //cartridge ROM 1009 //cartridge ROM
1007 context.mem_pointers[0] = cart; 1010 context.mem_pointers[0] = cart;
1008 context.target_cycle = context.sync_cycle = MCLKS_PER_FRAME/MCLKS_PER_68K; 1011 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K;
1009 //work RAM 1012 //work RAM
1010 context.mem_pointers[1] = ram; 1013 context.mem_pointers[1] = ram;
1011 uint32_t address; 1014 uint32_t address;
1012 /*address = cart[0x68/2] << 16 | cart[0x6A/2]; 1015 /*address = cart[0x68/2] << 16 | cart[0x6A/2];
1013 translate_m68k_stream(address, &context); 1016 translate_m68k_stream(address, &context);
1146 width = width < 320 ? 320 : width; 1149 width = width < 320 ? 320 : width;
1147 height = height < 240 ? (width/320) * 240 : height; 1150 height = height < 240 ? (width/320) * 240 : height;
1148 if (!headless) { 1151 if (!headless) {
1149 render_init(width, height, title); 1152 render_init(width, height, title);
1150 } 1153 }
1154 if (version_reg & 0x40) {
1155 mclks_per_frame = MCLKS_LINE * LINES_PAL;
1156 render_fps(50);
1157 }
1151 vdp_context v_context; 1158 vdp_context v_context;
1152 1159
1153 init_vdp_context(&v_context); 1160 init_vdp_context(&v_context);
1154 1161
1155 ym2612_context y_context; 1162 ym2612_context y_context;
1162 1169
1163 genesis_context gen; 1170 genesis_context gen;
1164 1171
1165 z_context.system = &gen; 1172 z_context.system = &gen;
1166 z_context.mem_pointers[0] = z80_ram; 1173 z_context.mem_pointers[0] = z80_ram;
1167 z_context.sync_cycle = z_context.target_cycle = MCLKS_PER_FRAME/MCLKS_PER_Z80; 1174 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80;
1168 z_context.int_cycle = CYCLE_NEVER; 1175 z_context.int_cycle = CYCLE_NEVER;
1169 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; 1176 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
1170 1177
1171 gen.z80 = &z_context; 1178 gen.z80 = &z_context;
1172 gen.vdp = &v_context; 1179 gen.vdp = &v_context;