comparison blastem.c @ 336:87b65e5ce1ab

Fix a stupid bug in z80 busreq acknowledge delay code and make some small improvements there too
author Mike Pavone <pavone@retrodev.com>
date Tue, 14 May 2013 22:52:15 -0700
parents 14a937097c2b
children 5c34a9c39394
comparison
equal deleted inserted replaced
335:14a937097c2b 336:87b65e5ce1ab
379 }*/ 379 }*/
380 } 380 }
381 381
382 uint32_t zram_counter = 0; 382 uint32_t zram_counter = 0;
383 #define Z80_ACK_DELAY 3 383 #define Z80_ACK_DELAY 3
384 #define Z80_BUSY_DELAY 2//TODO: Find the actual value for this 384 #define Z80_BUSY_DELAY 1//TODO: Find the actual value for this
385 #define Z80_REQ_BUSY 1 385 #define Z80_REQ_BUSY 1
386 #define Z80_REQ_ACK 0 386 #define Z80_REQ_ACK 0
387 #define Z80_RES_BUSACK reset 387 #define Z80_RES_BUSACK reset
388 388
389 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value) 389 m68k_context * io_write(uint32_t location, m68k_context * context, uint8_t value)
390 { 390 {
391 genesis_context * gen = context->system; 391 genesis_context * gen = context->system;
392 if (location < 0x10000) { 392 if (location < 0x10000) {
393 if (busack_cycle > context->current_cycle) { 393 if (busack_cycle <= context->current_cycle) {
394 busack = new_busack; 394 busack = new_busack;
395 busack_cycle = CYCLE_NEVER; 395 busack_cycle = CYCLE_NEVER;
396 } 396 }
397 if (!(busack || reset)) { 397 if (!(busack || reset)) {
398 location &= 0x7FFF; 398 location &= 0x7FFF;
431 break; 431 break;
432 } 432 }
433 } else { 433 } else {
434 if (location == 0x1100) { 434 if (location == 0x1100) {
435 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 435 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
436 if (busack_cycle > context->current_cycle) { 436 if (busack_cycle <= context->current_cycle) {
437 busack = new_busack; 437 busack = new_busack;
438 busack_cycle = CYCLE_NEVER; 438 busack_cycle = CYCLE_NEVER;
439 } 439 }
440 if (value & 1) { 440 if (value & 1) {
441 dputs("bus requesting Z80"); 441 dputs("bus requesting Z80");
442 busreq = 1; 442
443 if(!reset) { 443 if(!reset && !busreq) {
444 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY; 444 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//context->current_cycle + Z80_ACK_DELAY;
445 new_busack = Z80_REQ_ACK; 445 new_busack = Z80_REQ_ACK;
446 busreq = 1;
446 } 447 }
447 } else { 448 } else {
448 if (busreq) { 449 if (busreq) {
449 dputs("releasing z80 bus"); 450 dputs("releasing z80 bus");
450 #ifdef DO_DEBUG_PRINT 451 #ifdef DO_DEBUG_PRINT
452 sprintf(fname, "zram-%d", zram_counter++); 453 sprintf(fname, "zram-%d", zram_counter++);
453 FILE * f = fopen(fname, "wb"); 454 FILE * f = fopen(fname, "wb");
454 fwrite(z80_ram, 1, sizeof(z80_ram), f); 455 fwrite(z80_ram, 1, sizeof(z80_ram), f);
455 fclose(f); 456 fclose(f);
456 #endif 457 #endif
457 //TODO: Add necessary delay between release of busreq and resumption of execution 458 busack_cycle = ((gen->z80->current_cycle + Z80_BUSY_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;
458 } 459 new_busack = Z80_REQ_BUSY;
459 busreq = 0; 460 busreq = 0;
461 }
460 //busack_cycle = CYCLE_NEVER; 462 //busack_cycle = CYCLE_NEVER;
461 //busack = Z80_REQ_BUSY; 463 //busack = Z80_REQ_BUSY;
462 busack_cycle = ((gen->z80->current_cycle + Z80_BUSY_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K; 464
463 new_busack = Z80_REQ_BUSY;
464 } 465 }
465 } else if (location == 0x1200) { 466 } else if (location == 0x1200) {
466 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 467 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
467 if (value & 1) { 468 if (value & 1) {
468 if (reset && busreq) { 469 if (reset && busreq) {
487 488
488 m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value) 489 m68k_context * io_write_w(uint32_t location, m68k_context * context, uint16_t value)
489 { 490 {
490 genesis_context * gen = context->system; 491 genesis_context * gen = context->system;
491 if (location < 0x10000) { 492 if (location < 0x10000) {
492 if (busack_cycle > context->current_cycle) { 493 if (busack_cycle <= context->current_cycle) {
493 busack = new_busack; 494 busack = new_busack;
494 busack_cycle = CYCLE_NEVER; 495 busack_cycle = CYCLE_NEVER;
495 } 496 }
496 if (!(busack || reset)) { 497 if (!(busack || reset)) {
497 location &= 0x7FFF; 498 location &= 0x7FFF;
531 } 532 }
532 } else { 533 } else {
533 //printf("IO Write of %X to %X @ %d\n", value, location, context->current_cycle); 534 //printf("IO Write of %X to %X @ %d\n", value, location, context->current_cycle);
534 if (location == 0x1100) { 535 if (location == 0x1100) {
535 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 536 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
536 if (busack_cycle > context->current_cycle) { 537 if (busack_cycle <= context->current_cycle) {
537 busack = new_busack; 538 busack = new_busack;
538 busack_cycle = CYCLE_NEVER; 539 busack_cycle = CYCLE_NEVER;
539 } 540 }
540 if (value & 0x100) { 541 if (value & 0x100) {
541 dprintf("bus requesting Z80 @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80); 542 dprintf("bus requesting Z80 @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80);
542 busreq = 1; 543
543 if(!reset) { 544 if(!reset && !busreq) {
544 busack_cycle = ((gen->z80->current_cycle + Z80_ACK_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;//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;
545 new_busack = Z80_REQ_ACK; 546 new_busack = Z80_REQ_ACK;
547 busreq = 1;
546 } 548 }
547 } else { 549 } else {
548 if (busreq) { 550 if (busreq) {
549 dprintf("releasing Z80 bus @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80); 551 dprintf("releasing Z80 bus @ %d\n", (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80);
550 #ifdef DO_DEBUG_PRINT 552 #ifdef DO_DEBUG_PRINT
552 sprintf(fname, "zram-%d", zram_counter++); 554 sprintf(fname, "zram-%d", zram_counter++);
553 FILE * f = fopen(fname, "wb"); 555 FILE * f = fopen(fname, "wb");
554 fwrite(z80_ram, 1, sizeof(z80_ram), f); 556 fwrite(z80_ram, 1, sizeof(z80_ram), f);
555 fclose(f); 557 fclose(f);
556 #endif 558 #endif
557 //TODO: Add necessary delay between release of busreq and resumption of execution 559 busack_cycle = ((gen->z80->current_cycle + Z80_BUSY_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;
558 } 560 new_busack = Z80_REQ_BUSY;
559 busreq = 0; 561 busreq = 0;
562 }
560 //busack_cycle = CYCLE_NEVER; 563 //busack_cycle = CYCLE_NEVER;
561 //busack = Z80_REQ_BUSY; 564 //busack = Z80_REQ_BUSY;
562 busack_cycle = ((gen->z80->current_cycle + Z80_BUSY_DELAY) * MCLKS_PER_Z80) / MCLKS_PER_68K;
563 new_busack = Z80_REQ_BUSY;
564 } 565 }
565 } else if (location == 0x1200) { 566 } else if (location == 0x1200) {
566 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K); 567 sync_z80(gen->z80, context->current_cycle * MCLKS_PER_68K);
567 if (value & 0x100) { 568 if (value & 0x100) {
568 if (reset && busreq) { 569 if (reset && busreq) {
571 } 572 }
572 //TODO: Deal with the scenario in which reset is not asserted long enough 573 //TODO: Deal with the scenario in which reset is not asserted long enough
573 if (reset) { 574 if (reset) {
574 need_reset = 1; 575 need_reset = 1;
575 //TODO: Add necessary delay between release of reset and start of execution 576 //TODO: Add necessary delay between release of reset and start of execution
577 gen->z80->current_cycle = (context->current_cycle * MCLKS_PER_68K) / MCLKS_PER_Z80;
576 } 578 }
577 reset = 0; 579 reset = 0;
578 } else { 580 } else {
579 reset = 1; 581 reset = 1;
580 } 582 }
592 594
593 m68k_context * io_read(uint32_t location, m68k_context * context) 595 m68k_context * io_read(uint32_t location, m68k_context * context)
594 { 596 {
595 genesis_context *gen = context->system; 597 genesis_context *gen = context->system;
596 if (location < 0x10000) { 598 if (location < 0x10000) {
597 if (busack_cycle > context->current_cycle) { 599 if (busack_cycle <= context->current_cycle) {
598 busack = new_busack; 600 busack = new_busack;
599 busack_cycle = CYCLE_NEVER; 601 busack_cycle = CYCLE_NEVER;
600 } 602 }
601 if (!(busack==Z80_REQ_BUSY || reset)) { 603 if (!(busack==Z80_REQ_BUSY || reset)) {
602 location &= 0x7FFF; 604 location &= 0x7FFF;
636 context->value = gamepad_2.control; 638 context->value = gamepad_2.control;
637 break; 639 break;
638 } 640 }
639 } else { 641 } else {
640 if (location == 0x1100) { 642 if (location == 0x1100) {
641 if (busack_cycle > context->current_cycle) { 643 if (busack_cycle <= context->current_cycle) {
642 busack = new_busack; 644 busack = new_busack;
643 busack_cycle = CYCLE_NEVER; 645 busack_cycle = CYCLE_NEVER;
644 } 646 }
645 context->value = Z80_RES_BUSACK || busack; 647 context->value = Z80_RES_BUSACK || busack;
646 //printf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d)\n", context->value, context->current_cycle, reset, busack); 648 dprintf("Byte read of BUSREQ returned %d @ %d (reset: %d, busack: %d, busack_cycle %d)\n", context->value, context->current_cycle, reset, busack, busack_cycle);
647 } else if (location == 0x1200) { 649 } else if (location == 0x1200) {
648 context->value = !reset; 650 context->value = !reset;
649 } else { 651 } else {
650 printf("Byte read of unknown IO location: %X\n", location); 652 printf("Byte read of unknown IO location: %X\n", location);
651 } 653 }
656 658
657 m68k_context * io_read_w(uint32_t location, m68k_context * context) 659 m68k_context * io_read_w(uint32_t location, m68k_context * context)
658 { 660 {
659 genesis_context * gen = context->system; 661 genesis_context * gen = context->system;
660 if (location < 0x10000) { 662 if (location < 0x10000) {
661 if (busack_cycle > context->current_cycle) { 663 if (busack_cycle <= context->current_cycle) {
662 busack = new_busack; 664 busack = new_busack;
663 busack_cycle = CYCLE_NEVER; 665 busack_cycle = CYCLE_NEVER;
664 } 666 }
665 if (!(busack==Z80_REQ_BUSY || reset)) { 667 if (!(busack==Z80_REQ_BUSY || reset)) {
666 location &= 0x7FFF; 668 location &= 0x7FFF;
708 } 710 }
709 context->value = context->value | (context->value << 8); 711 context->value = context->value | (context->value << 8);
710 //printf("Word read to %X returned %d\n", location, context->value); 712 //printf("Word read to %X returned %d\n", location, context->value);
711 } else { 713 } else {
712 if (location == 0x1100) { 714 if (location == 0x1100) {
713 if (busack_cycle > context->current_cycle) { 715 if (busack_cycle <= context->current_cycle) {
714 busack = new_busack; 716 busack = new_busack;
715 busack_cycle = CYCLE_NEVER; 717 busack_cycle = CYCLE_NEVER;
716 } 718 }
717 context->value = (Z80_RES_BUSACK || busack) << 8; 719 context->value = (Z80_RES_BUSACK || busack) << 8;
718 //printf("Word read of BUSREQ returned %d\n", context->value); 720 //printf("Word read of BUSREQ returned %d\n", context->value);