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