pandora: fix readme and pxml version
[picodrive.git] / pico / cd / memory.c
CommitLineData
cff531af 1/*\r
2 * Memory I/O handlers for Sega/Mega CD.\r
3 * (C) notaz, 2007-2009\r
7bf552b5 4 * (C) irixxxx, 2019-2024\r
cff531af 5 *\r
6 * This work is licensed under the terms of MAME license.\r
7 * See COPYING file in the top-level directory.\r
8 */\r
cc68a136 9\r
efcba75f 10#include "../pico_int.h"\r
af37bca8 11#include "../memory.h"\r
de5da52e 12#include "megasd.h"\r
cc68a136 13\r
bcf65fd6 14uptr s68k_read8_map [0x1000000 >> M68K_MEM_SHIFT];\r
15uptr s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];\r
16uptr s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];\r
17uptr s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];\r
cc68a136 18\r
78d817c3 19#ifndef _ASM_CD_MEMORY_C\r
af37bca8 20MAKE_68K_READ8(s68k_read8, s68k_read8_map)\r
21MAKE_68K_READ16(s68k_read16, s68k_read16_map)\r
22MAKE_68K_READ32(s68k_read32, s68k_read16_map)\r
23MAKE_68K_WRITE8(s68k_write8, s68k_write8_map)\r
24MAKE_68K_WRITE16(s68k_write16, s68k_write16_map)\r
25MAKE_68K_WRITE32(s68k_write32, s68k_write16_map)\r
78d817c3 26#endif\r
b5e5172d 27\r
02ff0254 28u32 pcd_base_address;\r
29#define BASE pcd_base_address\r
30\r
cc68a136 31// -----------------------------------------------------------------\r
32\r
0ace9b9a 33// provided by ASM code:\r
34#ifdef _ASM_CD_MEMORY_C\r
0ace9b9a 35u32 PicoReadS68k8_pr(u32 a);\r
36u32 PicoReadS68k16_pr(u32 a);\r
37void PicoWriteS68k8_pr(u32 a, u32 d);\r
38void PicoWriteS68k16_pr(u32 a, u32 d);\r
39\r
40u32 PicoReadM68k8_cell0(u32 a);\r
41u32 PicoReadM68k8_cell1(u32 a);\r
42u32 PicoReadM68k16_cell0(u32 a);\r
43u32 PicoReadM68k16_cell1(u32 a);\r
44void PicoWriteM68k8_cell0(u32 a, u32 d);\r
45void PicoWriteM68k8_cell1(u32 a, u32 d);\r
46void PicoWriteM68k16_cell0(u32 a, u32 d);\r
47void PicoWriteM68k16_cell1(u32 a, u32 d);\r
48\r
49u32 PicoReadS68k8_dec0(u32 a);\r
50u32 PicoReadS68k8_dec1(u32 a);\r
51u32 PicoReadS68k16_dec0(u32 a);\r
52u32 PicoReadS68k16_dec1(u32 a);\r
53void PicoWriteS68k8_dec_m0b0(u32 a, u32 d);\r
54void PicoWriteS68k8_dec_m1b0(u32 a, u32 d);\r
55void PicoWriteS68k8_dec_m2b0(u32 a, u32 d);\r
56void PicoWriteS68k8_dec_m0b1(u32 a, u32 d);\r
57void PicoWriteS68k8_dec_m1b1(u32 a, u32 d);\r
58void PicoWriteS68k8_dec_m2b1(u32 a, u32 d);\r
59void PicoWriteS68k16_dec_m0b0(u32 a, u32 d);\r
60void PicoWriteS68k16_dec_m1b0(u32 a, u32 d);\r
61void PicoWriteS68k16_dec_m2b0(u32 a, u32 d);\r
62void PicoWriteS68k16_dec_m0b1(u32 a, u32 d);\r
63void PicoWriteS68k16_dec_m1b1(u32 a, u32 d);\r
64void PicoWriteS68k16_dec_m2b1(u32 a, u32 d);\r
65#endif\r
66\r
4fb43555 67static void remap_prg_window(u32 r1, u32 r3);\r
68static void remap_word_ram(u32 r3);\r
0ace9b9a 69\r
7a1f6e45 70// poller detection\r
efaa5e0b 71#define POLL_LIMIT 16\r
dd7c8c05 72#define POLL_CYCLES 52\r
cc68a136 73\r
cc5ffc3c 74void m68k_comm_check(u32 a)\r
bc3c13d3 75{\r
54022234 76 u32 cycles = SekCyclesDone();\r
77 u32 clkdiff = cycles - Pico_mcd->m.m68k_poll_clk;\r
78 pcd_sync_s68k(cycles, 0);\r
8eeb3426 79 if (a == 0x0e && !(Pico_mcd->m.state_flags & PCD_ST_S68K_SYNC) && (Pico_mcd->s68k_regs[3]&0x4)) {\r
6901d0e4 80 // there are cases when slave updates comm and only switches RAM\r
02db2308 81 // over after that (mcd1 bios), so there must be a resync..\r
6901d0e4 82 SekEndRun(64);\r
8eeb3426 83 Pico_mcd->m.state_flags |= PCD_ST_S68K_SYNC;\r
6901d0e4 84 }\r
54022234 85 Pico_mcd->m.m68k_poll_clk = cycles;\r
efaa5e0b 86 if (SekNotPolling || a != Pico_mcd->m.m68k_poll_a || clkdiff > POLL_CYCLES || clkdiff <= 16) {\r
bc3c13d3 87 Pico_mcd->m.m68k_poll_a = a;\r
88 Pico_mcd->m.m68k_poll_cnt = 0;\r
ecc8036e 89 SekNotPolling = 0;\r
cc5ffc3c 90 return;\r
bc3c13d3 91 }\r
08769494 92 Pico_mcd->m.m68k_poll_cnt++;\r
8eeb3426 93 Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;\r
94 if (Pico_mcd->m.m68k_poll_cnt >= POLL_LIMIT) {\r
95 Pico_mcd->m.state_flags |= PCD_ST_M68K_POLL;\r
02db2308 96 SekEndRun(8);\r
8eeb3426 97 }\r
bc3c13d3 98}\r
99\r
f27a1749 100u32 pcd_stopwatch_read(int sub)\r
101{\r
80f51a1d 102 // ugh... stopwatch runs 384 cycles per step, divide by mult with inverse\r
f27a1749 103 u32 d = sub ? SekCyclesDoneS68k() : pcd_cycles_m68k_to_s68k(SekCyclesDone());\r
80f51a1d 104 d = ((d - Pico_mcd->m.stopwatch_base_c) * ((1LL << 32) / 384)) >> 32;\r
f27a1749 105 return d & 0x0fff;\r
106}\r
107\r
4ff2d527 108#ifndef _ASM_CD_MEMORY_C\r
cb4a513a 109static u32 m68k_reg_read16(u32 a)\r
cc68a136 110{\r
4fb43555 111 u32 d = 0;\r
cc68a136 112 a &= 0x3e;\r
cc68a136 113\r
114 switch (a) {\r
672ad671 115 case 0:\r
178a9b68 116 pcd_sync_s68k(SekCyclesDone(), 0);\r
117 d = ((Pico_mcd->s68k_regs[0x33] & PCDS_IEN2) << 13) |\r
118 (Pico_mcd->m.state_flags & PCD_ST_S68K_IFL2) | Pico_mcd->m.busreq;\r
672ad671 119 goto end;\r
cc68a136 120 case 2:\r
cc5ffc3c 121 m68k_comm_check(a);\r
672ad671 122 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
af37bca8 123 elprintf(EL_CDREG3, "m68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
cc5ffc3c 124 goto end;\r
c459aefd 125 case 4:\r
dd7c8c05 126 pcd_sync_s68k(SekCyclesDone(), 0);\r
c459aefd 127 d = Pico_mcd->s68k_regs[4]<<8;\r
128 goto end;\r
129 case 6:\r
549dd407 130 d = *(u16 *)(Pico_mcd->bios + 0x72);\r
c459aefd 131 goto end;\r
cc68a136 132 case 8:\r
dd7c8c05 133 d = cdc_host_r(0);\r
cc68a136 134 goto end;\r
f27a1749 135 case 0xa:\r
ca61ee42 136 elprintf(EL_UIO, "m68k FIXME: reserved read");\r
c459aefd 137 goto end;\r
f27a1749 138 case 0xc: // 384 cycle stopwatch timer\r
dd7c8c05 139 pcd_sync_s68k(SekCyclesDone(), 0);\r
f27a1749 140 d = pcd_stopwatch_read(0);\r
af37bca8 141 elprintf(EL_CDREGS, "m68k stopwatch timer read (%04x)", d);\r
1cd356a3 142 goto end;\r
cc68a136 143 }\r
144\r
cc68a136 145 if (a < 0x30) {\r
146 // comm flag/cmd/status (0xE-0x2F)\r
cc5ffc3c 147 m68k_comm_check(a);\r
cc68a136 148 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
691abdfa 149 return d;\r
cc68a136 150 }\r
151\r
ca61ee42 152 elprintf(EL_UIO, "m68k_regs FIXME invalid read @ %02x", a);\r
cc68a136 153\r
154end:\r
cc68a136 155 return d;\r
156}\r
4ff2d527 157#endif\r
cc68a136 158\r
4ff2d527 159#ifndef _ASM_CD_MEMORY_C\r
160static\r
161#endif\r
162void m68k_reg_write8(u32 a, u32 d)\r
cc68a136 163{\r
af37bca8 164 u32 dold;\r
cc68a136 165 a &= 0x3f;\r
cc68a136 166\r
8eeb3426 167 Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;\r
fbebab69 168 Pico_mcd->m.m68k_poll_cnt = 0;\r
169\r
cc68a136 170 switch (a) {\r
171 case 0:\r
672ad671 172 d &= 1;\r
e61dbac1 173 pcd_sync_s68k(SekCyclesDone(), 0);\r
08769494 174 if (d && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN2)) {\r
175 elprintf(EL_INTS, "m68k: s68k irq 2");\r
e61dbac1 176 Pico_mcd->m.state_flags |= PCD_ST_S68K_IFL2;\r
eb36d9c7 177 pcd_irq_s68k(2, 1);\r
e61dbac1 178 } else {\r
179 Pico_mcd->m.state_flags &= ~PCD_ST_S68K_IFL2;\r
691abdfa 180 pcd_irq_s68k(2, 0);\r
e61dbac1 181 }\r
c459aefd 182 return;\r
cc68a136 183 case 1:\r
672ad671 184 d &= 3;\r
4fb43555 185 dold = Pico_mcd->m.busreq;\r
02ff0254 186// if (!(d & 1))\r
187// d |= 2; // verified: can't release bus on reset\r
4fb43555 188 if (dold == d)\r
bc3c13d3 189 return;\r
4fb43555 190\r
08769494 191 pcd_sync_s68k(SekCyclesDone(), 0);\r
bc3c13d3 192\r
4fb43555 193 if ((dold ^ d) & 1)\r
bc3c13d3 194 elprintf(EL_INTSW, "m68k: s68k reset %i", !(d&1));\r
4fb43555 195 if (!(d & 1))\r
196 Pico_mcd->m.state_flags |= PCD_ST_S68K_RST;\r
197 else if (d == 1 && (Pico_mcd->m.state_flags & PCD_ST_S68K_RST)) {\r
178a9b68 198 Pico_mcd->m.state_flags &= ~(PCD_ST_S68K_RST|PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP);\r
4fb43555 199 elprintf(EL_CDREGS, "m68k: resetting s68k");\r
200 SekResetS68k();\r
e61dbac1 201 SekCycleCntS68k += 40;\r
cc68a136 202 }\r
02ff0254 203 if (((dold & 3) == 1) != ((d & 3) == 1)) {\r
bc3c13d3 204 elprintf(EL_INTSW, "m68k: s68k brq %i", d >> 1);\r
4fb43555 205 remap_prg_window(d, Pico_mcd->s68k_regs[3]);\r
bc3c13d3 206 }\r
c459aefd 207 Pico_mcd->m.busreq = d;\r
208 return;\r
672ad671 209 case 2:\r
af37bca8 210 elprintf(EL_CDREGS, "m68k: prg wp=%02x", d);\r
fbebab69 211 goto write_comm;\r
af37bca8 212 case 3:\r
af37bca8 213 elprintf(EL_CDREG3, "m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
178a9b68 214 dold = Pico_mcd->s68k_regs[3];\r
af37bca8 215 if ((d ^ dold) & 0xc0) {\r
08769494 216 elprintf(EL_CDREGS, "m68k: prg bank: %i -> %i",\r
217 (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
4fb43555 218 remap_prg_window(Pico_mcd->m.busreq, d);\r
7a1f6e45 219 }\r
ba6e8bfd 220\r
221 // 2M mode state is tracked regardless of current mode\r
222 if (d & 2) {\r
223 Pico_mcd->m.dmna_ret_2m |= 2;\r
224 Pico_mcd->m.dmna_ret_2m &= ~1;\r
225 }\r
226 if (dold & 4) { // 1M mode\r
227 d ^= 2; // 0 sets DMNA, 1 does nothing\r
228 d = (d & 0xc2) | (dold & 0x1f);\r
229 }\r
230 else\r
231 d = (d & 0xc0) | (dold & 0x1c) | Pico_mcd->m.dmna_ret_2m;\r
8eeb3426 232 if ((dold ^ d) & 0x1f)\r
233 remap_word_ram(d);\r
08769494 234 goto write_comm;\r
c459aefd 235 case 6:\r
549dd407 236 Pico_mcd->bios[MEM_BE2(0x72)] = d; // simple hint vector changer\r
c459aefd 237 return;\r
238 case 7:\r
549dd407 239 Pico_mcd->bios[MEM_BE2(0x73)] = d;\r
af37bca8 240 elprintf(EL_CDREGS, "hint vector set to %04x%04x",\r
549dd407 241 ((u16 *)Pico_mcd->bios)[0x70/2], ((u16 *)Pico_mcd->bios)[0x72/2]);\r
c459aefd 242 return;\r
178a9b68 243 case 8:\r
dd7c8c05 244 (void) cdc_host_r(0); // acts same as reading\r
178a9b68 245 return;\r
08769494 246 case 0x0f:\r
08769494 247 a = 0x0e;\r
248 case 0x0e:\r
249 goto write_comm;\r
672ad671 250 }\r
251\r
08769494 252 if ((a&0xf0) == 0x10)\r
253 goto write_comm;\r
cc68a136 254\r
ca61ee42 255 elprintf(EL_UIO, "m68k FIXME: invalid write? [%02x] %02x", a, d);\r
08769494 256 return;\r
257\r
258write_comm:\r
b074a2b5 259 if (Pico_mcd->s68k_regs[a] == (u8)d)\r
08769494 260 return;\r
261\r
08769494 262 pcd_sync_s68k(SekCyclesDone(), 0);\r
30e8aac4 263 Pico_mcd->s68k_regs[a] = d;\r
1a95ce34 264 if (a == 0x03) {\r
265 // There are cases when master checks for successful switching of RAM to\r
266 // slave. This can produce race conditions where slave switches RAM back to\r
267 // master while master is delayed by interrupt before the check executes.\r
268 // Delay slave a bit to make sure master can check before slave changes.\r
02db2308 269 SekCycleCntS68k += 24; // Silpheed\r
1a95ce34 270 }\r
4a55f64a 271 if (!((Pico_mcd->m.s68k_poll_a ^ a) & ~1)) {\r
8eeb3426 272 if (Pico_mcd->m.state_flags & PCD_ST_S68K_POLL)\r
334d9fb6 273 elprintf(EL_CDPOLL, "s68k poll release, a=%02x", a);\r
8eeb3426 274 Pico_mcd->m.state_flags &= ~PCD_ST_S68K_POLL;\r
02db2308 275 Pico_mcd->m.s68k_poll_cnt = 0;\r
08769494 276 }\r
cc68a136 277}\r
278\r
2433f409 279u32 s68k_poll_detect(u32 a, u32 d)\r
280{\r
281#ifdef USE_POLL_DETECT\r
08769494 282 u32 cycles, cnt = 0;\r
8eeb3426 283 if (Pico_mcd->m.state_flags & (PCD_ST_S68K_POLL|PCD_ST_S68K_SLEEP))\r
08769494 284 return d;\r
285\r
286 cycles = SekCyclesDoneS68k();\r
ed9c0413 287 if (!SekNotPollingS68k && a == Pico_mcd->m.s68k_poll_a) {\r
08769494 288 u32 clkdiff = cycles - Pico_mcd->m.s68k_poll_clk;\r
2433f409 289 if (clkdiff <= POLL_CYCLES) {\r
08769494 290 cnt = Pico_mcd->m.s68k_poll_cnt + 1;\r
291 //printf("-- diff: %u, cnt = %i\n", clkdiff, cnt);\r
8eeb3426 292 Pico_mcd->m.state_flags &= ~PCD_ST_S68K_POLL;\r
02db2308 293 if (cnt > POLL_LIMIT) {\r
8eeb3426 294 Pico_mcd->m.state_flags |= PCD_ST_S68K_POLL;\r
c36dbc1d 295 SekEndRunS68k(8);\r
cc5ffc3c 296 elprintf(EL_CDPOLL, "s68k poll detected @%06x, a=%02x",\r
08769494 297 SekPcS68k, a);\r
c36dbc1d 298 } else if (cnt > 2)\r
178a9b68 299 SekEndRunS68k(240);\r
2433f409 300 }\r
301 }\r
08769494 302 Pico_mcd->m.s68k_poll_a = a;\r
303 Pico_mcd->m.s68k_poll_clk = cycles;\r
304 Pico_mcd->m.s68k_poll_cnt = cnt;\r
ecc8036e 305 SekNotPollingS68k = 0;\r
2433f409 306#endif\r
307 return d;\r
308}\r
cc68a136 309\r
913ef4b7 310#define READ_FONT_DATA(basemask) \\r
311{ \\r
0d8d97f8 312 unsigned int fnt = CPU_LE4(*(u32 *)(Pico_mcd->s68k_regs + 0x4c)); \\r
913ef4b7 313 unsigned int col0 = (fnt >> 8) & 0x0f, col1 = (fnt >> 12) & 0x0f; \\r
314 if (fnt & (basemask << 0)) d = col1 ; else d = col0; \\r
315 if (fnt & (basemask << 1)) d |= col1 << 4; else d |= col0 << 4; \\r
316 if (fnt & (basemask << 2)) d |= col1 << 8; else d |= col0 << 8; \\r
317 if (fnt & (basemask << 3)) d |= col1 << 12; else d |= col0 << 12; \\r
318}\r
319\r
cc68a136 320\r
4ff2d527 321#ifndef _ASM_CD_MEMORY_C\r
322static\r
323#endif\r
324u32 s68k_reg_read16(u32 a)\r
cc68a136 325{\r
326 u32 d=0;\r
cc68a136 327\r
cc68a136 328 switch (a) {\r
329 case 0:\r
178a9b68 330 d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
331 goto end;\r
672ad671 332 case 2:\r
2433f409 333 d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);\r
af37bca8 334 elprintf(EL_CDREG3, "s68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
178a9b68 335 s68k_poll_detect(a, d);\r
336 goto end;\r
337 case 4:\r
338 d = (Pico_mcd->s68k_regs[4]<<8) | (Pico_mcd->s68k_regs[5]&0x1f);\r
339 goto end;\r
cc68a136 340 case 6:\r
178a9b68 341 d = cdc_reg_r();\r
342 goto end;\r
cc68a136 343 case 8:\r
dd7c8c05 344 d = cdc_host_r(1);\r
178a9b68 345 goto end;\r
f27a1749 346 case 0xc:\r
347 d = pcd_stopwatch_read(1);\r
af37bca8 348 elprintf(EL_CDREGS, "s68k stopwatch timer read (%04x)", d);\r
178a9b68 349 goto end;\r
d1df8786 350 case 0x30:\r
178a9b68 351 elprintf(EL_CDREGS, "s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[0x31]);\r
352 d = Pico_mcd->s68k_regs[0x31];\r
353 goto end;\r
cc68a136 354 case 0x34: // fader\r
178a9b68 355 d = 0; // no busy bit\r
356 goto end;\r
913ef4b7 357 case 0x50: // font data (check: Lunar 2, Silpheed)\r
358 READ_FONT_DATA(0x00100000);\r
178a9b68 359 goto end;\r
913ef4b7 360 case 0x52:\r
361 READ_FONT_DATA(0x00010000);\r
178a9b68 362 goto end;\r
913ef4b7 363 case 0x54:\r
364 READ_FONT_DATA(0x10000000);\r
178a9b68 365 goto end;\r
913ef4b7 366 case 0x56:\r
367 READ_FONT_DATA(0x01000000);\r
178a9b68 368 goto end;\r
cc68a136 369 }\r
370\r
371 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
372\r
4985bad0 373 if ((a >= 0x0e && a < 0x30) || a == 0x58)\r
374 d = s68k_poll_detect(a, d);\r
7a1f6e45 375\r
178a9b68 376end:\r
cc68a136 377 return d;\r
378}\r
379\r
4ff2d527 380#ifndef _ASM_CD_MEMORY_C\r
381static\r
382#endif\r
383void s68k_reg_write8(u32 a, u32 d)\r
cc68a136 384{\r
48e8482f 385 // Warning: d might have upper bits set\r
cc68a136 386 switch (a) {\r
d0132772 387 case 1:\r
388 if (!(d & 1))\r
389 pcd_soft_reset();\r
390 return;\r
178a9b68 391 case 2: a++; // byte access only, ignores LDS/UDS\r
fa1e5e29 392 case 3: {\r
393 int dold = Pico_mcd->s68k_regs[3];\r
af37bca8 394 elprintf(EL_CDREG3, "s68k_regs w3: %02x @%06x", (u8)d, SekPcS68k);\r
672ad671 395 d &= 0x1d;\r
af37bca8 396 d |= dold & 0xc2;\r
ba6e8bfd 397\r
398 // 2M mode state\r
399 if (d & 1) {\r
400 Pico_mcd->m.dmna_ret_2m |= 1;\r
401 Pico_mcd->m.dmna_ret_2m &= ~2; // DMNA clears\r
402 }\r
403\r
af37bca8 404 if (d & 4)\r
39230401 405 {\r
fa1e5e29 406 if (!(dold & 4)) {\r
af37bca8 407 elprintf(EL_CDREG3, "wram mode 2M->1M");\r
fa1e5e29 408 wram_2M_to_1M(Pico_mcd->word_ram2M);\r
4ff2d527 409 }\r
ba6e8bfd 410\r
ba6e8bfd 411 if ((d ^ dold) & 0x05)\r
412 d &= ~2; // clear DMNA - swap complete\r
39230401 413 }\r
414 else\r
415 {\r
fa1e5e29 416 if (dold & 4) {\r
af37bca8 417 elprintf(EL_CDREG3, "wram mode 1M->2M");\r
fa1e5e29 418 wram_1M_to_2M(Pico_mcd->word_ram2M);\r
4ff2d527 419 }\r
ba6e8bfd 420 d = (d & ~3) | Pico_mcd->m.dmna_ret_2m;\r
d0d47c5b 421 }\r
8eeb3426 422 if ((dold ^ d) & 0x1f)\r
423 remap_word_ram(d);\r
08769494 424 goto write_comm;\r
fa1e5e29 425 }\r
cc68a136 426 case 4:\r
af37bca8 427 elprintf(EL_CDREGS, "s68k CDC dest: %x", d&7);\r
178a9b68 428 Pico_mcd->s68k_regs[a] = (d&7); // CDC mode\r
429 Pico_mcd->s68k_regs[0xa] = Pico_mcd->s68k_regs[0xb] = 0; // resets DMA\r
cc68a136 430 return;\r
431 case 5:\r
178a9b68 432 //dprintf("s68k CDC reg addr: %x", d&0x1f);\r
433 Pico_mcd->s68k_regs[a] = (d&0x1f);\r
434 return;\r
cc68a136 435 case 7:\r
f47d0a28 436 cdc_reg_w(d & 0xff);\r
cc68a136 437 return;\r
438 case 0xa:\r
178a9b68 439 case 0xb:\r
440 // word access only. 68k sets both bus halves to value d.\r
af37bca8 441 elprintf(EL_CDREGS, "s68k set CDC dma addr");\r
178a9b68 442 Pico_mcd->s68k_regs[0xa] = Pico_mcd->s68k_regs[0xb] = d;\r
443 return;\r
d1df8786 444 case 0xc:\r
ae214f1c 445 case 0xd: // 384 cycle stopwatch timer\r
446 elprintf(EL_CDREGS|EL_CD, "s68k clear stopwatch (%x)", d);\r
447 // does this also reset internal 384 cycle counter?\r
448 Pico_mcd->m.stopwatch_base_c = SekCyclesDoneS68k();\r
4f265db7 449 return;\r
178a9b68 450 case 0x0e: a++;\r
08769494 451 case 0x0f:\r
452 goto write_comm;\r
178a9b68 453 case 0x30: a++;\r
ae214f1c 454 case 0x31: // 384 cycle int3 timer\r
455 d &= 0xff;\r
456 elprintf(EL_CDREGS|EL_CD, "s68k set int3 timer: %02x", d);\r
457 Pico_mcd->s68k_regs[a] = (u8) d;\r
178a9b68 458 if (d) // XXX: d or d+1? mcd-verificator results suggest d+1\r
459 pcd_event_schedule_s68k(PCD_EVENT_TIMER3, (d+1) * 384);\r
ae214f1c 460 else\r
461 pcd_event_schedule(0, PCD_EVENT_TIMER3, 0);\r
d1df8786 462 break;\r
cc68a136 463 case 0x33: // IRQ mask\r
ae214f1c 464 elprintf(EL_CDREGS|EL_CD, "s68k irq mask: %02x", d);\r
465 d &= 0x7e;\r
691abdfa 466 if ((d ^ Pico_mcd->s68k_regs[0x33]) & PCDS_IEN4) {\r
274fcc35 467 // XXX: emulate pending irq instead?\r
691abdfa 468 if ((d & PCDS_IEN4) && (Pico_mcd->s68k_regs[0x37] & 4)) {\r
274fcc35 469 elprintf(EL_INTS, "cdd export irq 4 (unmask)");\r
eb36d9c7 470 pcd_irq_s68k(4, 1);\r
274fcc35 471 }\r
cc68a136 472 }\r
178a9b68 473 if ((d ^ Pico_mcd->s68k_regs[0x33]) & ~d & PCDS_IEN2)\r
474 pcd_irq_s68k(2, 0);\r
cc68a136 475 break;\r
476 case 0x34: // fader\r
477 Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
478 return;\r
672ad671 479 case 0x36:\r
480 return; // d/m bit is unsetable\r
481 case 0x37: {\r
482 u32 d_old = Pico_mcd->s68k_regs[0x37];\r
274fcc35 483 Pico_mcd->s68k_regs[0x37] = d & 7;\r
691abdfa 484 if ((d ^ d_old) & 4) {\r
691abdfa 485 if ((d & 4) && (Pico_mcd->s68k_regs[0x33] & PCDS_IEN4)) {\r
274fcc35 486 elprintf(EL_INTS, "cdd export irq 4");\r
eb36d9c7 487 pcd_irq_s68k(4, 1);\r
274fcc35 488 }\r
cc68a136 489 }\r
672ad671 490 return;\r
491 }\r
cc68a136 492 case 0x4b:\r
7b3ddc11 493 Pico_mcd->s68k_regs[a] = 0; // (u8) d; ?\r
274fcc35 494 cdd_process();\r
7b3ddc11 495 {\r
496 static const char *nm[] =\r
497 { "stat", "stop", "read_toc", "play",\r
498 "seek", "???", "pause", "resume",\r
499 "ff", "fr", "tjump", "???",\r
500 "close","open", "???", "???" };\r
501 u8 *c = &Pico_mcd->s68k_regs[0x42];\r
502 u8 *s = &Pico_mcd->s68k_regs[0x38];\r
503 elprintf(EL_CD,\r
504 "CDD command: %02x %02x %02x %02x %02x %02x %02x %02x %12s",\r
505 c[0], c[1], c[2], c[3], c[4], c[5], c[6], c[7], nm[c[0] & 0x0f]);\r
506 elprintf(EL_CD,\r
507 "CDD status: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",\r
508 s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);\r
509 }\r
cc68a136 510 return;\r
178a9b68 511 case 0x4c: a++;\r
512 break;\r
a93a80de 513 case 0x58:\r
514 return;\r
cc68a136 515 }\r
516\r
08769494 517 if ((a&0x1f0) == 0x20)\r
518 goto write_comm;\r
519\r
1cd356a3 520 if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
cc68a136 521 {\r
ca61ee42 522 elprintf(EL_UIO, "s68k FIXME: invalid write @ %02x?", a);\r
cc68a136 523 return;\r
524 }\r
525\r
08769494 526 Pico_mcd->s68k_regs[a] = (u8) d;\r
527 return;\r
bc3c13d3 528\r
08769494 529write_comm:\r
b074a2b5 530 if (Pico_mcd->s68k_regs[a] == (u8)d)\r
531 return;\r
532\r
cc68a136 533 Pico_mcd->s68k_regs[a] = (u8) d;\r
4a55f64a 534 if (!((Pico_mcd->m.m68k_poll_a ^ a) & ~1)) {\r
02db2308 535 SekEndRunS68k(8);\r
8eeb3426 536 Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;\r
537 Pico_mcd->m.m68k_poll_cnt = 0;\r
538 }\r
cc68a136 539}\r
540\r
a93a80de 541void s68k_reg_write16(u32 a, u32 d)\r
542{\r
543 u8 *r = Pico_mcd->s68k_regs;\r
544\r
8eeb3426 545 Pico_mcd->m.state_flags &= ~PCD_ST_S68K_POLL;\r
fbebab69 546 Pico_mcd->m.s68k_poll_cnt = 0;\r
547\r
a93a80de 548 if ((a & 0x1f0) == 0x20)\r
549 goto write_comm;\r
550\r
551 switch (a) {\r
178a9b68 552 case 0x02:\r
a93a80de 553 case 0x0e:\r
178a9b68 554 case 0x30:\r
555 case 0x4c:\r
556 // these are only byte registers, LDS/UDS ignored\r
557 return s68k_reg_write8(a + 1, d);\r
558 case 0x08:\r
dd7c8c05 559 return (void) cdc_host_r(1); // acts same as reading\r
178a9b68 560 case 0x0a: // DMA address\r
561 r[0xa] = d >> 8;\r
562 r[0xb] = d;\r
563 return;\r
a93a80de 564 case 0x58: // stamp data size\r
565 r[0x59] = d & 7;\r
566 return;\r
567 case 0x5a: // stamp map base address\r
568 r[0x5a] = d >> 8;\r
569 r[0x5b] = d & 0xe0;\r
570 return;\r
571 case 0x5c: // V cell size\r
572 r[0x5d] = d & 0x1f;\r
573 return;\r
574 case 0x5e: // image buffer start address\r
575 r[0x5e] = d >> 8;\r
576 r[0x5f] = d & 0xf8;\r
577 return;\r
578 case 0x60: // image buffer offset\r
579 r[0x61] = d & 0x3f;\r
580 return;\r
581 case 0x62: // h dot size\r
582 r[0x62] = (d >> 8) & 1;\r
583 r[0x63] = d;\r
584 return;\r
585 case 0x64: // v dot size\r
586 r[0x65] = d;\r
587 return;\r
588 case 0x66: // trace vector base address\r
589 d &= 0xfffe;\r
590 r[0x66] = d >> 8;\r
591 r[0x67] = d;\r
592 gfx_start(d);\r
593 return;\r
594 default:\r
595 break;\r
596 }\r
597\r
598 s68k_reg_write8(a, d >> 8);\r
599 s68k_reg_write8(a + 1, d & 0xff);\r
600 return;\r
601\r
602write_comm:\r
b074a2b5 603 if (r[a] == (u8)(d >> 8) && r[a + 1] == (u8)d)\r
604 return;\r
605\r
a93a80de 606 r[a] = d >> 8;\r
607 r[a + 1] = d;\r
4a55f64a 608 if (!((Pico_mcd->m.m68k_poll_a ^ a) & ~1)) {\r
02db2308 609 SekEndRunS68k(8);\r
8eeb3426 610 Pico_mcd->m.state_flags &= ~PCD_ST_M68K_POLL;\r
611 Pico_mcd->m.m68k_poll_cnt = 0;\r
612 }\r
a93a80de 613}\r
614\r
af37bca8 615// -----------------------------------------------------------------\r
616// Main 68k\r
617// -----------------------------------------------------------------\r
cc68a136 618\r
af37bca8 619#ifndef _ASM_CD_MEMORY_C\r
620#include "cell_map.c"\r
af37bca8 621\r
622// WORD RAM, cell aranged area (220000 - 23ffff)\r
0ace9b9a 623static u32 PicoReadM68k8_cell0(u32 a)\r
cc68a136 624{\r
af37bca8 625 a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
57c5a5e5 626 return Pico_mcd->word_ram1M[0][MEM_BE2(a)];\r
0ace9b9a 627}\r
628\r
629static u32 PicoReadM68k8_cell1(u32 a)\r
630{\r
631 a = (a&3) | (cell_map(a >> 2) << 2);\r
57c5a5e5 632 return Pico_mcd->word_ram1M[1][MEM_BE2(a)];\r
0ace9b9a 633}\r
634\r
635static u32 PicoReadM68k16_cell0(u32 a)\r
636{\r
637 a = (a&2) | (cell_map(a >> 2) << 2);\r
638 return *(u16 *)(Pico_mcd->word_ram1M[0] + a);\r
af37bca8 639}\r
cc68a136 640\r
0ace9b9a 641static u32 PicoReadM68k16_cell1(u32 a)\r
af37bca8 642{\r
af37bca8 643 a = (a&2) | (cell_map(a >> 2) << 2);\r
0ace9b9a 644 return *(u16 *)(Pico_mcd->word_ram1M[1] + a);\r
af37bca8 645}\r
cc68a136 646\r
0ace9b9a 647static void PicoWriteM68k8_cell0(u32 a, u32 d)\r
af37bca8 648{\r
af37bca8 649 a = (a&3) | (cell_map(a >> 2) << 2);\r
57c5a5e5 650 Pico_mcd->word_ram1M[0][MEM_BE2(a)] = d;\r
af37bca8 651}\r
8022f53d 652\r
0ace9b9a 653static void PicoWriteM68k8_cell1(u32 a, u32 d)\r
af37bca8 654{\r
af37bca8 655 a = (a&3) | (cell_map(a >> 2) << 2);\r
57c5a5e5 656 Pico_mcd->word_ram1M[1][MEM_BE2(a)] = d;\r
af37bca8 657}\r
658\r
0ace9b9a 659static void PicoWriteM68k16_cell0(u32 a, u32 d)\r
660{\r
661 a = (a&3) | (cell_map(a >> 2) << 2);\r
662 *(u16 *)(Pico_mcd->word_ram1M[0] + a) = d;\r
663}\r
664\r
665static void PicoWriteM68k16_cell1(u32 a, u32 d)\r
666{\r
667 a = (a&3) | (cell_map(a >> 2) << 2);\r
668 *(u16 *)(Pico_mcd->word_ram1M[1] + a) = d;\r
669}\r
670#endif\r
671\r
02ff0254 672// RAM cart (400000 - 7fffff, optional)\r
af37bca8 673static u32 PicoReadM68k8_ramc(u32 a)\r
674{\r
675 u32 d = 0;\r
8022f53d 676\r
ed5b27c9 677 if (Pico.romsize == 0 && (PicoIn.opt & POPT_EN_MCD_RAMCART)) {\r
411b2c19 678 if ((a & 0xf00001) == 0x400001) {\r
679 if (Pico.sv.data != NULL)\r
680 d = 3; // 64k cart\r
681 return d;\r
682 }\r
683\r
684 if ((a & 0xf00001) == 0x600001) {\r
685 if (Pico.sv.data != NULL)\r
686 d = Pico.sv.data[((a >> 1) & 0xffff) + 0x2000];\r
687 return d;\r
688 }\r
8022f53d 689\r
411b2c19 690 if ((a & 0xf00001) == 0x700001)\r
691 return Pico_mcd->m.bcram_reg;\r
692 }\r
cc68a136 693\r
af37bca8 694 elprintf(EL_UIO, "m68k unmapped r8 [%06x] @%06x", a, SekPc);\r
cc68a136 695 return d;\r
696}\r
697\r
af37bca8 698static u32 PicoReadM68k16_ramc(u32 a)\r
cc68a136 699{\r
411b2c19 700 elprintf(EL_ANOMALY, "ramcart r16: [%06x] @%06x", a, SekPc);\r
af37bca8 701 return PicoReadM68k8_ramc(a + 1);\r
702}\r
cc68a136 703\r
af37bca8 704static void PicoWriteM68k8_ramc(u32 a, u32 d)\r
705{\r
ed5b27c9 706 if (Pico.romsize == 0 && (PicoIn.opt & POPT_EN_MCD_RAMCART)) {\r
411b2c19 707 if ((a & 0xf00001) == 0x600001) {\r
708 if (Pico.sv.data != NULL && (Pico_mcd->m.bcram_reg & 1)) {\r
709 Pico.sv.data[((a >> 1) & 0xffff) + 0x2000] = d;\r
710 Pico.sv.changed = 1;\r
711 }\r
712 return;\r
8022f53d 713 }\r
8022f53d 714\r
411b2c19 715 if ((a & 0xf00001) == 0x700001) {\r
716 Pico_mcd->m.bcram_reg = d;\r
717 return;\r
718 }\r
8022f53d 719 }\r
720\r
c7fd7bb8 721 elprintf(EL_UIO, "m68k unmapped w8 [%06x] %02x @%06x",\r
722 a, d & 0xff, SekPc);\r
cc68a136 723}\r
724\r
af37bca8 725static void PicoWriteM68k16_ramc(u32 a, u32 d)\r
cc68a136 726{\r
c7fd7bb8 727 elprintf(EL_ANOMALY, "ramcart w16: [%06x] %04x @%06x",\r
728 a, d, SekPcS68k);\r
af37bca8 729 PicoWriteM68k8_ramc(a + 1, d);\r
cc68a136 730}\r
731\r
af37bca8 732// IO/control/cd registers (a10000 - ...)\r
0ace9b9a 733#ifndef _ASM_CD_MEMORY_C\r
fa8fb754 734u32 PicoRead8_mcd_io(u32 a)\r
cc68a136 735{\r
af37bca8 736 u32 d;\r
737 if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
738 d = m68k_reg_read16(a); // TODO: m68k_reg_read8\r
739 if (!(a & 1))\r
740 d >>= 8;\r
741 d &= 0xff;\r
c7fd7bb8 742 elprintf(EL_CDREGS, "m68k_regs r8: [%02x] %02x @%06x",\r
743 a & 0x3f, d, SekPc);\r
af37bca8 744 return d;\r
745 }\r
746\r
747 // fallback to default MD handler\r
748 return PicoRead8_io(a);\r
cc68a136 749}\r
750\r
fa8fb754 751u32 PicoRead16_mcd_io(u32 a)\r
cc68a136 752{\r
af37bca8 753 u32 d;\r
754 if ((a & 0xff00) == 0x2000) {\r
755 d = m68k_reg_read16(a);\r
c7fd7bb8 756 elprintf(EL_CDREGS, "m68k_regs r16: [%02x] %04x @%06x",\r
757 a & 0x3f, d, SekPc);\r
af37bca8 758 return d;\r
b542be46 759 }\r
cc68a136 760\r
af37bca8 761 return PicoRead16_io(a);\r
cc68a136 762}\r
763\r
fa8fb754 764void PicoWrite8_mcd_io(u32 a, u32 d)\r
cc68a136 765{\r
af37bca8 766 if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
c7fd7bb8 767 elprintf(EL_CDREGS, "m68k_regs w8: [%02x] %02x @%06x",\r
768 a & 0x3f, d, SekPc);\r
2433f409 769 m68k_reg_write8(a, d);\r
770 return;\r
771 }\r
672ad671 772\r
dd7882a3 773 if (carthw_ssf2_active)\r
5521edad 774 carthw_ssf2_write8(a, d); // for MSU/MD+\r
775 else\r
776 PicoWrite8_io(a, d);\r
cc68a136 777}\r
ab0607f7 778\r
fa8fb754 779void PicoWrite16_mcd_io(u32 a, u32 d)\r
cc68a136 780{\r
af37bca8 781 if ((a & 0xff00) == 0x2000) { // a12000 - a120ff\r
c7fd7bb8 782 elprintf(EL_CDREGS, "m68k_regs w16: [%02x] %04x @%06x",\r
783 a & 0x3f, d, SekPc);\r
08769494 784\r
334d9fb6 785 m68k_reg_write8(a, d >> 8);\r
08769494 786 if ((a & 0x3e) != 0x0e) // special case\r
787 m68k_reg_write8(a + 1, d & 0xff);\r
b542be46 788 return;\r
789 }\r
790\r
dd7882a3 791 if (carthw_ssf2_active)\r
5521edad 792 carthw_ssf2_write16(a, d); // for MSU/MD+\r
793 else\r
794 PicoWrite16_io(a, d);\r
cc68a136 795}\r
0ace9b9a 796#endif\r
cc68a136 797\r
721cd396 798// -----------------------------------------------------------------\r
af37bca8 799// Sub 68k\r
cc68a136 800// -----------------------------------------------------------------\r
801\r
af37bca8 802static u32 s68k_unmapped_read8(u32 a)\r
cc68a136 803{\r
af37bca8 804 elprintf(EL_UIO, "s68k unmapped r8 [%06x] @%06x", a, SekPc);\r
805 return 0;\r
cc68a136 806}\r
807\r
af37bca8 808static u32 s68k_unmapped_read16(u32 a)\r
cc68a136 809{\r
af37bca8 810 elprintf(EL_UIO, "s68k unmapped r16 [%06x] @%06x", a, SekPc);\r
811 return 0;\r
812}\r
4f265db7 813\r
af37bca8 814static void s68k_unmapped_write8(u32 a, u32 d)\r
815{\r
c7fd7bb8 816 elprintf(EL_UIO, "s68k unmapped w8 [%06x] %02x @%06x",\r
817 a, d & 0xff, SekPc);\r
af37bca8 818}\r
cc68a136 819\r
af37bca8 820static void s68k_unmapped_write16(u32 a, u32 d)\r
821{\r
c7fd7bb8 822 elprintf(EL_UIO, "s68k unmapped w16 [%06x] %04x @%06x",\r
823 a, d & 0xffff, SekPc);\r
af37bca8 824}\r
cc68a136 825\r
59991f11 826// PRG RAM protected range (000000 - 01fdff)?\r
0ace9b9a 827// XXX verify: ff00 or 1fe00 max?\r
828static void PicoWriteS68k8_prgwp(u32 a, u32 d)\r
829{\r
59991f11 830 if (a >= (Pico_mcd->s68k_regs[2] << 9))\r
57c5a5e5 831 Pico_mcd->prg_ram[MEM_BE2(a)] = d;\r
0ace9b9a 832}\r
833\r
834static void PicoWriteS68k16_prgwp(u32 a, u32 d)\r
835{\r
59991f11 836 if (a >= (Pico_mcd->s68k_regs[2] << 9))\r
0ace9b9a 837 *(u16 *)(Pico_mcd->prg_ram + a) = d;\r
838}\r
839\r
840#ifndef _ASM_CD_MEMORY_C\r
841\r
af37bca8 842// decode (080000 - 0bffff, in 1M mode)\r
0ace9b9a 843static u32 PicoReadS68k8_dec0(u32 a)\r
844{\r
57c5a5e5 845 u32 d = Pico_mcd->word_ram1M[0][MEM_BE2(a >> 1) & 0x1ffff];\r
0ace9b9a 846 if (a & 1)\r
847 d &= 0x0f;\r
848 else\r
849 d >>= 4;\r
850 return d;\r
851}\r
852\r
853static u32 PicoReadS68k8_dec1(u32 a)\r
af37bca8 854{\r
57c5a5e5 855 u32 d = Pico_mcd->word_ram1M[1][MEM_BE2(a >> 1) & 0x1ffff];\r
af37bca8 856 if (a & 1)\r
857 d &= 0x0f;\r
858 else\r
859 d >>= 4;\r
cc68a136 860 return d;\r
861}\r
862\r
0ace9b9a 863static u32 PicoReadS68k16_dec0(u32 a)\r
cc68a136 864{\r
57c5a5e5 865 u32 d = Pico_mcd->word_ram1M[0][MEM_BE2(a >> 1) & 0x1ffff];\r
af37bca8 866 d |= d << 4;\r
867 d &= ~0xf0;\r
cc68a136 868 return d;\r
869}\r
ab0607f7 870\r
0ace9b9a 871static u32 PicoReadS68k16_dec1(u32 a)\r
0a051f55 872{\r
57c5a5e5 873 u32 d = Pico_mcd->word_ram1M[1][MEM_BE2(a >> 1) & 0x1ffff];\r
0ace9b9a 874 d |= d << 4;\r
875 d &= ~0xf0;\r
876 return d;\r
0a051f55 877}\r
878\r
0ace9b9a 879/* check: jaguar xj 220 (draws entire world using decode) */\r
880#define mk_decode_w8(bank) \\r
881static void PicoWriteS68k8_dec_m0b##bank(u32 a, u32 d) \\r
882{ \\r
57c5a5e5 883 u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
0ace9b9a 884 \\r
885 if (!(a & 1)) \\r
886 *pd = (*pd & 0x0f) | (d << 4); \\r
887 else \\r
888 *pd = (*pd & 0xf0) | (d & 0x0f); \\r
889} \\r
890 \\r
891static void PicoWriteS68k8_dec_m1b##bank(u32 a, u32 d) \\r
892{ \\r
57c5a5e5 893 u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
0ace9b9a 894 u8 mask = (a & 1) ? 0x0f : 0xf0; \\r
895 \\r
896 if (!(*pd & mask) && (d & 0x0f)) /* underwrite */ \\r
897 PicoWriteS68k8_dec_m0b##bank(a, d); \\r
898} \\r
899 \\r
900static void PicoWriteS68k8_dec_m2b##bank(u32 a, u32 d) /* ...and m3? */ \\r
901{ \\r
902 if (d & 0x0f) /* overwrite */ \\r
903 PicoWriteS68k8_dec_m0b##bank(a, d); \\r
904}\r
0a051f55 905\r
0ace9b9a 906mk_decode_w8(0)\r
907mk_decode_w8(1)\r
908\r
909#define mk_decode_w16(bank) \\r
910static void PicoWriteS68k16_dec_m0b##bank(u32 a, u32 d) \\r
911{ \\r
57c5a5e5 912 u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
0ace9b9a 913 \\r
914 d &= 0x0f0f; \\r
915 *pd = d | (d >> 4); \\r
916} \\r
917 \\r
918static void PicoWriteS68k16_dec_m1b##bank(u32 a, u32 d) \\r
919{ \\r
57c5a5e5 920 u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
0ace9b9a 921 \\r
922 d &= 0x0f0f; /* underwrite */ \\r
923 if (!(*pd & 0xf0)) *pd |= d >> 4; \\r
924 if (!(*pd & 0x0f)) *pd |= d; \\r
925} \\r
926 \\r
927static void PicoWriteS68k16_dec_m2b##bank(u32 a, u32 d) \\r
928{ \\r
57c5a5e5 929 u8 *pd = &Pico_mcd->word_ram1M[bank][MEM_BE2(a >> 1) & 0x1ffff];\\r
0ace9b9a 930 \\r
931 d &= 0x0f0f; /* overwrite */ \\r
932 d |= d >> 4; \\r
933 \\r
934 if (!(d & 0xf0)) d |= *pd & 0xf0; \\r
935 if (!(d & 0x0f)) d |= *pd & 0x0f; \\r
936 *pd = d; \\r
937}\r
0a051f55 938\r
0ace9b9a 939mk_decode_w16(0)\r
940mk_decode_w16(1)\r
0a051f55 941\r
0ace9b9a 942#endif\r
0a051f55 943\r
af37bca8 944// backup RAM (fe0000 - feffff)\r
945static u32 PicoReadS68k8_bram(u32 a)\r
946{\r
947 return Pico_mcd->bram[(a>>1)&0x1fff];\r
948}\r
cc68a136 949\r
af37bca8 950static u32 PicoReadS68k16_bram(u32 a)\r
cc68a136 951{\r
af37bca8 952 u32 d;\r
953 elprintf(EL_ANOMALY, "FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
954 a = (a >> 1) & 0x1fff;\r
178a9b68 955 d = Pico_mcd->bram[a];\r
af37bca8 956 return d;\r
957}\r
cc68a136 958\r
af37bca8 959static void PicoWriteS68k8_bram(u32 a, u32 d)\r
960{\r
178a9b68 961 if (a & 1) {\r
962 Pico_mcd->bram[(a >> 1) & 0x1fff] = d;\r
963 Pico.sv.changed = 1;\r
964 }\r
af37bca8 965}\r
cc68a136 966\r
af37bca8 967static void PicoWriteS68k16_bram(u32 a, u32 d)\r
968{\r
969 elprintf(EL_ANOMALY, "s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
970 a = (a >> 1) & 0x1fff;\r
971 Pico_mcd->bram[a++] = d;\r
88fd63ad 972 Pico.sv.changed = 1;\r
af37bca8 973}\r
b5e5172d 974\r
0ace9b9a 975#ifndef _ASM_CD_MEMORY_C\r
976\r
af37bca8 977// PCM and registers (ff0000 - ffffff)\r
978static u32 PicoReadS68k8_pr(u32 a)\r
979{\r
980 u32 d = 0;\r
cc68a136 981\r
982 // regs\r
af37bca8 983 if ((a & 0xfe00) == 0x8000) {\r
cb4a513a 984 a &= 0x1ff;\r
af37bca8 985 if (a >= 0x0e && a < 0x30) {\r
986 d = Pico_mcd->s68k_regs[a];\r
4985bad0 987 d = s68k_poll_detect(a & ~1, d);\r
ba6e8bfd 988 goto regs_done;\r
d0d47c5b 989 }\r
a93a80de 990 d = s68k_reg_read16(a & ~1);\r
af37bca8 991 if (!(a & 1))\r
992 d >>= 8;\r
ba6e8bfd 993\r
994regs_done:\r
995 d &= 0xff;\r
cc5ffc3c 996 elprintf(EL_CDREGS, "s68k_regs r8: [%02x] %02x @%06x",\r
ba6e8bfd 997 a, d, SekPcS68k);\r
998 return d;\r
d0d47c5b 999 }\r
1000\r
4f265db7 1001 // PCM\r
0ace9b9a 1002 // XXX: verify: probably odd addrs only?\r
af37bca8 1003 if ((a & 0x8000) == 0x0000) {\r
4f265db7 1004 a &= 0x7fff;\r
1005 if (a >= 0x2000)\r
af37bca8 1006 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a >> 1) & 0xfff];\r
33be04ca 1007 else if (a >= 0x20)\r
1008 d = pcd_pcm_read(a >> 1);\r
1009\r
1010 return d;\r
ab0607f7 1011 }\r
1012\r
af37bca8 1013 return s68k_unmapped_read8(a);\r
cc68a136 1014}\r
1015\r
af37bca8 1016static u32 PicoReadS68k16_pr(u32 a)\r
cc68a136 1017{\r
af37bca8 1018 u32 d = 0;\r
cc68a136 1019\r
1020 // regs\r
af37bca8 1021 if ((a & 0xfe00) == 0x8000) {\r
cb4a513a 1022 a &= 0x1fe;\r
a93a80de 1023 d = s68k_reg_read16(a);\r
ba6e8bfd 1024\r
cc5ffc3c 1025 elprintf(EL_CDREGS, "s68k_regs r16: [%02x] %04x @%06x",\r
ba6e8bfd 1026 a, d, SekPcS68k);\r
af37bca8 1027 return d;\r
cc68a136 1028 }\r
1029\r
af37bca8 1030 // PCM\r
1031 if ((a & 0x8000) == 0x0000) {\r
af37bca8 1032 a &= 0x7fff;\r
1033 if (a >= 0x2000)\r
33be04ca 1034 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a >> 1) & 0xfff];\r
1035 else if (a >= 0x20)\r
1036 d = pcd_pcm_read(a >> 1);\r
1037\r
af37bca8 1038 return d;\r
d0d47c5b 1039 }\r
1040\r
af37bca8 1041 return s68k_unmapped_read16(a);\r
1042}\r
1043\r
1044static void PicoWriteS68k8_pr(u32 a, u32 d)\r
1045{\r
1046 // regs\r
1047 if ((a & 0xfe00) == 0x8000) {\r
1048 a &= 0x1ff;\r
cc5ffc3c 1049 elprintf(EL_CDREGS, "s68k_regs w8: [%02x] %02x @%06x", a, d, SekPcS68k);\r
a93a80de 1050 if (0x59 <= a && a < 0x68) // word regs\r
1051 s68k_reg_write16(a & ~1, (d << 8) | d);\r
1052 else\r
1053 s68k_reg_write8(a, d);\r
d0d47c5b 1054 return;\r
1055 }\r
1056\r
4f265db7 1057 // PCM\r
af37bca8 1058 if ((a & 0x8000) == 0x0000) {\r
4f265db7 1059 a &= 0x7fff;\r
1060 if (a >= 0x2000)\r
1061 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
1062 else if (a < 0x12)\r
33be04ca 1063 pcd_pcm_write(a>>1, d);\r
ab0607f7 1064 return;\r
1065 }\r
1066\r
af37bca8 1067 s68k_unmapped_write8(a, d);\r
cc68a136 1068}\r
ab0607f7 1069\r
af37bca8 1070static void PicoWriteS68k16_pr(u32 a, u32 d)\r
cc68a136 1071{\r
cc68a136 1072 // regs\r
af37bca8 1073 if ((a & 0xfe00) == 0x8000) {\r
cb4a513a 1074 a &= 0x1fe;\r
cc5ffc3c 1075 elprintf(EL_CDREGS, "s68k_regs w16: [%02x] %04x @%06x", a, d, SekPcS68k);\r
a93a80de 1076 s68k_reg_write16(a, d);\r
d0d47c5b 1077 return;\r
1078 }\r
1079\r
4f265db7 1080 // PCM\r
af37bca8 1081 if ((a & 0x8000) == 0x0000) {\r
4f265db7 1082 a &= 0x7fff;\r
af37bca8 1083 if (a >= 0x2000)\r
1084 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
1085 else if (a < 0x12)\r
33be04ca 1086 pcd_pcm_write(a>>1, d & 0xff);\r
ab0607f7 1087 return;\r
1088 }\r
1089\r
af37bca8 1090 s68k_unmapped_write16(a, d);\r
cc68a136 1091}\r
cc68a136 1092\r
0ace9b9a 1093#endif\r
1094\r
1095static const void *m68k_cell_read8[] = { PicoReadM68k8_cell0, PicoReadM68k8_cell1 };\r
1096static const void *m68k_cell_read16[] = { PicoReadM68k16_cell0, PicoReadM68k16_cell1 };\r
1097static const void *m68k_cell_write8[] = { PicoWriteM68k8_cell0, PicoWriteM68k8_cell1 };\r
1098static const void *m68k_cell_write16[] = { PicoWriteM68k16_cell0, PicoWriteM68k16_cell1 };\r
1099\r
1100static const void *s68k_dec_read8[] = { PicoReadS68k8_dec0, PicoReadS68k8_dec1 };\r
1101static const void *s68k_dec_read16[] = { PicoReadS68k16_dec0, PicoReadS68k16_dec1 };\r
1102\r
1103static const void *s68k_dec_write8[2][4] = {\r
1104 { PicoWriteS68k8_dec_m0b0, PicoWriteS68k8_dec_m1b0, PicoWriteS68k8_dec_m2b0, PicoWriteS68k8_dec_m2b0 },\r
1105 { PicoWriteS68k8_dec_m0b1, PicoWriteS68k8_dec_m1b1, PicoWriteS68k8_dec_m2b1, PicoWriteS68k8_dec_m2b1 },\r
1106};\r
1107\r
1108static const void *s68k_dec_write16[2][4] = {\r
1109 { PicoWriteS68k16_dec_m0b0, PicoWriteS68k16_dec_m1b0, PicoWriteS68k16_dec_m2b0, PicoWriteS68k16_dec_m2b0 },\r
1110 { PicoWriteS68k16_dec_m0b1, PicoWriteS68k16_dec_m1b1, PicoWriteS68k16_dec_m2b1, PicoWriteS68k16_dec_m2b1 },\r
1111};\r
1112\r
cc68a136 1113// -----------------------------------------------------------------\r
1114\r
4fb43555 1115static void remap_prg_window(u32 r1, u32 r3)\r
3aa1e148 1116{\r
02ff0254 1117 // PRG RAM, mapped to main CPU if sub is not running\r
1118 if ((r1 & 3) != 1) {\r
4fb43555 1119 void *bank = Pico_mcd->prg_ram_b[(r3 >> 6) & 3];\r
02ff0254 1120 cpu68k_map_all_ram(BASE+0x020000, BASE+0x03ffff, bank, 0);\r
1121 } else {\r
1122 m68k_map_unmap(BASE+0x020000, BASE+0x03ffff);\r
af37bca8 1123 }\r
0ace9b9a 1124}\r
1125\r
c36dbc1d 1126// if sub CPU accesses Word-RAM while it is assigned to the main CPU,\r
8eeb3426 1127// GA doesn't assert DTACK, which means the CPU is blocked until the Word_RAM\r
1128// is reassigned to it (e.g. Mega Race).\r
c36dbc1d 1129// since DTACK isn't on the expansion port, main cpu accesses are not blocked.\r
1130// XXX is data read/written if main is accessing Word_RAM while not owning it?\r
c36dbc1d 1131static u32 s68k_wordram_main_read8(u32 a)\r
8eeb3426 1132{\r
1133 Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;\r
1134 SekEndRunS68k(0);\r
1135 return Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff];\r
1136}\r
1137\r
c36dbc1d 1138static u32 s68k_wordram_main_read16(u32 a)\r
8eeb3426 1139{\r
1140 Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;\r
1141 SekEndRunS68k(0);\r
1142 return ((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff];\r
1143}\r
1144\r
c36dbc1d 1145static void s68k_wordram_main_write8(u32 a, u32 d)\r
8eeb3426 1146{\r
1147 Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;\r
1148 SekEndRunS68k(0);\r
1149 Pico_mcd->word_ram2M[MEM_BE2(a) & 0x3ffff] = d;\r
1150}\r
1151\r
c36dbc1d 1152static void s68k_wordram_main_write16(u32 a, u32 d)\r
8eeb3426 1153{\r
1154 Pico_mcd->m.state_flags |= PCD_ST_S68K_SLEEP;\r
1155 SekEndRunS68k(0);\r
1156 ((u16 *)Pico_mcd->word_ram2M)[(a >> 1) & 0x1ffff] = d;\r
1157}\r
1158\r
4fb43555 1159static void remap_word_ram(u32 r3)\r
0ace9b9a 1160{\r
1161 void *bank;\r
af37bca8 1162\r
1163 // WORD RAM\r
1164 if (!(r3 & 4)) {\r
8eeb3426 1165 // 2M mode.\r
af37bca8 1166 bank = Pico_mcd->word_ram2M;\r
8eeb3426 1167 if (r3 & 1) {\r
02ff0254 1168 cpu68k_map_all_ram(BASE+0x200000, BASE+0x23ffff, bank, 0);\r
8eeb3426 1169 cpu68k_map_all_funcs(0x80000, 0xbffff,\r
c36dbc1d 1170 s68k_wordram_main_read8, s68k_wordram_main_read16,\r
1171 s68k_wordram_main_write8, s68k_wordram_main_write16, 1);\r
8eeb3426 1172 } else {\r
1173 Pico_mcd->m.state_flags &= ~PCD_ST_S68K_SLEEP;\r
1174 cpu68k_map_all_ram(0x080000, 0x0bffff, bank, 1);\r
02ff0254 1175 m68k_map_unmap(BASE+0x200000, BASE+0x23ffff);\r
8eeb3426 1176 }\r
af37bca8 1177 // TODO: handle 0x0c0000\r
1178 }\r
1179 else {\r
0ace9b9a 1180 int b0 = r3 & 1;\r
1181 int m = (r3 & 0x18) >> 3;\r
c36dbc1d 1182 Pico_mcd->m.state_flags &= ~PCD_ST_S68K_SLEEP;\r
0ace9b9a 1183 bank = Pico_mcd->word_ram1M[b0];\r
02ff0254 1184 cpu68k_map_all_ram(BASE+0x200000, BASE+0x21ffff, bank, 0);\r
0ace9b9a 1185 bank = Pico_mcd->word_ram1M[b0 ^ 1];\r
af37bca8 1186 cpu68k_map_all_ram(0x0c0000, 0x0effff, bank, 1);\r
1187 // "cell arrange" on m68k\r
02ff0254 1188 cpu68k_map_all_funcs(BASE+0x220000, BASE+0x23ffff,\r
8eeb3426 1189 m68k_cell_read8[b0], m68k_cell_read16[b0],\r
1190 m68k_cell_write8[b0], m68k_cell_write16[b0], 0);\r
af37bca8 1191 // "decode format" on s68k\r
8eeb3426 1192 cpu68k_map_all_funcs(0x80000, 0xbffff,\r
1193 s68k_dec_read8[b0^1], s68k_dec_read16[b0^1],\r
1194 s68k_dec_write8[b0^1][m], s68k_dec_write16[b0^1][m], 1);\r
af37bca8 1195 }\r
3aa1e148 1196}\r
b837b69b 1197\r
ae214f1c 1198void pcd_state_loaded_mem(void)\r
0ace9b9a 1199{\r
4fb43555 1200 u32 r3 = Pico_mcd->s68k_regs[3];\r
0ace9b9a 1201\r
1202 /* after load events */\r
1203 if (r3 & 4) // 1M mode?\r
1204 wram_2M_to_1M(Pico_mcd->word_ram2M);\r
1205 remap_word_ram(r3);\r
4fb43555 1206 remap_prg_window(Pico_mcd->m.busreq, r3);\r
ba6e8bfd 1207 Pico_mcd->m.dmna_ret_2m &= 3;\r
0ace9b9a 1208\r
1209 // restore hint vector\r
549dd407 1210 *(u16 *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;\r
0ace9b9a 1211}\r
1212\r
9037e45d 1213#ifdef EMU_M68K\r
1214static void m68k_mem_setup_cd(void);\r
1215#endif\r
1216\r
eff55556 1217PICO_INTERNAL void PicoMemSetupCD(void)\r
b837b69b 1218{\r
8f0952ae 1219 if (Pico_mcd == NULL) {\r
1220 static u8 bios_id[4] = "SEGA";\r
1221 PicoCreateMCD(NULL, 0);\r
1222 // BIOS faking for MSU-MD, checks for "SEGA" at 0x400100 to detect CD drive\r
1223 memcpy(Pico_mcd->bios+0x100, bios_id, 4);\r
1224 }\r
1225\r
549dd407 1226 pcd_base_address = (Pico.romsize ? 0x400000 : 0x000000);\r
02ff0254 1227\r
af37bca8 1228 // setup default main68k map\r
1229 PicoMemSetup();\r
1230\r
411b2c19 1231 // main68k map (BIOS or MSU mapped by PicoMemSetup()):\r
549dd407 1232 cpu68k_map_set(m68k_read8_map, BASE, BASE+0x01ffff, Pico_mcd->bios, 0);\r
1233 cpu68k_map_set(m68k_read16_map, BASE, BASE+0x01ffff, Pico_mcd->bios, 0);\r
1234 if (pcd_base_address != 0) { // cartridge (for MSU/MD+)\r
5521edad 1235 // MD+ on MEGASD plus mirror\r
a0ddd242 1236 u32 base = 0x040000-(1<<M68K_MEM_SHIFT);\r
1237 cpu68k_map_set(m68k_write8_map, base, 0x03ffff, msd_write8, 1);\r
1238 cpu68k_map_set(m68k_write16_map, base, 0x03ffff, msd_write16, 1);\r
1239 cpu68k_map_set(m68k_write8_map, base+0x080000, 0x0bffff, msd_write8, 1);\r
1240 cpu68k_map_set(m68k_write16_map, base+0x080000, 0x0bffff, msd_write16, 1);\r
de5da52e 1241 msd_reset();\r
549dd407 1242 } else { // no cartridge\r
05d2acae 1243 // RAM cart\r
af37bca8 1244 cpu68k_map_set(m68k_read8_map, 0x400000, 0x7fffff, PicoReadM68k8_ramc, 1);\r
1245 cpu68k_map_set(m68k_read16_map, 0x400000, 0x7fffff, PicoReadM68k16_ramc, 1);\r
1246 cpu68k_map_set(m68k_write8_map, 0x400000, 0x7fffff, PicoWriteM68k8_ramc, 1);\r
1247 cpu68k_map_set(m68k_write16_map, 0x400000, 0x7fffff, PicoWriteM68k16_ramc, 1);\r
1248 }\r
1249\r
1250 // registers/IO:\r
fa8fb754 1251 cpu68k_map_set(m68k_read8_map, 0xa10000, 0xa1ffff, PicoRead8_mcd_io, 1);\r
1252 cpu68k_map_set(m68k_read16_map, 0xa10000, 0xa1ffff, PicoRead16_mcd_io, 1);\r
1253 cpu68k_map_set(m68k_write8_map, 0xa10000, 0xa1ffff, PicoWrite8_mcd_io, 1);\r
1254 cpu68k_map_set(m68k_write16_map, 0xa10000, 0xa1ffff, PicoWrite16_mcd_io, 1);\r
af37bca8 1255\r
1256 // sub68k map\r
02ff0254 1257 cpu68k_map_set(s68k_read8_map, 0x000000, 0xffffff, s68k_unmapped_read8, 3);\r
1258 cpu68k_map_set(s68k_read16_map, 0x000000, 0xffffff, s68k_unmapped_read16, 3);\r
1259 cpu68k_map_set(s68k_write8_map, 0x000000, 0xffffff, s68k_unmapped_write8, 3);\r
1260 cpu68k_map_set(s68k_write16_map, 0x000000, 0xffffff, s68k_unmapped_write16, 3);\r
af37bca8 1261\r
1262 // PRG RAM\r
02ff0254 1263 cpu68k_map_set(s68k_read8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 2);\r
1264 cpu68k_map_set(s68k_read16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 2);\r
1265 cpu68k_map_set(s68k_write8_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 2);\r
1266 cpu68k_map_set(s68k_write16_map, 0x000000, 0x07ffff, Pico_mcd->prg_ram, 2);\r
1267 cpu68k_map_set(s68k_write8_map, 0x000000, 0x01ffff, PicoWriteS68k8_prgwp, 3);\r
1268 cpu68k_map_set(s68k_write16_map, 0x000000, 0x01ffff, PicoWriteS68k16_prgwp, 3);\r
af37bca8 1269\r
1270 // BRAM\r
02ff0254 1271 cpu68k_map_set(s68k_read8_map, 0xfe0000, 0xfeffff, PicoReadS68k8_bram, 3);\r
1272 cpu68k_map_set(s68k_read16_map, 0xfe0000, 0xfeffff, PicoReadS68k16_bram, 3);\r
1273 cpu68k_map_set(s68k_write8_map, 0xfe0000, 0xfeffff, PicoWriteS68k8_bram, 3);\r
1274 cpu68k_map_set(s68k_write16_map, 0xfe0000, 0xfeffff, PicoWriteS68k16_bram, 3);\r
af37bca8 1275\r
1276 // PCM, regs\r
02ff0254 1277 cpu68k_map_set(s68k_read8_map, 0xff0000, 0xffffff, PicoReadS68k8_pr, 3);\r
1278 cpu68k_map_set(s68k_read16_map, 0xff0000, 0xffffff, PicoReadS68k16_pr, 3);\r
1279 cpu68k_map_set(s68k_write8_map, 0xff0000, 0xffffff, PicoWriteS68k8_pr, 3);\r
1280 cpu68k_map_set(s68k_write16_map, 0xff0000, 0xffffff, PicoWriteS68k16_pr, 3);\r
f53f286a 1281\r
0ace9b9a 1282 // RAMs\r
178a9b68 1283 remap_prg_window(2,1);\r
0ace9b9a 1284 remap_word_ram(1);\r
1285\r
b837b69b 1286#ifdef EMU_C68K\r
b837b69b 1287 // s68k\r
5e89f0f5 1288 PicoCpuCS68k.read8 = (void *)s68k_read8_map;\r
1289 PicoCpuCS68k.read16 = (void *)s68k_read16_map;\r
1290 PicoCpuCS68k.read32 = (void *)s68k_read16_map;\r
1291 PicoCpuCS68k.write8 = (void *)s68k_write8_map;\r
1292 PicoCpuCS68k.write16 = (void *)s68k_write16_map;\r
1293 PicoCpuCS68k.write32 = (void *)s68k_write16_map;\r
1294 PicoCpuCS68k.checkpc = NULL; /* unused */\r
1295 PicoCpuCS68k.fetch8 = NULL;\r
1296 PicoCpuCS68k.fetch16 = NULL;\r
1297 PicoCpuCS68k.fetch32 = NULL;\r
b837b69b 1298#endif\r
3aa1e148 1299#ifdef EMU_F68K\r
3aa1e148 1300 // s68k\r
4cc0fcaf 1301 PicoCpuFS68k.read_byte = (void *)s68k_read8;\r
1302 PicoCpuFS68k.read_word = (void *)s68k_read16;\r
1303 PicoCpuFS68k.read_long = (void *)s68k_read32;\r
1304 PicoCpuFS68k.write_byte = (void *)s68k_write8;\r
1305 PicoCpuFS68k.write_word = (void *)s68k_write16;\r
1306 PicoCpuFS68k.write_long = (void *)s68k_write32;\r
3aa1e148 1307#endif\r
9037e45d 1308#ifdef EMU_M68K\r
1309 m68k_mem_setup_cd();\r
1310#endif\r
b837b69b 1311}\r
1312\r
1313\r
cc68a136 1314#ifdef EMU_M68K\r
af37bca8 1315u32 m68k_read8(u32 a);\r
1316u32 m68k_read16(u32 a);\r
1317u32 m68k_read32(u32 a);\r
1318void m68k_write8(u32 a, u8 d);\r
1319void m68k_write16(u32 a, u16 d);\r
1320void m68k_write32(u32 a, u32 d);\r
1321\r
9037e45d 1322static unsigned int PicoReadCD8w (unsigned int a) {\r
af37bca8 1323 return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read8(a) : m68k_read8(a);\r
cc68a136 1324}\r
9037e45d 1325static unsigned int PicoReadCD16w(unsigned int a) {\r
af37bca8 1326 return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read16(a) : m68k_read16(a);\r
cc68a136 1327}\r
9037e45d 1328static unsigned int PicoReadCD32w(unsigned int a) {\r
af37bca8 1329 return m68ki_cpu_p == &PicoCpuMS68k ? s68k_read32(a) : m68k_read32(a);\r
cc68a136 1330}\r
9037e45d 1331static void PicoWriteCD8w (unsigned int a, unsigned char d) {\r
af37bca8 1332 if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write8(a, d); else m68k_write8(a, d);\r
cc68a136 1333}\r
9037e45d 1334static void PicoWriteCD16w(unsigned int a, unsigned short d) {\r
af37bca8 1335 if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write16(a, d); else m68k_write16(a, d);\r
cc68a136 1336}\r
9037e45d 1337static void PicoWriteCD32w(unsigned int a, unsigned int d) {\r
af37bca8 1338 if (m68ki_cpu_p == &PicoCpuMS68k) s68k_write32(a, d); else m68k_write32(a, d);\r
cc68a136 1339}\r
1340\r
9037e45d 1341extern unsigned int (*pm68k_read_memory_8) (unsigned int address);\r
1342extern unsigned int (*pm68k_read_memory_16)(unsigned int address);\r
1343extern unsigned int (*pm68k_read_memory_32)(unsigned int address);\r
1344extern void (*pm68k_write_memory_8) (unsigned int address, unsigned char value);\r
1345extern void (*pm68k_write_memory_16)(unsigned int address, unsigned short value);\r
1346extern void (*pm68k_write_memory_32)(unsigned int address, unsigned int value);\r
9037e45d 1347\r
1348static void m68k_mem_setup_cd(void)\r
1349{\r
1350 pm68k_read_memory_8 = PicoReadCD8w;\r
1351 pm68k_read_memory_16 = PicoReadCD16w;\r
1352 pm68k_read_memory_32 = PicoReadCD32w;\r
1353 pm68k_write_memory_8 = PicoWriteCD8w;\r
1354 pm68k_write_memory_16 = PicoWriteCD16w;\r
1355 pm68k_write_memory_32 = PicoWriteCD32w;\r
9037e45d 1356}\r
cc68a136 1357#endif // EMU_M68K\r
1358\r
ae214f1c 1359// vim:shiftwidth=2:ts=2:expandtab\r