Mercurial > repos > blastem
comparison blastem.c @ 268:6c2d7e003a55
Sync Z80 on writes to busreq/reset ports. NULL out extra_pc on z80 reset
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 02 May 2013 21:54:04 -0700 |
parents | 376df762ddf5 |
children | 969ee17471c5 |
comparison
equal
deleted
inserted
replaced
267:1788e3f29c28 | 268:6c2d7e003a55 |
---|---|
132 uint8_t busreq = 0; | 132 uint8_t busreq = 0; |
133 uint8_t busack = 0; | 133 uint8_t busack = 0; |
134 uint32_t busack_cycle = CYCLE_NEVER; | 134 uint32_t busack_cycle = CYCLE_NEVER; |
135 uint8_t new_busack = 0; | 135 uint8_t new_busack = 0; |
136 | 136 |
137 m68k_context * sync_components(m68k_context * context, uint32_t address) | 137 #ifdef DO_DEBUG_PRINT |
138 { | 138 #define dprintf printf |
139 //TODO: Handle sync targets smaller than a single frame | 139 #else |
140 z80_context * z_context = context->next_cpu; | 140 #define dprintf |
141 vdp_context * v_context = context->video_context; | 141 #endif |
142 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; | 142 |
143 void sync_z80(z80_context * z_context, uint32_t mclks) | |
144 { | |
143 if (z80_enabled && !reset && !busreq) { | 145 if (z80_enabled && !reset && !busreq) { |
144 if (need_reset) { | 146 if (need_reset) { |
145 z80_reset(z_context); | 147 z80_reset(z_context); |
146 need_reset = 0; | 148 need_reset = 0; |
147 } | 149 } |
149 while (z_context->current_cycle < z_context->sync_cycle) { | 151 while (z_context->current_cycle < z_context->sync_cycle) { |
150 if (z_context->iff1 && z_context->current_cycle < ZVINT_CYCLE) { | 152 if (z_context->iff1 && z_context->current_cycle < ZVINT_CYCLE) { |
151 z_context->int_cycle = ZVINT_CYCLE; | 153 z_context->int_cycle = ZVINT_CYCLE; |
152 } | 154 } |
153 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; | 155 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; |
154 //printf("Running Z80 from cycle %d to cycle %d. Native PC: %p\n", z_context->current_cycle, z_context->sync_cycle, z_context->native_pc); | 156 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); |
155 z80_run(z_context); | 157 z80_run(z_context); |
156 //printf("Z80 ran to cycle %d\n", z_context->current_cycle); | 158 dprintf("Z80 ran to cycle %d\n", z_context->current_cycle); |
157 } | 159 } |
158 } | 160 } |
161 } | |
162 | |
163 m68k_context * sync_components(m68k_context * context, uint32_t address) | |
164 { | |
165 //TODO: Handle sync targets smaller than a single frame | |
166 vdp_context * v_context = context->video_context; | |
167 z80_context * z_context = context->next_cpu; | |
168 uint32_t mclks = context->current_cycle * MCLKS_PER_68K; | |
169 sync_z80(z_context, mclks); | |
159 if (mclks >= MCLKS_PER_FRAME) { | 170 if (mclks >= MCLKS_PER_FRAME) { |
160 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); | 171 //printf("reached frame end | 68K Cycles: %d, MCLK Cycles: %d\n", context->current_cycle, mclks); |
161 vdp_run_context(v_context, MCLKS_PER_FRAME); | 172 vdp_run_context(v_context, MCLKS_PER_FRAME); |
162 if (!headless) { | 173 if (!headless) { |
163 break_on_sync |= wait_render_frame(v_context); | 174 break_on_sync |= wait_render_frame(v_context); |
371 gamepad_2.control = value; | 382 gamepad_2.control = value; |
372 break; | 383 break; |
373 } | 384 } |
374 } else { | 385 } else { |
375 if (location == 0x1100) { | 386 if (location == 0x1100) { |
387 sync_z80(context->next_cpu, context->current_cycle * MCLKS_PER_68K); | |
376 if (busack_cycle > context->current_cycle) { | 388 if (busack_cycle > context->current_cycle) { |
377 busack = new_busack; | 389 busack = new_busack; |
378 busack_cycle = CYCLE_NEVER; | 390 busack_cycle = CYCLE_NEVER; |
379 } | 391 } |
380 if (value & 1) { | 392 if (value & 1) { |
393 puts("bus requesting Z80"); | |
381 busreq = 1; | 394 busreq = 1; |
382 if(!reset) { | 395 if(!reset) { |
383 busack_cycle = context->current_cycle + Z80_ACK_DELAY; | 396 busack_cycle = context->current_cycle + Z80_ACK_DELAY; |
384 new_busack = 0; | 397 new_busack = 0; |
385 } | 398 } |
386 } else { | 399 } else { |
387 if (busreq) { | 400 if (busreq) { |
401 puts("releasing z80 bus"); | |
388 z80_context * z_context = context->next_cpu; | 402 z80_context * z_context = context->next_cpu; |
389 //TODO: Add necessary delay between release of busreq and resumption of execution | 403 //TODO: Add necessary delay between release of busreq and resumption of execution |
390 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; | 404 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; |
391 } | 405 } |
392 busreq = 0; | 406 busreq = 0; |
393 busack_cycle = CYCLE_NEVER; | 407 busack_cycle = CYCLE_NEVER; |
394 busack = 1; | 408 busack = 1; |
395 } | 409 } |
396 } else if (location == 0x1200) { | 410 } else if (location == 0x1200) { |
411 sync_z80(context->next_cpu, context->current_cycle * MCLKS_PER_68K); | |
397 if (value & 1) { | 412 if (value & 1) { |
398 if (reset && busreq) { | 413 if (reset && busreq) { |
399 new_busack = 0; | 414 new_busack = 0; |
400 busack_cycle = context->current_cycle + Z80_ACK_DELAY; | 415 busack_cycle = context->current_cycle + Z80_ACK_DELAY; |
401 } | 416 } |
451 break; | 466 break; |
452 } | 467 } |
453 } else { | 468 } else { |
454 //printf("IO Write of %X to %X @ %d\n", value, location, context->current_cycle); | 469 //printf("IO Write of %X to %X @ %d\n", value, location, context->current_cycle); |
455 if (location == 0x1100) { | 470 if (location == 0x1100) { |
471 sync_z80(context->next_cpu, context->current_cycle * MCLKS_PER_68K); | |
456 if (busack_cycle > context->current_cycle) { | 472 if (busack_cycle > context->current_cycle) { |
457 busack = new_busack; | 473 busack = new_busack; |
458 busack_cycle = CYCLE_NEVER; | 474 busack_cycle = CYCLE_NEVER; |
459 } | 475 } |
460 if (value & 0x100) { | 476 if (value & 0x100) { |
477 printf("bus requesting Z80 @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80); | |
461 busreq = 1; | 478 busreq = 1; |
462 if(!reset) { | 479 if(!reset) { |
463 busack_cycle = context->current_cycle + Z80_ACK_DELAY; | 480 busack_cycle = context->current_cycle + Z80_ACK_DELAY; |
464 new_busack = 0; | 481 new_busack = 0; |
465 } | 482 } |
466 } else { | 483 } else { |
467 if (busreq) { | 484 if (busreq) { |
485 printf("releasing Z80 bus @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80); | |
468 z80_context * z_context = context->next_cpu; | 486 z80_context * z_context = context->next_cpu; |
469 //TODO: Add necessary delay between release of busreq and resumption of execution | 487 //TODO: Add necessary delay between release of busreq and resumption of execution |
470 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; | 488 z_context->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80; |
471 } | 489 } |
472 busreq = 0; | 490 busreq = 0; |
473 busack_cycle = CYCLE_NEVER; | 491 busack_cycle = CYCLE_NEVER; |
474 busack = 1; | 492 busack = 1; |
475 } | 493 } |
476 } else if (location == 0x1200) { | 494 } else if (location == 0x1200) { |
495 sync_z80(context->next_cpu, context->current_cycle * MCLKS_PER_68K); | |
477 if (value & 0x100) { | 496 if (value & 0x100) { |
478 if (reset && busreq) { | 497 if (reset && busreq) { |
479 new_busack = 0; | 498 new_busack = 0; |
480 busack_cycle = context->current_cycle + Z80_ACK_DELAY; | 499 busack_cycle = context->current_cycle + Z80_ACK_DELAY; |
481 } | 500 } |