comparison blastem.c @ 289:1cc0850ab6bc

Hopefully more correct implementation of the Z80 busack status
author Mike Pavone <pavone@retrodev.com>
date Mon, 06 May 2013 00:22:24 -0700
parents a8ee7934a1f8
children 171f97e70d85
comparison
equal deleted inserted replaced
288:a8ee7934a1f8 289:1cc0850ab6bc
123 } 123 }
124 } 124 }
125 } 125 }
126 126
127 int break_on_sync = 0; 127 int break_on_sync = 0;
128 #define Z80_ACK_DELAY 3 //TODO: Calculate this on the fly based on how synced up the Z80 and 68K clocks are
129 128
130 uint8_t reset = 1; 129 uint8_t reset = 1;
131 uint8_t need_reset = 0; 130 uint8_t need_reset = 0;
132 uint8_t busreq = 0; 131 uint8_t busreq = 0;
133 uint8_t busack = 0; 132 uint8_t busack = 0;
157 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle; 156 z_context->target_cycle = z_context->sync_cycle < z_context->int_cycle ? z_context->sync_cycle : z_context->int_cycle;
158 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); 157 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);
159 z80_run(z_context); 158 z80_run(z_context);
160 dprintf("Z80 ran to cycle %d\n", z_context->current_cycle); 159 dprintf("Z80 ran to cycle %d\n", z_context->current_cycle);
161 } 160 }
161 } else {
162 z_context->current_cycle = mclks / MCLKS_PER_Z80;
162 } 163 }
163 } 164 }
164 165
165 m68k_context * sync_components(m68k_context * context, uint32_t address) 166 m68k_context * sync_components(m68k_context * context, uint32_t address)
166 { 167 {
352 printf ("value: %X\n", context->value); 353 printf ("value: %X\n", context->value);
353 }*/ 354 }*/
354 } 355 }
355 356
356 uint32_t zram_counter = 0; 357 uint32_t zram_counter = 0;
358 #define Z80_ACK_DELAY 3
359 #define Z80_BUSY_DELAY 2//TODO: Find the actual value for this
360 #define Z80_REQ_BUSY 1
361 #define Z80_REQ_ACK 0
362 #define Z80_RES_BUSACK reset
357 363
358 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) 364 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value)
359 { 365 {
360 genesis_context * gen = context->system; 366 genesis_context * gen = context->system;
361 if (location < 0x10000) { 367 if (location < 0x10000) {
408 } 414 }
409 if (value & 1) { 415 if (value & 1) {
410 dputs("bus requesting Z80"); 416 dputs("bus requesting Z80");
411 busreq = 1; 417 busreq = 1;
412 if(!reset) { 418 if(!reset) {
413 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 419 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
414 new_busack = 0; 420 new_busack = Z80_REQ_ACK;
415 } 421 }
416 } else { 422 } else {
417 if (busreq) { 423 if (busreq) {
418 dputs("releasing z80 bus"); 424 dputs("releasing z80 bus");
419 #ifdef DO_DEBUG_PRINT 425 #ifdef DO_DEBUG_PRINT
422 FILE * f = fopen(fname, "wb"); 428 FILE * f = fopen(fname, "wb");
423 fwrite(z80_ram, 1, sizeof(z80_ram), f); 429 fwrite(z80_ram, 1, sizeof(z80_ram), f);
424 fclose(f); 430 fclose(f);
425 #endif 431 #endif
426 //TODO: Add necessary delay between release of busreq and resumption of execution 432 //TODO: Add necessary delay between release of busreq and resumption of execution
427 gen->z80->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
428 } 433 }
429 busreq = 0; 434 busreq = 0;
430 busack_cycle = CYCLE_NEVER; 435 //busack_cycle = CYCLE_NEVER;
431 busack = 1; 436 //busack = Z80_REQ_BUSY;
437 busack_cycle = ((gen->z80->current_cycle + Z80_BUSY_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;
438 new_busack = Z80_REQ_BUSY;
432 } 439 }
433 } else if (location == 0x1200) { 440 } else if (location == 0x1200) {
434 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 441 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
435 if (value & 1) { 442 if (value & 1) {
436 if (reset && busreq) { 443 if (reset && busreq) {
437 new_busack = 0; 444 new_busack = 0;
438 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 445 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
439 } 446 }
440 //TODO: Deal with the scenario in which reset is not asserted long enough 447 //TODO: Deal with the scenario in which reset is not asserted long enough
441 if (reset) { 448 if (reset) {
442 need_reset = 1; 449 need_reset = 1;
443 //TODO: Add necessary delay between release of reset and start of execution 450 //TODO: Add necessary delay between release of reset and start of execution
507 } 514 }
508 if (value & 0x100) { 515 if (value & 0x100) {
509 dprintf("bus requesting Z80 @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80); 516 dprintf("bus requesting Z80 @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80);
510 busreq = 1; 517 busreq = 1;
511 if(!reset) { 518 if(!reset) {
512 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 519 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
513 new_busack = 0; 520 new_busack = Z80_REQ_ACK;
514 } 521 }
515 } else { 522 } else {
516 if (busreq) { 523 if (busreq) {
517 dprintf("releasing Z80 bus @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80); 524 dprintf("releasing Z80 bus @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80);
518 #ifdef DO_DEBUG_PRINT 525 #ifdef DO_DEBUG_PRINT
521 FILE * f = fopen(fname, "wb"); 528 FILE * f = fopen(fname, "wb");
522 fwrite(z80_ram, 1, sizeof(z80_ram), f); 529 fwrite(z80_ram, 1, sizeof(z80_ram), f);
523 fclose(f); 530 fclose(f);
524 #endif 531 #endif
525 //TODO: Add necessary delay between release of busreq and resumption of execution 532 //TODO: Add necessary delay between release of busreq and resumption of execution
526 gen->z80->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
527 } 533 }
528 busreq = 0; 534 busreq = 0;
529 busack_cycle = CYCLE_NEVER; 535 //busack_cycle = CYCLE_NEVER;
530 busack = 1; 536 //busack = Z80_REQ_BUSY;
537 busack_cycle = ((gen->z80->current_cycle + Z80_BUSY_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;
538 new_busack = Z80_REQ_BUSY;
531 } 539 }
532 } else if (location == 0x1200) { 540 } else if (location == 0x1200) {
533 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 541 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
534 if (value & 0x100) { 542 if (value & 0x100) {
535 if (reset && busreq) { 543 if (reset && busreq) {
536 new_busack = 0; 544 new_busack = 0;
537 busack_cycle = context->current_cycle + Z80_ACK_DELAY; 545 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
538 } 546 }
539 //TODO: Deal with the scenario in which reset is not asserted long enough 547 //TODO: Deal with the scenario in which reset is not asserted long enough
540 if (reset) { 548 if (reset) {
541 need_reset = 1; 549 need_reset = 1;
542 //TODO: Add necessary delay between release of reset and start of execution 550 //TODO: Add necessary delay between release of reset and start of execution
543 gen->z80->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
544 } 551 }
545 reset = 0; 552 reset = 0;
546 } else { 553 } else {
547 reset = 1; 554 reset = 1;
548 } 555 }
564 if (location < 0x10000) { 571 if (location < 0x10000) {
565 if (busack_cycle > context->current_cycle) { 572 if (busack_cycle > context->current_cycle) {
566 busack = new_busack; 573 busack = new_busack;
567 busack_cycle = CYCLE_NEVER; 574 busack_cycle = CYCLE_NEVER;
568 } 575 }
569 if (!(busack || reset)) { 576 if (!(busack==Z80_REQ_BUSY || reset)) {
570 location &= 0x7FFF; 577 location &= 0x7FFF;
571 if (location < 0x4000) { 578 if (location < 0x4000) {
572 context->value = z80_ram[location & 0x1FFF]; 579 context->value = z80_ram[location & 0x1FFF];
573 } else if (location < 0x6000) { 580 } else if (location < 0x6000) {
574 ym_run(gen->ym, context->current_cycle); 581 ym_run(gen->ym, context->current_cycle);
608 if (location == 0x1100) { 615 if (location == 0x1100) {
609 if (busack_cycle > context->current_cycle) { 616 if (busack_cycle > context->current_cycle) {
610 busack = new_busack; 617 busack = new_busack;
611 busack_cycle = CYCLE_NEVER; 618 busack_cycle = CYCLE_NEVER;
612 } 619 }
613 context->value = reset || busack; 620 context->value = Z80_RES_BUSACK || busack;
614 //printf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d)\n", context->value, context->current_cycle, reset, busack); 621 //printf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d)\n", context->value, context->current_cycle, reset, busack);
615 } else if (location == 0x1200) { 622 } else if (location == 0x1200) {
616 context->value = !reset; 623 context->value = !reset;
617 } else { 624 } else {
618 printf("Byte read of unknown IO location: %X\n", location); 625 printf("Byte read of unknown IO location: %X\n", location);
628 if (location < 0x10000) { 635 if (location < 0x10000) {
629 if (busack_cycle > context->current_cycle) { 636 if (busack_cycle > context->current_cycle) {
630 busack = new_busack; 637 busack = new_busack;
631 busack_cycle = CYCLE_NEVER; 638 busack_cycle = CYCLE_NEVER;
632 } 639 }
633 if (!(busack || reset)) { 640 if (!(busack==Z80_REQ_BUSY || reset)) {
634 location &= 0x7FFF; 641 location &= 0x7FFF;
635 uint16_t value; 642 uint16_t value;
636 if (location < 0x4000) { 643 if (location < 0x4000) {
637 value = z80_ram[location & 0x1FFE]; 644 value = z80_ram[location & 0x1FFE];
638 } else if (location < 0x6000) { 645 } else if (location < 0x6000) {
680 if (location == 0x1100) { 687 if (location == 0x1100) {
681 if (busack_cycle > context->current_cycle) { 688 if (busack_cycle > context->current_cycle) {
682 busack = new_busack; 689 busack = new_busack;
683 busack_cycle = CYCLE_NEVER; 690 busack_cycle = CYCLE_NEVER;
684 } 691 }
685 context->value = (reset || busack) << 8; 692 context->value = (Z80_RES_BUSACK || busack) << 8;
686 //printf("Word read of BUSREQ returned %d\n", context->value); 693 //printf("Word read of BUSREQ returned %d\n", context->value);
687 } else if (location == 0x1200) { 694 } else if (location == 0x1200) {
688 context->value = (!reset) << 8; 695 context->value = (!reset) << 8;
689 } else { 696 } else {
690 printf("Word read of unknown IO location: %X\n", location); 697 printf("Word read of unknown IO location: %X\n", location);