Mercurial > repos > blastem
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); |