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;