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