font data implemented
[picodrive.git] / Pico / cd / Memory.c
CommitLineData
cc68a136 1// This is part of Pico Library\r
2\r
3// (c) Copyright 2004 Dave, All rights reserved.\r
b837b69b 4// (c) Copyright 2007 notaz, All rights reserved.\r
cc68a136 5// Free for non-commercial use.\r
6\r
7// For commercial use, separate licencing terms must be obtained.\r
8\r
9// A68K no longer supported here\r
10\r
11//#define __debug_io\r
12\r
13#include "../PicoInt.h"\r
14\r
15#include "../sound/sound.h"\r
16#include "../sound/ym2612.h"\r
17#include "../sound/sn76496.h"\r
18\r
cb4a513a 19#include "gfx_cd.h"\r
4f265db7 20#include "pcm.h"\r
cb4a513a 21\r
fa1e5e29 22#include "cell_map.c"\r
23\r
cc68a136 24typedef unsigned char u8;\r
25typedef unsigned short u16;\r
26typedef unsigned int u32;\r
27\r
28//#define __debug_io\r
29//#define __debug_io2\r
d1df8786 30//#define rdprintf dprintf\r
31#define rdprintf(...)\r
913ef4b7 32#define wrdprintf(...)\r
cc68a136 33\r
34// -----------------------------------------------------------------\r
35\r
cc68a136 36\r
cb4a513a 37static u32 m68k_reg_read16(u32 a)\r
cc68a136 38{\r
39 u32 d=0;\r
40 a &= 0x3e;\r
672ad671 41 // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc);\r
cc68a136 42\r
43 switch (a) {\r
672ad671 44 case 0:\r
c459aefd 45 d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens\r
672ad671 46 goto end;\r
cc68a136 47 case 2:\r
672ad671 48 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
1cd356a3 49 dprintf("m68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
cc68a136 50 goto end;\r
c459aefd 51 case 4:\r
52 d = Pico_mcd->s68k_regs[4]<<8;\r
53 goto end;\r
54 case 6:\r
913ef4b7 55 d = *(u16 *)(Pico_mcd->bios + 0x72);\r
c459aefd 56 goto end;\r
cc68a136 57 case 8:\r
cc68a136 58 d = Read_CDC_Host(0);\r
59 goto end;\r
c459aefd 60 case 0xA:\r
fa1e5e29 61 dprintf("m68k FIXME: reserved read");\r
c459aefd 62 goto end;\r
cc68a136 63 case 0xC:\r
d1df8786 64 dprintf("m68k stopwatch timer read");\r
1cd356a3 65 d = Pico_mcd->m.timer_stopwatch >> 16;\r
66 goto end;\r
cc68a136 67 }\r
68\r
cc68a136 69 if (a < 0x30) {\r
70 // comm flag/cmd/status (0xE-0x2F)\r
71 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
72 goto end;\r
73 }\r
74\r
fa1e5e29 75 dprintf("m68k_regs FIXME invalid read @ %02x", a);\r
cc68a136 76\r
77end:\r
78\r
672ad671 79 // dprintf("ret = %04x", d);\r
cc68a136 80 return d;\r
81}\r
82\r
cb4a513a 83static void m68k_reg_write8(u32 a, u32 d)\r
cc68a136 84{\r
85 a &= 0x3f;\r
672ad671 86 // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc);\r
cc68a136 87\r
88 switch (a) {\r
89 case 0:\r
672ad671 90 d &= 1;\r
cc68a136 91 if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { dprintf("m68k: s68k irq 2"); SekInterruptS68k(2); }\r
c459aefd 92 return;\r
cc68a136 93 case 1:\r
672ad671 94 d &= 3;\r
51a902ae 95 if (!(d&1)) Pico_mcd->m.state_flags |= 1; // reset pending, needed to be sure we fetch the right vectors on reset\r
c459aefd 96 if ( (Pico_mcd->m.busreq&1) != (d&1)) dprintf("m68k: s68k reset %i", !(d&1));\r
97 if ( (Pico_mcd->m.busreq&2) != (d&2)) dprintf("m68k: s68k brq %i", (d&2)>>1);\r
51a902ae 98 if ((Pico_mcd->m.state_flags&1) && (d&3)==1) {\r
cc68a136 99 SekResetS68k(); // S68k comes out of RESET or BRQ state\r
51a902ae 100 Pico_mcd->m.state_flags&=~1;\r
672ad671 101 dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
cc68a136 102 }\r
c459aefd 103 Pico_mcd->m.busreq = d;\r
104 return;\r
672ad671 105 case 2:\r
106 Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
107 return;\r
cc68a136 108 case 3:\r
bf098bc5 109 dprintf("m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
672ad671 110 d &= 0xc2;\r
111 if ((Pico_mcd->s68k_regs[3]>>6) != ((d>>6)&3))\r
112 dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
113 //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2);\r
114 //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") :\r
115 // ((d&2) ? "word ram to s68k" : "word ram to m68k"));\r
116 d |= Pico_mcd->s68k_regs[3]&0x1d;\r
d0d47c5b 117 if (!(d & 4) && (d & 2)) d &= ~1; // return word RAM to s68k in 2M mode\r
672ad671 118 Pico_mcd->s68k_regs[3] = d; // really use s68k side register\r
119 return;\r
c459aefd 120 case 6:\r
d1df8786 121 Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
c459aefd 122 return;\r
123 case 7:\r
d1df8786 124 Pico_mcd->bios[0x72] = d;\r
913ef4b7 125 dprintf("hint vector set to %08x", PicoRead32(0x70));\r
c459aefd 126 return;\r
cc68a136 127 case 0xe:\r
672ad671 128 //dprintf("m68k: comm flag: %02x", d);\r
cc68a136 129 Pico_mcd->s68k_regs[0xe] = d;\r
c459aefd 130 return;\r
672ad671 131 }\r
132\r
133 if ((a&0xf0) == 0x10) {\r
cc68a136 134 Pico_mcd->s68k_regs[a] = d;\r
672ad671 135 return;\r
cc68a136 136 }\r
137\r
fa1e5e29 138 dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);\r
cc68a136 139}\r
140\r
141\r
913ef4b7 142#define READ_FONT_DATA(basemask) \\r
143{ \\r
144 unsigned int fnt = *(unsigned int *)(Pico_mcd->s68k_regs + 0x4c); \\r
145 unsigned int col0 = (fnt >> 8) & 0x0f, col1 = (fnt >> 12) & 0x0f; \\r
146 if (fnt & (basemask << 0)) d = col1 ; else d = col0; \\r
147 if (fnt & (basemask << 1)) d |= col1 << 4; else d |= col0 << 4; \\r
148 if (fnt & (basemask << 2)) d |= col1 << 8; else d |= col0 << 8; \\r
149 if (fnt & (basemask << 3)) d |= col1 << 12; else d |= col0 << 12; \\r
150}\r
151\r
cc68a136 152\r
cb4a513a 153static u32 s68k_reg_read16(u32 a)\r
cc68a136 154{\r
155 u32 d=0;\r
cc68a136 156\r
672ad671 157 // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k);\r
cc68a136 158\r
159 switch (a) {\r
160 case 0:\r
cb4a513a 161 d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
c459aefd 162 goto end;\r
672ad671 163 case 2:\r
164 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
bf098bc5 165 dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
672ad671 166 goto end;\r
cc68a136 167 case 6:\r
168 d = CDC_Read_Reg();\r
169 goto end;\r
170 case 8:\r
cb4a513a 171 d = Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
cc68a136 172 goto end;\r
173 case 0xC:\r
d1df8786 174 dprintf("s68k stopwatch timer read");\r
4f265db7 175 d = Pico_mcd->m.timer_stopwatch >> 16;\r
176 goto end;\r
d1df8786 177 case 0x30:\r
178 dprintf("s68k int3 timer read");\r
cc68a136 179 break;\r
180 case 0x34: // fader\r
181 d = 0; // no busy bit\r
182 goto end;\r
913ef4b7 183 case 0x50: // font data (check: Lunar 2, Silpheed)\r
184 READ_FONT_DATA(0x00100000);\r
185 goto end;\r
186 case 0x52:\r
187 READ_FONT_DATA(0x00010000);\r
188 goto end;\r
189 case 0x54:\r
190 READ_FONT_DATA(0x10000000);\r
191 goto end;\r
192 case 0x56:\r
193 READ_FONT_DATA(0x01000000);\r
194 goto end;\r
cc68a136 195 }\r
196\r
197 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
198\r
199end:\r
200\r
672ad671 201 // dprintf("ret = %04x", d);\r
cc68a136 202\r
203 return d;\r
204}\r
205\r
cb4a513a 206static void s68k_reg_write8(u32 a, u32 d)\r
cc68a136 207{\r
672ad671 208 //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k);\r
cc68a136 209\r
210 // TODO: review against Gens\r
211 switch (a) {\r
672ad671 212 case 2:\r
213 return; // only m68k can change WP\r
fa1e5e29 214 case 3: {\r
215 int dold = Pico_mcd->s68k_regs[3];\r
bf098bc5 216 dprintf("s68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
672ad671 217 d &= 0x1d;\r
d0d47c5b 218 if (d&4) {\r
fa1e5e29 219 d |= dold&0xc2;\r
220 if ((d ^ dold) & 5) d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
221 if (!(dold & 4)) {\r
222 dprintf("wram mode 2M->1M");\r
223 wram_2M_to_1M(Pico_mcd->word_ram2M);\r
224 }\r
d0d47c5b 225 } else {\r
226 d |= Pico_mcd->s68k_regs[3]&0xc3;\r
227 if (d&1) d &= ~2; // return word RAM to m68k in 2M mode\r
fa1e5e29 228 if (dold & 4) {\r
229 dprintf("wram mode 1M->2M");\r
230 wram_1M_to_2M(Pico_mcd->word_ram2M);\r
231 }\r
d0d47c5b 232 }\r
672ad671 233 break;\r
fa1e5e29 234 }\r
cc68a136 235 case 4:\r
236 dprintf("s68k CDC dest: %x", d&7);\r
237 Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode\r
238 return;\r
239 case 5:\r
c459aefd 240 //dprintf("s68k CDC reg addr: %x", d&0xf);\r
cc68a136 241 break;\r
242 case 7:\r
243 CDC_Write_Reg(d);\r
244 return;\r
245 case 0xa:\r
246 dprintf("s68k set CDC dma addr");\r
247 break;\r
d1df8786 248 case 0xc:\r
4f265db7 249 case 0xd:\r
d1df8786 250 dprintf("s68k set stopwatch timer");\r
4f265db7 251 Pico_mcd->m.timer_stopwatch = 0;\r
252 return;\r
1cd356a3 253 case 0xe:\r
254 Pico_mcd->s68k_regs[0Xf] = (d>>1) | (d<<7); // ror8, Gens note: Dragons lair\r
255 Pico_mcd->m.timer_stopwatch = 0;\r
256 return;\r
d1df8786 257 case 0x31:\r
4f265db7 258 dprintf("s68k set int3 timer: %02x", d);\r
259 Pico_mcd->m.timer_int3 = d << 16;\r
d1df8786 260 break;\r
cc68a136 261 case 0x33: // IRQ mask\r
262 dprintf("s68k irq mask: %02x", d);\r
263 if ((d&(1<<4)) && (Pico_mcd->s68k_regs[0x37]&4) && !(Pico_mcd->s68k_regs[0x33]&(1<<4))) {\r
264 CDD_Export_Status();\r
cc68a136 265 }\r
266 break;\r
267 case 0x34: // fader\r
268 Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
269 return;\r
672ad671 270 case 0x36:\r
271 return; // d/m bit is unsetable\r
272 case 0x37: {\r
273 u32 d_old = Pico_mcd->s68k_regs[0x37];\r
274 Pico_mcd->s68k_regs[0x37] = d&7;\r
275 if ((d&4) && !(d_old&4)) {\r
cc68a136 276 CDD_Export_Status();\r
cc68a136 277 }\r
672ad671 278 return;\r
279 }\r
cc68a136 280 case 0x4b:\r
281 Pico_mcd->s68k_regs[a] = (u8) d;\r
282 CDD_Import_Command();\r
283 return;\r
284 }\r
285\r
1cd356a3 286 if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
cc68a136 287 {\r
fa1e5e29 288 dprintf("s68k FIXME: invalid write @ %02x?", a);\r
cc68a136 289 return;\r
290 }\r
291\r
292 Pico_mcd->s68k_regs[a] = (u8) d;\r
293}\r
294\r
295\r
296\r
fa1e5e29 297static u32 OtherRead16End(u32 a, int realsize)\r
cc68a136 298{\r
299 u32 d=0;\r
300\r
672ad671 301 if ((a&0xffffc0)==0xa12000) {\r
cb4a513a 302 d=m68k_reg_read16(a);\r
672ad671 303 goto end;\r
304 }\r
cc68a136 305\r
fa1e5e29 306 dprintf("m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
cc68a136 307\r
308end:\r
309 return d;\r
310}\r
311\r
cc68a136 312\r
fa1e5e29 313static void OtherWrite8End(u32 a, u32 d, int realsize)\r
cc68a136 314{\r
cb4a513a 315 if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
cc68a136 316\r
fa1e5e29 317 dprintf("m68k FIXME: strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
cc68a136 318}\r
319\r
cc68a136 320\r
fa1e5e29 321#undef _ASM_MEMORY_C\r
322#include "../MemoryCmn.c"\r
323\r
cc68a136 324\r
325// -----------------------------------------------------------------\r
326// Read Rom and read Ram\r
327\r
328u8 PicoReadM68k8(u32 a)\r
329{\r
330 u32 d=0;\r
331\r
332 if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram\r
333\r
334 a&=0xffffff;\r
335\r
336 if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios\r
337\r
338 // prg RAM\r
339 if ((a&0xfe0000)==0x020000) {\r
672ad671 340 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 341 d = *(prg_bank+((a^1)&0x1ffff));\r
342 goto end;\r
343 }\r
344\r
b837b69b 345#if 0\r
346 if (a == 0x200000 && SekPc == 0xff0b66 && Pico.m.frame_count > 1000)\r
347 {\r
348 int i;\r
349 FILE *ff;\r
350 unsigned short *ram = (unsigned short *) Pico.ram;\r
351 // unswap and dump RAM\r
352 for (i = 0; i < 0x10000/2; i++)\r
353 ram[i] = (ram[i]>>8) | (ram[i]<<8);\r
354 ff = fopen("ram.bin", "wb");\r
355 fwrite(ram, 1, 0x10000, ff);\r
356 fclose(ff);\r
357 exit(0);\r
358 }\r
359#endif\r
360\r
d0d47c5b 361 // word RAM\r
362 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 363 wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
d0d47c5b 364 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 365 int bank = Pico_mcd->s68k_regs[3]&1;\r
366 if (a >= 0x220000)\r
367 a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
368 else a &= 0x1ffff;\r
369 d = Pico_mcd->word_ram1M[bank][a^1];\r
d0d47c5b 370 } else {\r
371 // allow access in any mode, like Gens does\r
fa1e5e29 372 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
d0d47c5b 373 }\r
913ef4b7 374 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 375 goto end;\r
376 }\r
377\r
cc68a136 378 if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
379\r
c459aefd 380 if ((a&0xffffc0)==0xa12000)\r
381 rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 382\r
cc68a136 383 d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
384\r
c459aefd 385 if ((a&0xffffc0)==0xa12000)\r
386 rdprintf("ret = %02x", (u8)d);\r
672ad671 387\r
cc68a136 388 end:\r
389\r
390#ifdef __debug_io\r
391 dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
392#endif\r
393 return (u8)d;\r
394}\r
395\r
ab0607f7 396\r
cc68a136 397u16 PicoReadM68k16(u32 a)\r
398{\r
399 u16 d=0;\r
400\r
401 if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram\r
402\r
403 a&=0xfffffe;\r
404\r
405 if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios\r
406\r
407 // prg RAM\r
408 if ((a&0xfe0000)==0x020000) {\r
672ad671 409 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 410 d = *(u16 *)(prg_bank+(a&0x1fffe));\r
411 goto end;\r
412 }\r
413\r
d0d47c5b 414 // word RAM\r
415 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 416 wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
d0d47c5b 417 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 418 int bank = Pico_mcd->s68k_regs[3]&1;\r
419 if (a >= 0x220000)\r
420 a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
421 else a &= 0x1fffe;\r
422 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a);\r
d0d47c5b 423 } else {\r
424 // allow access in any mode, like Gens does\r
fa1e5e29 425 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 426 }\r
913ef4b7 427 wrdprintf("ret = %04x", d);\r
d0d47c5b 428 goto end;\r
429 }\r
430\r
c459aefd 431 if ((a&0xffffc0)==0xa12000)\r
432 rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 433\r
cc68a136 434 d = (u16)OtherRead16(a, 16);\r
435\r
c459aefd 436 if ((a&0xffffc0)==0xa12000)\r
437 rdprintf("ret = %04x", d);\r
672ad671 438\r
cc68a136 439 end:\r
440\r
441#ifdef __debug_io\r
442 dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
443#endif\r
444 return d;\r
445}\r
446\r
ab0607f7 447\r
cc68a136 448u32 PicoReadM68k32(u32 a)\r
449{\r
450 u32 d=0;\r
451\r
452 if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram\r
453\r
454 a&=0xfffffe;\r
455\r
456 if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios\r
457\r
458 // prg RAM\r
459 if ((a&0xfe0000)==0x020000) {\r
672ad671 460 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 461 u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
462 d = (pm[0]<<16)|pm[1];\r
463 goto end;\r
464 }\r
465\r
d0d47c5b 466 // word RAM\r
467 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 468 wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
d0d47c5b 469 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 470 int bank = Pico_mcd->s68k_regs[3]&1;\r
471 if (a >= 0x220000) { // cell arranged\r
472 u32 a1, a2;\r
473 a1 = (a&2) | (cell_map(a >> 2) << 2);\r
474 if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
475 else a2 = a1 + 2;\r
476 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) << 16;\r
477 d |= *(u16 *)(Pico_mcd->word_ram1M[bank]+a2);\r
bf098bc5 478 } else {\r
fa1e5e29 479 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
bf098bc5 480 }\r
d0d47c5b 481 } else {\r
482 // allow access in any mode, like Gens does\r
fa1e5e29 483 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d0d47c5b 484 }\r
913ef4b7 485 wrdprintf("ret = %08x", d);\r
d0d47c5b 486 goto end;\r
487 }\r
488\r
c459aefd 489 if ((a&0xffffc0)==0xa12000)\r
490 rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 491\r
cc68a136 492 d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
493\r
c459aefd 494 if ((a&0xffffc0)==0xa12000)\r
495 rdprintf("ret = %08x", d);\r
672ad671 496\r
cc68a136 497 end:\r
498#ifdef __debug_io\r
499 dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
500#endif\r
501 return d;\r
502}\r
503\r
ab0607f7 504\r
cc68a136 505// -----------------------------------------------------------------\r
506// Write Ram\r
507\r
508void PicoWriteM68k8(u32 a,u8 d)\r
509{\r
510#ifdef __debug_io\r
511 dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);\r
512#endif\r
513 //if ((a&0xe0ffff)==0xe0a9ba+0x69c)\r
514 // dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);\r
515\r
516\r
ab0607f7 517 if ((a&0xe00000)==0xe00000) { // Ram\r
518 *(u8 *)(Pico.ram+((a^1)&0xffff)) = d;\r
519 return;\r
520 }\r
cc68a136 521\r
522 a&=0xffffff;\r
523\r
524 // prg RAM\r
525 if ((a&0xfe0000)==0x020000) {\r
672ad671 526 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
bf098bc5 527 *(u8 *)(prg_bank+((a^1)&0x1ffff))=d;\r
cc68a136 528 return;\r
529 }\r
530\r
d0d47c5b 531 // word RAM\r
532 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 533 wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
d0d47c5b 534 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 535 int bank = Pico_mcd->s68k_regs[3]&1;\r
536 if (a >= 0x220000)\r
537 a = (a&3) | (cell_map(a >> 2) << 2); // cell arranged\r
538 else a &= 0x1ffff;\r
539 *(u8 *)(Pico_mcd->word_ram1M[bank]+(a^1))=d;\r
d0d47c5b 540 } else {\r
541 // allow access in any mode, like Gens does\r
fa1e5e29 542 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
d0d47c5b 543 }\r
544 return;\r
545 }\r
546\r
c459aefd 547 if ((a&0xffffc0)==0xa12000)\r
548 rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
672ad671 549\r
cc68a136 550 OtherWrite8(a,d,8);\r
551}\r
552\r
ab0607f7 553\r
cc68a136 554void PicoWriteM68k16(u32 a,u16 d)\r
555{\r
556#ifdef __debug_io\r
557 dprintf("w16: %06x, %04x", a&0xffffff, d);\r
558#endif\r
cc68a136 559 // dprintf("w16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
560\r
ab0607f7 561 if ((a&0xe00000)==0xe00000) { // Ram\r
562 *(u16 *)(Pico.ram+(a&0xfffe))=d;\r
563 return;\r
564 }\r
cc68a136 565\r
566 a&=0xfffffe;\r
567\r
568 // prg RAM\r
569 if ((a&0xfe0000)==0x020000) {\r
672ad671 570 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 571 *(u16 *)(prg_bank+(a&0x1fffe))=d;\r
572 return;\r
573 }\r
574\r
d0d47c5b 575 // word RAM\r
576 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 577 wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
d0d47c5b 578 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 579 int bank = Pico_mcd->s68k_regs[3]&1;\r
580 if (a >= 0x220000)\r
581 a = (a&2) | (cell_map(a >> 2) << 2); // cell arranged\r
582 else a &= 0x1fffe;\r
583 *(u16 *)(Pico_mcd->word_ram1M[bank]+a)=d;\r
d0d47c5b 584 } else {\r
585 // allow access in any mode, like Gens does\r
fa1e5e29 586 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
d0d47c5b 587 }\r
588 return;\r
589 }\r
590\r
c459aefd 591 if ((a&0xffffc0)==0xa12000)\r
592 rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
cc68a136 593\r
594 OtherWrite16(a,d);\r
595}\r
596\r
ab0607f7 597\r
cc68a136 598void PicoWriteM68k32(u32 a,u32 d)\r
599{\r
600#ifdef __debug_io\r
601 dprintf("w32: %06x, %08x", a&0xffffff, d);\r
602#endif\r
603\r
604 if ((a&0xe00000)==0xe00000)\r
605 {\r
606 // Ram:\r
607 u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
608 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
609 return;\r
610 }\r
611\r
612 a&=0xfffffe;\r
613\r
614 // prg RAM\r
615 if ((a&0xfe0000)==0x020000) {\r
672ad671 616 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 617 u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
618 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
619 return;\r
620 }\r
621\r
672ad671 622 // word RAM\r
d0d47c5b 623 if ((a&0xfc0000)==0x200000) {\r
624 if (d != 0) // don't log clears\r
913ef4b7 625 wrdprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc);\r
d0d47c5b 626 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 627 int bank = Pico_mcd->s68k_regs[3]&1;\r
628 if (a >= 0x220000) { // cell arranged\r
629 u32 a1, a2;\r
630 a1 = (a&2) | (cell_map(a >> 2) << 2);\r
631 if (a&2) a2 = cell_map((a+2) >> 2) << 2;\r
632 else a2 = a1 + 2;\r
633 *(u16 *)(Pico_mcd->word_ram1M[bank]+a1) = d >> 16;\r
634 *(u16 *)(Pico_mcd->word_ram1M[bank]+a2) = d;\r
bf098bc5 635 } else {\r
fa1e5e29 636 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
637 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
bf098bc5 638 }\r
d0d47c5b 639 } else {\r
640 // allow access in any mode, like Gens does\r
fa1e5e29 641 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 642 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
643 }\r
672ad671 644 return;\r
d0d47c5b 645 }\r
672ad671 646\r
c459aefd 647 if ((a&0xffffc0)==0xa12000)\r
648 rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
cc68a136 649\r
650 OtherWrite16(a, (u16)(d>>16));\r
651 OtherWrite16(a+2,(u16)d);\r
652}\r
653\r
654\r
655// -----------------------------------------------------------------\r
656\r
657\r
658u8 PicoReadS68k8(u32 a)\r
659{\r
660 u32 d=0;\r
661\r
662 a&=0xffffff;\r
663\r
664 // prg RAM\r
665 if (a < 0x80000) {\r
666 d = *(Pico_mcd->prg_ram+(a^1));\r
667 goto end;\r
668 }\r
669\r
670 // regs\r
671 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 672 a &= 0x1ff;\r
673 rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 674 if (a >= 0x58 && a < 0x68)\r
cb4a513a 675 d = gfx_cd_read(a&~1);\r
676 else d = s68k_reg_read16(a&~1);\r
677 if ((a&1)==0) d>>=8;\r
c459aefd 678 rdprintf("ret = %02x", (u8)d);\r
cc68a136 679 goto end;\r
680 }\r
681\r
d0d47c5b 682 // word RAM (2M area)\r
683 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
fa1e5e29 684 // test: batman returns\r
913ef4b7 685 wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 686 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
687 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
688 d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
689 if (a&1) d &= 0x0f;\r
690 else d >>= 4;\r
691 dprintf("FIXME: decode");\r
d0d47c5b 692 } else {\r
693 // allow access in any mode, like Gens does\r
fa1e5e29 694 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
d0d47c5b 695 }\r
913ef4b7 696 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 697 goto end;\r
698 }\r
699\r
700 // word RAM (1M area)\r
fa1e5e29 701 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
702 int bank;\r
913ef4b7 703 wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 704 if (!(Pico_mcd->s68k_regs[3]&4))\r
705 dprintf("s68k_wram1M FIXME: wrong mode");\r
706 bank = !(Pico_mcd->s68k_regs[3]&1);\r
707 d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];\r
913ef4b7 708 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 709 goto end;\r
710 }\r
711\r
4f265db7 712 // PCM\r
713 if ((a&0xff8000)==0xff0000) {\r
1cd356a3 714 dprintf("s68k_pcm r8: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 715 a &= 0x7fff;\r
716 if (a >= 0x2000)\r
717 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
718 else if (a >= 0x20) {\r
719 a &= 0x1e;\r
720 d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
721 if (a & 2) d >>= 8;\r
722 }\r
723 dprintf("ret = %02x", (u8)d);\r
724 goto end;\r
725 }\r
726\r
ab0607f7 727 // bram\r
728 if ((a&0xff0000)==0xfe0000) {\r
729 d = Pico_mcd->bram[(a>>1)&0x1fff];\r
730 goto end;\r
731 }\r
732\r
cc68a136 733 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
734\r
735 end:\r
736\r
737#ifdef __debug_io2\r
738 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
739#endif\r
740 return (u8)d;\r
741}\r
742\r
ab0607f7 743\r
cc68a136 744u16 PicoReadS68k16(u32 a)\r
745{\r
4f265db7 746 u32 d=0;\r
cc68a136 747\r
748 a&=0xfffffe;\r
749\r
750 // prg RAM\r
751 if (a < 0x80000) {\r
752 d = *(u16 *)(Pico_mcd->prg_ram+a);\r
753 goto end;\r
754 }\r
755\r
756 // regs\r
757 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 758 a &= 0x1fe;\r
759 rdprintf("s68k_regs r16: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 760 if (a >= 0x58 && a < 0x68)\r
cb4a513a 761 d = gfx_cd_read(a);\r
762 else d = s68k_reg_read16(a);\r
c459aefd 763 rdprintf("ret = %04x", d);\r
cc68a136 764 goto end;\r
765 }\r
766\r
d0d47c5b 767 // word RAM (2M area)\r
768 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 769 wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 770 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
771 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
772 d = Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff];\r
773 d |= d << 4; d &= ~0xf0;\r
774 dprintf("FIXME: decode");\r
d0d47c5b 775 } else {\r
776 // allow access in any mode, like Gens does\r
fa1e5e29 777 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 778 }\r
913ef4b7 779 wrdprintf("ret = %04x", d);\r
d0d47c5b 780 goto end;\r
781 }\r
782\r
783 // word RAM (1M area)\r
fa1e5e29 784 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
785 int bank;\r
913ef4b7 786 wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 787 if (!(Pico_mcd->s68k_regs[3]&4))\r
788 dprintf("s68k_wram1M FIXME: wrong mode");\r
789 bank = !(Pico_mcd->s68k_regs[3]&1);\r
790 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
913ef4b7 791 wrdprintf("ret = %04x", d);\r
ab0607f7 792 goto end;\r
793 }\r
794\r
795 // bram\r
796 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 797 dprintf("s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
ab0607f7 798 a = (a>>1)&0x1fff;\r
4f265db7 799 d = Pico_mcd->bram[a++]; // Gens does little endian here, and so do we..\r
ab0607f7 800 d|= Pico_mcd->bram[a++] << 8;\r
801 dprintf("ret = %04x", d);\r
d0d47c5b 802 goto end;\r
803 }\r
804\r
4f265db7 805 // PCM\r
806 if ((a&0xff8000)==0xff0000) {\r
1cd356a3 807 dprintf("s68k_pcm r16: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 808 a &= 0x7fff;\r
809 if (a >= 0x2000)\r
810 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff];\r
811 else if (a >= 0x20) {\r
812 a &= 0x1e;\r
813 d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
814 if (a & 2) d >>= 8;\r
815 }\r
816 dprintf("ret = %04x", d);\r
817 goto end;\r
818 }\r
819\r
cc68a136 820 dprintf("s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
821\r
822 end:\r
823\r
824#ifdef __debug_io2\r
825 dprintf("s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
826#endif\r
827 return d;\r
828}\r
829\r
ab0607f7 830\r
cc68a136 831u32 PicoReadS68k32(u32 a)\r
832{\r
833 u32 d=0;\r
834\r
835 a&=0xfffffe;\r
836\r
837 // prg RAM\r
838 if (a < 0x80000) {\r
839 u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
840 d = (pm[0]<<16)|pm[1];\r
841 goto end;\r
842 }\r
843\r
844 // regs\r
845 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 846 a &= 0x1fe;\r
847 rdprintf("s68k_regs r32: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 848 if (a >= 0x58 && a < 0x68)\r
cb4a513a 849 d = (gfx_cd_read(a)<<16)|gfx_cd_read(a+2);\r
850 else d = (s68k_reg_read16(a)<<16)|s68k_reg_read16(a+2);\r
c459aefd 851 rdprintf("ret = %08x", d);\r
cc68a136 852 goto end;\r
853 }\r
854\r
d0d47c5b 855 // word RAM (2M area)\r
856 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 857 wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 858 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
859 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
860 a >>= 1;\r
861 d = Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] << 16;\r
862 d |= Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff];\r
863 d |= d << 4; d &= 0x0f0f0f0f;\r
864 dprintf("FIXME: decode");\r
d0d47c5b 865 } else {\r
866 // allow access in any mode, like Gens does\r
fa1e5e29 867 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d0d47c5b 868 }\r
913ef4b7 869 wrdprintf("ret = %08x", d);\r
d0d47c5b 870 goto end;\r
871 }\r
872\r
873 // word RAM (1M area)\r
fa1e5e29 874 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
875 int bank;\r
913ef4b7 876 wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 877 if (!(Pico_mcd->s68k_regs[3]&4))\r
878 dprintf("s68k_wram1M FIXME: wrong mode");\r
879 bank = !(Pico_mcd->s68k_regs[3]&1);\r
880 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
913ef4b7 881 wrdprintf("ret = %08x", d);\r
ab0607f7 882 goto end;\r
883 }\r
884\r
4f265db7 885 // PCM\r
886 if ((a&0xff8000)==0xff0000) {\r
1cd356a3 887 dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 888 a &= 0x7fff;\r
889 if (a >= 0x2000) {\r
890 a >>= 1;\r
891 d = Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] << 16;\r
892 d |= Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff];\r
893 } else if (a >= 0x20) {\r
894 a &= 0x1e;\r
895 if (a & 2) {\r
896 a >>= 2;\r
897 d = (Pico_mcd->pcm.ch[a].addr >> (PCM_STEP_SHIFT-8)) & 0xff0000;\r
898 d |= (Pico_mcd->pcm.ch[(a+1)&7].addr >> PCM_STEP_SHIFT) & 0xff;\r
899 } else {\r
900 d = Pico_mcd->pcm.ch[a>>2].addr >> PCM_STEP_SHIFT;\r
901 d = ((d<<16)&0xff0000) | ((d>>8)&0xff); // PCM chip is LE\r
902 }\r
903 }\r
904 dprintf("ret = %08x", d);\r
905 goto end;\r
906 }\r
907\r
ab0607f7 908 // bram\r
909 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 910 dprintf("s68k_bram r32: [%06x] @%06x", a, SekPcS68k);\r
ab0607f7 911 a = (a>>1)&0x1fff;\r
912 d = Pico_mcd->bram[a++] << 16; // middle endian? TODO: verify against Fusion..\r
913 d|= Pico_mcd->bram[a++] << 24;\r
914 d|= Pico_mcd->bram[a++];\r
915 d|= Pico_mcd->bram[a++] << 8;\r
916 dprintf("ret = %08x", d);\r
d0d47c5b 917 goto end;\r
918 }\r
919\r
cc68a136 920 dprintf("s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
921\r
922 end:\r
923\r
924#ifdef __debug_io2\r
925 dprintf("s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
926#endif\r
927 return d;\r
928}\r
929\r
ab0607f7 930\r
cc68a136 931// -----------------------------------------------------------------\r
932\r
933void PicoWriteS68k8(u32 a,u8 d)\r
934{\r
935#ifdef __debug_io2\r
936 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
937#endif\r
938\r
939 a&=0xffffff;\r
940\r
941 // prg RAM\r
942 if (a < 0x80000) {\r
943 u8 *pm=(u8 *)(Pico_mcd->prg_ram+(a^1));\r
944 *pm=d;\r
945 return;\r
946 }\r
947\r
948 // regs\r
949 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 950 a &= 0x1ff;\r
951 rdprintf("s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k);\r
913ef4b7 952 if (a >= 0x58 && a < 0x68)\r
cb4a513a 953 gfx_cd_write(a&~1, (d<<8)|d);\r
954 else s68k_reg_write8(a,d);\r
cc68a136 955 return;\r
956 }\r
957\r
d0d47c5b 958 // word RAM (2M area)\r
959 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 960 wrdprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
fa1e5e29 961 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
962 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
963 if (a&1) d &= 0x0f;\r
964 else d >>= 4;\r
965 Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff]=d;\r
966 dprintf("FIXME: decode");\r
d0d47c5b 967 } else {\r
968 // allow access in any mode, like Gens does\r
fa1e5e29 969 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
d0d47c5b 970 }\r
971 return;\r
972 }\r
973\r
974 // word RAM (1M area)\r
fa1e5e29 975 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
976 int bank;\r
d0d47c5b 977 if (d)\r
913ef4b7 978 wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
fa1e5e29 979 if (!(Pico_mcd->s68k_regs[3]&4))\r
980 dprintf("s68k_wram1M FIXME: wrong mode");\r
981 bank = !(Pico_mcd->s68k_regs[3]&1);\r
982 *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;\r
d0d47c5b 983 return;\r
984 }\r
985\r
4f265db7 986 // PCM\r
987 if ((a&0xff8000)==0xff0000) {\r
988 a &= 0x7fff;\r
989 if (a >= 0x2000)\r
990 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
991 else if (a < 0x12)\r
992 pcm_write(a>>1, d);\r
993 return;\r
994 }\r
995\r
ab0607f7 996 // bram\r
997 if ((a&0xff0000)==0xfe0000) {\r
998 Pico_mcd->bram[(a>>1)&0x1fff] = d;\r
999 SRam.changed = 1;\r
1000 return;\r
1001 }\r
1002\r
cc68a136 1003 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
1004}\r
1005\r
ab0607f7 1006\r
cc68a136 1007void PicoWriteS68k16(u32 a,u16 d)\r
1008{\r
1009#ifdef __debug_io2\r
1010 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1011#endif\r
1012\r
1013 a&=0xfffffe;\r
1014\r
1015 // prg RAM\r
1016 if (a < 0x80000) {\r
1017 *(u16 *)(Pico_mcd->prg_ram+a)=d;\r
1018 return;\r
1019 }\r
1020\r
1021 // regs\r
1022 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 1023 a &= 0x1fe;\r
1024 rdprintf("s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1025 if (a >= 0x58 && a < 0x68)\r
cb4a513a 1026 gfx_cd_write(a, d);\r
1027 else {\r
1cd356a3 1028 if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
1029 Pico_mcd->s68k_regs[0xf] = d;\r
1030 return;\r
1031 }\r
cb4a513a 1032 s68k_reg_write8(a, d>>8);\r
1033 s68k_reg_write8(a+1,d&0xff);\r
1034 }\r
cc68a136 1035 return;\r
1036 }\r
1037\r
d0d47c5b 1038 // word RAM (2M area)\r
1039 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 1040 wrdprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
fa1e5e29 1041 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
1042 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
1043 d &= ~0xf0; d |= d >> 8;\r
1044 Pico_mcd->word_ram1M[bank][((a>>1)^1)&0x1ffff] = d;\r
1045 dprintf("FIXME: decode");\r
d0d47c5b 1046 } else {\r
1047 // allow access in any mode, like Gens does\r
fa1e5e29 1048 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
d0d47c5b 1049 }\r
1050 return;\r
1051 }\r
1052\r
1053 // word RAM (1M area)\r
fa1e5e29 1054 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
1055 int bank;\r
d0d47c5b 1056 if (d)\r
913ef4b7 1057 wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
fa1e5e29 1058 if (!(Pico_mcd->s68k_regs[3]&4))\r
1059 dprintf("s68k_wram1M FIXME: wrong mode");\r
1060 bank = !(Pico_mcd->s68k_regs[3]&1);\r
1061 *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;\r
d0d47c5b 1062 return;\r
1063 }\r
1064\r
4f265db7 1065 // PCM\r
1066 if ((a&0xff8000)==0xff0000) {\r
1067 a &= 0x7fff;\r
1068 if (a >= 0x2000)\r
1069 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a>>1)&0xfff] = d;\r
1070 else if (a < 0x12)\r
1071 pcm_write(a>>1, d & 0xff);\r
1072 return;\r
1073 }\r
1074\r
ab0607f7 1075 // bram\r
1076 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 1077 dprintf("s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
ab0607f7 1078 a = (a>>1)&0x1fff;\r
1079 Pico_mcd->bram[a++] = d; // Gens does little endian here, an so do we..\r
1080 Pico_mcd->bram[a++] = d >> 8;\r
1081 SRam.changed = 1;\r
1082 return;\r
1083 }\r
1084\r
cc68a136 1085 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1086}\r
1087\r
ab0607f7 1088\r
cc68a136 1089void PicoWriteS68k32(u32 a,u32 d)\r
1090{\r
1091#ifdef __debug_io2\r
1092 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1093#endif\r
1094\r
1095 a&=0xfffffe;\r
1096\r
1097 // prg RAM\r
1098 if (a < 0x80000) {\r
1099 u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
1100 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
1101 return;\r
1102 }\r
1103\r
1104 // regs\r
1105 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 1106 a &= 0x1fe;\r
1107 rdprintf("s68k_regs w32: [%02x] %08x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1108 if (a >= 0x58 && a < 0x68) {\r
cb4a513a 1109 gfx_cd_write(a, d>>16);\r
1110 gfx_cd_write(a+2, d&0xffff);\r
1111 } else {\r
1112 s68k_reg_write8(a, d>>24);\r
1113 s68k_reg_write8(a+1,(d>>16)&0xff);\r
1114 s68k_reg_write8(a+2,(d>>8) &0xff);\r
1115 s68k_reg_write8(a+3, d &0xff);\r
1116 }\r
cc68a136 1117 return;\r
1118 }\r
1119\r
d0d47c5b 1120 // word RAM (2M area)\r
1121 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 1122 wrdprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
fa1e5e29 1123 if (Pico_mcd->s68k_regs[3]&4) { // 1M decode mode?\r
1124 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
1125 a >>= 1;\r
1126 d &= 0x0f0f0f0f; d |= d >> 4;\r
1127 Pico_mcd->word_ram1M[bank][((a+0)^1)&0x1ffff] = d >> 16;\r
1128 Pico_mcd->word_ram1M[bank][((a+1)^1)&0x1ffff] = d;\r
1129 dprintf("FIXME: decode");\r
d0d47c5b 1130 } else {\r
1131 // allow access in any mode, like Gens does\r
fa1e5e29 1132 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 1133 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
1134 }\r
1135 return;\r
1136 }\r
1137\r
1138 // word RAM (1M area)\r
fa1e5e29 1139 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
1140 int bank;\r
1141 u16 *pm;\r
d0d47c5b 1142 if (d)\r
913ef4b7 1143 wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
fa1e5e29 1144 if (!(Pico_mcd->s68k_regs[3]&4))\r
1145 dprintf("s68k_wram1M FIXME: wrong mode");\r
1146 bank = !(Pico_mcd->s68k_regs[3]&1);\r
1147 pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1148 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
d0d47c5b 1149 return;\r
1150 }\r
ab0607f7 1151\r
4f265db7 1152 // PCM\r
1153 if ((a&0xff8000)==0xff0000) {\r
1154 a &= 0x7fff;\r
1155 if (a >= 0x2000) {\r
1156 a >>= 1;\r
1157 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][a&0xfff] = (d >> 16);\r
1158 Pico_mcd->pcm_ram_b[Pico_mcd->pcm.bank][(a+1)&0xfff] = d;\r
1159 } else if (a < 0x12) {\r
1160 a >>= 1;\r
1161 pcm_write(a, (d>>16) & 0xff);\r
1162 pcm_write(a+1, d & 0xff);\r
1163 }\r
1164 return;\r
1165 }\r
1166\r
ab0607f7 1167 // bram\r
1168 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 1169 dprintf("s68k_bram w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
ab0607f7 1170 a = (a>>1)&0x1fff;\r
1171 Pico_mcd->bram[a++] = d >> 16; // middle endian? verify?\r
1172 Pico_mcd->bram[a++] = d >> 24;\r
1173 Pico_mcd->bram[a++] = d;\r
1174 Pico_mcd->bram[a++] = d >> 8;\r
1175 SRam.changed = 1;\r
1176 return;\r
1177 }\r
1178\r
cc68a136 1179 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1180}\r
1181\r
1182\r
1183\r
1184// -----------------------------------------------------------------\r
1185\r
b837b69b 1186\r
1187#if defined(EMU_C68K)\r
1188static __inline int PicoMemBaseM68k(u32 pc)\r
1189{\r
fa1e5e29 1190 if ((pc&0xe00000)==0xe00000)\r
1191 return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
b837b69b 1192\r
1193 if (pc < 0x20000)\r
fa1e5e29 1194 return (int)Pico_mcd->bios; // Program Counter in BIOS\r
1195\r
1196 if ((pc&0xfc0000)==0x200000)\r
b837b69b 1197 {\r
fa1e5e29 1198 if (!(Pico_mcd->s68k_regs[3]&4))\r
1199 return (int)Pico_mcd->word_ram2M - 0x200000; // Program Counter in Word Ram\r
1200 if (pc < 0x220000) {\r
1201 int bank = (Pico_mcd->s68k_regs[3]&1);\r
1202 return (int)Pico_mcd->word_ram1M[bank] - 0x200000;\r
1203 }\r
b837b69b 1204 }\r
1205\r
fa1e5e29 1206 // Error - Program Counter is invalid\r
1207 dprintf("m68k FIXME: unhandled jump to %06x", pc);\r
1208\r
1209 return (int)Pico_mcd->bios;\r
b837b69b 1210}\r
1211\r
1212\r
1213static u32 PicoCheckPcM68k(u32 pc)\r
1214{\r
1215 pc-=PicoCpu.membase; // Get real pc\r
1216 pc&=0xfffffe;\r
1217\r
1218 PicoCpu.membase=PicoMemBaseM68k(pc);\r
1219\r
1220 return PicoCpu.membase+pc;\r
1221}\r
1222\r
1223\r
1224static __inline int PicoMemBaseS68k(u32 pc)\r
1225{\r
fa1e5e29 1226 if (pc < 0x80000) // PRG RAM\r
1227 return (int)Pico_mcd->prg_ram;\r
b837b69b 1228\r
fa1e5e29 1229 if ((pc&0xfc0000)==0x080000) // WORD RAM 2M area (assume we are in the right mode..)\r
1230 return (int)Pico_mcd->word_ram2M - 0x080000;\r
1231\r
1232 if ((pc&0xfe0000)==0x0c0000) { // word RAM 1M area\r
1233 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
1234 return (int)Pico_mcd->word_ram1M[bank] - 0x0c0000;\r
b837b69b 1235 }\r
1236\r
fa1e5e29 1237 // Error - Program Counter is invalid\r
1238 dprintf("s68k FIXME: unhandled jump to %06x", pc);\r
1239\r
1240 return (int)Pico_mcd->prg_ram;\r
b837b69b 1241}\r
1242\r
1243\r
1244static u32 PicoCheckPcS68k(u32 pc)\r
1245{\r
1246 pc-=PicoCpuS68k.membase; // Get real pc\r
1247 pc&=0xfffffe;\r
1248\r
1249 PicoCpuS68k.membase=PicoMemBaseS68k(pc);\r
1250\r
1251 return PicoCpuS68k.membase+pc;\r
1252}\r
1253#endif\r
1254\r
1255\r
1256void PicoMemSetupCD()\r
1257{\r
1258 dprintf("PicoMemSetupCD()");\r
1259#ifdef EMU_C68K\r
1260 // Setup m68k memory callbacks:\r
1261 PicoCpu.checkpc=PicoCheckPcM68k;\r
1262 PicoCpu.fetch8 =PicoCpu.read8 =PicoReadM68k8;\r
1263 PicoCpu.fetch16=PicoCpu.read16=PicoReadM68k16;\r
1264 PicoCpu.fetch32=PicoCpu.read32=PicoReadM68k32;\r
1265 PicoCpu.write8 =PicoWriteM68k8;\r
1266 PicoCpu.write16=PicoWriteM68k16;\r
1267 PicoCpu.write32=PicoWriteM68k32;\r
1268 // s68k\r
1269 PicoCpuS68k.checkpc=PicoCheckPcS68k;\r
1270 PicoCpuS68k.fetch8 =PicoCpuS68k.read8 =PicoReadS68k8;\r
1271 PicoCpuS68k.fetch16=PicoCpuS68k.read16=PicoReadS68k16;\r
1272 PicoCpuS68k.fetch32=PicoCpuS68k.read32=PicoReadS68k32;\r
1273 PicoCpuS68k.write8 =PicoWriteS68k8;\r
1274 PicoCpuS68k.write16=PicoWriteS68k16;\r
1275 PicoCpuS68k.write32=PicoWriteS68k32;\r
1276#endif\r
1277}\r
1278\r
1279\r
cc68a136 1280#ifdef EMU_M68K\r
1281unsigned char PicoReadCD8w (unsigned int a) {\r
1282 return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k8(a) : PicoReadM68k8(a);\r
1283}\r
1284unsigned short PicoReadCD16w(unsigned int a) {\r
1285 return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k16(a) : PicoReadM68k16(a);\r
1286}\r
1287unsigned int PicoReadCD32w(unsigned int a) {\r
1288 return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k32(a) : PicoReadM68k32(a);\r
1289}\r
1290void PicoWriteCD8w (unsigned int a, unsigned char d) {\r
1291 if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);\r
1292}\r
1293void PicoWriteCD16w(unsigned int a, unsigned short d) {\r
1294 if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);\r
1295}\r
1296void PicoWriteCD32w(unsigned int a, unsigned int d) {\r
1297 if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);\r
1298}\r
1299\r
1300// these are allowed to access RAM\r
1301unsigned int m68k_read_pcrelative_CD8 (unsigned int a) {\r
1302 a&=0xffffff;\r
1303 if(m68ki_cpu_p == &PicoS68kCPU) {\r
1304 if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram\r
fa1e5e29 1305 if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
1306 return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));\r
1307 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
1308 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
1309 return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));\r
1310 }\r
1311 dprintf("s68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);\r
cc68a136 1312 } else {\r
cc68a136 1313 if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
fa1e5e29 1314 if(a<0x20000) return *(u8 *)(Pico.rom+(a^1)); // Bios\r
1315 if((a&0xfc0000)==0x200000) { // word RAM\r
1316 if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
1317 return *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff));\r
1318 else if (a < 0x220000) {\r
1319 int bank = Pico_mcd->s68k_regs[3]&1;\r
1320 return *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff));\r
1321 }\r
1322 }\r
1323 dprintf("m68k_read_pcrelative_CD8 FIXME: can't handle %06x", a);\r
cc68a136 1324 }\r
1325 return 0;//(u8) lastread_d;\r
1326}\r
1327unsigned int m68k_read_pcrelative_CD16(unsigned int a) {\r
1328 a&=0xffffff;\r
1329 if(m68ki_cpu_p == &PicoS68kCPU) {\r
1330 if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram\r
fa1e5e29 1331 if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
1332 return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
1333 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
1334 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
1335 return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1336 }\r
1337 dprintf("s68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);\r
cc68a136 1338 } else {\r
cc68a136 1339 if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram\r
fa1e5e29 1340 if(a<0x20000) return *(u16 *)(Pico.rom+(a&~1)); // Bios\r
1341 if((a&0xfc0000)==0x200000) { // word RAM\r
1342 if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
1343 return *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
1344 else if (a < 0x220000) {\r
1345 int bank = Pico_mcd->s68k_regs[3]&1;\r
1346 return *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1347 }\r
1348 }\r
1349 dprintf("m68k_read_pcrelative_CD16 FIXME: can't handle %06x", a);\r
cc68a136 1350 }\r
b837b69b 1351 return 0;\r
cc68a136 1352}\r
1353unsigned int m68k_read_pcrelative_CD32(unsigned int a) {\r
fa1e5e29 1354 u16 *pm;\r
cc68a136 1355 a&=0xffffff;\r
1356 if(m68ki_cpu_p == &PicoS68kCPU) {\r
1357 if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram\r
fa1e5e29 1358 if ((a&0xfc0000)==0x080000 && !(Pico_mcd->s68k_regs[3]&4)) // word RAM (2M area: 080000-0bffff)\r
1359 { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
1360 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // word RAM (1M area: 0c0000-0dffff)\r
1361 int bank = !(Pico_mcd->s68k_regs[3]&1);\r
1362 pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1363 return (pm[0]<<16)|pm[1];\r
1364 }\r
1365 dprintf("s68k_read_pcrelative_CD32 FIXME: can't handle %06x", a);\r
cc68a136 1366 } else {\r
cc68a136 1367 if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram\r
fa1e5e29 1368 if(a<0x20000) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; }\r
1369 if((a&0xfc0000)==0x200000) { // word RAM\r
1370 if(!(Pico_mcd->s68k_regs[3]&4)) // 2M?\r
1371 { pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); return (pm[0]<<16)|pm[1]; }\r
1372 else if (a < 0x220000) {\r
1373 int bank = Pico_mcd->s68k_regs[3]&1;\r
1374 pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
1375 return (pm[0]<<16)|pm[1];\r
1376 }\r
1377 }\r
1378 dprintf("m68k_read_pcrelative_CD32 FIXME: can't handle %06x", a);\r
cc68a136 1379 }\r
b837b69b 1380 return 0;\r
cc68a136 1381}\r
1382#endif // EMU_M68K\r
1383\r