comparison segacd.c @ 2057:88deea42caf0 segacd

Fix a bunch of stuff to pass more mcd-verificator tests
author Michael Pavone <pavone@retrodev.com>
date Thu, 20 Jan 2022 00:56:46 -0800
parents 27bbfcb7850a
children 70260f6051dd
comparison
equal deleted inserted replaced
2056:27bbfcb7850a 2057:88deea42caf0
35 GA_COMM_STATUS7, 35 GA_COMM_STATUS7,
36 GA_TIMER, 36 GA_TIMER,
37 GA_INT_MASK, 37 GA_INT_MASK,
38 GA_CDD_FADER, 38 GA_CDD_FADER,
39 GA_CDD_CTRL, 39 GA_CDD_CTRL,
40 GA_CDD_STATUS0,
41 GA_CDD_STATUS1,
42 GA_CDD_STATUS2,
43 GA_CDD_STATUS3,
44 GA_CDD_STATUS4,
45 GA_CDD_CMD0,
46 GA_CDD_CMD1,
47 GA_CDD_CMD2,
48 GA_CDD_CMD3,
49 GA_CDD_CMD4,
50 GA_FONT_COLOR,
51 GA_FONT_BITS,
52 GA_FONT_DATA0,
53 GA_FONT_DATA1,
54 GA_FONT_DATA2,
55 GA_FONT_DATA3,
40 56
41 GA_HINT_VECTOR = GA_CDC_REG_DATA 57 GA_HINT_VECTOR = GA_CDC_REG_DATA
42 }; 58 };
43 //GA_SUB_CPU_CTRL 59 //GA_SUB_CPU_CTRL
44 #define BIT_IEN2 0x8000 60 #define BIT_IEN2 0x8000
45 #define BIT_IFL2 0x0100 61 #define BIT_IFL2 0x0100
46 #define BIT_LEDG 0x0100 62 #define BIT_LEDG 0x0200
47 #define BIT_LEDR 0x0080 63 #define BIT_LEDR 0x0100
48 #define BIT_SBRQ 0x0002 64 #define BIT_SBRQ 0x0002
49 #define BIT_SRES 0x0001 65 #define BIT_SRES 0x0001
50 #define BIT_PRES 0x0001 66 #define BIT_PRES 0x0001
51 //GA_MEM_MODE 67 //GA_MEM_MODE
52 #define MASK_PROG_BANK 0x00C0 68 #define MASK_PROG_BANK 0x00C0
53 #define MASK_PRIORITY 0x0018 69 #define BIT_OVERWRITE 0x0010
70 #define BIT_UNDERWRITE 0x0008
71 #define MASK_PRIORITY (BIT_OVERWRITE|BIT_UNDERWRITE)
54 #define BIT_MEM_MODE 0x0004 72 #define BIT_MEM_MODE 0x0004
55 #define BIT_DMNA 0x0002 73 #define BIT_DMNA 0x0002
56 #define BIT_RET 0x0001 74 #define BIT_RET 0x0001
75
57 //GA_INT_MASK 76 //GA_INT_MASK
58 #define BIT_MASK_IEN1 0x0002 77 #define BIT_MASK_IEN1 0x0002
59 #define BIT_MASK_IEN2 0x0004 78 #define BIT_MASK_IEN2 0x0004
60 #define BIT_MASK_IEN3 0x0008 79 #define BIT_MASK_IEN3 0x0008
61 #define BIT_MASK_IEN4 0x0010 80 #define BIT_MASK_IEN4 0x0010
64 83
65 static void *prog_ram_wp_write16(uint32_t address, void *vcontext, uint16_t value) 84 static void *prog_ram_wp_write16(uint32_t address, void *vcontext, uint16_t value)
66 { 85 {
67 m68k_context *m68k = vcontext; 86 m68k_context *m68k = vcontext;
68 segacd_context *cd = m68k->system; 87 segacd_context *cd = m68k->system;
69 if (!(cd->gate_array[GA_MEM_MODE] & (1 << ((address >> 17) + 8)))) { 88 //if (!(cd->gate_array[GA_MEM_MODE] & (1 << ((address >> 9) + 8)))) {
89 if (address >= ((cd->gate_array[GA_MEM_MODE] & 0xFF00) << 1)) {
70 cd->prog_ram[address >> 1] = value; 90 cd->prog_ram[address >> 1] = value;
71 m68k_invalidate_code_range(m68k, address, address + 2); 91 m68k_invalidate_code_range(m68k, address, address + 2);
72 } 92 }
73 return vcontext; 93 return vcontext;
74 } 94 }
75 95
76 static void *prog_ram_wp_write8(uint32_t address, void *vcontext, uint8_t value) 96 static void *prog_ram_wp_write8(uint32_t address, void *vcontext, uint8_t value)
77 { 97 {
78 m68k_context *m68k = vcontext; 98 m68k_context *m68k = vcontext;
79 segacd_context *cd = m68k->system; 99 segacd_context *cd = m68k->system;
80 if (!(cd->gate_array[GA_MEM_MODE] & (1 << ((address >> 17) + 8)))) { 100 if (address >= ((cd->gate_array[GA_MEM_MODE] & 0xFF00) << 1)) {
81 ((uint8_t *)cd->prog_ram)[address ^ 1] = value; 101 ((uint8_t *)cd->prog_ram)[address ^ 1] = value;
82 m68k_invalidate_code_range(m68k, address, address + 1); 102 m68k_invalidate_code_range(m68k, address, address + 1);
83 } 103 }
84 return vcontext; 104 return vcontext;
85 } 105 }
86 106
87 static uint16_t word_ram_2M_read16(uint32_t address, void *vcontext) 107 static uint16_t word_ram_2M_read16(uint32_t address, void *vcontext)
88 { 108 {
109 m68k_context *m68k = vcontext;
110 //TODO: fixme for interleaving
111 uint16_t* bank = m68k->mem_pointers[1];
112 uint16_t raw = bank[address >> 2];
113 if (address & 2) {
114 return (raw & 0xF) | (raw << 4 & 0xF00);
115 } else {
116 return (raw >> 4 & 0xF00) | (raw >> 8 & 0xF);
117 }
118 }
119
120 static uint8_t word_ram_2M_read8(uint32_t address, void *vcontext)
121 {
122 uint16_t word = word_ram_2M_read16(address, vcontext);
123 if (address & 1) {
124 return word;
125 }
126 return word >> 8;
127 }
128
129 static void *word_ram_2M_write8(uint32_t address, void *vcontext, uint8_t value)
130 {
131 m68k_context *m68k = vcontext;
132 segacd_context *cd = m68k->system;
133 value &= 0xF;
134 uint16_t priority = cd->gate_array[GA_MEM_MODE] & MASK_PRIORITY;
135
136 if (priority == BIT_OVERWRITE && !value) {
137 return vcontext;
138 }
139 if (priority == BIT_UNDERWRITE) {
140 if (!value) {
141 return vcontext;
142 }
143 uint8_t old = word_ram_2M_read8(address, vcontext);
144 if (old) {
145 return vcontext;
146 }
147 }
148 uint16_t* bank = m68k->mem_pointers[1];
149 uint16_t raw = bank[address >> 2];
150 uint16_t shift = ((address & 3) * 4);
151 raw &= ~(0xF000 >> shift);
152 raw |= value << (12 - shift);
153 bank[address >> 2] = raw;
154 return vcontext;
155 }
156
157
158 static void *word_ram_2M_write16(uint32_t address, void *vcontext, uint16_t value)
159 {
160 word_ram_2M_write8(address, vcontext, value >> 8);
161 return word_ram_2M_write8(address + 1, vcontext, value);
162 }
163
164 static uint16_t word_ram_1M_read16(uint32_t address, void *vcontext)
165 {
89 return 0; 166 return 0;
90 } 167 }
91 168
92 static uint8_t word_ram_2M_read8(uint32_t address, void *vcontext) 169 static uint8_t word_ram_1M_read8(uint32_t address, void *vcontext)
93 { 170 {
94 return 0; 171 return 0;
95 } 172 }
96 173
97 static void *word_ram_2M_write16(uint32_t address, void *vcontext, uint16_t value) 174 static void *word_ram_1M_write16(uint32_t address, void *vcontext, uint16_t value)
98 { 175 {
99 return vcontext; 176 return vcontext;
100 } 177 }
101 178
102 static void *word_ram_2M_write8(uint32_t address, void *vcontext, uint8_t value) 179 static void *word_ram_1M_write8(uint32_t address, void *vcontext, uint8_t value)
103 { 180 {
104 return vcontext; 181 return vcontext;
105 } 182 }
106 183
107 static uint16_t word_ram_1M_read16(uint32_t address, void *vcontext) 184
185 static uint16_t unmapped_prog_read16(uint32_t address, void *vcontext)
186 {
187 return 0xFFFF;
188 }
189
190 static uint8_t unmapped_prog_read8(uint32_t address, void *vcontext)
191 {
192 return 0xFF;
193 }
194
195 static void *unmapped_prog_write16(uint32_t address, void *vcontext, uint16_t value)
196 {
197 return vcontext;
198 }
199
200 static void *unmapped_prog_write8(uint32_t address, void *vcontext, uint8_t value)
201 {
202 return vcontext;
203 }
204
205 static uint16_t unmapped_word_read16(uint32_t address, void *vcontext)
206 {
207 return 0xFFFF;
208 }
209
210 static uint8_t unmapped_word_read8(uint32_t address, void *vcontext)
211 {
212 return 0xFF;
213 }
214
215 static void *unmapped_word_write16(uint32_t address, void *vcontext, uint16_t value)
216 {
217 return vcontext;
218 }
219
220 static void *unmapped_word_write8(uint32_t address, void *vcontext, uint8_t value)
221 {
222 return vcontext;
223 }
224
225 static uint16_t cell_image_read16(uint32_t address, void *vcontext)
226 {
227 return 0xFFFF;
228 }
229
230 static uint8_t cell_image_read8(uint32_t address, void *vcontext)
231 {
232 return 0xFF;
233 }
234
235 static void *cell_image_write16(uint32_t address, void *vcontext, uint16_t value)
236 {
237 return vcontext;
238 }
239
240 static void *cell_image_write8(uint32_t address, void *vcontext, uint8_t value)
241 {
242 return vcontext;
243 }
244
245 static uint8_t pcm_read8(uint32_t address, void *vcontext)
108 { 246 {
109 return 0; 247 return 0;
110 } 248 }
111 249
112 static uint8_t word_ram_1M_read8(uint32_t address, void *vcontext)
113 {
114 return 0;
115 }
116
117 static void *word_ram_1M_write16(uint32_t address, void *vcontext, uint16_t value)
118 {
119 return vcontext;
120 }
121
122 static void *word_ram_1M_write8(uint32_t address, void *vcontext, uint8_t value)
123 {
124 return vcontext;
125 }
126
127
128 static uint16_t unmapped_prog_read16(uint32_t address, void *vcontext)
129 {
130 return 0xFFFF;
131 }
132
133 static uint8_t unmapped_prog_read8(uint32_t address, void *vcontext)
134 {
135 return 0xFF;
136 }
137
138 static void *unmapped_prog_write16(uint32_t address, void *vcontext, uint16_t value)
139 {
140 return vcontext;
141 }
142
143 static void *unmapped_prog_write8(uint32_t address, void *vcontext, uint8_t value)
144 {
145 return vcontext;
146 }
147
148 static uint8_t pcm_read8(uint32_t address, void *vcontext)
149 {
150 return 0;
151 }
152
153 static uint16_t pcm_read16(uint32_t address, void *vcontext) 250 static uint16_t pcm_read16(uint32_t address, void *vcontext)
154 { 251 {
155 return 0xFF00 | pcm_read8(address+1, vcontext); 252 return 0xFF00 | pcm_read8(address+1, vcontext);
156 } 253 }
157 254
166 } 263 }
167 264
168 265
169 static void timers_run(segacd_context *cd, uint32_t cycle) 266 static void timers_run(segacd_context *cd, uint32_t cycle)
170 { 267 {
268 if (cycle <= cd->stopwatch_cycle) {
269 return;
270 }
171 uint32_t ticks = (cycle - cd->stopwatch_cycle) / TIMER_TICK_CLKS; 271 uint32_t ticks = (cycle - cd->stopwatch_cycle) / TIMER_TICK_CLKS;
172 cd->stopwatch_cycle += ticks * TIMER_TICK_CLKS; 272 cd->stopwatch_cycle += ticks * TIMER_TICK_CLKS;
173 cd->gate_array[GA_STOP_WATCH] += ticks; 273 cd->gate_array[GA_STOP_WATCH] += ticks;
174 cd->gate_array[GA_STOP_WATCH] &= 0xFFF; 274 cd->gate_array[GA_STOP_WATCH] &= 0xFFF;
175 if (!cd->timer_value) { 275 if (ticks && !cd->timer_value) {
176 --ticks; 276 --ticks;
177 cd->timer_value = cd->gate_array[GA_TIMER]; 277 cd->timer_value = cd->gate_array[GA_TIMER];
178 } 278 }
179 if (cd->timer_value) { 279 if (ticks && cd->timer_value) {
180 while (ticks >= (cd->timer_value + 1)) { 280 while (ticks >= (cd->timer_value + 1)) {
181 ticks -= cd->timer_value + 1; 281 ticks -= cd->timer_value + 1;
182 cd->timer_value = cd->gate_array[GA_TIMER]; 282 cd->timer_value = cd->gate_array[GA_TIMER];
183 cd->timer_pending = 1; 283 cd->timer_pending = 1;
184 } 284 }
257 return cd->gate_array[reg] & 0xFF1F; 357 return cd->gate_array[reg] & 0xFF1F;
258 case GA_STOP_WATCH: 358 case GA_STOP_WATCH:
259 case GA_TIMER: 359 case GA_TIMER:
260 timers_run(cd, m68k->current_cycle); 360 timers_run(cd, m68k->current_cycle);
261 return cd->gate_array[reg]; 361 return cd->gate_array[reg];
362 case GA_FONT_DATA0:
363 case GA_FONT_DATA1:
364 case GA_FONT_DATA2:
365 case GA_FONT_DATA3: {
366 uint16_t shift = 4 * (3 - (reg - GA_FONT_DATA0));
367 uint16_t value = 0;
368 uint16_t fg = cd->gate_array[GA_FONT_COLOR] >> 4;
369 uint16_t bg = cd->gate_array[GA_FONT_COLOR] & 0xF;
370 for (int i = 0; i < 4; i++) {
371 uint16_t pixel = 0;
372 if (cd->gate_array[GA_FONT_BITS] & 1 << (shift + i)) {
373 pixel = fg;
374 } else {
375 pixel = bg;
376 }
377 value |= pixel << (i * 4);
378 }
379 return value;
380 }
262 default: 381 default:
263 return cd->gate_array[reg]; 382 return cd->gate_array[reg];
264 } 383 }
265 } 384 }
266 385
313 } 432 }
314 } 433 }
315 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); 434 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000);
316 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); 435 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000);
317 } else if (changed & BIT_RET) { 436 } else if (changed & BIT_RET) {
318 cd->gate_array[reg] &= ~BIT_DMNA;
319 if (value & BIT_MEM_MODE) { 437 if (value & BIT_MEM_MODE) {
438 cd->gate_array[reg] &= ~BIT_DMNA;
320 //swapping banks in 1M mode 439 //swapping banks in 1M mode
321 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram; 440 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = (value & BIT_RET) ? cd->word_ram + 0x10000 : cd->word_ram;
322 m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 0x10000; 441 m68k->mem_pointers[1] = (value & BIT_RET) ? cd->word_ram : cd->word_ram + 0x10000;
323 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); 442 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000);
324 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); 443 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000);
325 } else if (value & BIT_RET) { 444 } else if (value & BIT_RET) {
445 cd->gate_array[reg] &= ~BIT_DMNA;
326 //giving word ram to main CPU in 2M mode 446 //giving word ram to main CPU in 2M mode
327 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = cd->word_ram; 447 gen->m68k->mem_pointers[cd->memptr_start_index + 1] = cd->word_ram;
328 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = cd->word_ram + 0x10000; 448 gen->m68k->mem_pointers[cd->memptr_start_index + 2] = cd->word_ram + 0x10000;
329 m68k->mem_pointers[0] = NULL; 449 m68k->mem_pointers[0] = NULL;
330 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000); 450 m68k_invalidate_code_range(gen->m68k, cd->base + 0x200000, cd->base + 0x240000);
331 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000); 451 m68k_invalidate_code_range(m68k, 0x080000, 0x0E0000);
452 } else {
453 value |= BIT_RET;
332 } 454 }
333 } 455 }
334 cd->gate_array[reg] &= 0xFFC2; 456 cd->gate_array[reg] &= 0xFFC2;
335 cd->gate_array[reg] |= value & (BIT_RET|BIT_MEM_MODE|MASK_PRIORITY); 457 cd->gate_array[reg] |= value & (BIT_RET|BIT_MEM_MODE|MASK_PRIORITY);
336 break; 458 break;
337 } 459 }
338 case GA_STOP_WATCH: 460 case GA_STOP_WATCH:
339 //docs say you should only write zero to reset 461 //docs say you should only write zero to reset
340 //unclear what happens when other values are written 462 //mcd-verificator comments suggest any value will reset
341 timers_run(cd, m68k->current_cycle); 463 timers_run(cd, m68k->current_cycle);
342 cd->gate_array[reg] = value & 0xFFF; 464 cd->gate_array[reg] = 0;
343 break; 465 break;
344 case GA_COMM_FLAG: 466 case GA_COMM_FLAG:
345 cd->gate_array[reg] &= 0xFF00; 467 cd->gate_array[reg] &= 0xFF00;
346 cd->gate_array[reg] |= value & 0xFF; 468 cd->gate_array[reg] |= value & 0xFF;
347 break; 469 break;
363 break; 485 break;
364 case GA_INT_MASK: 486 case GA_INT_MASK:
365 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1); 487 cd->gate_array[reg] = value & (BIT_MASK_IEN6|BIT_MASK_IEN5|BIT_MASK_IEN4|BIT_MASK_IEN3|BIT_MASK_IEN2|BIT_MASK_IEN1);
366 calculate_target_cycle(m68k); 488 calculate_target_cycle(m68k);
367 break; 489 break;
490 case GA_FONT_COLOR:
491 cd->gate_array[reg] = value & 0xFF;
492 break;
493 case GA_FONT_BITS:
494 cd->gate_array[reg] = value;
495 break;
368 default: 496 default:
369 printf("Unhandled gate array write %X:%X\n", address, value); 497 printf("Unhandled gate array write %X:%X\n", address, value);
370 } 498 }
371 return vcontext; 499 return vcontext;
372 } 500 }
381 { 509 {
382 case GA_CDC_HOST_DATA: 510 case GA_CDC_HOST_DATA:
383 case GA_CDC_DMA_ADDR: 511 case GA_CDC_DMA_ADDR:
384 case GA_STOP_WATCH: 512 case GA_STOP_WATCH:
385 case GA_COMM_FLAG: 513 case GA_COMM_FLAG:
514 case GA_TIMER:
386 case GA_CDD_FADER: 515 case GA_CDD_FADER:
516 case GA_FONT_COLOR:
387 //these registers treat all writes as word-wide 517 //these registers treat all writes as word-wide
388 value16 = value | (value << 8); 518 value16 = value | (value << 8);
389 break; 519 break;
390 default: 520 default:
391 if (address & 1) { 521 if (address & 1) {
410 540
411 static m68k_context *sync_components(m68k_context * context, uint32_t address) 541 static m68k_context *sync_components(m68k_context * context, uint32_t address)
412 { 542 {
413 segacd_context *cd = context->system; 543 segacd_context *cd = context->system;
414 scd_peripherals_run(cd, context->current_cycle); 544 scd_peripherals_run(cd, context->current_cycle);
545 switch (context->int_ack)
546 {
547 case 2:
548 cd->int2_cycle = CYCLE_NEVER;
549 break;
550 case 3:
551 cd->timer_pending = 0;
552 break;
553 }
554 context->int_ack = 0;
415 calculate_target_cycle(context); 555 calculate_target_cycle(context);
416 return context; 556 return context;
417 } 557 }
418 558
419 void scd_run(segacd_context *cd, uint32_t cycle) 559 void scd_run(segacd_context *cd, uint32_t cycle)
521 uint8_t old_reset = cd->reset; 661 uint8_t old_reset = cd->reset;
522 cd->reset = value & BIT_SRES; 662 cd->reset = value & BIT_SRES;
523 if (cd->reset && !old_reset) { 663 if (cd->reset && !old_reset) {
524 cd->need_reset = 1; 664 cd->need_reset = 1;
525 } 665 }
526 cd->gate_array[reg] &= 0x7FFF; 666 if (value & BIT_IFL2) {
527 cd->gate_array[reg] |= value & 0x8000; 667 cd->int2_cycle = scd_cycle;
668 }
669 /*cd->gate_array[reg] &= 0x7FFF;
670 cd->gate_array[reg] |= value & 0x8000;*/
528 uint8_t new_access = can_main_access_prog(cd); 671 uint8_t new_access = can_main_access_prog(cd);
529 uint32_t bank = cd->gate_array[GA_MEM_MODE] >> 6 & 0x3; 672 uint32_t bank = cd->gate_array[GA_MEM_MODE] >> 6 & 0x3;
530 if (new_access) { 673 if (new_access) {
531 if (!old_access) { 674 if (!old_access) {
532 m68k->mem_pointers[cd->memptr_start_index] = cd->prog_ram + bank * 0x10000; 675 m68k->mem_pointers[cd->memptr_start_index] = cd->prog_ram + bank * 0x10000;
540 break; 683 break;
541 } 684 }
542 case GA_MEM_MODE: { 685 case GA_MEM_MODE: {
543 uint16_t changed = cd->gate_array[reg] ^ value; 686 uint16_t changed = cd->gate_array[reg] ^ value;
544 //Main CPU can't write priority mode bits, MODE or RET 687 //Main CPU can't write priority mode bits, MODE or RET
545 cd->gate_array[reg] &= 0x001D; 688 cd->gate_array[reg] &= 0x001F;
546 cd->gate_array[reg] |= value & 0xFFC0; 689 cd->gate_array[reg] |= value & 0xFFC0;
547 if ((cd->gate_array[reg] & BIT_MEM_MODE)) { 690 if ((cd->gate_array[reg] & BIT_MEM_MODE)) {
548 //1M mode 691 //1M mode
549 if (!(value & BIT_DMNA)) { 692 if (!(value & BIT_DMNA)) {
550 cd->gate_array[reg] |= BIT_DMNA; 693 cd->gate_array[reg] |= BIT_DMNA;
551 } 694 }
552 } else { 695 } else {
553 cd->gate_array[reg] |= value & BIT_DMNA;
554 //2M mode 696 //2M mode
555 if (changed & value & BIT_DMNA) { 697 if (changed & value & BIT_DMNA) {
698 cd->gate_array[reg] |= BIT_DMNA;
556 m68k->mem_pointers[cd->memptr_start_index + 1] = NULL; 699 m68k->mem_pointers[cd->memptr_start_index + 1] = NULL;
557 m68k->mem_pointers[cd->memptr_start_index + 2] = NULL; 700 m68k->mem_pointers[cd->memptr_start_index + 2] = NULL;
558 cd->m68k->mem_pointers[0] = cd->word_ram; 701 cd->m68k->mem_pointers[0] = cd->word_ram;
702 cd->gate_array[reg] &= ~BIT_RET;
559 703
560 m68k_invalidate_code_range(m68k, cd->base + 0x200000, cd->base + 0x240000); 704 m68k_invalidate_code_range(m68k, cd->base + 0x200000, cd->base + 0x240000);
561 m68k_invalidate_code_range(cd->m68k, 0x080000, 0x0C0000); 705 m68k_invalidate_code_range(cd->m68k, 0x080000, 0x0C0000);
562 } 706 }
563 } 707 }
564 if (changed & MASK_PROG_BANK) { 708 if (changed & MASK_PROG_BANK && can_main_access_prog(cd)) {
565 uint32_t bank = cd->gate_array[GA_MEM_MODE] >> 6 & 0x3; 709 uint32_t bank = cd->gate_array[GA_MEM_MODE] >> 6 & 0x3;
566 m68k->mem_pointers[cd->memptr_start_index] = cd->prog_ram + bank * 0x10000; 710 m68k->mem_pointers[cd->memptr_start_index] = cd->prog_ram + bank * 0x10000;
567 m68k_invalidate_code_range(m68k, cd->base + 0x220000, cd->base + 0x240000); 711 m68k_invalidate_code_range(m68k, cd->base + 0x220000, cd->base + 0x240000);
568 } 712 }
569 break; 713 break;
600 segacd_context *cd = gen->expansion; 744 segacd_context *cd = gen->expansion;
601 uint32_t reg = (address & 0x1FF) >> 1; 745 uint32_t reg = (address & 0x1FF) >> 1;
602 uint16_t value16; 746 uint16_t value16;
603 switch (reg >> 1) 747 switch (reg >> 1)
604 { 748 {
749 case GA_SUB_CPU_CTRL:
750 if (address & 1) {
751 value16 = value;
752 } else {
753 value16 = value << 8;
754 if (cd->reset) {
755 value16 |= BIT_SRES;
756 }
757 if (cd->busreq) {
758 value16 |= BIT_SBRQ;
759 }
760 }
761 break;
605 case GA_HINT_VECTOR: 762 case GA_HINT_VECTOR:
606 case GA_COMM_FLAG: 763 case GA_COMM_FLAG:
607 //writes to these regs are always treated as word wide 764 //writes to these regs are always treated as word wide
608 value16 = value | (value << 8); 765 value16 = value | (value << 8);
609 break; 766 break;
618 } 775 }
619 776
620 segacd_context *alloc_configure_segacd(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info) 777 segacd_context *alloc_configure_segacd(system_media *media, uint32_t opts, uint8_t force_region, rom_info *info)
621 { 778 {
622 static memmap_chunk sub_cpu_map[] = { 779 static memmap_chunk sub_cpu_map[] = {
623 {0x000000, 0x00FEFF, 0xFFFFFF, .flags=MMAP_READ | MMAP_CODE, .write_16 = prog_ram_wp_write16, .write_8 = prog_ram_wp_write8}, 780 {0x000000, 0x01FEFF, 0xFFFFFF, .flags=MMAP_READ | MMAP_CODE, .write_16 = prog_ram_wp_write16, .write_8 = prog_ram_wp_write8},
624 {0x00FF00, 0x07FFFF, 0xFFFFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE}, 781 {0x01FF00, 0x07FFFF, 0xFFFFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE},
625 {0x080000, 0x0BFFFF, 0x03FFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL, .ptr_index = 0, 782 {0x080000, 0x0BFFFF, 0x03FFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL, .ptr_index = 0,
626 .read_16 = word_ram_2M_read16, .write_16 = word_ram_2M_write16, .read_8 = word_ram_2M_read8, .write_8 = word_ram_2M_write8}, 783 .read_16 = word_ram_2M_read16, .write_16 = word_ram_2M_write16, .read_8 = word_ram_2M_read8, .write_8 = word_ram_2M_write8},
627 {0x0C0000, 0x0DFFFF, 0x01FFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL, .ptr_index = 1, 784 {0x0C0000, 0x0DFFFF, 0x01FFFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_CODE | MMAP_PTR_IDX | MMAP_FUNC_NULL, .ptr_index = 1,
628 .read_16 = word_ram_1M_read16, .write_16 = word_ram_1M_write16, .read_8 = word_ram_1M_read8, .write_8 = word_ram_1M_write8}, 785 .read_16 = word_ram_1M_read16, .write_16 = word_ram_1M_write16, .read_8 = word_ram_1M_read8, .write_8 = word_ram_1M_write8},
629 {0xFE0000, 0xFEFFFF, 0x003FFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_ONLY_ODD}, 786 {0xFE0000, 0xFEFFFF, 0x003FFF, .flags=MMAP_READ | MMAP_WRITE | MMAP_ONLY_ODD},
682 {0x000000, 0x01FFFF, 0x01FFFF, .flags=MMAP_READ}, 839 {0x000000, 0x01FFFF, 0x01FFFF, .flags=MMAP_READ},
683 {0x020000, 0x03FFFF, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 0, 840 {0x020000, 0x03FFFF, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 0,
684 .read_16 = unmapped_prog_read16, .write_16 = unmapped_prog_write16, .read_8 = unmapped_prog_read8, .write_8 = unmapped_prog_write8}, 841 .read_16 = unmapped_prog_read16, .write_16 = unmapped_prog_write16, .read_8 = unmapped_prog_read8, .write_8 = unmapped_prog_write8},
685 {0x040000, 0x05FFFF, 0x01FFFF, .flags=MMAP_READ}, //first ROM alias 842 {0x040000, 0x05FFFF, 0x01FFFF, .flags=MMAP_READ}, //first ROM alias
686 //TODO: additional ROM/prog RAM aliases 843 //TODO: additional ROM/prog RAM aliases
687 {0x200000, 0x21FFFF, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 1}, 844 {0x200000, 0x21FFFF, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 1,
688 {0x220000, 0x23FFFF, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 2}, 845 .read_16 = unmapped_word_read16, .write_16 = unmapped_word_write16, .read_8 = unmapped_word_read8, .write_8 = unmapped_word_write8},
846 {0x220000, 0x23FFFF, 0x01FFFF, .flags=MMAP_READ|MMAP_WRITE|MMAP_PTR_IDX|MMAP_FUNC_NULL|MMAP_CODE, .ptr_index = 2,
847 .read_16 = cell_image_read16, .write_16 = cell_image_write16, .read_8 = cell_image_read8, .write_8 = cell_image_write8},
689 {0xA12000, 0xA12FFF, 0xFFFFFF, .read_16 = main_gate_read16, .write_16 = main_gate_write16, .read_8 = main_gate_read8, .write_8 = main_gate_write8} 848 {0xA12000, 0xA12FFF, 0xFFFFFF, .read_16 = main_gate_read16, .write_16 = main_gate_write16, .read_8 = main_gate_read8, .write_8 = main_gate_write8}
690 }; 849 };
691 for (int i = 0; i < sizeof(main_cpu_map) / sizeof(*main_cpu_map); i++) 850 for (int i = 0; i < sizeof(main_cpu_map) / sizeof(*main_cpu_map); i++)
692 { 851 {
693 if (main_cpu_map[i].start < 0x800000) { 852 if (main_cpu_map[i].start < 0x800000) {