Mercurial > repos > blastem
comparison genesis.c @ 2227:eaaf28af3c94
Implement VDP read latency and invalid write delays revealed by Ti_'s instruction timing ROM
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Mon, 05 Sep 2022 22:18:25 -0700 |
parents | 01ff005b08f6 |
children | 0db9dc6a9020 |
comparison
equal
deleted
inserted
replaced
2226:d15c68157288 | 2227:eaaf28af3c94 |
---|---|
632 //context->current_cycle = v_context->cycles; | 632 //context->current_cycle = v_context->cycles; |
633 } | 633 } |
634 } else if(vdp_port < 8) { | 634 } else if(vdp_port < 8) { |
635 vdp_run_context_full(v_context, context->current_cycle); | 635 vdp_run_context_full(v_context, context->current_cycle); |
636 before_cycle = v_context->cycles; | 636 before_cycle = v_context->cycles; |
637 blocked = vdp_control_port_write(v_context, value); | 637 blocked = vdp_control_port_write(v_context, value, context->current_cycle); |
638 if (blocked) { | 638 if (blocked) { |
639 while (blocked) { | 639 while (blocked) { |
640 while(v_context->flags & FLAG_DMA_RUN) { | 640 while(v_context->flags & FLAG_DMA_RUN) { |
641 vdp_run_dma_done(v_context, gen->frame_end); | 641 vdp_run_dma_done(v_context, gen->frame_end); |
642 if (v_context->cycles >= gen->frame_end) { | 642 if (v_context->cycles >= gen->frame_end) { |
651 gen->bus_busy = 0; | 651 gen->bus_busy = 0; |
652 } | 652 } |
653 } | 653 } |
654 | 654 |
655 if (blocked < 0) { | 655 if (blocked < 0) { |
656 blocked = vdp_control_port_write(v_context, value); | 656 blocked = vdp_control_port_write(v_context, value, context->current_cycle); |
657 } else { | 657 } else { |
658 blocked = 0; | 658 blocked = 0; |
659 } | 659 } |
660 } | 660 } |
661 } else { | 661 } else { |
717 if (vdp_port < 4) { | 717 if (vdp_port < 4) { |
718 vdp_run_context(gen->vdp, context->Z80_CYCLE); | 718 vdp_run_context(gen->vdp, context->Z80_CYCLE); |
719 vdp_data_port_write(gen->vdp, value << 8 | value); | 719 vdp_data_port_write(gen->vdp, value << 8 | value); |
720 } else if (vdp_port < 8) { | 720 } else if (vdp_port < 8) { |
721 vdp_run_context_full(gen->vdp, context->Z80_CYCLE); | 721 vdp_run_context_full(gen->vdp, context->Z80_CYCLE); |
722 vdp_control_port_write(gen->vdp, value << 8 | value); | 722 vdp_control_port_write(gen->vdp, value << 8 | value, context->Z80_CYCLE); |
723 } else { | 723 } else { |
724 fatal_error("Illegal write to HV Counter port %X\n", vdp_port); | 724 fatal_error("Illegal write to HV Counter port %X\n", vdp_port); |
725 } | 725 } |
726 } else if (vdp_port < 0x18) { | 726 } else if (vdp_port < 0x18) { |
727 sync_sound(gen, context->Z80_CYCLE); | 727 sync_sound(gen, context->Z80_CYCLE); |
750 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); | 750 refresh_counter = refresh_counter % (MCLKS_PER_68K * REFRESH_INTERVAL); |
751 last_sync_cycle = context->current_cycle; | 751 last_sync_cycle = context->current_cycle; |
752 #endif | 752 #endif |
753 sync_components(context, 0); | 753 sync_components(context, 0); |
754 vdp_context * v_context = gen->vdp; | 754 vdp_context * v_context = gen->vdp; |
755 uint32_t before_cycle = v_context->cycles; | 755 uint32_t before_cycle = context->current_cycle; |
756 if (vdp_port < 0x10) { | 756 if (vdp_port < 0x10) { |
757 if (vdp_port < 4) { | 757 if (vdp_port < 4) { |
758 value = vdp_data_port_read(v_context); | 758 value = vdp_data_port_read(v_context, &context->current_cycle, MCLKS_PER_68K); |
759 } else if(vdp_port < 8) { | 759 } else if(vdp_port < 8) { |
760 value = vdp_control_port_read(v_context); | 760 value = vdp_control_port_read(v_context); |
761 } else { | 761 } else { |
762 value = vdp_hv_counter_read(v_context); | 762 value = vdp_hv_counter_read(v_context); |
763 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); | 763 //printf("HV Counter: %X at cycle %d\n", value, v_context->cycles); |
765 } else if (vdp_port < 0x18){ | 765 } else if (vdp_port < 0x18){ |
766 fatal_error("Illegal read from PSG port %X\n", vdp_port); | 766 fatal_error("Illegal read from PSG port %X\n", vdp_port); |
767 } else { | 767 } else { |
768 value = get_open_bus_value(&gen->header); | 768 value = get_open_bus_value(&gen->header); |
769 } | 769 } |
770 if (v_context->cycles != before_cycle) { | 770 if (context->current_cycle != before_cycle) { |
771 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle); | 771 //printf("68K paused for %d (%d) cycles at cycle %d (%d) for read\n", v_context->cycles - context->current_cycle, v_context->cycles - before_cycle, context->current_cycle, before_cycle); |
772 context->current_cycle = v_context->cycles; | |
773 //Lock the Z80 out of the bus until the VDP access is complete | 772 //Lock the Z80 out of the bus until the VDP access is complete |
774 genesis_context *gen = context->system; | 773 genesis_context *gen = context->system; |
775 gen->bus_busy = 1; | 774 gen->bus_busy = 1; |
776 sync_z80(gen, v_context->cycles); | 775 sync_z80(gen, context->current_cycle); |
777 gen->bus_busy = 0; | 776 gen->bus_busy = 0; |
778 } | 777 } |
779 #ifdef REFRESH_EMULATION | 778 #ifdef REFRESH_EMULATION |
780 last_sync_cycle -= 4 * MCLKS_PER_68K; | 779 last_sync_cycle -= 4 * MCLKS_PER_68K; |
781 //refresh may have happened while we were waiting on the VDP, | 780 //refresh may have happened while we were waiting on the VDP, |
816 vdp_port &= 0x1F; | 815 vdp_port &= 0x1F; |
817 uint16_t ret; | 816 uint16_t ret; |
818 if (vdp_port < 0x10) { | 817 if (vdp_port < 0x10) { |
819 //These probably won't currently interact well with the 68K accessing the VDP | 818 //These probably won't currently interact well with the 68K accessing the VDP |
820 vdp_run_context(gen->vdp, context->Z80_CYCLE); | 819 vdp_run_context(gen->vdp, context->Z80_CYCLE); |
820 uint32_t before = context->Z80_CYCLE; | |
821 if (vdp_port < 4) { | 821 if (vdp_port < 4) { |
822 ret = vdp_data_port_read(gen->vdp); | 822 ret = vdp_data_port_read(gen->vdp, &context->Z80_CYCLE, MCLKS_PER_Z80); |
823 } else if (vdp_port < 8) { | 823 } else if (vdp_port < 8) { |
824 ret = vdp_control_port_read(gen->vdp); | 824 ret = vdp_control_port_read(gen->vdp); |
825 } else { | 825 } else { |
826 ret = vdp_hv_counter_read(gen->vdp); | 826 ret = vdp_hv_counter_read(gen->vdp); |
827 } | |
828 if (context->Z80_CYCLE != before) { | |
829 gen->m68k->current_cycle += context->Z80_CYCLE - before; | |
827 } | 830 } |
828 } else { | 831 } else { |
829 //TODO: Figure out the correct value today | 832 //TODO: Figure out the correct value today |
830 ret = 0xFFFF; | 833 ret = 0xFFFF; |
831 } | 834 } |