comparison blastem.c @ 652:f822d9216968

Merge
author Michael Pavone <pavone@retrodev.com>
date Tue, 30 Dec 2014 19:11:34 -0800
parents 649db9397fa1 d77c79cec800
children 759c38bf97f8
comparison
equal deleted inserted replaced
620:9d6fed6501ba 652:f822d9216968
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
189 if (z_context->current_cycle < z_context->sync_cycle) { 189 if (z_context->current_cycle < z_context->sync_cycle) {
190 if (need_reset) { 190 if (need_reset) {
191 z80_reset(z_context); 191 z80_reset(z_context);
192 need_reset = 0; 192 need_reset = 0;
193 } 193 }
194 uint32_t vint_cycle = vdp_next_vint_z80(gen->vdp) / MCLKS_PER_Z80; 194
195 while (z_context->current_cycle < z_context->sync_cycle) { 195 while (z_context->current_cycle < z_context->sync_cycle) {
196 if (z_context->iff1 && z_context->current_cycle < (vint_cycle + Z80_VINT_DURATION)) { 196 if (z_context->int_pulse_end < z_context->current_cycle || z_context->int_pulse_end == CYCLE_NEVER) {
197 z_context->int_cycle = vint_cycle < z_context->int_enable_cycle ? z_context->int_enable_cycle : vint_cycle; 197 z_context->int_pulse_start = vdp_next_vint_z80(gen->vdp) / MCLKS_PER_Z80;
198 z_context->int_pulse_end = z_context->int_pulse_start + Z80_VINT_DURATION;
199 }
200 if (z_context->iff1) {
201 z_context->int_cycle = z_context->int_pulse_start < z_context->int_enable_cycle ? z_context->int_enable_cycle : z_context->int_pulse_start;
198 } else { 202 } else {
199 z_context->int_cycle = CYCLE_NEVER; 203 z_context->int_cycle = CYCLE_NEVER;
200 } 204 }
201 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; 205 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle;
202 dprintf("Running Z80 from cycle %d to cycle %d. Native PC: %p\n", z_context->current_cycle, z_context->sync_cycle, z_context->native_pc); 206 dprintf("Running Z80 from cycle %d to cycle %d. Int cycle: %d\n", z_context->current_cycle, z_context->sync_cycle, z_context->int_cycle);
203 z_context->run(z_context); 207 z_context->run(z_context);
204 dprintf("Z80 ran to cycle %d\n", z_context->current_cycle); 208 dprintf("Z80 ran to cycle %d\n", z_context->current_cycle);
205 } 209 }
206 } 210 }
207 } else 211 } else
234 genesis_context * gen = context->system; 238 genesis_context * gen = context->system;
235 vdp_context * v_context = gen->vdp; 239 vdp_context * v_context = gen->vdp;
236 z80_context * z_context = gen->z80; 240 z80_context * z_context = gen->z80;
237 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; 241 uint32_t mclks = context->current_cycle * MCLKS_PER_68K;
238 sync_z80(z_context, mclks); 242 sync_z80(z_context, mclks);
239 if (mclks >= mclks_per_frame) { 243 if (mclks >= mclk_target) {
240 sync_sound(gen, mclks); 244 sync_sound(gen, mclks);
241 gen->ym->current_cycle -= mclks_per_frame; 245 gen->ym->current_cycle -= mclk_target;
242 gen->psg->cycles -= mclks_per_frame; 246 gen->psg->cycles -= mclk_target;
243 if (gen->ym->write_cycle != CYCLE_NEVER) { 247 if (gen->ym->write_cycle != CYCLE_NEVER) {
244 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; 248 gen->ym->write_cycle = gen->ym->write_cycle >= mclk_target/MCLKS_PER_68K ? gen->ym->write_cycle - mclk_target/MCLKS_PER_68K : 0;
245 } 249 }
246 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); 250 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks);
247 vdp_run_context(v_context, mclks_per_frame); 251 vdp_run_context(v_context, mclk_target);
248 252
249 if (!headless) { 253 if (!headless) {
250 break_on_sync |= wait_render_frame(v_context, frame_limit); 254 break_on_sync |= wait_render_frame(v_context, frame_limit);
251 } else if(exit_after){ 255 } else if(exit_after){
252 --exit_after; 256 --exit_after;
253 if (!exit_after) { 257 if (!exit_after) {
254 exit(0); 258 exit(0);
255 } 259 }
256 } 260 }
257 frame++; 261 frame++;
258 mclks -= mclks_per_frame; 262 mclks -= mclk_target;
259 vdp_adjust_cycles(v_context, mclks_per_frame); 263 vdp_adjust_cycles(v_context, mclk_target);
260 io_adjust_cycles(gen->ports, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); 264 io_adjust_cycles(gen->ports, context->current_cycle, mclk_target/MCLKS_PER_68K);
261 io_adjust_cycles(gen->ports+1, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); 265 io_adjust_cycles(gen->ports+1, context->current_cycle, mclk_target/MCLKS_PER_68K);
262 io_adjust_cycles(gen->ports+2, context->current_cycle, mclks_per_frame/MCLKS_PER_68K); 266 io_adjust_cycles(gen->ports+2, context->current_cycle, mclk_target/MCLKS_PER_68K);
263 if (busack_cycle != CYCLE_NEVER) { 267 if (busack_cycle != CYCLE_NEVER) {
264 if (busack_cycle > mclks_per_frame/MCLKS_PER_68K) { 268 if (busack_cycle > mclk_target/MCLKS_PER_68K) {
265 busack_cycle -= mclks_per_frame/MCLKS_PER_68K; 269 busack_cycle -= mclk_target/MCLKS_PER_68K;
266 } else { 270 } else {
267 busack_cycle = CYCLE_NEVER; 271 busack_cycle = CYCLE_NEVER;
268 busack = new_busack; 272 busack = new_busack;
269 } 273 }
270 } 274 }
271 context->current_cycle -= mclks_per_frame/MCLKS_PER_68K; 275 context->current_cycle -= mclk_target/MCLKS_PER_68K;
272 if (z_context->current_cycle >= mclks_per_frame/MCLKS_PER_Z80) { 276 if (z_context->current_cycle >= mclk_target/MCLKS_PER_Z80) {
273 z_context->current_cycle -= mclks_per_frame/MCLKS_PER_Z80; 277 z_context->current_cycle -= mclk_target/MCLKS_PER_Z80;
274 } else { 278 } else {
275 z_context->current_cycle = 0; 279 z_context->current_cycle = 0;
276 } 280 }
281 if (z_context->int_cycle != CYCLE_NEVER) {
282 if (z_context->int_cycle >= mclk_target/MCLKS_PER_Z80) {
283 z_context->int_cycle -= mclk_target/MCLKS_PER_Z80;
284 } else {
285 z_context->int_cycle = 0;
286 }
287 }
288 if (z_context->int_pulse_start != CYCLE_NEVER) {
289 if (z_context->int_pulse_end >= mclk_target/MCLKS_PER_Z80) {
290 z_context->int_pulse_end -= mclk_target/MCLKS_PER_Z80;
291 if (z_context->int_pulse_start >= mclk_target/MCLKS_PER_Z80) {
292 z_context->int_pulse_start -= mclk_target/MCLKS_PER_Z80;
293 } else {
294 z_context->int_pulse_start = 0;
295 }
296 }
297 } else {
298 z_context->int_pulse_start = CYCLE_NEVER;
299 z_context->int_pulse_end = CYCLE_NEVER;
300 }
301 if (z_context->int_enable_cycle >= mclk_target/MCLKS_PER_Z80) {
302 z_context->int_enable_cycle -= mclk_target/MCLKS_PER_Z80;
303 } else {
304 z_context->int_enable_cycle = 0;
305 }
277 if (mclks) { 306 if (mclks) {
278 vdp_run_context(v_context, mclks); 307 vdp_run_context(v_context, mclks);
279 } 308 }
309 mclk_target = vdp_cycles_to_frame_end(v_context);
280 } else { 310 } else {
281 //printf("running VDP for %d cycles\n", mclks - v_context->cycles); 311 //printf("running VDP for %d cycles\n", mclks - v_context->cycles);
282 vdp_run_context(v_context, mclks); 312 vdp_run_context(v_context, mclks);
283 sync_sound(gen, mclks); 313 sync_sound(gen, mclks);
284 } 314 }
320 uint32_t before_cycle = v_context->cycles; 350 uint32_t before_cycle = v_context->cycles;
321 if (vdp_port < 4) { 351 if (vdp_port < 4) {
322 gen->bus_busy = 1; 352 gen->bus_busy = 1;
323 while (vdp_data_port_write(v_context, value) < 0) { 353 while (vdp_data_port_write(v_context, value) < 0) {
324 while(v_context->flags & FLAG_DMA_RUN) { 354 while(v_context->flags & FLAG_DMA_RUN) {
325 vdp_run_dma_done(v_context, mclks_per_frame); 355 vdp_run_dma_done(v_context, mclk_target);
326 if (v_context->cycles >= mclks_per_frame) { 356 if (v_context->cycles >= mclk_target) {
327 context->current_cycle = v_context->cycles / MCLKS_PER_68K; 357 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
328 if (context->current_cycle * MCLKS_PER_68K < mclks_per_frame) { 358 if (context->current_cycle * MCLKS_PER_68K < mclk_target) {
329 ++context->current_cycle; 359 ++context->current_cycle;
330 } 360 }
331 sync_components(context, 0); 361 sync_components(context, 0);
332 } 362 }
333 } 363 }
337 gen->bus_busy = 1; 367 gen->bus_busy = 1;
338 blocked = vdp_control_port_write(v_context, value); 368 blocked = vdp_control_port_write(v_context, value);
339 if (blocked) { 369 if (blocked) {
340 while (blocked) { 370 while (blocked) {
341 while(v_context->flags & FLAG_DMA_RUN) { 371 while(v_context->flags & FLAG_DMA_RUN) {
342 vdp_run_dma_done(v_context, mclks_per_frame); 372 vdp_run_dma_done(v_context, mclk_target);
343 if (v_context->cycles >= mclks_per_frame) { 373 if (v_context->cycles >= mclk_target) {
344 context->current_cycle = v_context->cycles / MCLKS_PER_68K; 374 context->current_cycle = v_context->cycles / MCLKS_PER_68K;
345 if (context->current_cycle * MCLKS_PER_68K < mclks_per_frame) { 375 if (context->current_cycle * MCLKS_PER_68K < mclk_target) {
346 ++context->current_cycle; 376 ++context->current_cycle;
347 } 377 }
348 sync_components(context, 0); 378 sync_components(context, 0);
349 } 379 }
350 } 380 }
1043 1073
1044 context.video_context = gen->vdp; 1074 context.video_context = gen->vdp;
1045 context.system = gen; 1075 context.system = gen;
1046 //cartridge ROM 1076 //cartridge ROM
1047 context.mem_pointers[0] = cart; 1077 context.mem_pointers[0] = cart;
1048 context.target_cycle = context.sync_cycle = mclks_per_frame/MCLKS_PER_68K; 1078 context.target_cycle = context.sync_cycle = mclk_target/MCLKS_PER_68K;
1049 //work RAM 1079 //work RAM
1050 context.mem_pointers[1] = ram; 1080 context.mem_pointers[1] = ram;
1051 //save RAM/map 1081 //save RAM/map
1052 context.mem_pointers[2] = initial_mapped; 1082 context.mem_pointers[2] = initial_mapped;
1053 context.mem_pointers[3] = (uint16_t *)gen->save_ram; 1083 context.mem_pointers[3] = (uint16_t *)gen->save_ram;
1298 } 1328 }
1299 width = width < 320 ? def_width : width; 1329 width = width < 320 ? def_width : width;
1300 height = height < 240 ? (width/320) * 240 : height; 1330 height = height < 240 ? (width/320) * 240 : height;
1301 uint32_t fps = 60; 1331 uint32_t fps = 60;
1302 if (version_reg & 0x40) { 1332 if (version_reg & 0x40) {
1303 mclks_per_frame = MCLKS_LINE * LINES_PAL;
1304 fps = 50; 1333 fps = 50;
1305 } 1334 }
1306 if (!headless) { 1335 if (!headless) {
1307 render_init(width, height, title, fps, fullscreen, use_gl); 1336 render_init(width, height, title, fps, fullscreen, use_gl);
1308 } 1337 }
1309 vdp_context v_context; 1338 vdp_context v_context;
1310 genesis_context gen; 1339 genesis_context gen;
1311 memset(&gen, 0, sizeof(gen)); 1340 memset(&gen, 0, sizeof(gen));
1312 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL; 1341 gen.master_clock = gen.normal_clock = fps == 60 ? MCLKS_NTSC : MCLKS_PAL;
1313 1342
1314 init_vdp_context(&v_context); 1343 init_vdp_context(&v_context, version_reg & 0x40);
1344 mclk_target = vdp_cycles_to_frame_end(&v_context);
1315 1345
1316 ym2612_context y_context; 1346 ym2612_context y_context;
1317 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0); 1347 ym_init(&y_context, render_sample_rate(), gen.master_clock, MCLKS_PER_YM, render_audio_buffer(), ym_log ? YM_OPT_WAVE_LOG : 0);
1318 1348
1319 psg_context p_context; 1349 psg_context p_context;
1326 init_z80_context(&z_context, &z_opts); 1356 init_z80_context(&z_context, &z_opts);
1327 #endif 1357 #endif
1328 1358
1329 z_context.system = &gen; 1359 z_context.system = &gen;
1330 z_context.mem_pointers[0] = z80_ram; 1360 z_context.mem_pointers[0] = z80_ram;
1331 z_context.sync_cycle = z_context.target_cycle = mclks_per_frame/MCLKS_PER_Z80; 1361 z_context.sync_cycle = z_context.target_cycle = mclk_target/MCLKS_PER_Z80;
1332 z_context.int_cycle = CYCLE_NEVER; 1362 z_context.int_cycle = CYCLE_NEVER;
1333 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart; 1363 z_context.mem_pointers[1] = z_context.mem_pointers[2] = (uint8_t *)cart;
1334 1364
1335 gen.z80 = &z_context; 1365 gen.z80 = &z_context;
1336 gen.vdp = &v_context; 1366 gen.vdp = &v_context;
1349 } 1379 }
1350 } 1380 }
1351 if (i < 0) { 1381 if (i < 0) {
1352 strcpy(sram_filename + fname_size, ".sram"); 1382 strcpy(sram_filename + fname_size, ".sram");
1353 } 1383 }
1354 set_keybindings(); 1384 set_keybindings(gen.ports);
1355 1385
1356 init_run_cpu(&gen, address_log, statefile, debuggerfun); 1386 init_run_cpu(&gen, address_log, statefile, debuggerfun);
1357 return 0; 1387 return 0;
1358 } 1388 }