Mercurial > repos > blastem
comparison segacd.c @ 2135:95b3752925e0
Can now pass all CDC DMA3 tests in mcd-verificator
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 18 Mar 2022 21:55:30 -0700 |
parents | 9caebcfeac72 |
children | 01fcbcba5cf8 |
comparison
equal
deleted
inserted
replaced
2134:9caebcfeac72 | 2135:95b3752925e0 |
---|---|
738 cdd_run(cd, m68k->current_cycle); | 738 cdd_run(cd, m68k->current_cycle); |
739 lc8951_ar_write(&cd->cdc, value); | 739 lc8951_ar_write(&cd->cdc, value); |
740 //cd->gate_array[reg] &= 0xC000; | 740 //cd->gate_array[reg] &= 0xC000; |
741 //apparently this clears EDT, should it also clear DSR? | 741 //apparently this clears EDT, should it also clear DSR? |
742 cd->gate_array[reg] = value & 0x0700; | 742 cd->gate_array[reg] = value & 0x0700; |
743 cd->gate_array[GA_CDC_DMA_ADDR] = 0; | |
743 cd->cdc_dst_low = 0; | 744 cd->cdc_dst_low = 0; |
744 break; | 745 break; |
745 case GA_CDC_REG_DATA: | 746 case GA_CDC_REG_DATA: |
746 cdd_run(cd, m68k->current_cycle); | 747 cdd_run(cd, m68k->current_cycle); |
747 printf("CDC write %X: %X @ %u\n", cd->cdc.ar, value, m68k->current_cycle); | 748 printf("CDC write %X: %X @ %u\n", cd->cdc.ar, value, m68k->current_cycle); |
748 lc8951_reg_write(&cd->cdc, value); | 749 lc8951_reg_write(&cd->cdc, value); |
749 calculate_target_cycle(m68k); | 750 calculate_target_cycle(m68k); |
751 break; | |
752 case GA_CDC_HOST_DATA: | |
753 //writes to this register have the same side effects as reads | |
754 sub_gate_read16(address, vcontext); | |
750 break; | 755 break; |
751 case GA_CDC_DMA_ADDR: | 756 case GA_CDC_DMA_ADDR: |
752 cdd_run(cd, m68k->current_cycle); | 757 cdd_run(cd, m68k->current_cycle); |
753 cd->gate_array[reg] = value; | 758 cd->gate_array[reg] = value; |
754 cd->cdc_dst_low = 0; | 759 cd->cdc_dst_low = 0; |
912 } | 917 } |
913 } | 918 } |
914 return sub_gate_write16(address, vcontext, value16); | 919 return sub_gate_write16(address, vcontext, value16); |
915 } | 920 } |
916 | 921 |
922 static uint8_t can_main_access_prog(segacd_context *cd) | |
923 { | |
924 //TODO: use actual busack | |
925 return cd->busreq || !cd->reset; | |
926 } | |
927 | |
917 static uint8_t handle_cdc_byte(void *vsys, uint8_t value) | 928 static uint8_t handle_cdc_byte(void *vsys, uint8_t value) |
918 { | 929 { |
919 segacd_context *cd = vsys; | 930 segacd_context *cd = vsys; |
920 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) { | 931 if (cd->gate_array[GA_CDC_CTRL] & BIT_DSR) { |
921 //host reg is already full, pause transfer | 932 //host reg is already full, pause transfer |
960 dma_addr += 2; | 971 dma_addr += 2; |
961 cd->cdc_dst_low = dma_addr & 7; | 972 cd->cdc_dst_low = dma_addr & 7; |
962 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; | 973 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; |
963 break; | 974 break; |
964 case DST_PROG_RAM: | 975 case DST_PROG_RAM: |
976 if (can_main_access_prog(cd)) { | |
977 return 0; | |
978 } | |
965 cd->prog_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; | 979 cd->prog_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; |
966 m68k_invalidate_code_range(cd->m68k, dma_addr - 1, dma_addr + 1); | 980 m68k_invalidate_code_range(cd->m68k, dma_addr - 1, dma_addr + 1); |
967 dma_addr++; | 981 dma_addr++; |
968 cd->cdc_dst_low = dma_addr & 7; | 982 cd->cdc_dst_low = dma_addr & 7; |
969 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; | 983 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; |
970 break; | 984 break; |
971 case DST_WORD_RAM: | 985 case DST_WORD_RAM: |
972 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { | 986 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { |
973 //1M mode, write to bank assigned to Sub CPU | 987 //1M mode, write to bank assigned to Sub CPU |
974 dma_addr &= (1 << 17) - 2; | 988 |
975 cd->m68k->mem_pointers[1][dma_addr] = cd->gate_array[GA_CDC_HOST_DATA]; | 989 uint32_t masked = dma_addr & (1 << 17) - 2; |
976 m68k_invalidate_code_range(cd->m68k, 0x0C0000 + dma_addr - 1, 0x0C0000 + dma_addr + 1); | 990 cd->m68k->mem_pointers[1][masked] = cd->gate_array[GA_CDC_HOST_DATA]; |
991 m68k_invalidate_code_range(cd->m68k, 0x0C0000 + masked - 1, 0x0C0000 + masked + 1); | |
977 } else { | 992 } else { |
978 //2M mode, check if Sub CPU has access | 993 //2M mode, check if Sub CPU has access |
979 if (cd->main_has_word2m) { | 994 if (cd->main_has_word2m) { |
980 return 0; | 995 return 0; |
981 } else { | 996 } else { |
991 break; | 1006 break; |
992 default: | 1007 default: |
993 printf("Invalid CDC transfer destination %d\n", dest); | 1008 printf("Invalid CDC transfer destination %d\n", dest); |
994 } | 1009 } |
995 return 1; | 1010 return 1; |
996 } | |
997 | |
998 static uint8_t can_main_access_prog(segacd_context *cd) | |
999 { | |
1000 //TODO: use actual busack | |
1001 return cd->busreq || !cd->reset; | |
1002 } | 1011 } |
1003 | 1012 |
1004 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) | 1013 static void scd_peripherals_run(segacd_context *cd, uint32_t cycle) |
1005 { | 1014 { |
1006 timers_run(cd, cycle); | 1015 timers_run(cd, cycle); |
1223 } | 1232 } |
1224 } else if (old_access) { | 1233 } else if (old_access) { |
1225 m68k->mem_pointers[cd->memptr_start_index] = NULL; | 1234 m68k->mem_pointers[cd->memptr_start_index] = NULL; |
1226 m68k_invalidate_code_range(m68k, cd->base + 0x220000, cd->base + 0x240000); | 1235 m68k_invalidate_code_range(m68k, cd->base + 0x220000, cd->base + 0x240000); |
1227 m68k_invalidate_code_range(cd->m68k, bank * 0x20000, (bank + 1) * 0x20000); | 1236 m68k_invalidate_code_range(cd->m68k, bank * 0x20000, (bank + 1) * 0x20000); |
1228 if (!new_access) { | 1237 dump_prog_ram(cd); |
1229 dump_prog_ram(cd); | 1238 uint16_t dst = cd->gate_array[GA_CDC_CTRL] >> 8 & 0x7; |
1239 if (dst == DST_PROG_RAM) { | |
1240 lc8951_resume_transfer(&cd->cdc, cd->cdc.cycle); | |
1230 } | 1241 } |
1231 } | 1242 } |
1232 break; | 1243 break; |
1233 } | 1244 } |
1234 case GA_MEM_MODE: { | 1245 case GA_MEM_MODE: { |
1273 } | 1284 } |
1274 break; | 1285 break; |
1275 } | 1286 } |
1276 case GA_HINT_VECTOR: | 1287 case GA_HINT_VECTOR: |
1277 cd->rom_mut[0x72/2] = value; | 1288 cd->rom_mut[0x72/2] = value; |
1289 break; | |
1290 case GA_CDC_HOST_DATA: | |
1291 //writes to this register have the same side effects as reads | |
1292 main_gate_read16(address, vcontext); | |
1278 break; | 1293 break; |
1279 case GA_COMM_FLAG: | 1294 case GA_COMM_FLAG: |
1280 //Main CPU can only write the upper byte; | 1295 //Main CPU can only write the upper byte; |
1281 cd->gate_array[reg] &= 0xFF; | 1296 cd->gate_array[reg] &= 0xFF; |
1282 cd->gate_array[reg] |= value & 0xFF00; | 1297 cd->gate_array[reg] |= value & 0xFF00; |