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