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