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