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