comparison segacd.c @ 2066:a61a8a87410c segacd

Fix a bunch of CDC/CDD related mcd-verificator failures
author Michael Pavone <pavone@retrodev.com>
date Sun, 30 Jan 2022 00:21:58 -0800
parents 02a9846668d1
children f573f2c31bc9
comparison
equal deleted inserted replaced
2065:02a9846668d1 2066:a61a8a87410c
330 context->int_cycle = CYCLE_NEVER; 330 context->int_cycle = CYCLE_NEVER;
331 uint8_t mask = context->status & 0x7; 331 uint8_t mask = context->status & 0x7;
332 if (mask < 5) { 332 if (mask < 5) {
333 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) { 333 if (cd->gate_array[GA_INT_MASK] & BIT_MASK_IEN5) {
334 uint32_t cdc_cycle = lc8951_next_interrupt(&cd->cdc); 334 uint32_t cdc_cycle = lc8951_next_interrupt(&cd->cdc);
335 //CDC interrupts only generated on falling edge of !INT signal
336 if (cd->cdc_int_ack) {
337 if (cdc_cycle > cd->cdc.cycle) {
338 cd->cdc_int_ack = 0;
339 } else {
340 cdc_cycle = CYCLE_NEVER;
341 }
342 }
335 if (cdc_cycle < context->int_cycle) { 343 if (cdc_cycle < context->int_cycle) {
336 context->int_cycle = cdc_cycle; 344 context->int_cycle = cdc_cycle;
337 context->int_num = 5; 345 context->int_num = 5;
338 } 346 }
339 } 347 }
399 return cd->gate_array[reg] | cd->cdc.ar; 407 return cd->gate_array[reg] | cd->cdc.ar;
400 case GA_CDC_REG_DATA: 408 case GA_CDC_REG_DATA:
401 cdd_run(cd, m68k->current_cycle); 409 cdd_run(cd, m68k->current_cycle);
402 return lc8951_reg_read(&cd->cdc); 410 return lc8951_reg_read(&cd->cdc);
403 case GA_CDC_HOST_DATA: { 411 case GA_CDC_HOST_DATA: {
412 cdd_run(cd, m68k->current_cycle);
404 uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7; 413 uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7;
405 if (dst == DST_SUB_CPU) { 414 if (dst == DST_SUB_CPU) {
406 cdd_run(cd, m68k->current_cycle);
407 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) { 415 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) {
408 cd->gate_array[GA_CDC_CTRL] &= ~BIT_DSR; 416 cd->gate_array[GA_CDC_CTRL] &= ~BIT_DSR;
409 lc8951_resume_transfer(&cd->cdc); 417 lc8951_resume_transfer(&cd->cdc, cd->cdc.cycle);
410 } 418 }
411 calculate_target_cycle(cd->m68k); 419 calculate_target_cycle(cd->m68k);
412 return cd->gate_array[reg]; 420
413 } else { 421 }
414 return 0xFFFF; 422 return cd->gate_array[reg];
415 }
416 } 423 }
417 case GA_STOP_WATCH: 424 case GA_STOP_WATCH:
418 case GA_TIMER: 425 case GA_TIMER:
419 timers_run(cd, m68k->current_cycle); 426 timers_run(cd, m68k->current_cycle);
420 return cd->gate_array[reg]; 427 return cd->gate_array[reg];
525 break; 532 break;
526 } 533 }
527 case GA_CDC_CTRL: 534 case GA_CDC_CTRL:
528 cdd_run(cd, m68k->current_cycle); 535 cdd_run(cd, m68k->current_cycle);
529 lc8951_ar_write(&cd->cdc, value); 536 lc8951_ar_write(&cd->cdc, value);
530 cd->gate_array[reg] &= 0xC000; 537 //cd->gate_array[reg] &= 0xC000;
538 //apparently this clears EDT, should it also clear DSR?
531 cd->gate_array[reg] = value & 0x0700; 539 cd->gate_array[reg] = value & 0x0700;
540 cd->cdc_dst_low = 0;
532 break; 541 break;
533 case GA_CDC_REG_DATA: 542 case GA_CDC_REG_DATA:
534 cdd_run(cd, m68k->current_cycle); 543 cdd_run(cd, m68k->current_cycle);
544 printf("CDC write %X: %X @ %u\n", cd->cdc.ar, value, m68k->current_cycle);
535 lc8951_reg_write(&cd->cdc, value); 545 lc8951_reg_write(&cd->cdc, value);
536 calculate_target_cycle(m68k); 546 calculate_target_cycle(m68k);
537 break; 547 break;
538 case GA_CDC_DMA_ADDR: 548 case GA_CDC_DMA_ADDR:
539 cdd_run(cd, m68k->current_cycle); 549 cdd_run(cd, m68k->current_cycle);
628 value16 = value | (value << 8); 638 value16 = value | (value << 8);
629 break; 639 break;
630 case GA_CDC_CTRL: 640 case GA_CDC_CTRL:
631 if (address & 1) { 641 if (address & 1) {
632 lc8951_ar_write(&cd->cdc, value); 642 lc8951_ar_write(&cd->cdc, value);
643 return vcontext;
633 } else { 644 } else {
634 cd->gate_array[reg] = value << 8; 645 value16 = cd->cdc.ar | (value << 8);
635 } 646 }
636 return vcontext; 647 break;
637 case GA_CDD_CMD4: 648 case GA_CDD_CMD4:
638 if (!address) { 649 if (!address) {
639 //byte write to $FF804A should not trigger transfer 650 //byte write to $FF804A should not trigger transfer
640 cdd_run(cd, m68k->current_cycle); 651 cdd_run(cd, m68k->current_cycle);
641 cd->gate_array[reg] &= 0x0F; 652 cd->gate_array[reg] &= 0x0F;
654 } 665 }
655 666
656 static uint8_t handle_cdc_byte(void *vsys, uint8_t value) 667 static uint8_t handle_cdc_byte(void *vsys, uint8_t value)
657 { 668 {
658 segacd_context *cd = vsys; 669 segacd_context *cd = vsys;
670 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) {
671 //host reg is already full, pause transfer
672 return 0;
673 }
674 if (cd->cdc.cycle == cd->cdc.transfer_end) {
675 cd->gate_array[GA_CDC_CTRL] |= BIT_EDT;
676 printf("EDT set at %u\n", cd->cdc.cycle);
677 }
659 uint16_t dest = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7; 678 uint16_t dest = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7;
679 if (!(cd->cdc_dst_low & 1)) {
680 cd->gate_array[GA_CDC_HOST_DATA] &= 0xFF;
681 cd->gate_array[GA_CDC_HOST_DATA] |= value << 8;
682 cd->cdc_dst_low++;
683 if (dest != DST_PCM_RAM) {
684 //PCM RAM writes a byte at a time
685 return 1;
686 }
687 } else {
688 cd->gate_array[GA_CDC_HOST_DATA] &= 0xFF00;
689 cd->gate_array[GA_CDC_HOST_DATA] |= value;
690 }
691
660 uint32_t dma_addr = cd->gate_array[GA_CDC_DMA_ADDR] << 3; 692 uint32_t dma_addr = cd->gate_array[GA_CDC_DMA_ADDR] << 3;
661 dma_addr |= cd->cdc_dst_low; 693 dma_addr |= cd->cdc_dst_low;
662 switch (dest) 694 switch (dest)
663 { 695 {
664 case DST_MAIN_CPU: 696 case DST_MAIN_CPU:
665 case DST_SUB_CPU: 697 case DST_SUB_CPU:
666 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) { 698 cd->cdc_dst_low = 0;
667 //host reg is already full, pause transfer 699 cd->gate_array[GA_CDC_CTRL] |= BIT_DSR;
668 return 0; 700 printf("DSR set at %u, (transfer_end %u, dbcl %X, dbch %X)\n", cd->cdc.cycle, cd->cdc.transfer_end, cd->cdc.regs[2], cd->cdc.regs[3]);
669 }
670 if (cd->cdc_dst_low) {
671 cd->gate_array[GA_CDC_HOST_DATA] &= 0xFF00;
672 cd->gate_array[GA_CDC_HOST_DATA] |= value;
673 cd->cdc_dst_low = 0;
674 cd->gate_array[GA_CDC_CTRL] |= BIT_DSR;
675 } else {
676 cd->gate_array[GA_CDC_HOST_DATA] &= 0xFF;
677 cd->gate_array[GA_CDC_HOST_DATA] |= value << 8;
678 cd->cdc_dst_low = 1;
679 return 1;
680 }
681 break; 701 break;
682 case DST_PCM_RAM: 702 case DST_PCM_RAM:
683 dma_addr &= (1 << 13) - 1; 703 dma_addr &= (1 << 13) - 1;
684 //TODO: write to currently visible 8K bank of PCM RAM I guess? 704 //TODO: write to currently visible 8K bank of PCM RAM I guess?
685 dma_addr++; 705 dma_addr += 2;
686 cd->cdc_dst_low = dma_addr & 7; 706 cd->cdc_dst_low = dma_addr & 7;
687 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; 707 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3;
688 break; 708 break;
689 case DST_PROG_RAM: 709 case DST_PROG_RAM:
690 ((uint8_t*)cd->prog_ram)[dma_addr ^ 1] = value; 710 cd->prog_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA];
691 m68k_invalidate_code_range(cd->m68k, dma_addr, dma_addr + 1); 711 m68k_invalidate_code_range(cd->m68k, dma_addr - 1, dma_addr + 1);
692 dma_addr++; 712 dma_addr++;
693 cd->cdc_dst_low = dma_addr & 7; 713 cd->cdc_dst_low = dma_addr & 7;
694 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; 714 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3;
695 break; 715 break;
696 case DST_WORD_RAM: 716 case DST_WORD_RAM:
697 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { 717 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) {
698 //1M mode, write to bank assigned to Sub CPU 718 //1M mode, write to bank assigned to Sub CPU
699 dma_addr &= (1 << 17) - 1; 719 dma_addr &= (1 << 17) - 1;
700 ((uint8_t*)cd->m68k->mem_pointers[1])[dma_addr ^ 1] = value; 720 cd->m68k->mem_pointers[1][dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA];
701 m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr, 0x0C0000 + dma_addr + 1); 721 m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr - 1, 0x0C0000 + dma_addr + 1);
702 } else { 722 } else {
703 //2M mode, check if Sub CPU has access 723 //2M mode, check if Sub CPU has access
704 if (!(cd->gate_array[GA_MEM_MODE] & BIT_RET)) { 724 if (!(cd->gate_array[GA_MEM_MODE] & BIT_RET)) {
705 dma_addr &= (1 << 18) - 1; 725 dma_addr &= (1 << 18) - 1;
706 ((uint8_t*)cd->word_ram)[dma_addr ^ 1] = value; 726 cd->word_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA];
707 m68k_invalidate_code_range(cd->m68k, 0x080000 + dma_addr, 0x080000 + dma_addr + 1); 727 m68k_invalidate_code_range(cd->m68k, 0x080000 + dma_addr, 0x080000 + dma_addr + 1);
708 } 728 }
709 } 729 }
710 dma_addr++; 730 dma_addr++;
711 cd->cdc_dst_low = dma_addr & 7; 731 cd->cdc_dst_low = dma_addr & 7;
712 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; 732 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3;
713 break; 733 break;
714 default: 734 default:
715 printf("Invalid CDC transfer destination %d\n", dest); 735 printf("Invalid CDC transfer destination %d\n", dest);
716 }
717 if (cd->cdc.cycle == cd->cdc.transfer_end) {
718 cd->gate_array[GA_CDC_CTRL] |= BIT_EDT;
719 } 736 }
720 return 1; 737 return 1;
721 } 738 }
722 739
723 static uint8_t can_main_access_prog(segacd_context *cd) 740 static uint8_t can_main_access_prog(segacd_context *cd)
744 case 3: 761 case 3:
745 cd->timer_pending = 0; 762 cd->timer_pending = 0;
746 break; 763 break;
747 case 4: 764 case 4:
748 cd->cdd.int_pending = 0; 765 cd->cdd.int_pending = 0;
766 break;
767 case 5:
768 cd->cdc_int_ack = 1;
769 break;
749 } 770 }
750 context->int_ack = 0; 771 context->int_ack = 0;
751 calculate_target_cycle(context); 772 calculate_target_cycle(context);
752 return context; 773 return context;
753 } 774 }
754 775
755 void scd_run(segacd_context *cd, uint32_t cycle) 776 void scd_run(segacd_context *cd, uint32_t cycle)
756 { 777 {
757 uint8_t m68k_run = !can_main_access_prog(cd); 778 uint8_t m68k_run = !can_main_access_prog(cd);
758 if (m68k_run) { 779 if (cycle > cd->m68k->current_cycle) {
759 cd->m68k->sync_cycle = cycle; 780 if (m68k_run) {
760 if (cd->need_reset) { 781 uint32_t start = cd->m68k->current_cycle;
761 cd->need_reset = 0; 782 cd->m68k->sync_cycle = cycle;
762 m68k_reset(cd->m68k); 783 if (cd->need_reset) {
784 cd->need_reset = 0;
785 m68k_reset(cd->m68k);
786 } else {
787 calculate_target_cycle(cd->m68k);
788 resume_68k(cd->m68k);
789 }
763 } else { 790 } else {
764 calculate_target_cycle(cd->m68k); 791 cd->m68k->current_cycle = cycle;
765 resume_68k(cd->m68k); 792 }
766 }
767 } else {
768 cd->m68k->current_cycle = cycle;
769 } 793 }
770 scd_peripherals_run(cd, cycle); 794 scd_peripherals_run(cd, cycle);
771 } 795 }
772 796
773 uint32_t gen_cycle_to_scd(uint32_t cycle, genesis_context *gen) 797 uint32_t gen_cycle_to_scd(uint32_t cycle, genesis_context *gen)
789 cd->periph_reset_cycle = CYCLE_NEVER; 813 cd->periph_reset_cycle = CYCLE_NEVER;
790 } else if (cd->periph_reset_cycle != CYCLE_NEVER) { 814 } else if (cd->periph_reset_cycle != CYCLE_NEVER) {
791 cd->periph_reset_cycle -= deduction; 815 cd->periph_reset_cycle -= deduction;
792 } 816 }
793 cdd_mcu_adjust_cycle(&cd->cdd, deduction); 817 cdd_mcu_adjust_cycle(&cd->cdd, deduction);
818 lc8951_adjust_cycles(&cd->cdc, deduction);
794 } 819 }
795 820
796 static uint16_t main_gate_read16(uint32_t address, void *vcontext) 821 static uint16_t main_gate_read16(uint32_t address, void *vcontext)
797 { 822 {
798 m68k_context *m68k = vcontext; 823 m68k_context *m68k = vcontext;
826 return cd->rom_mut[0x72/2]; 851 return cd->rom_mut[0x72/2];
827 case GA_CDC_HOST_DATA: { 852 case GA_CDC_HOST_DATA: {
828 uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7; 853 uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7;
829 if (dst == DST_MAIN_CPU) { 854 if (dst == DST_MAIN_CPU) {
830 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) { 855 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) {
856 printf("DSR cleared at %u (%u)\n", scd_cycle, cd->cdc.cycle);
831 cd->gate_array[GA_CDC_CTRL] &= ~BIT_DSR; 857 cd->gate_array[GA_CDC_CTRL] &= ~BIT_DSR;
832 lc8951_resume_transfer(&cd->cdc); 858 lc8951_resume_transfer(&cd->cdc, scd_cycle);
859 } else {
860 printf("Read of CDC host data with DSR clear at %u\n", scd_cycle);
833 } 861 }
834 calculate_target_cycle(cd->m68k); 862 calculate_target_cycle(cd->m68k);
835 return cd->gate_array[offset]; 863 }
836 } else { 864 return cd->gate_array[offset];
837 return 0xFFFF;
838 }
839 } 865 }
840 case GA_CDC_DMA_ADDR: 866 case GA_CDC_DMA_ADDR:
841 //TODO: open bus maybe? 867 //TODO: open bus maybe?
842 return 0xFFFF; 868 return 0xFFFF;
843 default: 869 default:
844 if (offset < GA_TIMER) { 870 if (offset < GA_TIMER) {
871 if (offset == GA_CDC_CTRL) {
872 printf("CDC read(main): %X - %X @ %u (%u)\n", address, cd->gate_array[offset], m68k->current_cycle, scd_cycle);
873 } else if (offset >= GA_COMM_FLAG && offset <= GA_COMM_STATUS7) {
874 printf("COMM read(main): %X - %X @ %u (%u)\n", address, cd->gate_array[offset], m68k->current_cycle, scd_cycle);
875 }
845 return cd->gate_array[offset]; 876 return cd->gate_array[offset];
846 } 877 }
847 //TODO: open bus maybe? 878 //TODO: open bus maybe?
848 return 0xFFFF; 879 return 0xFFFF;
849 } 880 }
927 break; 958 break;
928 case GA_COMM_FLAG: 959 case GA_COMM_FLAG:
929 //Main CPU can only write the upper byte; 960 //Main CPU can only write the upper byte;
930 cd->gate_array[reg] &= 0xFF; 961 cd->gate_array[reg] &= 0xFF;
931 cd->gate_array[reg] |= value & 0xFF00; 962 cd->gate_array[reg] |= value & 0xFF00;
963 printf("COMM write(main): %X - %X @ %u (%u)\n", address, value, m68k->current_cycle, scd_cycle);
932 break; 964 break;
933 case GA_COMM_CMD0: 965 case GA_COMM_CMD0:
934 case GA_COMM_CMD1: 966 case GA_COMM_CMD1:
935 case GA_COMM_CMD2: 967 case GA_COMM_CMD2:
936 case GA_COMM_CMD3: 968 case GA_COMM_CMD3:
937 case GA_COMM_CMD4: 969 case GA_COMM_CMD4:
938 case GA_COMM_CMD5: 970 case GA_COMM_CMD5:
939 case GA_COMM_CMD6: 971 case GA_COMM_CMD6:
940 case GA_COMM_CMD7: 972 case GA_COMM_CMD7:
941 //no effects for these other than saving the value 973 //no effects for these other than saving the value
974 printf("COMM write(main): %X - %X @ %u (%u)\n", address, value, m68k->current_cycle, scd_cycle);
942 cd->gate_array[reg] = value; 975 cd->gate_array[reg] = value;
943 break; 976 break;
944 default: 977 default:
945 printf("Unhandled gate array write %X:%X\n", address, value); 978 printf("Unhandled gate array write %X:%X\n", address, value);
946 } 979 }