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 }