Mercurial > repos > blastem
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; |