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