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