Mercurial > repos > blastem
comparison blastem.c @ 623:66cc60215e5c
Fix most of the breakage caused by the vcounter/hcounter changes
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 18 Jun 2014 16:30:19 -0700 |
parents | c641006da28e |
children | 6aa2a8ab9c70 |
comparison
equal
deleted
inserted
replaced
622:b76d2a628ab9 | 623:66cc60215e5c |
---|---|
31 #define LINES_NTSC 262 | 31 #define LINES_NTSC 262 |
32 #define LINES_PAL 312 | 32 #define LINES_PAL 312 |
33 | 33 |
34 #define MAX_SOUND_CYCLES 100000 | 34 #define MAX_SOUND_CYCLES 100000 |
35 | 35 |
36 uint32_t mclks_per_frame = MCLKS_LINE*LINES_NTSC; | 36 uint32_t mclk_target = 0; |
37 | 37 |
38 uint16_t cart[CARTRIDGE_WORDS]; | 38 uint16_t cart[CARTRIDGE_WORDS]; |
39 uint16_t ram[RAM_WORDS]; | 39 uint16_t ram[RAM_WORDS]; |
40 uint8_t z80_ram[Z80_RAM_BYTES]; | 40 uint8_t z80_ram[Z80_RAM_BYTES]; |
41 | 41 |
229 genesis_context * gen = context->system; | 229 genesis_context * gen = context->system; |
230 vdp_context * v_context = gen->vdp; | 230 vdp_context * v_context = gen->vdp; |
231 z80_context * z_context = gen->z80; | 231 z80_context * z_context = gen->z80; |
232 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; | 232 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; |
233 sync_z80(z_context, mclks); | 233 sync_z80(z_context, mclks); |
234 if (mclks >= mclks_per_frame) { | 234 if (mclks >= mclk_target) { |
235 sync_sound(gen, mclks); | 235 sync_sound(gen, mclks); |
236 gen->ym->current_cycle -= mclks_per_frame; | 236 gen->ym->current_cycle -= mclk_target; |
237 gen->psg->cycles -= mclks_per_frame; | 237 gen->psg->cycles -= mclk_target; |
238 if (gen->ym->write_cycle != CYCLE_NEVER) { | 238 if (gen->ym->write_cycle != CYCLE_NEVER) { |
239 gen->ym->write_cycle = gen->ym->write_cycle >= mclks_per_frame/MCLKS_PER_68K ? gen->ym->write_cycle - mclks_per_frame/MCLKS_PER_68K : 0; | 239 gen->ym->write_cycle = gen->ym->write_cycle >= mclk_target/MCLKS_PER_68K ? gen->ym->write_cycle - mclk_target/MCLKS_PER_68K : 0; |
240 } | 240 } |
241 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); | 241 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); |
242 vdp_run_context(v_context, mclks_per_frame); | 242 vdp_run_context(v_context, mclk_target); |
243 | 243 |
244 if (!headless) { | 244 if (!headless) { |
245 break_on_sync |= wait_render_frame(v_context, frame_limit); | 245 break_on_sync |= wait_render_frame(v_context, frame_limit); |
246 } else if(exit_after){ | 246 } else if(exit_after){ |
247 --exit_after; | 247 --exit_after; |
248 if (!exit_after) { | 248 if (!exit_after) { |
249 exit(0); | 249 exit(0); |
250 } | 250 } |
251 } | 251 } |
252 frame++; | 252 frame++; |
253 mclks -= mclks_per_frame; | 253 mclks -= mclk_target; |
254 vdp_adjust_cycles(v_context, mclks_per_frame); | 254 vdp_adjust_cycles(v_context, mclk_target); |
255 io_adjust_cycles(gen->ports, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); | 255 io_adjust_cycles(gen->ports, context->current_cycle, mclk_target/MCLKS_PER_68K); |
256 io_adjust_cycles(gen->ports+1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); | 256 io_adjust_cycles(gen->ports+1, context->current_cycle, mclk_target/MCLKS_PER_68K); |
257 io_adjust_cycles(gen->ports+2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); | 257 io_adjust_cycles(gen->ports+2, context->current_cycle, mclk_target/MCLKS_PER_68K); |
258 if (busack_cycle != CYCLE_NEVER) { | 258 if (busack_cycle != CYCLE_NEVER) { |
259 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { | 259 if (busack_cycle > mclk_target/MCLKS_PER_68K) { |
260 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; | 260 busack_cycle -= mclk_target/MCLKS_PER_68K; |
261 } else { | 261 } else { |
262 busack_cycle = CYCLE_NEVER; | 262 busack_cycle = CYCLE_NEVER; |
263 busack = new_busack; | 263 busack = new_busack; |
264 } | 264 } |
265 } | 265 } |
266 context->current_cycle -= mclks_per_frame/MCLKS_PER_68K; | 266 context->current_cycle -= mclk_target/MCLKS_PER_68K; |
267 if (z_context->current_cycle >= mclks_per_frame/MCLKS_PER_Z80) { | 267 if (z_context->current_cycle >= mclk_target/MCLKS_PER_Z80) { |
268 z_context->current_cycle -= mclks_per_frame/MCLKS_PER_Z80; | 268 z_context->current_cycle -= mclk_target/MCLKS_PER_Z80; |
269 } else { | 269 } else { |
270 z_context->current_cycle = 0; | 270 z_context->current_cycle = 0; |
271 } | 271 } |
272 if (mclks) { | 272 if (mclks) { |
273 vdp_run_context(v_context, mclks); | 273 vdp_run_context(v_context, mclks); |
274 } | 274 } |
275 mclk_target = vdp_cycles_to_frame_end(v_context); | |
275 } else { | 276 } else { |
276 //printf("running VDP for %d cycles\n", mclks - v_context->cycles); | 277 //printf("running VDP for %d cycles\n", mclks - v_context->cycles); |
277 vdp_run_context(v_context, mclks); | 278 vdp_run_context(v_context, mclks); |
278 sync_sound(gen, mclks); | 279 sync_sound(gen, mclks); |
279 } | 280 } |
315 uint32_t before_cycle = v_context->cycles; | 316 uint32_t before_cycle = v_context->cycles; |
316 if (vdp_port < 4) { | 317 if (vdp_port < 4) { |
317 gen->bus_busy = 1; | 318 gen->bus_busy = 1; |
318 while (vdp_data_port_write(v_context, value) < 0) { | 319 while (vdp_data_port_write(v_context, value) < 0) { |
319 while(v_context->flags & FLAG_DMA_RUN) { | 320 while(v_context->flags & FLAG_DMA_RUN) { |
320 vdp_run_dma_done(v_context, mclks_per_frame); | 321 vdp_run_dma_done(v_context, mclk_target); |
321 if (v_context->cycles >= mclks_per_frame) { | 322 if (v_context->cycles >= mclk_target) { |
322 context->current_cycle = v_context->cycles / MCLKS_PER_68K; | 323 context->current_cycle = v_context->cycles / MCLKS_PER_68K; |
323 if (context->current_cycle * MCLKS_PER_68K < mclks_per_frame) { | 324 if (context->current_cycle * MCLKS_PER_68K < mclk_target) { |
324 ++context->current_cycle; | 325 ++context->current_cycle; |
325 } | 326 } |
326 sync_components(context, 0); | 327 sync_components(context, 0); |
327 } | 328 } |
328 } | 329 } |
332 gen->bus_busy = 1; | 333 gen->bus_busy = 1; |
333 blocked = vdp_control_port_write(v_context, value); | 334 blocked = vdp_control_port_write(v_context, value); |
334 if (blocked) { | 335 if (blocked) { |
335 while (blocked) { | 336 while (blocked) { |
336 while(v_context->flags & FLAG_DMA_RUN) { | 337 while(v_context->flags & FLAG_DMA_RUN) { |
337 vdp_run_dma_done(v_context, mclks_per_frame); | 338 vdp_run_dma_done(v_context, mclk_target); |
338 if (v_context->cycles >= mclks_per_frame) { | 339 if (v_context->cycles >= mclk_target) { |
339 context->current_cycle = v_context->cycles / MCLKS_PER_68K; | 340 context->current_cycle = v_context->cycles / MCLKS_PER_68K; |
340 if (context->current_cycle * MCLKS_PER_68K < mclks_per_frame) { | 341 if (context->current_cycle * MCLKS_PER_68K < mclk_target) { |
341 ++context->current_cycle; | 342 ++context->current_cycle; |
342 } | 343 } |
343 sync_components(context, 0); | 344 sync_components(context, 0); |
344 } | 345 } |
345 } | 346 } |
964 | 965 |
965 context.video_context = gen->vdp; | 966 context.video_context = gen->vdp; |
966 context.system = gen; | 967 context.system = gen; |
967 //cartridge ROM | 968 //cartridge ROM |
968 context.mem_pointers[0] = cart; | 969 context.mem_pointers[0] = cart; |
969 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K; | 970 context.target_cycle = context.sync_cycle = mclk_target/MCLKS_PER_68K; |
970 //work RAM | 971 //work RAM |
971 context.mem_pointers[1] = ram; | 972 context.mem_pointers[1] = ram; |
972 //save RAM/map | 973 //save RAM/map |
973 context.mem_pointers[2] = initial_mapped; | 974 context.mem_pointers[2] = initial_mapped; |
974 context.mem_pointers[3] = (uint16_t *)gen->save_ram; | 975 context.mem_pointers[3] = (uint16_t *)gen->save_ram; |
1208 } | 1209 } |
1209 width = width < 320 ? def_width : width; | 1210 width = width < 320 ? def_width : width; |
1210 height = height < 240 ? (width/320) * 240 : height; | 1211 height = height < 240 ? (width/320) * 240 : height; |
1211 uint32_t fps = 60; | 1212 uint32_t fps = 60; |
1212 if (version_reg & 0x40) { | 1213 if (version_reg & 0x40) { |
1213 mclks_per_frame = MCLKS_LINE * LINES_PAL; | |
1214 fps = 50; | 1214 fps = 50; |
1215 } | 1215 } |
1216 if (!headless) { | 1216 if (!headless) { |
1217 render_init(width, height, title, fps, fullscreen, use_gl); | 1217 render_init(width, height, title, fps, fullscreen, use_gl); |
1218 } | 1218 } |
1219 vdp_context v_context; | 1219 vdp_context v_context; |
1220 genesis_context gen; | 1220 genesis_context gen; |
1221 memset(&gen, 0, sizeof(gen)); | 1221 memset(&gen, 0, sizeof(gen)); |
1222 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL; | 1222 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL; |
1223 | 1223 |
1224 init_vdp_context(&v_context); | 1224 init_vdp_context(&v_context, version_reg & 0x40); |
1225 mclk_target = vdp_cycles_to_frame_end(&v_context); | |
1225 | 1226 |
1226 ym2612_context y_context; | 1227 ym2612_context y_context; |
1227 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); | 1228 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); |
1228 | 1229 |
1229 psg_context p_context; | 1230 psg_context p_context; |
1234 init_x86_z80_opts(&z_opts); | 1235 init_x86_z80_opts(&z_opts); |
1235 init_z80_context(&z_context, &z_opts); | 1236 init_z80_context(&z_context, &z_opts); |
1236 | 1237 |
1237 z_context.system = &gen; | 1238 z_context.system = &gen; |
1238 z_context.mem_pointers[0] = z80_ram; | 1239 z_context.mem_pointers[0] = z80_ram; |
1239 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; | 1240 z_context.sync_cycle = z_context.target_cycle = mclk_target/MCLKS_PER_Z80; |
1240 z_context.int_cycle = CYCLE_NEVER; | 1241 z_context.int_cycle = CYCLE_NEVER; |
1241 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; | 1242 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; |
1242 | 1243 |
1243 gen.z80 = &z_context; | 1244 gen.z80 = &z_context; |
1244 gen.vdp = &v_context; | 1245 gen.vdp = &v_context; |