comparison segacd.c @ 2148:2da377ea932f

Initial stab at CDC DMA cycle stealing and sub CPU refresh delays
author Michael Pavone <pavone@retrodev.com>
date Sat, 26 Mar 2022 20:14:41 -0700
parents 10e4439d8f13
children 3f09312685e3
comparison
equal deleted inserted replaced
2147:4cd60eecb0b1 2148:2da377ea932f
990 } 990 }
991 rf5c164_write(&cd->pcm, 0x1000 | (dma_addr >> 1), value); 991 rf5c164_write(&cd->pcm, 0x1000 | (dma_addr >> 1), value);
992 dma_addr += 2; 992 dma_addr += 2;
993 cd->cdc_dst_low = dma_addr & 7; 993 cd->cdc_dst_low = dma_addr & 7;
994 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; 994 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3;
995 //TODO: determine actual main CPU penalty
996 cd->m68k->current_cycle += 2 * cd->m68k->options->gen.bus_cycles;
995 break; 997 break;
996 case DST_PROG_RAM: 998 case DST_PROG_RAM:
997 if (can_main_access_prog(cd)) { 999 if (can_main_access_prog(cd)) {
998 return 0; 1000 return 0;
999 } 1001 }
1000 cd->prog_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA]; 1002 cd->prog_ram[dma_addr >> 1] = cd->gate_array[GA_CDC_HOST_DATA];
1001 m68k_invalidate_code_range(cd->m68k, dma_addr - 1, dma_addr + 1); 1003 m68k_invalidate_code_range(cd->m68k, dma_addr - 1, dma_addr + 1);
1002 dma_addr++; 1004 dma_addr++;
1003 cd->cdc_dst_low = dma_addr & 7; 1005 cd->cdc_dst_low = dma_addr & 7;
1004 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3; 1006 cd->gate_array[GA_CDC_DMA_ADDR] = dma_addr >> 3;
1007 //TODO: determine actual main CPU penalty
1008 cd->m68k->current_cycle += 2 * cd->m68k->options->gen.bus_cycles;
1005 break; 1009 break;
1006 case DST_WORD_RAM: 1010 case DST_WORD_RAM:
1007 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) { 1011 if (cd->gate_array[GA_MEM_MODE] & BIT_MEM_MODE) {
1008 //1M mode, write to bank assigned to Sub CPU 1012 //1M mode, write to bank assigned to Sub CPU
1009 1013
1038 cdd_run(cd, cycle); 1042 cdd_run(cd, cycle);
1039 cd_graphics_run(cd, cycle); 1043 cd_graphics_run(cd, cycle);
1040 rf5c164_run(&cd->pcm, cycle); 1044 rf5c164_run(&cd->pcm, cycle);
1041 } 1045 }
1042 1046
1047 //TODO: do some logic analyzer captuers to get actual values
1048 #define REFRESH_INTERVAL 256
1049 #define REFRESH_DELAY 4
1050
1043 static m68k_context *sync_components(m68k_context * context, uint32_t address) 1051 static m68k_context *sync_components(m68k_context * context, uint32_t address)
1044 { 1052 {
1045 segacd_context *cd = context->system; 1053 segacd_context *cd = context->system;
1054
1055 uint32_t num_refresh = (context->current_cycle - cd->last_refresh_cycle) / REFRESH_INTERVAL;
1056 cd->last_refresh_cycle = cd->last_refresh_cycle + num_refresh * REFRESH_INTERVAL;
1057 context->current_cycle += num_refresh * REFRESH_DELAY;
1058
1046 scd_peripherals_run(cd, context->current_cycle); 1059 scd_peripherals_run(cd, context->current_cycle);
1047 if (address && cd->enter_debugger) { 1060 if (address && cd->enter_debugger) {
1048 genesis_context *gen = cd->genesis; 1061 genesis_context *gen = cd->genesis;
1049 cd->enter_debugger = 0; 1062 cd->enter_debugger = 0;
1050 if (gen->header.debugger_type == DEBUGGER_NATIVE) { 1063 if (gen->header.debugger_type == DEBUGGER_NATIVE) {
1083 { 1096 {
1084 uint8_t m68k_run = !can_main_access_prog(cd); 1097 uint8_t m68k_run = !can_main_access_prog(cd);
1085 while (cycle > cd->m68k->current_cycle) { 1098 while (cycle > cd->m68k->current_cycle) {
1086 if (m68k_run && !cd->sub_paused_wordram) { 1099 if (m68k_run && !cd->sub_paused_wordram) {
1087 uint32_t start = cd->m68k->current_cycle; 1100 uint32_t start = cd->m68k->current_cycle;
1101
1088 cd->m68k->sync_cycle = cd->enter_debugger ? cd->m68k->current_cycle + 1 : cycle; 1102 cd->m68k->sync_cycle = cd->enter_debugger ? cd->m68k->current_cycle + 1 : cycle;
1089 if (cd->need_reset) { 1103 if (cd->need_reset) {
1090 cd->need_reset = 0; 1104 cd->need_reset = 0;
1091 m68k_reset(cd->m68k); 1105 m68k_reset(cd->m68k);
1092 } else { 1106 } else {
1093 calculate_target_cycle(cd->m68k); 1107 calculate_target_cycle(cd->m68k);
1094 resume_68k(cd->m68k); 1108 resume_68k(cd->m68k);
1095 } 1109 }
1096 } else { 1110 } else {
1097 cd->m68k->current_cycle = cycle; 1111 cd->m68k->current_cycle = cycle;
1112 cd->last_refresh_cycle = cycle;
1098 } 1113 }
1099 scd_peripherals_run(cd, cd->m68k->current_cycle); 1114 scd_peripherals_run(cd, cd->m68k->current_cycle);
1100 } 1115 }
1101 1116
1102 } 1117 }
1128 if (cd->graphics_int_cycle > deduction) { 1143 if (cd->graphics_int_cycle > deduction) {
1129 cd->graphics_int_cycle -= deduction; 1144 cd->graphics_int_cycle -= deduction;
1130 } else { 1145 } else {
1131 cd->graphics_int_cycle = 0; 1146 cd->graphics_int_cycle = 0;
1132 } 1147 }
1148 }
1149 if (deduction >= cd->last_refresh_cycle) {
1150 cd->last_refresh_cycle -= deduction;
1151 } else {
1152 cd->last_refresh_cycle = 0;
1133 } 1153 }
1134 cd->pcm.cycle -= deduction; 1154 cd->pcm.cycle -= deduction;
1135 } 1155 }
1136 1156
1137 static uint16_t main_gate_read16(uint32_t address, void *vcontext) 1157 static uint16_t main_gate_read16(uint32_t address, void *vcontext)