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