comparison segacd.c @ 2119:5ec2f97365a2

More accurate RET/DMNA implementation
author Michael Pavone <pavone@retrodev.com>
date Tue, 08 Mar 2022 23:28:06 -0800
parents cd057d6fe030
children 91ed3c4cdfd9
comparison
equal deleted inserted replaced
2118:c5d0edf1d7e7 2119:5ec2f97365a2
569 cd->periph_reset_cycle = m68k->current_cycle; 569 cd->periph_reset_cycle = m68k->current_cycle;
570 } 570 }
571 break; 571 break;
572 case GA_MEM_MODE: { 572 case GA_MEM_MODE: {
573 uint16_t changed = value ^ cd->gate_array[reg]; 573 uint16_t changed = value ^ cd->gate_array[reg];
574 uint8_t old_main_has_word2m = cd->main_has_word2m;
575 if (value & BIT_RET) {
576 cd->main_has_word2m = 1;
577 }
578 uint8_t old_bank_toggle = cd->bank_toggle;
579 cd->bank_toggle = value & BIT_RET;
574 genesis_context *gen = cd->genesis; 580 genesis_context *gen = cd->genesis;
581 cd->gate_array[reg] &= 0xFFC0;
575 if (changed & BIT_MEM_MODE) { 582 if (changed & BIT_MEM_MODE) {
576 //FIXME: ram banks are supposed to be interleaved when in 2M mode 583 //FIXME: ram banks are supposed to be interleaved when in 2M mode
577 cd->gate_array[reg] &= ~BIT_DMNA; 584 cd->main_swap_request = old_bank_toggle != cd->bank_toggle;
578 if (value & BIT_MEM_MODE) { 585 if (value & BIT_MEM_MODE) {
579 //switch to 1M mode 586 //switch to 1M mode
580 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram; 587 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram;
581 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; 588 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL;
582 m68k->mem_pointers[0] = NULL; 589 m68k->mem_pointers[0] = NULL;
583 m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 0x10000; 590 m68k->mem_pointers[1] = cd->bank_toggle ? cd->word_ram : cd->word_ram + 0x10000;
591 cd->gate_array[reg] |= value & (MASK_PRIORITY|BIT_RET|BIT_MEM_MODE);
592 if (cd->main_swap_request) {
593 cd->gate_array[reg] |= BIT_DMNA;
594 }
584 } else { 595 } else {
585 //switch to 2M mode 596 //switch to 2M mode
586 if (value & BIT_RET) { 597 if (cd->main_has_word2m) {
587 //Main CPU will have word ram 598 //Main CPU will have word ram
588 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = cd->word_ram; 599 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = cd->word_ram;
589 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = cd->word_ram + 0x10000; 600 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = cd->word_ram + 0x10000;
590 m68k->mem_pointers[0] = NULL; 601 m68k->mem_pointers[0] = NULL;
591 m68k->mem_pointers[1] = NULL; 602 m68k->mem_pointers[1] = NULL;
594 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = NULL; 605 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = NULL;
595 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; 606 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = NULL;
596 m68k->mem_pointers[0] = cd->word_ram; 607 m68k->mem_pointers[0] = cd->word_ram;
597 m68k->mem_pointers[1] = NULL; 608 m68k->mem_pointers[1] = NULL;
598 } 609 }
610 cd->gate_array[reg] |= value & (MASK_PRIORITY|BIT_MEM_MODE);
611 cd->gate_array[reg] |= cd->main_has_word2m ? BIT_RET : BIT_DMNA;
599 } 612 }
600 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); 613 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000);
601 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); 614 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000);
602 } else if (changed & BIT_RET) { 615 } else if (value & BIT_MEM_MODE) {
603 if (value & BIT_MEM_MODE) { 616 //1M mode
604 cd->gate_array[reg] &= ~BIT_DMNA; 617 if (old_bank_toggle != cd->bank_toggle) {
605 //swapping banks in 1M mode
606 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram; 618 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram;
607 m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 0x10000; 619 m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 0x10000;
608 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); 620 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000);
609 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); 621 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000);
610 } else if (value & BIT_RET) { 622 cd->main_swap_request = 0;
611 cd->gate_array[reg] &= ~BIT_DMNA; 623 }
612 //giving word ram to main CPU in 2M mode 624 cd->gate_array[reg] |= value & (MASK_PRIORITY|BIT_RET|BIT_MEM_MODE);
625 if (cd->main_swap_request) {
626 cd->gate_array[reg] |= BIT_DMNA;
627 }
628 } else {
629 //2M mode
630 if (old_main_has_word2m != cd->main_has_word2m) {
613 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = cd->word_ram; 631 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = cd->word_ram;
614 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = cd->word_ram + 0x10000; 632 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = cd->word_ram + 0x10000;
615 m68k->mem_pointers[0] = NULL; 633 m68k->mem_pointers[0] = NULL;
616 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); 634 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000);
617 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); 635 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000);
618 } else { 636 }
619 value |= BIT_RET; 637 cd->gate_array[reg] |= value & MASK_PRIORITY;
620 } 638 cd->gate_array[reg] |= cd->main_has_word2m ? BIT_RET : BIT_DMNA;
621 } 639 }
622 cd->gate_array[reg] &= 0xFFC2;
623 cd->gate_array[reg] |= value & (BIT_RET|BIT_MEM_MODE|MASK_PRIORITY);
624 break; 640 break;
625 } 641 }
626 case GA_CDC_CTRL: 642 case GA_CDC_CTRL:
627 cdd_run(cd, m68k->current_cycle); 643 cdd_run(cd, m68k->current_cycle);
628 lc8951_ar_write(&cd->cdc, value); 644 lc8951_ar_write(&cd->cdc, value);
763 segacd_context *cd = m68k->system; 779 segacd_context *cd = m68k->system;
764 uint32_t reg = (address & 0x1FF) >> 1; 780 uint32_t reg = (address & 0x1FF) >> 1;
765 uint16_t value16; 781 uint16_t value16;
766 switch (address >> 1) 782 switch (address >> 1)
767 { 783 {
784 case GA_MEM_MODE:
768 case GA_CDC_HOST_DATA: 785 case GA_CDC_HOST_DATA:
769 case GA_CDC_DMA_ADDR: 786 case GA_CDC_DMA_ADDR:
770 case GA_STOP_WATCH: 787 case GA_STOP_WATCH:
771 case GA_COMM_FLAG: 788 case GA_COMM_FLAG:
772 case GA_TIMER: 789 case GA_TIMER:
1121 cd->gate_array[reg] |= value & 0xFFC0; 1138 cd->gate_array[reg] |= value & 0xFFC0;
1122 if ((cd->gate_array[reg] & BIT_MEM_MODE)) { 1139 if ((cd->gate_array[reg] & BIT_MEM_MODE)) {
1123 //1M mode 1140 //1M mode
1124 if (!(value & BIT_DMNA)) { 1141 if (!(value & BIT_DMNA)) {
1125 cd->gate_array[reg] |= BIT_DMNA; 1142 cd->gate_array[reg] |= BIT_DMNA;
1143 cd->main_swap_request = 1;
1144 } else {
1145 cd->main_has_word2m = 0;
1126 } 1146 }
1127 } else { 1147 } else {
1128 //2M mode 1148 //2M mode
1129 if (changed & value & BIT_DMNA) { 1149 if (changed & value & BIT_DMNA) {
1130 cd->gate_array[reg] |= BIT_DMNA; 1150 cd->gate_array[reg] |= BIT_DMNA;
1131 m68k->mem_pointers[cd->memptr_start_index + 1] = NULL; 1151 m68k->mem_pointers[cd->memptr_start_index + 1] = NULL;
1132 m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; 1152 m68k->mem_pointers[cd->memptr_start_index + 2] = NULL;
1133 cd->m68k->mem_pointers[0] = cd->word_ram; 1153 cd->m68k->mem_pointers[0] = cd->word_ram;
1134 cd->gate_array[reg] &= ~BIT_RET; 1154 cd->gate_array[reg] &= ~BIT_RET;
1155 cd->main_has_word2m = 0;
1135 1156
1136 m68k_invalidate_code_range(m68k, cd->base + 0x200000, cd->base + 0x240000); 1157 m68k_invalidate_code_range(m68k, cd->base + 0x200000, cd->base + 0x240000);
1137 m68k_invalidate_code_range(cd->m68k, 0x080000, 0x0C0000); 1158 m68k_invalidate_code_range(cd->m68k, 0x080000, 0x0C0000);
1138 } 1159 }
1139 } 1160 }
1255 cd->need_reset = 1; 1276 cd->need_reset = 1;
1256 cd->reset = 1; //active low, so reset is not active on start 1277 cd->reset = 1; //active low, so reset is not active on start
1257 cd->memptr_start_index = 0; 1278 cd->memptr_start_index = 0;
1258 cd->gate_array[1] = 1; 1279 cd->gate_array[1] = 1;
1259 cd->gate_array[GA_CDD_CTRL] = BIT_MUTE; //Data/mute flag is set on start 1280 cd->gate_array[GA_CDD_CTRL] = BIT_MUTE; //Data/mute flag is set on start
1281 cd->main_has_word2m = 1;
1260 lc8951_init(&cd->cdc, handle_cdc_byte, cd); 1282 lc8951_init(&cd->cdc, handle_cdc_byte, cd);
1261 if (media->chain && media->type != MEDIA_CDROM) { 1283 if (media->chain && media->type != MEDIA_CDROM) {
1262 media = media->chain; 1284 media = media->chain;
1263 } 1285 }
1264 cdd_mcu_init(&cd->cdd, media); 1286 cdd_mcu_init(&cd->cdd, media);