psp mp3 implementation
[picodrive.git] / Pico / cd / Memory.c
CommitLineData
6cadc2da 1// Memory I/O handlers for Sega/Mega CD.\r
2// Loosely based on Gens code.\r
3// (c) Copyright 2007, Grazvydas "notaz" Ignotas\r
cc68a136 4\r
cc68a136 5\r
6//#define __debug_io\r
7\r
8#include "../PicoInt.h"\r
9\r
cc68a136 10#include "../sound/ym2612.h"\r
11#include "../sound/sn76496.h"\r
12\r
cb4a513a 13#include "gfx_cd.h"\r
4f265db7 14#include "pcm.h"\r
cb4a513a 15\r
eff55556 16#ifndef UTYPES_DEFINED\r
cc68a136 17typedef unsigned char u8;\r
18typedef unsigned short u16;\r
19typedef unsigned int u32;\r
eff55556 20#define UTYPES_DEFINED\r
21#endif\r
cc68a136 22\r
23//#define __debug_io\r
24//#define __debug_io2\r
66fdc0f0 25\r
b5e5172d 26//#define rdprintf dprintf\r
27#define rdprintf(...)\r
68cba51e 28//#define wrdprintf dprintf\r
913ef4b7 29#define wrdprintf(...)\r
721cd396 30#define plprintf dprintf\r
31//#define plprintf(...)\r
cc68a136 32\r
b5e5172d 33#ifdef EMU_CORE_DEBUG\r
34extern u32 lastread_a, lastread_d[16], lastwrite_cyc_d[16];\r
35extern int lrp_cyc, lwp_cyc;\r
36#undef USE_POLL_DETECT\r
37#endif\r
38\r
cc68a136 39// -----------------------------------------------------------------\r
40\r
7a1f6e45 41// poller detection\r
7a1f6e45 42#define POLL_LIMIT 16\r
43#define POLL_CYCLES 124\r
44// int m68k_poll_addr, m68k_poll_cnt;\r
45unsigned int s68k_poll_adclk, s68k_poll_cnt;\r
cc68a136 46\r
4ff2d527 47#ifndef _ASM_CD_MEMORY_C\r
cb4a513a 48static u32 m68k_reg_read16(u32 a)\r
cc68a136 49{\r
50 u32 d=0;\r
51 a &= 0x3e;\r
672ad671 52 // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc);\r
cc68a136 53\r
54 switch (a) {\r
672ad671 55 case 0:\r
c459aefd 56 d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens\r
672ad671 57 goto end;\r
cc68a136 58 case 2:\r
672ad671 59 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
c008977e 60 // the DMNA delay must only be visible on s68k side (Lunar2, Silpheed)\r
61 if (Pico_mcd->m.state_flags&2) { d &= ~1; d |= 2; }\r
62 //printf("m68k_regs r3: %02x @%06x\n", (u8)d, SekPc);\r
cc68a136 63 goto end;\r
c459aefd 64 case 4:\r
65 d = Pico_mcd->s68k_regs[4]<<8;\r
66 goto end;\r
67 case 6:\r
913ef4b7 68 d = *(u16 *)(Pico_mcd->bios + 0x72);\r
c459aefd 69 goto end;\r
cc68a136 70 case 8:\r
cc68a136 71 d = Read_CDC_Host(0);\r
72 goto end;\r
c459aefd 73 case 0xA:\r
fa1e5e29 74 dprintf("m68k FIXME: reserved read");\r
c459aefd 75 goto end;\r
cc68a136 76 case 0xC:\r
1cd356a3 77 d = Pico_mcd->m.timer_stopwatch >> 16;\r
4ff2d527 78 dprintf("m68k stopwatch timer read (%04x)", d);\r
1cd356a3 79 goto end;\r
cc68a136 80 }\r
81\r
cc68a136 82 if (a < 0x30) {\r
83 // comm flag/cmd/status (0xE-0x2F)\r
84 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
85 goto end;\r
86 }\r
87\r
fa1e5e29 88 dprintf("m68k_regs FIXME invalid read @ %02x", a);\r
cc68a136 89\r
90end:\r
91\r
672ad671 92 // dprintf("ret = %04x", d);\r
cc68a136 93 return d;\r
94}\r
4ff2d527 95#endif\r
cc68a136 96\r
4ff2d527 97#ifndef _ASM_CD_MEMORY_C\r
98static\r
99#endif\r
100void m68k_reg_write8(u32 a, u32 d)\r
cc68a136 101{\r
102 a &= 0x3f;\r
672ad671 103 // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc);\r
cc68a136 104\r
105 switch (a) {\r
106 case 0:\r
672ad671 107 d &= 1;\r
cc68a136 108 if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { dprintf("m68k: s68k irq 2"); SekInterruptS68k(2); }\r
c459aefd 109 return;\r
cc68a136 110 case 1:\r
672ad671 111 d &= 3;\r
51a902ae 112 if (!(d&1)) Pico_mcd->m.state_flags |= 1; // reset pending, needed to be sure we fetch the right vectors on reset\r
c459aefd 113 if ( (Pico_mcd->m.busreq&1) != (d&1)) dprintf("m68k: s68k reset %i", !(d&1));\r
114 if ( (Pico_mcd->m.busreq&2) != (d&2)) dprintf("m68k: s68k brq %i", (d&2)>>1);\r
51a902ae 115 if ((Pico_mcd->m.state_flags&1) && (d&3)==1) {\r
cc68a136 116 SekResetS68k(); // S68k comes out of RESET or BRQ state\r
4ff2d527 117 Pico_mcd->m.state_flags&=~1;\r
118 dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
cc68a136 119 }\r
c459aefd 120 Pico_mcd->m.busreq = d;\r
121 return;\r
672ad671 122 case 2:\r
721cd396 123 dprintf("m68k: prg wp=%02x", d);\r
672ad671 124 Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
125 return;\r
66fdc0f0 126 case 3: {\r
127 u32 dold = Pico_mcd->s68k_regs[3]&0x1f;\r
c008977e 128 //printf("m68k_regs w3: %02x @%06x\n", (u8)d, SekPc);\r
672ad671 129 d &= 0xc2;\r
66fdc0f0 130 if ((dold>>6) != ((d>>6)&3))\r
672ad671 131 dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
132 //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2);\r
133 //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") :\r
134 // ((d&2) ? "word ram to s68k" : "word ram to m68k"));\r
66fdc0f0 135 if (dold & 4) {\r
136 d ^= 2; // writing 0 to DMNA actually sets it, 1 does nothing\r
137 } else {\r
138 //dold &= ~2; // ??\r
89fa852d 139#if 1\r
140 if ((d & 2) && !(dold & 2)) {\r
141 Pico_mcd->m.state_flags |= 2; // we must delay setting DMNA bit (needed for Silpheed)\r
142 d &= ~2;\r
143 }\r
144#else\r
66fdc0f0 145 if (d & 2) dold &= ~1; // return word RAM to s68k in 2M mode\r
89fa852d 146#endif\r
66fdc0f0 147 }\r
148 Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register\r
7a1f6e45 149#ifdef USE_POLL_DETECT\r
150 if ((s68k_poll_adclk&0xfe) == 2 && s68k_poll_cnt > POLL_LIMIT) {\r
151 SekSetStopS68k(0); s68k_poll_adclk = 0;\r
2433f409 152 plprintf("s68k poll release, a=%02x\n", a);\r
7a1f6e45 153 }\r
154#endif\r
672ad671 155 return;\r
66fdc0f0 156 }\r
c459aefd 157 case 6:\r
d1df8786 158 Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
c459aefd 159 return;\r
160 case 7:\r
d1df8786 161 Pico_mcd->bios[0x72] = d;\r
913ef4b7 162 dprintf("hint vector set to %08x", PicoRead32(0x70));\r
c459aefd 163 return;\r
7a1f6e45 164 case 0xf:\r
165 d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
cc68a136 166 case 0xe:\r
672ad671 167 //dprintf("m68k: comm flag: %02x", d);\r
cc68a136 168 Pico_mcd->s68k_regs[0xe] = d;\r
7a1f6e45 169#ifdef USE_POLL_DETECT\r
170 if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
171 SekSetStopS68k(0); s68k_poll_adclk = 0;\r
2433f409 172 plprintf("s68k poll release, a=%02x\n", a);\r
7a1f6e45 173 }\r
174#endif\r
c459aefd 175 return;\r
672ad671 176 }\r
177\r
178 if ((a&0xf0) == 0x10) {\r
cc68a136 179 Pico_mcd->s68k_regs[a] = d;\r
7a1f6e45 180#ifdef USE_POLL_DETECT\r
181 if ((a&0xfe) == (s68k_poll_adclk&0xfe) && s68k_poll_cnt > POLL_LIMIT) {\r
182 SekSetStopS68k(0); s68k_poll_adclk = 0;\r
2433f409 183 plprintf("s68k poll release, a=%02x\n", a);\r
7a1f6e45 184 }\r
185#endif\r
672ad671 186 return;\r
cc68a136 187 }\r
188\r
fa1e5e29 189 dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);\r
cc68a136 190}\r
191\r
2433f409 192#ifndef _ASM_CD_MEMORY_C\r
193static\r
194#endif\r
195u32 s68k_poll_detect(u32 a, u32 d)\r
196{\r
197#ifdef USE_POLL_DETECT\r
198 // polling detection\r
199 if (a == (s68k_poll_adclk&0xff)) {\r
200 unsigned int clkdiff = SekCyclesDoneS68k() - (s68k_poll_adclk>>8);\r
201 if (clkdiff <= POLL_CYCLES) {\r
202 s68k_poll_cnt++;\r
203 //printf("-- diff: %u, cnt = %i\n", clkdiff, s68k_poll_cnt);\r
204 if (s68k_poll_cnt > POLL_LIMIT) {\r
205 SekSetStopS68k(1);\r
206 plprintf("s68k poll detected @ %06x, a=%02x\n", SekPcS68k, a);\r
207 }\r
208 s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
209 return d;\r
210 }\r
211 }\r
212 s68k_poll_adclk = (SekCyclesDoneS68k() << 8) | a;\r
213 s68k_poll_cnt = 0;\r
214#endif\r
215 return d;\r
216}\r
cc68a136 217\r
913ef4b7 218#define READ_FONT_DATA(basemask) \\r
219{ \\r
220 unsigned int fnt = *(unsigned int *)(Pico_mcd->s68k_regs + 0x4c); \\r
221 unsigned int col0 = (fnt >> 8) & 0x0f, col1 = (fnt >> 12) & 0x0f; \\r
222 if (fnt & (basemask << 0)) d = col1 ; else d = col0; \\r
223 if (fnt & (basemask << 1)) d |= col1 << 4; else d |= col0 << 4; \\r
224 if (fnt & (basemask << 2)) d |= col1 << 8; else d |= col0 << 8; \\r
225 if (fnt & (basemask << 3)) d |= col1 << 12; else d |= col0 << 12; \\r
226}\r
227\r
cc68a136 228\r
4ff2d527 229#ifndef _ASM_CD_MEMORY_C\r
230static\r
231#endif\r
232u32 s68k_reg_read16(u32 a)\r
cc68a136 233{\r
234 u32 d=0;\r
cc68a136 235\r
672ad671 236 // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k);\r
cc68a136 237\r
238 switch (a) {\r
239 case 0:\r
7a1f6e45 240 return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
672ad671 241 case 2:\r
2433f409 242 d = (Pico_mcd->s68k_regs[2]<<8) | (Pico_mcd->s68k_regs[3]&0x1f);\r
c008977e 243 //printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k);\r
2433f409 244 return s68k_poll_detect(a, d);\r
cc68a136 245 case 6:\r
7a1f6e45 246 return CDC_Read_Reg();\r
cc68a136 247 case 8:\r
7a1f6e45 248 return Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
cc68a136 249 case 0xC:\r
4f265db7 250 d = Pico_mcd->m.timer_stopwatch >> 16;\r
4ff2d527 251 dprintf("s68k stopwatch timer read (%04x)", d);\r
7a1f6e45 252 return d;\r
d1df8786 253 case 0x30:\r
7a1f6e45 254 dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
255 return Pico_mcd->s68k_regs[31];\r
cc68a136 256 case 0x34: // fader\r
7a1f6e45 257 return 0; // no busy bit\r
913ef4b7 258 case 0x50: // font data (check: Lunar 2, Silpheed)\r
259 READ_FONT_DATA(0x00100000);\r
7a1f6e45 260 return d;\r
913ef4b7 261 case 0x52:\r
262 READ_FONT_DATA(0x00010000);\r
7a1f6e45 263 return d;\r
913ef4b7 264 case 0x54:\r
265 READ_FONT_DATA(0x10000000);\r
7a1f6e45 266 return d;\r
913ef4b7 267 case 0x56:\r
268 READ_FONT_DATA(0x01000000);\r
7a1f6e45 269 return d;\r
cc68a136 270 }\r
271\r
272 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
273\r
2433f409 274 if (a >= 0x0e && a < 0x30)\r
275 return s68k_poll_detect(a, d);\r
7a1f6e45 276\r
cc68a136 277 return d;\r
278}\r
279\r
4ff2d527 280#ifndef _ASM_CD_MEMORY_C\r
281static\r
282#endif\r
283void s68k_reg_write8(u32 a, u32 d)\r
cc68a136 284{\r
672ad671 285 //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k);\r
cc68a136 286\r
48e8482f 287 // Warning: d might have upper bits set\r
cc68a136 288 switch (a) {\r
672ad671 289 case 2:\r
290 return; // only m68k can change WP\r
fa1e5e29 291 case 3: {\r
292 int dold = Pico_mcd->s68k_regs[3];\r
c008977e 293 //printf("s68k_regs w3: %02x @%06x\n", (u8)d, SekPcS68k);\r
672ad671 294 d &= 0x1d;\r
4ff2d527 295 d |= dold&0xc2;\r
d0d47c5b 296 if (d&4) {\r
4ff2d527 297 if ((d ^ dold) & 5) {\r
298 d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
4ff2d527 299 PicoMemResetCD(d);\r
4ff2d527 300 }\r
48e8482f 301#ifdef _ASM_CD_MEMORY_C\r
302 if ((d ^ dold) & 0x1d)\r
303 PicoMemResetCDdecode(d);\r
304#endif\r
fa1e5e29 305 if (!(dold & 4)) {\r
306 dprintf("wram mode 2M->1M");\r
307 wram_2M_to_1M(Pico_mcd->word_ram2M);\r
4ff2d527 308 }\r
d0d47c5b 309 } else {\r
fa1e5e29 310 if (dold & 4) {\r
311 dprintf("wram mode 1M->2M");\r
4ff2d527 312 if (!(d&1)) { // it didn't set the ret bit, which means it doesn't want to give WRAM to m68k\r
313 d &= ~3;\r
314 d |= (dold&1) ? 2 : 1; // then give it to the one which had bank0 in 1M mode\r
315 }\r
fa1e5e29 316 wram_1M_to_2M(Pico_mcd->word_ram2M);\r
4ff2d527 317 PicoMemResetCD(d);\r
4ff2d527 318 }\r
319 else\r
320 d |= dold&1;\r
321 if (d&1) d &= ~2; // return word RAM to m68k in 2M mode\r
d0d47c5b 322 }\r
672ad671 323 break;\r
fa1e5e29 324 }\r
cc68a136 325 case 4:\r
326 dprintf("s68k CDC dest: %x", d&7);\r
327 Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode\r
328 return;\r
329 case 5:\r
c459aefd 330 //dprintf("s68k CDC reg addr: %x", d&0xf);\r
cc68a136 331 break;\r
332 case 7:\r
333 CDC_Write_Reg(d);\r
334 return;\r
335 case 0xa:\r
336 dprintf("s68k set CDC dma addr");\r
337 break;\r
d1df8786 338 case 0xc:\r
4f265db7 339 case 0xd:\r
d1df8786 340 dprintf("s68k set stopwatch timer");\r
4f265db7 341 Pico_mcd->m.timer_stopwatch = 0;\r
342 return;\r
1cd356a3 343 case 0xe:\r
7a1f6e45 344 Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
1cd356a3 345 return;\r
d1df8786 346 case 0x31:\r
4f265db7 347 dprintf("s68k set int3 timer: %02x", d);\r
48e8482f 348 Pico_mcd->m.timer_int3 = (d & 0xff) << 16;\r
d1df8786 349 break;\r
cc68a136 350 case 0x33: // IRQ mask\r
351 dprintf("s68k irq mask: %02x", d);\r
352 if ((d&(1<<4)) && (Pico_mcd->s68k_regs[0x37]&4) && !(Pico_mcd->s68k_regs[0x33]&(1<<4))) {\r
353 CDD_Export_Status();\r
cc68a136 354 }\r
355 break;\r
356 case 0x34: // fader\r
357 Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
358 return;\r
672ad671 359 case 0x36:\r
360 return; // d/m bit is unsetable\r
361 case 0x37: {\r
362 u32 d_old = Pico_mcd->s68k_regs[0x37];\r
363 Pico_mcd->s68k_regs[0x37] = d&7;\r
364 if ((d&4) && !(d_old&4)) {\r
cc68a136 365 CDD_Export_Status();\r
cc68a136 366 }\r
672ad671 367 return;\r
368 }\r
cc68a136 369 case 0x4b:\r
370 Pico_mcd->s68k_regs[a] = (u8) d;\r
371 CDD_Import_Command();\r
372 return;\r
373 }\r
374\r
1cd356a3 375 if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
cc68a136 376 {\r
fa1e5e29 377 dprintf("s68k FIXME: invalid write @ %02x?", a);\r
cc68a136 378 return;\r
379 }\r
380\r
381 Pico_mcd->s68k_regs[a] = (u8) d;\r
382}\r
383\r
384\r
4ff2d527 385#ifndef _ASM_CD_MEMORY_C\r
fa1e5e29 386static u32 OtherRead16End(u32 a, int realsize)\r
cc68a136 387{\r
388 u32 d=0;\r
389\r
672ad671 390 if ((a&0xffffc0)==0xa12000) {\r
cb4a513a 391 d=m68k_reg_read16(a);\r
672ad671 392 goto end;\r
393 }\r
cc68a136 394\r
fa1e5e29 395 dprintf("m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
cc68a136 396\r
397end:\r
398 return d;\r
399}\r
400\r
cc68a136 401\r
fa1e5e29 402static void OtherWrite8End(u32 a, u32 d, int realsize)\r
cc68a136 403{\r
cb4a513a 404 if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
cc68a136 405\r
721cd396 406 dprintf("m68k FIXME: strange w%i: [%06x], %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
cc68a136 407}\r
408\r
69996cb7 409#define _CD_MEMORY_C\r
fa1e5e29 410#undef _ASM_MEMORY_C\r
411#include "../MemoryCmn.c"\r
4ff2d527 412#include "cell_map.c"\r
413#endif // !def _ASM_CD_MEMORY_C\r
cc68a136 414\r
2433f409 415\r
cc68a136 416// -----------------------------------------------------------------\r
417// Read Rom and read Ram\r
418\r
4ff2d527 419#ifdef _ASM_CD_MEMORY_C\r
0af33fe0 420u32 PicoReadM68k8(u32 a);\r
4ff2d527 421#else\r
0af33fe0 422static u32 PicoReadM68k8(u32 a)\r
cc68a136 423{\r
424 u32 d=0;\r
425\r
426 if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram\r
427\r
428 a&=0xffffff;\r
429\r
430 if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios\r
431\r
432 // prg RAM\r
721cd396 433 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
672ad671 434 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 435 d = *(prg_bank+((a^1)&0x1ffff));\r
436 goto end;\r
437 }\r
438\r
d0d47c5b 439 // word RAM\r
440 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 441 wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
d0d47c5b 442 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 443 int bank = Pico_mcd->s68k_regs[3]&1;\r
444 if (a >= 0x220000)\r
445 a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
446 else a &= 0x1ffff;\r
447 d = Pico_mcd->word_ram1M[bank][a^1];\r
d0d47c5b 448 } else {\r
449 // allow access in any mode, like Gens does\r
fa1e5e29 450 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
d0d47c5b 451 }\r
913ef4b7 452 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 453 goto end;\r
454 }\r
455\r
cc68a136 456 if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
457\r
c459aefd 458 if ((a&0xffffc0)==0xa12000)\r
459 rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 460\r
cc68a136 461 d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
462\r
c459aefd 463 if ((a&0xffffc0)==0xa12000)\r
464 rdprintf("ret = %02x", (u8)d);\r
672ad671 465\r
cc68a136 466 end:\r
467\r
468#ifdef __debug_io\r
469 dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
b5e5172d 470#endif\r
471#ifdef EMU_CORE_DEBUG\r
472 if (a>=Pico.romsize) {\r
473 lastread_a = a;\r
474 lastread_d[lrp_cyc++&15] = d;\r
475 }\r
cc68a136 476#endif\r
0af33fe0 477 return d;\r
cc68a136 478}\r
4ff2d527 479#endif\r
cc68a136 480\r
ab0607f7 481\r
4ff2d527 482#ifdef _ASM_CD_MEMORY_C\r
0af33fe0 483u32 PicoReadM68k16(u32 a);\r
4ff2d527 484#else\r
0af33fe0 485static u32 PicoReadM68k16(u32 a)\r
cc68a136 486{\r
0af33fe0 487 u32 d=0;\r
cc68a136 488\r
489 if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram\r
490\r
491 a&=0xfffffe;\r
492\r
493 if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios\r
494\r
495 // prg RAM\r
721cd396 496 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
672ad671 497 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
c008977e 498 wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
cc68a136 499 d = *(u16 *)(prg_bank+(a&0x1fffe));\r
c008977e 500 wrdprintf("ret = %04x", d);\r
cc68a136 501 goto end;\r
502 }\r
503\r
d0d47c5b 504 // word RAM\r
505 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 506 wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
d0d47c5b 507 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 508 int bank = Pico_mcd->s68k_regs[3]&1;\r
509 if (a >= 0x220000)\r
510 a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
511 else a &= 0x1fffe;\r
512 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
d0d47c5b 513 } else {\r
514 // allow access in any mode, like Gens does\r
fa1e5e29 515 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 516 }\r
913ef4b7 517 wrdprintf("ret = %04x", d);\r
d0d47c5b 518 goto end;\r
519 }\r
520\r
c459aefd 521 if ((a&0xffffc0)==0xa12000)\r
522 rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 523\r
0af33fe0 524 d = OtherRead16(a, 16);\r
cc68a136 525\r
c459aefd 526 if ((a&0xffffc0)==0xa12000)\r
527 rdprintf("ret = %04x", d);\r
672ad671 528\r
cc68a136 529 end:\r
530\r
531#ifdef __debug_io\r
532 dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
b5e5172d 533#endif\r
534#ifdef EMU_CORE_DEBUG\r
535 if (a>=Pico.romsize) {\r
536 lastread_a = a;\r
537 lastread_d[lrp_cyc++&15] = d;\r
538 }\r
cc68a136 539#endif\r
540 return d;\r
541}\r
4ff2d527 542#endif\r
cc68a136 543\r
ab0607f7 544\r
4ff2d527 545#ifdef _ASM_CD_MEMORY_C\r
546u32 PicoReadM68k32(u32 a);\r
547#else\r
548static u32 PicoReadM68k32(u32 a)\r
cc68a136 549{\r
550 u32 d=0;\r
551\r
552 if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram\r
553\r
554 a&=0xfffffe;\r
555\r
556 if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios\r
557\r
558 // prg RAM\r
721cd396 559 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
672ad671 560 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 561 u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
562 d = (pm[0]<<16)|pm[1];\r
563 goto end;\r
564 }\r
565\r
d0d47c5b 566 // word RAM\r
567 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 568 wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
d0d47c5b 569 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 570 int bank = Pico_mcd->s68k_regs[3]&1;\r
571 if (a >= 0x220000) { // cell arranged\r
572 u32 a1, a2;\r
573 a1 = (a&2) | (cell_map(a >> 2) << 2);\r
4ff2d527 574 if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
575 else a2 = a1 + 2;\r
576 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;\r
577 d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);\r
bf098bc5 578 } else {\r
fa1e5e29 579 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
bf098bc5 580 }\r
d0d47c5b 581 } else {\r
582 // allow access in any mode, like Gens does\r
fa1e5e29 583 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d0d47c5b 584 }\r
913ef4b7 585 wrdprintf("ret = %08x", d);\r
d0d47c5b 586 goto end;\r
587 }\r
588\r
c459aefd 589 if ((a&0xffffc0)==0xa12000)\r
590 rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 591\r
cc68a136 592 d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
593\r
c459aefd 594 if ((a&0xffffc0)==0xa12000)\r
595 rdprintf("ret = %08x", d);\r
672ad671 596\r
cc68a136 597 end:\r
598#ifdef __debug_io\r
599 dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
b5e5172d 600#endif\r
601#ifdef EMU_CORE_DEBUG\r
602 if (a>=Pico.romsize) {\r
603 lastread_a = a;\r
604 lastread_d[lrp_cyc++&15] = d;\r
605 }\r
cc68a136 606#endif\r
607 return d;\r
608}\r
4ff2d527 609#endif\r
cc68a136 610\r
ab0607f7 611\r
cc68a136 612// -----------------------------------------------------------------\r
cc68a136 613\r
4ff2d527 614#ifdef _ASM_CD_MEMORY_C\r
615void PicoWriteM68k8(u32 a,u8 d);\r
616#else\r
617static void PicoWriteM68k8(u32 a,u8 d)\r
cc68a136 618{\r
619#ifdef __debug_io\r
620 dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);\r
621#endif\r
b5e5172d 622#ifdef EMU_CORE_DEBUG\r
623 lastwrite_cyc_d[lwp_cyc++&15] = d;\r
624#endif\r
cc68a136 625\r
ab0607f7 626 if ((a&0xe00000)==0xe00000) { // Ram\r
627 *(u8 *)(Pico.ram+((a^1)&0xffff)) = d;\r
628 return;\r
629 }\r
cc68a136 630\r
631 a&=0xffffff;\r
632\r
633 // prg RAM\r
721cd396 634 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
672ad671 635 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
bf098bc5 636 *(u8 *)(prg_bank+((a^1)&0x1ffff))=d;\r
cc68a136 637 return;\r
638 }\r
639\r
d0d47c5b 640 // word RAM\r
641 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 642 wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
d0d47c5b 643 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 644 int bank = Pico_mcd->s68k_regs[3]&1;\r
645 if (a >= 0x220000)\r
646 a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
647 else a &= 0x1ffff;\r
648 *(u8 *)(Pico_mcd->word_ram1M[bank]+(a^1))=d;\r
d0d47c5b 649 } else {\r
650 // allow access in any mode, like Gens does\r
fa1e5e29 651 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
d0d47c5b 652 }\r
653 return;\r
654 }\r
655\r
2433f409 656 if ((a&0xffffc0)==0xa12000) {\r
c459aefd 657 rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
2433f409 658 m68k_reg_write8(a, d);\r
659 return;\r
660 }\r
672ad671 661\r
fb9bec94 662 OtherWrite8(a,d);\r
cc68a136 663}\r
4ff2d527 664#endif\r
cc68a136 665\r
ab0607f7 666\r
4ff2d527 667#ifdef _ASM_CD_MEMORY_C\r
668void PicoWriteM68k16(u32 a,u16 d);\r
669#else\r
670static void PicoWriteM68k16(u32 a,u16 d)\r
cc68a136 671{\r
672#ifdef __debug_io\r
673 dprintf("w16: %06x, %04x", a&0xffffff, d);\r
674#endif\r
b5e5172d 675#ifdef EMU_CORE_DEBUG\r
676 lastwrite_cyc_d[lwp_cyc++&15] = d;\r
677#endif\r
cc68a136 678\r
ab0607f7 679 if ((a&0xe00000)==0xe00000) { // Ram\r
680 *(u16 *)(Pico.ram+(a&0xfffe))=d;\r
681 return;\r
682 }\r
cc68a136 683\r
684 a&=0xfffffe;\r
685\r
686 // prg RAM\r
721cd396 687 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
672ad671 688 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
c008977e 689 wrdprintf("m68k_prgram w16: [%i,%06x] %04x @%06x", Pico_mcd->s68k_regs[3]>>6, a, d, SekPc);\r
cc68a136 690 *(u16 *)(prg_bank+(a&0x1fffe))=d;\r
691 return;\r
692 }\r
693\r
d0d47c5b 694 // word RAM\r
695 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 696 wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
d0d47c5b 697 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 698 int bank = Pico_mcd->s68k_regs[3]&1;\r
699 if (a >= 0x220000)\r
700 a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
701 else a &= 0x1fffe;\r
702 *(u16 *)(Pico_mcd->word_ram1M[bank]+a)=d;\r
d0d47c5b 703 } else {\r
704 // allow access in any mode, like Gens does\r
fa1e5e29 705 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
d0d47c5b 706 }\r
707 return;\r
708 }\r
709\r
7a1f6e45 710 // regs\r
711 if ((a&0xffffc0)==0xa12000) {\r
c459aefd 712 rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
7a1f6e45 713 if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
714 Pico_mcd->s68k_regs[0xe] = d >> 8;\r
715#ifdef USE_POLL_DETECT\r
716 if ((s68k_poll_adclk&0xfe) == 0xe && s68k_poll_cnt > POLL_LIMIT) {\r
6cadc2da 717 SekSetStopS68k(0); s68k_poll_adclk = 0;\r
2433f409 718 plprintf("s68k poll release, a=%02x\n", a);\r
7a1f6e45 719 }\r
720#endif\r
721 return;\r
722 }\r
723 m68k_reg_write8(a, d>>8);\r
724 m68k_reg_write8(a+1,d&0xff);\r
725 return;\r
726 }\r
cc68a136 727\r
728 OtherWrite16(a,d);\r
729}\r
4ff2d527 730#endif\r
cc68a136 731\r
ab0607f7 732\r
4ff2d527 733#ifdef _ASM_CD_MEMORY_C\r
734void PicoWriteM68k32(u32 a,u32 d);\r
735#else\r
736static void PicoWriteM68k32(u32 a,u32 d)\r
cc68a136 737{\r
738#ifdef __debug_io\r
739 dprintf("w32: %06x, %08x", a&0xffffff, d);\r
740#endif\r
b5e5172d 741#ifdef EMU_CORE_DEBUG\r
742 lastwrite_cyc_d[lwp_cyc++&15] = d;\r
743#endif\r
cc68a136 744\r
745 if ((a&0xe00000)==0xe00000)\r
746 {\r
747 // Ram:\r
748 u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
749 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
750 return;\r
751 }\r
752\r
753 a&=0xfffffe;\r
754\r
755 // prg RAM\r
721cd396 756 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&3)!=1) {\r
672ad671 757 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 758 u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
759 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
760 return;\r
761 }\r
762\r
672ad671 763 // word RAM\r
d0d47c5b 764 if ((a&0xfc0000)==0x200000) {\r
765 if (d != 0) // don't log clears\r
913ef4b7 766 wrdprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc);\r
d0d47c5b 767 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 768 int bank = Pico_mcd->s68k_regs[3]&1;\r
769 if (a >= 0x220000) { // cell arranged\r
770 u32 a1, a2;\r
771 a1 = (a&2) | (cell_map(a >> 2) << 2);\r
4ff2d527 772 if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
773 else a2 = a1 + 2;\r
774 *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) = d >> 16;\r
775 *(u16 *)(Pico_mcd->word_ram1M[bank]+a2) = d;\r
bf098bc5 776 } else {\r
fa1e5e29 777 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
778 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
bf098bc5 779 }\r
d0d47c5b 780 } else {\r
781 // allow access in any mode, like Gens does\r
fa1e5e29 782 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 783 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
784 }\r
672ad671 785 return;\r
d0d47c5b 786 }\r
672ad671 787\r
2433f409 788 if ((a&0xffffc0)==0xa12000) {\r
c459aefd 789 rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
2433f409 790 if ((a&0x3e) == 0xe) dprintf("m68k FIXME: w32 [%02x]", a&0x3f);\r
791 }\r
cc68a136 792\r
793 OtherWrite16(a, (u16)(d>>16));\r
794 OtherWrite16(a+2,(u16)d);\r
795}\r
4ff2d527 796#endif\r
cc68a136 797\r
798\r
721cd396 799// -----------------------------------------------------------------\r
800// S68k\r
cc68a136 801// -----------------------------------------------------------------\r
802\r
4ff2d527 803#ifdef _ASM_CD_MEMORY_C\r
0af33fe0 804u32 PicoReadS68k8(u32 a);\r
4ff2d527 805#else\r
0af33fe0 806static u32 PicoReadS68k8(u32 a)\r
cc68a136 807{\r
808 u32 d=0;\r
809\r
b5e5172d 810#ifdef EMU_CORE_DEBUG\r
811 u32 ab=a&0xfffffe;\r
812#endif\r
cc68a136 813 a&=0xffffff;\r
814\r
815 // prg RAM\r
816 if (a < 0x80000) {\r
817 d = *(Pico_mcd->prg_ram+(a^1));\r
818 goto end;\r
819 }\r
820\r
821 // regs\r
822 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 823 a &= 0x1ff;\r
824 rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
2433f409 825 if (a >= 0x0e && a < 0x30) {\r
826 d = Pico_mcd->s68k_regs[a];\r
827 s68k_poll_detect(a, d);\r
828 rdprintf("ret = %02x", (u8)d);\r
829 goto end;\r
830 }\r
831 else if (a >= 0x58 && a < 0x68)\r
cb4a513a 832 d = gfx_cd_read(a&~1);\r
833 else d = s68k_reg_read16(a&~1);\r
834 if ((a&1)==0) d>>=8;\r
c459aefd 835 rdprintf("ret = %02x", (u8)d);\r
cc68a136 836 goto end;\r
837 }\r
838\r
d0d47c5b 839 // word RAM (2M area)\r
840 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
fa1e5e29 841 // test: batman returns\r
913ef4b7 842 wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 843 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
3aa1e148 844 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 845 d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
846 if (a&1) d &= 0x0f;\r
847 else d >>= 4;\r
848 dprintf("FIXME: decode");\r
d0d47c5b 849 } else {\r
850 // allow access in any mode, like Gens does\r
fa1e5e29 851 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
d0d47c5b 852 }\r
913ef4b7 853 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 854 goto end;\r
855 }\r
856\r
857 // word RAM (1M area)\r
68cba51e 858 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 859 int bank;\r
913ef4b7 860 wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);\r
68cba51e 861// if (!(Pico_mcd->s68k_regs[3]&4))\r
862// dprintf("s68k_wram1M FIXME: wrong mode");\r
3aa1e148 863 bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 864 d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];\r
913ef4b7 865 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 866 goto end;\r
867 }\r
868\r
4f265db7 869 // PCM\r
870 if ((a&0xff8000)==0xff0000) {\r
1cd356a3 871 dprintf("s68k_pcm r8: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 872 a &= 0x7fff;\r
873 if (a >= 0x2000)\r
874 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
875 else if (a >= 0x20) {\r
876 a &= 0x1e;\r
877 d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
878 if (a & 2) d >>= 8;\r
879 }\r
880 dprintf("ret = %02x", (u8)d);\r
881 goto end;\r
882 }\r
883\r
ab0607f7 884 // bram\r
885 if ((a&0xff0000)==0xfe0000) {\r
886 d = Pico_mcd->bram[(a>>1)&0x1fff];\r
887 goto end;\r
888 }\r
889\r
cc68a136 890 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
891\r
892 end:\r
893\r
894#ifdef __debug_io2\r
895 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
b5e5172d 896#endif\r
897#ifdef EMU_CORE_DEBUG\r
898 lastread_a = ab;\r
899 lastread_d[lrp_cyc++&15] = d;\r
cc68a136 900#endif\r
0af33fe0 901 return d;\r
cc68a136 902}\r
4ff2d527 903#endif\r
cc68a136 904\r
ab0607f7 905\r
4ff2d527 906#ifdef _ASM_CD_MEMORY_C\r
0af33fe0 907u32 PicoReadS68k16(u32 a);\r
4ff2d527 908#else\r
0af33fe0 909static u32 PicoReadS68k16(u32 a)\r
cc68a136 910{\r
4f265db7 911 u32 d=0;\r
cc68a136 912\r
b5e5172d 913#ifdef EMU_CORE_DEBUG\r
914 u32 ab=a&0xfffffe;\r
915#endif\r
cc68a136 916 a&=0xfffffe;\r
917\r
918 // prg RAM\r
919 if (a < 0x80000) {\r
c008977e 920 wrdprintf("s68k_prgram r16: [%06x] @%06x", a, SekPcS68k);\r
cc68a136 921 d = *(u16 *)(Pico_mcd->prg_ram+a);\r
c008977e 922 wrdprintf("ret = %04x", d);\r
cc68a136 923 goto end;\r
924 }\r
925\r
926 // regs\r
927 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 928 a &= 0x1fe;\r
929 rdprintf("s68k_regs r16: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 930 if (a >= 0x58 && a < 0x68)\r
cb4a513a 931 d = gfx_cd_read(a);\r
932 else d = s68k_reg_read16(a);\r
c459aefd 933 rdprintf("ret = %04x", d);\r
cc68a136 934 goto end;\r
935 }\r
936\r
d0d47c5b 937 // word RAM (2M area)\r
938 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 939 wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 940 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
3aa1e148 941 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 942 d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
943 d |= d << 4; d &= ~0xf0;\r
944 dprintf("FIXME: decode");\r
d0d47c5b 945 } else {\r
946 // allow access in any mode, like Gens does\r
fa1e5e29 947 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 948 }\r
913ef4b7 949 wrdprintf("ret = %04x", d);\r
d0d47c5b 950 goto end;\r
951 }\r
952\r
953 // word RAM (1M area)\r
68cba51e 954 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 955 int bank;\r
913ef4b7 956 wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);\r
68cba51e 957// if (!(Pico_mcd->s68k_regs[3]&4))\r
958// dprintf("s68k_wram1M FIXME: wrong mode");\r
3aa1e148 959 bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 960 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
913ef4b7 961 wrdprintf("ret = %04x", d);\r
ab0607f7 962 goto end;\r
963 }\r
964\r
965 // bram\r
966 if ((a&0xff0000)==0xfe0000) {\r
4ff2d527 967 dprintf("FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
ab0607f7 968 a = (a>>1)&0x1fff;\r
4f265db7 969 d = Pico_mcd->bram[a++]; // Gens does little endian here, and so do we..\r
4ff2d527 970 d|= Pico_mcd->bram[a++] << 8; // This is most likely wrong\r
ab0607f7 971 dprintf("ret = %04x", d);\r
d0d47c5b 972 goto end;\r
973 }\r
974\r
4f265db7 975 // PCM\r
976 if ((a&0xff8000)==0xff0000) {\r
4ff2d527 977 dprintf("FIXME: s68k_pcm r16: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 978 a &= 0x7fff;\r
979 if (a >= 0x2000)\r
980 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
981 else if (a >= 0x20) {\r
982 a &= 0x1e;\r
983 d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
984 if (a & 2) d >>= 8;\r
985 }\r
986 dprintf("ret = %04x", d);\r
987 goto end;\r
988 }\r
989\r
cc68a136 990 dprintf("s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
991\r
992 end:\r
993\r
994#ifdef __debug_io2\r
995 dprintf("s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
b5e5172d 996#endif\r
997#ifdef EMU_CORE_DEBUG\r
998 lastread_a = ab;\r
999 lastread_d[lrp_cyc++&15] = d;\r
cc68a136 1000#endif\r
1001 return d;\r
1002}\r
4ff2d527 1003#endif\r
cc68a136 1004\r
ab0607f7 1005\r
4ff2d527 1006#ifdef _ASM_CD_MEMORY_C\r
1007u32 PicoReadS68k32(u32 a);\r
1008#else\r
1009static u32 PicoReadS68k32(u32 a)\r
cc68a136 1010{\r
1011 u32 d=0;\r
1012\r
b5e5172d 1013#ifdef EMU_CORE_DEBUG\r
1014 u32 ab=a&0xfffffe;\r
1015#endif\r
cc68a136 1016 a&=0xfffffe;\r
1017\r
1018 // prg RAM\r
1019 if (a < 0x80000) {\r
1020 u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
1021 d = (pm[0]<<16)|pm[1];\r
1022 goto end;\r
1023 }\r
1024\r
1025 // regs\r
1026 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 1027 a &= 0x1fe;\r
1028 rdprintf("s68k_regs r32: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 1029 if (a >= 0x58 && a < 0x68)\r
cb4a513a 1030 d = (gfx_cd_read(a)<<16)|gfx_cd_read(a+2);\r
1031 else d = (s68k_reg_read16(a)<<16)|s68k_reg_read16(a+2);\r
c459aefd 1032 rdprintf("ret = %08x", d);\r
cc68a136 1033 goto end;\r
1034 }\r
1035\r
d0d47c5b 1036 // word RAM (2M area)\r
1037 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 1038 wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 1039 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
3aa1e148 1040 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1041 a >>= 1;\r
1042 d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;\r
1043 d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff];\r
1044 d |= d << 4; d &= 0x0f0f0f0f;\r
d0d47c5b 1045 } else {\r
1046 // allow access in any mode, like Gens does\r
fa1e5e29 1047 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d0d47c5b 1048 }\r
913ef4b7 1049 wrdprintf("ret = %08x", d);\r
d0d47c5b 1050 goto end;\r
1051 }\r
1052\r
1053 // word RAM (1M area)\r
68cba51e 1054 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 1055 int bank;\r
913ef4b7 1056 wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);\r
68cba51e 1057// if (!(Pico_mcd->s68k_regs[3]&4))\r
1058// dprintf("s68k_wram1M FIXME: wrong mode");\r
3aa1e148 1059 bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1060 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
913ef4b7 1061 wrdprintf("ret = %08x", d);\r
ab0607f7 1062 goto end;\r
1063 }\r
1064\r
4f265db7 1065 // PCM\r
1066 if ((a&0xff8000)==0xff0000) {\r
2433f409 1067 dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 1068 a &= 0x7fff;\r
1069 if (a >= 0x2000) {\r
1070 a >>= 1;\r
1071 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] << 16;\r
1072 d |= Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff];\r
1073 } else if (a >= 0x20) {\r
1074 a &= 0x1e;\r
1075 if (a & 2) {\r
1076 a >>= 2;\r
1077 d = (Pico_mcd->pcm.ch[a].addr >> (PCM_STEP_SHIFT-8)) & 0xff0000;\r
1078 d |= (Pico_mcd->pcm.ch[(a+1)&7].addr >> PCM_STEP_SHIFT) & 0xff;\r
1079 } else {\r
1080 d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
1081 d = ((d<<16)&0xff0000) | ((d>>8)&0xff); // PCM chip is LE\r
1082 }\r
1083 }\r
1084 dprintf("ret = %08x", d);\r
1085 goto end;\r
1086 }\r
1087\r
ab0607f7 1088 // bram\r
1089 if ((a&0xff0000)==0xfe0000) {\r
4ff2d527 1090 dprintf("FIXME: s68k_bram r32: [%06x] @%06x", a, SekPcS68k);\r
ab0607f7 1091 a = (a>>1)&0x1fff;\r
1092 d = Pico_mcd->bram[a++] << 16; // middle endian? TODO: verify against Fusion..\r
1093 d|= Pico_mcd->bram[a++] << 24;\r
1094 d|= Pico_mcd->bram[a++];\r
1095 d|= Pico_mcd->bram[a++] << 8;\r
1096 dprintf("ret = %08x", d);\r
d0d47c5b 1097 goto end;\r
1098 }\r
1099\r
cc68a136 1100 dprintf("s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1101\r
1102 end:\r
1103\r
1104#ifdef __debug_io2\r
1105 dprintf("s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
b5e5172d 1106#endif\r
1107#ifdef EMU_CORE_DEBUG\r
1108 if (ab > 0x78) { // not vectors and stuff\r
1109 lastread_a = ab;\r
1110 lastread_d[lrp_cyc++&15] = d;\r
1111 }\r
cc68a136 1112#endif\r
1113 return d;\r
1114}\r
4ff2d527 1115#endif\r
cc68a136 1116\r
ab0607f7 1117\r
a4030801 1118#ifndef _ASM_CD_MEMORY_C\r
0a051f55 1119/* check: jaguar xj 220 (draws entire world using decode) */\r
1120static void decode_write8(u32 a, u8 d, int r3)\r
1121{\r
3aa1e148 1122 u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff);\r
0a051f55 1123 u8 oldmask = (a&1) ? 0xf0 : 0x0f;\r
1124\r
0a051f55 1125 r3 &= 0x18;\r
1126 d &= 0x0f;\r
1127 if (!(a&1)) d <<= 4;\r
1128\r
0a051f55 1129 if (r3 == 8) {\r
1130 if ((!(*pd & (~oldmask))) && d) goto do_it;\r
1131 } else if (r3 > 8) {\r
1132 if (d) goto do_it;\r
1133 } else {\r
1134 goto do_it;\r
1135 }\r
1136\r
1137 return;\r
1138do_it:\r
1139 *pd = d | (*pd & oldmask);\r
1140}\r
1141\r
1142\r
1143static void decode_write16(u32 a, u16 d, int r3)\r
1144{\r
3aa1e148 1145 u8 *pd = Pico_mcd->word_ram1M[(r3 & 1)^1] + (((a>>1)^1)&0x1ffff);\r
0a051f55 1146\r
1147 //if ((a & 0x3ffff) < 0x28000) return;\r
1148\r
1149 r3 &= 0x18;\r
1150 d &= 0x0f0f;\r
1151 d |= d >> 4;\r
1152\r
1153 if (r3 == 8) {\r
1154 u8 dold = *pd;\r
1155 if (!(dold & 0xf0)) dold |= d & 0xf0;\r
1156 if (!(dold & 0x0f)) dold |= d & 0x0f;\r
1157 *pd = dold;\r
1158 } else if (r3 > 8) {\r
1159 u8 dold = *pd;\r
1160 if (!(d & 0xf0)) d |= dold & 0xf0;\r
1161 if (!(d & 0x0f)) d |= dold & 0x0f;\r
1162 *pd = d;\r
1163 } else {\r
1164 *pd = d;\r
1165 }\r
0a051f55 1166}\r
a4030801 1167#endif\r
0a051f55 1168\r
cc68a136 1169// -----------------------------------------------------------------\r
1170\r
4ff2d527 1171#ifdef _ASM_CD_MEMORY_C\r
1172void PicoWriteS68k8(u32 a,u8 d);\r
1173#else\r
1174static void PicoWriteS68k8(u32 a,u8 d)\r
cc68a136 1175{\r
1176#ifdef __debug_io2\r
1177 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
1178#endif\r
1179\r
1180 a&=0xffffff;\r
1181\r
b5e5172d 1182#ifdef EMU_CORE_DEBUG\r
1183 lastwrite_cyc_d[lwp_cyc++&15] = d;\r
1184#endif\r
1185\r
cc68a136 1186 // prg RAM\r
1187 if (a < 0x80000) {\r
1188 u8 *pm=(u8 *)(Pico_mcd->prg_ram+(a^1));\r
721cd396 1189 if (a >= (Pico_mcd->s68k_regs[2]<<8)) *pm=d;\r
cc68a136 1190 return;\r
1191 }\r
1192\r
1193 // regs\r
1194 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 1195 a &= 0x1ff;\r
1196 rdprintf("s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1197 if (a >= 0x58 && a < 0x68)\r
48e8482f 1198 gfx_cd_write16(a&~1, (d<<8)|d);\r
cb4a513a 1199 else s68k_reg_write8(a,d);\r
cc68a136 1200 return;\r
1201 }\r
1202\r
d0d47c5b 1203 // word RAM (2M area)\r
1204 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
0a051f55 1205 int r3 = Pico_mcd->s68k_regs[3];\r
913ef4b7 1206 wrdprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
0a051f55 1207 if (r3 & 4) { // 1M decode mode?\r
1208 decode_write8(a, d, r3);\r
d0d47c5b 1209 } else {\r
1210 // allow access in any mode, like Gens does\r
fa1e5e29 1211 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
d0d47c5b 1212 }\r
1213 return;\r
1214 }\r
1215\r
1216 // word RAM (1M area)\r
68cba51e 1217 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
1218 // Wing Commander tries to write here in wrong mode\r
fa1e5e29 1219 int bank;\r
d0d47c5b 1220 if (d)\r
913ef4b7 1221 wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
68cba51e 1222// if (!(Pico_mcd->s68k_regs[3]&4))\r
1223// dprintf("s68k_wram1M FIXME: wrong mode");\r
3aa1e148 1224 bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1225 *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;\r
d0d47c5b 1226 return;\r
1227 }\r
1228\r
4f265db7 1229 // PCM\r
1230 if ((a&0xff8000)==0xff0000) {\r
1231 a &= 0x7fff;\r
1232 if (a >= 0x2000)\r
1233 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
1234 else if (a < 0x12)\r
1235 pcm_write(a>>1, d);\r
1236 return;\r
1237 }\r
1238\r
ab0607f7 1239 // bram\r
1240 if ((a&0xff0000)==0xfe0000) {\r
1241 Pico_mcd->bram[(a>>1)&0x1fff] = d;\r
1242 SRam.changed = 1;\r
1243 return;\r
1244 }\r
1245\r
cc68a136 1246 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
1247}\r
4ff2d527 1248#endif\r
cc68a136 1249\r
ab0607f7 1250\r
4ff2d527 1251#ifdef _ASM_CD_MEMORY_C\r
1252void PicoWriteS68k16(u32 a,u16 d);\r
1253#else\r
1254static void PicoWriteS68k16(u32 a,u16 d)\r
cc68a136 1255{\r
1256#ifdef __debug_io2\r
1257 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1258#endif\r
1259\r
1260 a&=0xfffffe;\r
1261\r
b5e5172d 1262#ifdef EMU_CORE_DEBUG\r
1263 lastwrite_cyc_d[lwp_cyc++&15] = d;\r
1264#endif\r
1265\r
cc68a136 1266 // prg RAM\r
1267 if (a < 0x80000) {\r
c008977e 1268 wrdprintf("s68k_prgram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
721cd396 1269 if (a >= (Pico_mcd->s68k_regs[2]<<8)) // needed for Dungeon Explorer\r
1270 *(u16 *)(Pico_mcd->prg_ram+a)=d;\r
cc68a136 1271 return;\r
1272 }\r
1273\r
1274 // regs\r
1275 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 1276 a &= 0x1fe;\r
1277 rdprintf("s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1278 if (a >= 0x58 && a < 0x68)\r
48e8482f 1279 gfx_cd_write16(a, d);\r
cb4a513a 1280 else {\r
1cd356a3 1281 if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
1282 Pico_mcd->s68k_regs[0xf] = d;\r
4ff2d527 1283 return;\r
1cd356a3 1284 }\r
cb4a513a 1285 s68k_reg_write8(a, d>>8);\r
1286 s68k_reg_write8(a+1,d&0xff);\r
1287 }\r
cc68a136 1288 return;\r
1289 }\r
1290\r
d0d47c5b 1291 // word RAM (2M area)\r
1292 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
0a051f55 1293 int r3 = Pico_mcd->s68k_regs[3];\r
913ef4b7 1294 wrdprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
0a051f55 1295 if (r3 & 4) { // 1M decode mode?\r
1296 decode_write16(a, d, r3);\r
d0d47c5b 1297 } else {\r
1298 // allow access in any mode, like Gens does\r
fa1e5e29 1299 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
d0d47c5b 1300 }\r
1301 return;\r
1302 }\r
1303\r
1304 // word RAM (1M area)\r
68cba51e 1305 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 1306 int bank;\r
d0d47c5b 1307 if (d)\r
913ef4b7 1308 wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
68cba51e 1309// if (!(Pico_mcd->s68k_regs[3]&4))\r
1310// dprintf("s68k_wram1M FIXME: wrong mode");\r
3aa1e148 1311 bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1312 *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;\r
d0d47c5b 1313 return;\r
1314 }\r
1315\r
4f265db7 1316 // PCM\r
1317 if ((a&0xff8000)==0xff0000) {\r
1318 a &= 0x7fff;\r
1319 if (a >= 0x2000)\r
1320 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
1321 else if (a < 0x12)\r
1322 pcm_write(a>>1, d & 0xff);\r
1323 return;\r
1324 }\r
1325\r
ab0607f7 1326 // bram\r
1327 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 1328 dprintf("s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
ab0607f7 1329 a = (a>>1)&0x1fff;\r
1330 Pico_mcd->bram[a++] = d; // Gens does little endian here, an so do we..\r
1331 Pico_mcd->bram[a++] = d >> 8;\r
1332 SRam.changed = 1;\r
1333 return;\r
1334 }\r
1335\r
cc68a136 1336 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1337}\r
4ff2d527 1338#endif\r
cc68a136 1339\r
ab0607f7 1340\r
4ff2d527 1341#ifdef _ASM_CD_MEMORY_C\r
1342void PicoWriteS68k32(u32 a,u32 d);\r
1343#else\r
1344static void PicoWriteS68k32(u32 a,u32 d)\r
cc68a136 1345{\r
1346#ifdef __debug_io2\r
1347 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1348#endif\r
1349\r
1350 a&=0xfffffe;\r
1351\r
b5e5172d 1352#ifdef EMU_CORE_DEBUG\r
1353 lastwrite_cyc_d[lwp_cyc++&15] = d;\r
1354#endif\r
1355\r
cc68a136 1356 // prg RAM\r
1357 if (a < 0x80000) {\r
721cd396 1358 if (a >= (Pico_mcd->s68k_regs[2]<<8)) {\r
1359 u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
1360 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
1361 }\r
cc68a136 1362 return;\r
1363 }\r
1364\r
1365 // regs\r
1366 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 1367 a &= 0x1fe;\r
1368 rdprintf("s68k_regs w32: [%02x] %08x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1369 if (a >= 0x58 && a < 0x68) {\r
48e8482f 1370 gfx_cd_write16(a, d>>16);\r
1371 gfx_cd_write16(a+2, d&0xffff);\r
cb4a513a 1372 } else {\r
2433f409 1373 if ((a&0x1fe) == 0xe) dprintf("s68k FIXME: w32 [%02x]", a&0x3f);\r
cb4a513a 1374 s68k_reg_write8(a, d>>24);\r
1375 s68k_reg_write8(a+1,(d>>16)&0xff);\r
1376 s68k_reg_write8(a+2,(d>>8) &0xff);\r
1377 s68k_reg_write8(a+3, d &0xff);\r
1378 }\r
cc68a136 1379 return;\r
1380 }\r
1381\r
d0d47c5b 1382 // word RAM (2M area)\r
1383 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
0a051f55 1384 int r3 = Pico_mcd->s68k_regs[3];\r
913ef4b7 1385 wrdprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
0a051f55 1386 if (r3 & 4) { // 1M decode mode?\r
1387 decode_write16(a , d >> 16, r3);\r
1388 decode_write16(a+2, d , r3);\r
d0d47c5b 1389 } else {\r
1390 // allow access in any mode, like Gens does\r
fa1e5e29 1391 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 1392 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
1393 }\r
1394 return;\r
1395 }\r
1396\r
1397 // word RAM (1M area)\r
68cba51e 1398 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 1399 int bank;\r
1400 u16 *pm;\r
d0d47c5b 1401 if (d)\r
913ef4b7 1402 wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
68cba51e 1403// if (!(Pico_mcd->s68k_regs[3]&4))\r
1404// dprintf("s68k_wram1M FIXME: wrong mode");\r
3aa1e148 1405 bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1406 pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1407 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
d0d47c5b 1408 return;\r
1409 }\r
ab0607f7 1410\r
4f265db7 1411 // PCM\r
1412 if ((a&0xff8000)==0xff0000) {\r
1413 a &= 0x7fff;\r
1414 if (a >= 0x2000) {\r
1415 a >>= 1;\r
1416 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] = (d >> 16);\r
1417 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff] = d;\r
1418 } else if (a < 0x12) {\r
1419 a >>= 1;\r
1420 pcm_write(a, (d>>16) & 0xff);\r
1421 pcm_write(a+1, d & 0xff);\r
1422 }\r
1423 return;\r
1424 }\r
1425\r
ab0607f7 1426 // bram\r
1427 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 1428 dprintf("s68k_bram w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
ab0607f7 1429 a = (a>>1)&0x1fff;\r
1430 Pico_mcd->bram[a++] = d >> 16; // middle endian? verify?\r
1431 Pico_mcd->bram[a++] = d >> 24;\r
1432 Pico_mcd->bram[a++] = d;\r
1433 Pico_mcd->bram[a++] = d >> 8;\r
1434 SRam.changed = 1;\r
1435 return;\r
1436 }\r
1437\r
cc68a136 1438 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1439}\r
4ff2d527 1440#endif\r
cc68a136 1441\r
1442\r
1443// -----------------------------------------------------------------\r
1444\r
b837b69b 1445\r
3aa1e148 1446#ifdef EMU_C68K\r
b837b69b 1447static __inline int PicoMemBaseM68k(u32 pc)\r
1448{\r
fa1e5e29 1449 if ((pc&0xe00000)==0xe00000)\r
1450 return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
b837b69b 1451\r
1452 if (pc < 0x20000)\r
fa1e5e29 1453 return (int)Pico_mcd->bios; // Program Counter in BIOS\r
1454\r
1455 if ((pc&0xfc0000)==0x200000)\r
b837b69b 1456 {\r
fa1e5e29 1457 if (!(Pico_mcd->s68k_regs[3]&4))\r
1458 return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram\r
1459 if (pc < 0x220000) {\r
3aa1e148 1460 int bank = Pico_mcd->s68k_regs[3]&1;\r
fa1e5e29 1461 return (int)Pico_mcd->word_ram1M[bank] - 0x200000;\r
1462 }\r
b837b69b 1463 }\r
1464\r
fa1e5e29 1465 // Error - Program Counter is invalid\r
1466 dprintf("m68k FIXME: unhandled jump to %06x", pc);\r
1467\r
1468 return (int)Pico_mcd->bios;\r
b837b69b 1469}\r
1470\r
1471\r
1472static u32 PicoCheckPcM68k(u32 pc)\r
1473{\r
3aa1e148 1474 pc-=PicoCpuCM68k.membase; // Get real pc\r
b837b69b 1475 pc&=0xfffffe;\r
1476\r
3aa1e148 1477 PicoCpuCM68k.membase=PicoMemBaseM68k(pc);\r
b837b69b 1478\r
3aa1e148 1479 return PicoCpuCM68k.membase+pc;\r
b837b69b 1480}\r
1481\r
1482\r
1483static __inline int PicoMemBaseS68k(u32 pc)\r
1484{\r
fa1e5e29 1485 if (pc < 0x80000) // PRG RAM\r
1486 return (int)Pico_mcd->prg_ram;\r
b837b69b 1487\r
fa1e5e29 1488 if ((pc&0xfc0000)==0x080000) // WORD RAM 2M area (assume we are in the right mode..)\r
1489 return (int)Pico_mcd->word_ram2M - 0x080000;\r
1490\r
1491 if ((pc&0xfe0000)==0x0c0000) { // word RAM 1M area\r
3aa1e148 1492 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1493 return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;\r
b837b69b 1494 }\r
1495\r
fa1e5e29 1496 // Error - Program Counter is invalid\r
1497 dprintf("s68k FIXME: unhandled jump to %06x", pc);\r
1498\r
1499 return (int)Pico_mcd->prg_ram;\r
b837b69b 1500}\r
1501\r
1502\r
1503static u32 PicoCheckPcS68k(u32 pc)\r
1504{\r
3aa1e148 1505 pc-=PicoCpuCS68k.membase; // Get real pc\r
b837b69b 1506 pc&=0xfffffe;\r
1507\r
3aa1e148 1508 PicoCpuCS68k.membase=PicoMemBaseS68k(pc);\r
b837b69b 1509\r
3aa1e148 1510 return PicoCpuCS68k.membase+pc;\r
b837b69b 1511}\r
1512#endif\r
1513\r
3aa1e148 1514#ifndef _ASM_CD_MEMORY_C\r
1515void PicoMemResetCD(int r3)\r
1516{\r
1517#ifdef EMU_F68K\r
1518 // update fetchmap..\r
1519 int i;\r
1520 if (!(r3 & 4))\r
1521 {\r
1522 for (i = M68K_FETCHBANK1*2/16; (i<<(24-FAMEC_FETCHBITS)) < 0x240000; i++)\r
1523 PicoCpuFM68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram2M - 0x200000;\r
1524 }\r
1525 else\r
1526 {\r
1527 for (i = M68K_FETCHBANK1*2/16; (i<<(24-FAMEC_FETCHBITS)) < 0x220000; i++)\r
1528 PicoCpuFM68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram1M[r3 & 1] - 0x200000;\r
1529 for (i = M68K_FETCHBANK1*0x0c/0x100; (i<<(24-FAMEC_FETCHBITS)) < 0x0e0000; i++)\r
1530 PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram1M[(r3&1)^1] - 0x0c0000;\r
1531 }\r
1532#endif\r
1533}\r
1534#endif\r
b837b69b 1535\r
eff55556 1536PICO_INTERNAL void PicoMemSetupCD(void)\r
b837b69b 1537{\r
1538 dprintf("PicoMemSetupCD()");\r
1539#ifdef EMU_C68K\r
1540 // Setup m68k memory callbacks:\r
3aa1e148 1541 PicoCpuCM68k.checkpc=PicoCheckPcM68k;\r
1542 PicoCpuCM68k.fetch8 =PicoCpuCM68k.read8 =PicoReadM68k8;\r
1543 PicoCpuCM68k.fetch16=PicoCpuCM68k.read16=PicoReadM68k16;\r
1544 PicoCpuCM68k.fetch32=PicoCpuCM68k.read32=PicoReadM68k32;\r
1545 PicoCpuCM68k.write8 =PicoWriteM68k8;\r
1546 PicoCpuCM68k.write16=PicoWriteM68k16;\r
1547 PicoCpuCM68k.write32=PicoWriteM68k32;\r
b837b69b 1548 // s68k\r
3aa1e148 1549 PicoCpuCS68k.checkpc=PicoCheckPcS68k;\r
1550 PicoCpuCS68k.fetch8 =PicoCpuCS68k.read8 =PicoReadS68k8;\r
1551 PicoCpuCS68k.fetch16=PicoCpuCS68k.read16=PicoReadS68k16;\r
1552 PicoCpuCS68k.fetch32=PicoCpuCS68k.read32=PicoReadS68k32;\r
1553 PicoCpuCS68k.write8 =PicoWriteS68k8;\r
1554 PicoCpuCS68k.write16=PicoWriteS68k16;\r
1555 PicoCpuCS68k.write32=PicoWriteS68k32;\r
b837b69b 1556#endif\r
3aa1e148 1557#ifdef EMU_F68K\r
1558 // m68k\r
1559 PicoCpuFM68k.read_byte =PicoReadM68k8;\r
1560 PicoCpuFM68k.read_word =PicoReadM68k16;\r
1561 PicoCpuFM68k.read_long =PicoReadM68k32;\r
1562 PicoCpuFM68k.write_byte=PicoWriteM68k8;\r
1563 PicoCpuFM68k.write_word=PicoWriteM68k16;\r
1564 PicoCpuFM68k.write_long=PicoWriteM68k32;\r
1565 // s68k\r
1566 PicoCpuFS68k.read_byte =PicoReadS68k8;\r
1567 PicoCpuFS68k.read_word =PicoReadS68k16;\r
1568 PicoCpuFS68k.read_long =PicoReadS68k32;\r
1569 PicoCpuFS68k.write_byte=PicoWriteS68k8;\r
1570 PicoCpuFS68k.write_word=PicoWriteS68k16;\r
1571 PicoCpuFS68k.write_long=PicoWriteS68k32;\r
1572\r
1573 // setup FAME fetchmap\r
1574 {\r
1575 int i;\r
1576 // M68k\r
1577 // by default, point everything to fitst 64k of ROM (BIOS)\r
1578 for (i = 0; i < M68K_FETCHBANK1; i++)\r
1579 PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom - (i<<(24-FAMEC_FETCHBITS));\r
1580 // now real ROM (BIOS)\r
1581 for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < Pico.romsize; i++)\r
1582 PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.rom;\r
1583 // .. and RAM\r
1584 for (i = M68K_FETCHBANK1*14/16; i < M68K_FETCHBANK1; i++)\r
1585 PicoCpuFM68k.Fetch[i] = (unsigned int)Pico.ram - (i<<(24-FAMEC_FETCHBITS));\r
1586 // S68k\r
1587 // PRG RAM is default\r
1588 for (i = 0; i < M68K_FETCHBANK1; i++)\r
1589 PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->prg_ram - (i<<(24-FAMEC_FETCHBITS));\r
1590 // real PRG RAM\r
1591 for (i = 0; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0x80000; i++)\r
1592 PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->prg_ram;\r
1593 // WORD RAM 2M area\r
1594 for (i = M68K_FETCHBANK1*0x08/0x100; i < M68K_FETCHBANK1 && (i<<(24-FAMEC_FETCHBITS)) < 0xc0000; i++)\r
1595 PicoCpuFS68k.Fetch[i] = (unsigned int)Pico_mcd->word_ram2M - 0x80000;\r
1596 // PicoMemResetCD() will setup word ram for both\r
1597 }\r
1598#endif\r
1599\r
7a1f6e45 1600 // m68k_poll_addr = m68k_poll_cnt = 0;\r
1601 s68k_poll_adclk = s68k_poll_cnt = 0;\r
b837b69b 1602}\r
1603\r
1604\r
cc68a136 1605#ifdef EMU_M68K\r
1606unsigned char PicoReadCD8w (unsigned int a) {\r
3aa1e148 1607 return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k8(a) : PicoReadM68k8(a);\r
cc68a136 1608}\r
1609unsigned short PicoReadCD16w(unsigned int a) {\r
3aa1e148 1610 return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k16(a) : PicoReadM68k16(a);\r
cc68a136 1611}\r
1612unsigned int PicoReadCD32w(unsigned int a) {\r
3aa1e148 1613 return m68ki_cpu_p == &PicoCpuMS68k ? PicoReadS68k32(a) : PicoReadM68k32(a);\r
cc68a136 1614}\r
1615void PicoWriteCD8w (unsigned int a, unsigned char d) {\r
3aa1e148 1616 if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);\r
cc68a136 1617}\r
1618void PicoWriteCD16w(unsigned int a, unsigned short d) {\r
3aa1e148 1619 if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);\r
cc68a136 1620}\r
1621void PicoWriteCD32w(unsigned int a, unsigned int d) {\r
3aa1e148 1622 if (m68ki_cpu_p == &PicoCpuMS68k) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);\r
cc68a136 1623}\r
1624\r
1625// these are allowed to access RAM\r
b5e5172d 1626unsigned int m68k_read_pcrelative_CD8 (unsigned int a)\r
1627{\r
cc68a136 1628 a&=0xffffff;\r
3aa1e148 1629 if(m68ki_cpu_p == &PicoCpuMS68k) {\r
cc68a136 1630 if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram\r
fa1e5e29 1631 if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
1632 return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));\r
1633 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
3aa1e148 1634 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1635 return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));\r
1636 }\r
1637 dprintf("s68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);\r
cc68a136 1638 } else {\r
cc68a136 1639 if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
fa1e5e29 1640 if(a<0x20000) return *(u8 *)(Pico.rom+(a^1)); // Bios\r
1641 if((a&0xfc0000)==0x200000) { // word RAM\r
1642 if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
1643 return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));\r
1644 else if (a < 0x220000) {\r
1645 int bank = Pico_mcd->s68k_regs[3]&1;\r
1646 return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));\r
1647 }\r
1648 }\r
1649 dprintf("m68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);\r
cc68a136 1650 }\r
1651 return 0;//(u8) lastread_d;\r
1652}\r
b5e5172d 1653unsigned int m68k_read_pcrelative_CD16(unsigned int a)\r
1654{\r
cc68a136 1655 a&=0xffffff;\r
3aa1e148 1656 if(m68ki_cpu_p == &PicoCpuMS68k) {\r
cc68a136 1657 if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram\r
fa1e5e29 1658 if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
1659 return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
1660 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
3aa1e148 1661 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1662 return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1663 }\r
1664 dprintf("s68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);\r
cc68a136 1665 } else {\r
cc68a136 1666 if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram\r
fa1e5e29 1667 if(a<0x20000) return *(u16 *)(Pico.rom+(a&~1)); // Bios\r
1668 if((a&0xfc0000)==0x200000) { // word RAM\r
1669 if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
1670 return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
1671 else if (a < 0x220000) {\r
1672 int bank = Pico_mcd->s68k_regs[3]&1;\r
1673 return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1674 }\r
1675 }\r
1676 dprintf("m68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);\r
cc68a136 1677 }\r
b837b69b 1678 return 0;\r
cc68a136 1679}\r
b5e5172d 1680unsigned int m68k_read_pcrelative_CD32(unsigned int a)\r
1681{\r
fa1e5e29 1682 u16 *pm;\r
cc68a136 1683 a&=0xffffff;\r
3aa1e148 1684 if(m68ki_cpu_p == &PicoCpuMS68k) {\r
cc68a136 1685 if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram\r
fa1e5e29 1686 if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
1687 { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
1688 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
3aa1e148 1689 int bank = (Pico_mcd->s68k_regs[3]&1)^1;\r
fa1e5e29 1690 pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1691 return (pm[0]<<16)|pm[1];\r
1692 }\r
1693 dprintf("s68k_read_pcrelative_CD32 FIXME: can't handle %06x", a);\r
cc68a136 1694 } else {\r
cc68a136 1695 if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram\r
fa1e5e29 1696 if(a<0x20000) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; }\r
1697 if((a&0xfc0000)==0x200000) { // word RAM\r
1698 if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
1699 { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
1700 else if (a < 0x220000) {\r
1701 int bank = Pico_mcd->s68k_regs[3]&1;\r
1702 pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1703 return (pm[0]<<16)|pm[1];\r
1704 }\r
1705 }\r
1706 dprintf("m68k_read_pcrelative_CD32 FIXME: can't handle %06x", a);\r
cc68a136 1707 }\r
b837b69b 1708 return 0;\r
cc68a136 1709}\r
1710#endif // EMU_M68K\r
1711\r