runs code in 1M wram, cell arrange, decode (untested)
[picodrive.git] / Pico / cd / Memory.c
... / ...
CommitLineData
1// This is part of Pico Library\r
2\r
3// (c) Copyright 2004 Dave, All rights reserved.\r
4// (c) Copyright 2007 notaz, All rights reserved.\r
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
19#include "gfx_cd.h"\r
20#include "pcm.h"\r
21\r
22#include "cell_map.c"\r
23\r
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
30//#define rdprintf dprintf\r
31#define rdprintf(...)\r
32\r
33// -----------------------------------------------------------------\r
34\r
35\r
36static u32 m68k_reg_read16(u32 a)\r
37{\r
38 u32 d=0;\r
39 a &= 0x3e;\r
40 // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc);\r
41\r
42 switch (a) {\r
43 case 0:\r
44 d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens\r
45 goto end;\r
46 case 2:\r
47 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
48 dprintf("m68k_regs r3: %02x @%06x", (u8)d, SekPcS68k);\r
49 goto end;\r
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
56 case 8:\r
57 d = Read_CDC_Host(0);\r
58 goto end;\r
59 case 0xA:\r
60 dprintf("m68k FIXME: reserved read");\r
61 goto end;\r
62 case 0xC:\r
63 dprintf("m68k stopwatch timer read");\r
64 d = Pico_mcd->m.timer_stopwatch >> 16;\r
65 goto end;\r
66 }\r
67\r
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
74 dprintf("m68k_regs FIXME invalid read @ %02x", a);\r
75\r
76end:\r
77\r
78 // dprintf("ret = %04x", d);\r
79 return d;\r
80}\r
81\r
82static void m68k_reg_write8(u32 a, u32 d)\r
83{\r
84 a &= 0x3f;\r
85 // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc);\r
86\r
87 switch (a) {\r
88 case 0:\r
89 d &= 1;\r
90 if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { dprintf("m68k: s68k irq 2"); SekInterruptS68k(2); }\r
91 return;\r
92 case 1:\r
93 d &= 3;\r
94 if (!(d&1)) Pico_mcd->m.state_flags |= 1; // reset pending, needed to be sure we fetch the right vectors on reset\r
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
97 if ((Pico_mcd->m.state_flags&1) && (d&3)==1) {\r
98 SekResetS68k(); // S68k comes out of RESET or BRQ state\r
99 Pico_mcd->m.state_flags&=~1;\r
100 dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
101 }\r
102 Pico_mcd->m.busreq = d;\r
103 return;\r
104 case 2:\r
105 Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
106 return;\r
107 case 3:\r
108 dprintf("m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
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
116 if (!(d & 4) && (d & 2)) d &= ~1; // return word RAM to s68k in 2M mode\r
117 Pico_mcd->s68k_regs[3] = d; // really use s68k side register\r
118 return;\r
119 case 6:\r
120 dprintf("FIXME hint[2]: %02x @%06x", (u8)d, SekPc);\r
121 Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
122 return;\r
123 case 7:\r
124 dprintf("FIXME hint[3]: %02x @%06x", (u8)d, SekPc);\r
125 Pico_mcd->bios[0x72] = d;\r
126 dprintf("vector is now %08x", PicoRead32(0x70));\r
127 return;\r
128 case 0xe:\r
129 //dprintf("m68k: comm flag: %02x", d);\r
130 Pico_mcd->s68k_regs[0xe] = d;\r
131 return;\r
132 }\r
133\r
134 if ((a&0xf0) == 0x10) {\r
135 Pico_mcd->s68k_regs[a] = d;\r
136 return;\r
137 }\r
138\r
139 dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);\r
140}\r
141\r
142\r
143\r
144static u32 s68k_reg_read16(u32 a)\r
145{\r
146 u32 d=0;\r
147\r
148 // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k);\r
149\r
150 switch (a) {\r
151 case 0:\r
152 d = ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
153 goto end;\r
154 case 2:\r
155 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
156 dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
157 goto end;\r
158 case 6:\r
159 d = CDC_Read_Reg();\r
160 goto end;\r
161 case 8:\r
162 d = Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
163 goto end;\r
164 case 0xC:\r
165 dprintf("s68k stopwatch timer read");\r
166 d = Pico_mcd->m.timer_stopwatch >> 16;\r
167 goto end;\r
168 case 0x30:\r
169 dprintf("s68k int3 timer read");\r
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
180 // dprintf("ret = %04x", d);\r
181\r
182 return d;\r
183}\r
184\r
185static void s68k_reg_write8(u32 a, u32 d)\r
186{\r
187 //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k);\r
188\r
189 // TODO: review against Gens\r
190 switch (a) {\r
191 case 2:\r
192 return; // only m68k can change WP\r
193 case 3: {\r
194 int dold = Pico_mcd->s68k_regs[3];\r
195 dprintf("s68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
196 d &= 0x1d;\r
197 if (d&4) {\r
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
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
207 if (dold & 4) {\r
208 dprintf("wram mode 1M->2M");\r
209 wram_1M_to_2M(Pico_mcd->word_ram2M);\r
210 }\r
211 }\r
212 break;\r
213 }\r
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
219 //dprintf("s68k CDC reg addr: %x", d&0xf);\r
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
227 case 0xc:\r
228 case 0xd:\r
229 dprintf("s68k set stopwatch timer");\r
230 Pico_mcd->m.timer_stopwatch = 0;\r
231 return;\r
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
236 case 0x31:\r
237 dprintf("s68k set int3 timer: %02x", d);\r
238 Pico_mcd->m.timer_int3 = d << 16;\r
239 break;\r
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
244 }\r
245 break;\r
246 case 0x34: // fader\r
247 Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
248 return;\r
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
255 CDD_Export_Status();\r
256 }\r
257 return;\r
258 }\r
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
265 if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
266 {\r
267 dprintf("s68k FIXME: invalid write @ %02x?", a);\r
268 return;\r
269 }\r
270\r
271 Pico_mcd->s68k_regs[a] = (u8) d;\r
272}\r
273\r
274\r
275\r
276static u32 OtherRead16End(u32 a, int realsize)\r
277{\r
278 u32 d=0;\r
279\r
280 if ((a&0xffffc0)==0xa12000) {\r
281 d=m68k_reg_read16(a);\r
282 goto end;\r
283 }\r
284\r
285 dprintf("m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
286\r
287end:\r
288 return d;\r
289}\r
290\r
291\r
292static void OtherWrite8End(u32 a, u32 d, int realsize)\r
293{\r
294 if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
295\r
296 dprintf("m68k FIXME: strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
297}\r
298\r
299\r
300#undef _ASM_MEMORY_C\r
301#include "../MemoryCmn.c"\r
302\r
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
319 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
320 d = *(prg_bank+((a^1)&0x1ffff));\r
321 goto end;\r
322 }\r
323\r
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
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
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
349 } else {\r
350 // allow access in any mode, like Gens does\r
351 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
352 }\r
353 dprintf("ret = %02x", (u8)d);\r
354 goto end;\r
355 }\r
356\r
357 if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
358\r
359 if ((a&0xffffc0)==0xa12000)\r
360 rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
361\r
362 d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
363\r
364 if ((a&0xffffc0)==0xa12000)\r
365 rdprintf("ret = %02x", (u8)d);\r
366\r
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
375\r
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
388 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
389 d = *(u16 *)(prg_bank+(a&0x1fffe));\r
390 goto end;\r
391 }\r
392\r
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
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
402 } else {\r
403 // allow access in any mode, like Gens does\r
404 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
405 }\r
406 dprintf("ret = %04x", d);\r
407 goto end;\r
408 }\r
409\r
410 if ((a&0xffffc0)==0xa12000)\r
411 rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
412\r
413 d = (u16)OtherRead16(a, 16);\r
414\r
415 if ((a&0xffffc0)==0xa12000)\r
416 rdprintf("ret = %04x", d);\r
417\r
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
426\r
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
439 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
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
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
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
457 } else {\r
458 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
459 }\r
460 } else {\r
461 // allow access in any mode, like Gens does\r
462 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
463 }\r
464 dprintf("ret = %08x", d);\r
465 goto end;\r
466 }\r
467\r
468 if ((a&0xffffc0)==0xa12000)\r
469 rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
470\r
471 d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
472\r
473 if ((a&0xffffc0)==0xa12000)\r
474 rdprintf("ret = %08x", d);\r
475\r
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
483\r
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
496 if ((a&0xe00000)==0xe00000) { // Ram\r
497 *(u8 *)(Pico.ram+((a^1)&0xffff)) = d;\r
498 return;\r
499 }\r
500\r
501 a&=0xffffff;\r
502\r
503 // prg RAM\r
504 if ((a&0xfe0000)==0x020000) {\r
505 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
506 *(u8 *)(prg_bank+((a^1)&0x1ffff))=d;\r
507 return;\r
508 }\r
509\r
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
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
519 } else {\r
520 // allow access in any mode, like Gens does\r
521 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
522 }\r
523 return;\r
524 }\r
525\r
526 if ((a&0xffffc0)==0xa12000)\r
527 rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
528\r
529 OtherWrite8(a,d,8);\r
530}\r
531\r
532\r
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
538 // dprintf("w16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
539\r
540 if ((a&0xe00000)==0xe00000) { // Ram\r
541 *(u16 *)(Pico.ram+(a&0xfffe))=d;\r
542 return;\r
543 }\r
544\r
545 a&=0xfffffe;\r
546\r
547 // prg RAM\r
548 if ((a&0xfe0000)==0x020000) {\r
549 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
550 *(u16 *)(prg_bank+(a&0x1fffe))=d;\r
551 return;\r
552 }\r
553\r
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
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
563 } else {\r
564 // allow access in any mode, like Gens does\r
565 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
566 }\r
567 return;\r
568 }\r
569\r
570 if ((a&0xffffc0)==0xa12000)\r
571 rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
572\r
573 OtherWrite16(a,d);\r
574}\r
575\r
576\r
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
595 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
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
601 // word RAM\r
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
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
614 } else {\r
615 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
616 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
617 }\r
618 } else {\r
619 // allow access in any mode, like Gens does\r
620 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
621 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
622 }\r
623 return;\r
624 }\r
625\r
626 if ((a&0xffffc0)==0xa12000)\r
627 rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
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
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
657 rdprintf("ret = %02x", (u8)d);\r
658 goto end;\r
659 }\r
660\r
661 // word RAM (2M area)\r
662 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
663 // test: batman returns\r
664 dprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);\r
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
671 } else {\r
672 // allow access in any mode, like Gens does\r
673 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
674 }\r
675 dprintf("ret = %02x", (u8)d);\r
676 goto end;\r
677 }\r
678\r
679 // word RAM (1M area)\r
680 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
681 int bank;\r
682 dprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);\r
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
687 dprintf("ret = %02x", (u8)d);\r
688 goto end;\r
689 }\r
690\r
691 // PCM\r
692 if ((a&0xff8000)==0xff0000) {\r
693 dprintf("s68k_pcm r8: [%06x] @%06x", a, SekPcS68k);\r
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
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
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
722\r
723u16 PicoReadS68k16(u32 a)\r
724{\r
725 u32 d=0;\r
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
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
742 rdprintf("ret = %04x", d);\r
743 goto end;\r
744 }\r
745\r
746 // word RAM (2M area)\r
747 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
748 dprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);\r
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
754 } else {\r
755 // allow access in any mode, like Gens does\r
756 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
757 }\r
758 dprintf("ret = %04x", d);\r
759 goto end;\r
760 }\r
761\r
762 // word RAM (1M area)\r
763 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
764 int bank;\r
765 dprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);\r
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
770 dprintf("ret = %04x", d);\r
771 goto end;\r
772 }\r
773\r
774 // bram\r
775 if ((a&0xff0000)==0xfe0000) {\r
776 dprintf("s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
777 a = (a>>1)&0x1fff;\r
778 d = Pico_mcd->bram[a++]; // Gens does little endian here, and so do we..\r
779 d|= Pico_mcd->bram[a++] << 8;\r
780 dprintf("ret = %04x", d);\r
781 goto end;\r
782 }\r
783\r
784 // PCM\r
785 if ((a&0xff8000)==0xff0000) {\r
786 dprintf("s68k_pcm r16: [%06x] @%06x", a, SekPcS68k);\r
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
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
809\r
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
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
830 rdprintf("ret = %08x", d);\r
831 goto end;\r
832 }\r
833\r
834 // word RAM (2M area)\r
835 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
836 dprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);\r
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
844 } else {\r
845 // allow access in any mode, like Gens does\r
846 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
847 }\r
848 dprintf("ret = %08x", d);\r
849 goto end;\r
850 }\r
851\r
852 // word RAM (1M area)\r
853 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
854 int bank;\r
855 dprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);\r
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
860 dprintf("ret = %08x", d);\r
861 goto end;\r
862 }\r
863\r
864 // PCM\r
865 if ((a&0xff8000)==0xff0000) {\r
866 dprintf("s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
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
887 // bram\r
888 if ((a&0xff0000)==0xfe0000) {\r
889 dprintf("s68k_bram r32: [%06x] @%06x", a, SekPcS68k);\r
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
896 goto end;\r
897 }\r
898\r
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
909\r
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
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
934 return;\r
935 }\r
936\r
937 // word RAM (2M area)\r
938 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
939 dprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
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
946 } else {\r
947 // allow access in any mode, like Gens does\r
948 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
949 }\r
950 return;\r
951 }\r
952\r
953 // word RAM (1M area)\r
954 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
955 int bank;\r
956 if (d)\r
957 dprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
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
962 return;\r
963 }\r
964\r
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
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
982 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
983}\r
984\r
985\r
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
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
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
1011 s68k_reg_write8(a, d>>8);\r
1012 s68k_reg_write8(a+1,d&0xff);\r
1013 }\r
1014 return;\r
1015 }\r
1016\r
1017 // word RAM (2M area)\r
1018 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
1019 dprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
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
1025 } else {\r
1026 // allow access in any mode, like Gens does\r
1027 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
1028 }\r
1029 return;\r
1030 }\r
1031\r
1032 // word RAM (1M area)\r
1033 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
1034 int bank;\r
1035 if (d)\r
1036 dprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
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
1041 return;\r
1042 }\r
1043\r
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
1054 // bram\r
1055 if ((a&0xff0000)==0xfe0000) {\r
1056 dprintf("s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
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
1064 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1065}\r
1066\r
1067\r
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
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
1096 return;\r
1097 }\r
1098\r
1099 // word RAM (2M area)\r
1100 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
1101 dprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
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
1109 } else {\r
1110 // allow access in any mode, like Gens does\r
1111 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
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
1118 if ((a&0xfe0000)==0x0c0000) { // 0c0000-0dffff\r
1119 int bank;\r
1120 u16 *pm;\r
1121 if (d)\r
1122 dprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
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
1128 return;\r
1129 }\r
1130\r
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
1146 // bram\r
1147 if ((a&0xff0000)==0xfe0000) {\r
1148 dprintf("s68k_bram w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
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
1158 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1159}\r
1160\r
1161\r
1162\r
1163// -----------------------------------------------------------------\r
1164\r
1165\r
1166#if defined(EMU_C68K)\r
1167static __inline int PicoMemBaseM68k(u32 pc)\r
1168{\r
1169 if ((pc&0xe00000)==0xe00000)\r
1170 return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
1171\r
1172 if (pc < 0x20000)\r
1173 return (int)Pico_mcd->bios; // Program Counter in BIOS\r
1174\r
1175 if ((pc&0xfc0000)==0x200000)\r
1176 {\r
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
1183 }\r
1184\r
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
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
1205 if (pc < 0x80000) // PRG RAM\r
1206 return (int)Pico_mcd->prg_ram;\r
1207\r
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
1214 }\r
1215\r
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
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
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
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
1291 } else {\r
1292 if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
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
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
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
1317 } else {\r
1318 if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram\r
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
1329 }\r
1330 return 0;\r
1331}\r
1332unsigned int m68k_read_pcrelative_CD32(unsigned int a) {\r
1333 u16 *pm;\r
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
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
1345 } else {\r
1346 if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram\r
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
1358 }\r
1359 return 0;\r
1360}\r
1361#endif // EMU_M68K\r
1362\r