shows: press start button
[picodrive.git] / Pico / cd / Memory.c
CommitLineData
cc68a136 1// This is part of Pico Library\r
2\r
3// (c) Copyright 2004 Dave, All rights reserved.\r
4// (c) Copyright 2006 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
19typedef unsigned char u8;\r
20typedef unsigned short u16;\r
21typedef unsigned int u32;\r
22\r
23//#define __debug_io\r
24//#define __debug_io2\r
c459aefd 25#define rdprintf dprintf\r
cc68a136 26\r
27// -----------------------------------------------------------------\r
28\r
8c1952f0 29// extern m68ki_cpu_core m68ki_cpu;\r
cc68a136 30\r
31extern int counter75hz;\r
32\r
33\r
34static u32 m68k_reg_read16(u32 a, int realsize)\r
35{\r
36 u32 d=0;\r
37 a &= 0x3e;\r
672ad671 38 // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc);\r
cc68a136 39\r
40 switch (a) {\r
672ad671 41 case 0:\r
c459aefd 42 d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens\r
672ad671 43 goto end;\r
cc68a136 44 case 2:\r
672ad671 45 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
bf098bc5 46 dprintf("m68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
cc68a136 47 goto end;\r
c459aefd 48 case 4:\r
49 d = Pico_mcd->s68k_regs[4]<<8;\r
50 goto end;\r
51 case 6:\r
52 d = Pico_mcd->m.hint_vector;\r
53 goto end;\r
cc68a136 54 case 8:\r
55 dprintf("m68k host data read");\r
56 d = Read_CDC_Host(0);\r
57 goto end;\r
c459aefd 58 case 0xA:\r
59 dprintf("m68k reserved read");\r
60 goto end;\r
cc68a136 61 case 0xC:\r
62 dprintf("m68k stopwatch read");\r
63 break;\r
64 }\r
65\r
cc68a136 66 if (a < 0x30) {\r
67 // comm flag/cmd/status (0xE-0x2F)\r
68 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
69 goto end;\r
70 }\r
71\r
72 dprintf("m68k_regs invalid read @ %02x", a);\r
73\r
74end:\r
75\r
672ad671 76 // dprintf("ret = %04x", d);\r
cc68a136 77 return d;\r
78}\r
79\r
80static void m68k_reg_write8(u32 a, u32 d, int realsize)\r
81{\r
82 a &= 0x3f;\r
672ad671 83 // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc);\r
cc68a136 84\r
85 switch (a) {\r
86 case 0:\r
672ad671 87 d &= 1;\r
cc68a136 88 if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { dprintf("m68k: s68k irq 2"); SekInterruptS68k(2); }\r
c459aefd 89 return;\r
cc68a136 90 case 1:\r
672ad671 91 d &= 3;\r
cc68a136 92 if (!(d&1)) PicoMCD |= 2; // reset pending, needed to be sure we fetch the right vectors on reset\r
c459aefd 93 if ( (Pico_mcd->m.busreq&1) != (d&1)) dprintf("m68k: s68k reset %i", !(d&1));\r
94 if ( (Pico_mcd->m.busreq&2) != (d&2)) dprintf("m68k: s68k brq %i", (d&2)>>1);\r
95 if ((PicoMCD&2) && (d&3)==1) {\r
cc68a136 96 SekResetS68k(); // S68k comes out of RESET or BRQ state\r
97 PicoMCD&=~2;\r
672ad671 98 dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
cc68a136 99 }\r
c459aefd 100 Pico_mcd->m.busreq = d;\r
101 return;\r
672ad671 102 case 2:\r
103 Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
104 return;\r
cc68a136 105 case 3:\r
bf098bc5 106 dprintf("m68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
672ad671 107 d &= 0xc2;\r
108 if ((Pico_mcd->s68k_regs[3]>>6) != ((d>>6)&3))\r
109 dprintf("m68k: prg bank: %i -> %i", (Pico_mcd->s68k_regs[a]>>6), ((d>>6)&3));\r
110 //if ((Pico_mcd->s68k_regs[3]&4) != (d&4)) dprintf("m68k: ram mode %i mbit", (d&4) ? 1 : 2);\r
111 //if ((Pico_mcd->s68k_regs[3]&2) != (d&2)) dprintf("m68k: %s", (d&4) ? ((d&2) ? "word swap req" : "noop?") :\r
112 // ((d&2) ? "word ram to s68k" : "word ram to m68k"));\r
113 d |= Pico_mcd->s68k_regs[3]&0x1d;\r
d0d47c5b 114 if (!(d & 4) && (d & 2)) d &= ~1; // return word RAM to s68k in 2M mode\r
672ad671 115 Pico_mcd->s68k_regs[3] = d; // really use s68k side register\r
116 return;\r
c459aefd 117 case 6:\r
118 *((char *)&Pico_mcd->m.hint_vector+1) = d;\r
119 return;\r
120 case 7:\r
121 *(char *)&Pico_mcd->m.hint_vector = d;\r
122 return;\r
cc68a136 123 case 0xe:\r
672ad671 124 //dprintf("m68k: comm flag: %02x", d);\r
cc68a136 125\r
672ad671 126 //dprintf("s68k @ %06x", SekPcS68k);\r
cc68a136 127\r
128 Pico_mcd->s68k_regs[0xe] = d;\r
c459aefd 129 return;\r
672ad671 130 }\r
131\r
132 if ((a&0xf0) == 0x10) {\r
cc68a136 133 Pico_mcd->s68k_regs[a] = d;\r
672ad671 134 return;\r
cc68a136 135 }\r
136\r
c459aefd 137 dprintf("m68k: invalid write? [%02x] %02x", a, d);\r
cc68a136 138}\r
139\r
140\r
141\r
142static u32 s68k_reg_read16(u32 a, int realsize)\r
143{\r
144 u32 d=0;\r
145 a &= 0x1fe;\r
146\r
672ad671 147 // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k);\r
cc68a136 148\r
149 switch (a) {\r
150 case 0:\r
c459aefd 151 d = 1; // ver = 0, not in reset state\r
152 goto end;\r
672ad671 153 case 2:\r
154 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
bf098bc5 155 dprintf("s68k_regs r3: %02x @%06x", (u8)d, SekPc);\r
672ad671 156 goto end;\r
cc68a136 157 case 6:\r
158 d = CDC_Read_Reg();\r
159 goto end;\r
160 case 8:\r
161 dprintf("s68k host data read");\r
162 d = Read_CDC_Host(1);\r
163 goto end;\r
164 case 0xC:\r
165 dprintf("s68k stopwatch read");\r
166 break;\r
167 case 0x34: // fader\r
168 d = 0; // no busy bit\r
169 goto end;\r
170 }\r
171\r
172 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
173\r
174end:\r
175\r
672ad671 176 // dprintf("ret = %04x", d);\r
cc68a136 177\r
178 return d;\r
179}\r
180\r
181static void s68k_reg_write8(u32 a, u32 d, int realsize)\r
182{\r
183 a &= 0x1ff;\r
672ad671 184 //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k);\r
cc68a136 185\r
186 // TODO: review against Gens\r
187 switch (a) {\r
672ad671 188 case 2:\r
189 return; // only m68k can change WP\r
190 case 3:\r
bf098bc5 191 dprintf("s68k_regs w3: %02x @%06x", (u8)d, SekPc);\r
672ad671 192 d &= 0x1d;\r
d0d47c5b 193 if (d&4) {\r
194 d |= Pico_mcd->s68k_regs[3]&0xc2;\r
195 if ((d ^ Pico_mcd->s68k_regs[3]) & 5) d &= ~2; // in case of mode or bank change we clear DMNA (m68k req) bit\r
196 } else {\r
197 d |= Pico_mcd->s68k_regs[3]&0xc3;\r
198 if (d&1) d &= ~2; // return word RAM to m68k in 2M mode\r
199 }\r
672ad671 200 break;\r
cc68a136 201 case 4:\r
202 dprintf("s68k CDC dest: %x", d&7);\r
203 Pico_mcd->s68k_regs[4] = (Pico_mcd->s68k_regs[4]&0xC0) | (d&7); // CDC mode\r
204 return;\r
205 case 5:\r
c459aefd 206 //dprintf("s68k CDC reg addr: %x", d&0xf);\r
cc68a136 207 break;\r
208 case 7:\r
209 CDC_Write_Reg(d);\r
210 return;\r
211 case 0xa:\r
212 dprintf("s68k set CDC dma addr");\r
213 break;\r
214 case 0x33: // IRQ mask\r
215 dprintf("s68k irq mask: %02x", d);\r
216 if ((d&(1<<4)) && (Pico_mcd->s68k_regs[0x37]&4) && !(Pico_mcd->s68k_regs[0x33]&(1<<4))) {\r
217 CDD_Export_Status();\r
218 // counter75hz = 0; // ???\r
219 }\r
220 break;\r
221 case 0x34: // fader\r
222 Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
223 return;\r
672ad671 224 case 0x36:\r
225 return; // d/m bit is unsetable\r
226 case 0x37: {\r
227 u32 d_old = Pico_mcd->s68k_regs[0x37];\r
228 Pico_mcd->s68k_regs[0x37] = d&7;\r
229 if ((d&4) && !(d_old&4)) {\r
cc68a136 230 CDD_Export_Status();\r
231 // counter75hz = 0; // ???\r
232 }\r
672ad671 233 return;\r
234 }\r
cc68a136 235 case 0x4b:\r
236 Pico_mcd->s68k_regs[a] = (u8) d;\r
237 CDD_Import_Command();\r
238 return;\r
239 }\r
240\r
241 if ((a&0x1f0) == 0x10 || a == 0x0e || (a >= 0x38 && a < 0x42))\r
242 {\r
243 dprintf("m68k: invalid write @ %02x?", a);\r
244 return;\r
245 }\r
246\r
247 Pico_mcd->s68k_regs[a] = (u8) d;\r
248}\r
249\r
250\r
251\r
252\r
253\r
254static int PadRead(int i)\r
255{\r
256 int pad=0,value=0,TH;\r
257 pad=~PicoPad[i]; // Get inverse of pad MXYZ SACB RLDU\r
258 TH=Pico.ioports[i+1]&0x40;\r
259\r
260 if(PicoOpt & 0x20) { // 6 button gamepad enabled\r
261 int phase = Pico.m.padTHPhase[i];\r
262\r
263 if(phase == 2 && !TH) {\r
264 value=(pad&0xc0)>>2; // ?0SA 0000\r
265 goto end;\r
266 } else if(phase == 3 && TH) {\r
267 value=(pad&0x30)|((pad>>8)&0xf); // ?1CB MXYZ\r
268 goto end;\r
269 } else if(phase == 3 && !TH) {\r
270 value=((pad&0xc0)>>2)|0x0f; // ?0SA 1111\r
271 goto end;\r
272 }\r
273 }\r
274\r
275 if(TH) value=(pad&0x3f); // ?1CB RLDU\r
276 else value=((pad&0xc0)>>2)|(pad&3); // ?0SA 00DU\r
277\r
278 end:\r
279\r
280 // orr the bits, which are set as output\r
281 value |= Pico.ioports[i+1]&Pico.ioports[i+4];\r
282\r
283 return value; // will mirror later\r
284}\r
285\r
286static u8 z80Read8(u32 a)\r
287{\r
288 if(Pico.m.z80Run&1) return 0;\r
289\r
290 a&=0x1fff;\r
291\r
292 if(!(PicoOpt&4)) {\r
293 // Z80 disabled, do some faking\r
294 static u8 zerosent = 0;\r
295 if(a == Pico.m.z80_lastaddr) { // probably polling something\r
296 u8 d = Pico.m.z80_fakeval;\r
297 if((d & 0xf) == 0xf && !zerosent) {\r
298 d = 0; zerosent = 1;\r
299 } else {\r
300 Pico.m.z80_fakeval++;\r
301 zerosent = 0;\r
302 }\r
303 return d;\r
304 } else {\r
305 Pico.m.z80_fakeval = 0;\r
306 }\r
307 }\r
308\r
309 Pico.m.z80_lastaddr = (u16) a;\r
310 return Pico.zram[a];\r
311}\r
312\r
313\r
314// for nonstandard reads\r
315static u32 UnusualRead16(u32 a, int realsize)\r
316{\r
317 u32 d=0;\r
318\r
319 dprintf("unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
320\r
321\r
322 dprintf("ret = %04x", d);\r
323 return d;\r
324}\r
325\r
326static u32 OtherRead16(u32 a, int realsize)\r
327{\r
328 u32 d=0;\r
329\r
330 if ((a&0xff0000)==0xa00000) {\r
331 if ((a&0x4000)==0x0000) { d=z80Read8(a); d|=d<<8; goto end; } // Z80 ram (not byteswaped)\r
332 if ((a&0x6000)==0x4000) { if(PicoOpt&1) d=YM2612Read(); else d=Pico.m.rotate++&3; goto end; } // 0x4000-0x5fff, Fudge if disabled\r
333 d=0xffff; goto end;\r
334 }\r
335 if ((a&0xffffe0)==0xa10000) { // I/O ports\r
336 a=(a>>1)&0xf;\r
337 switch(a) {\r
338 case 0: d=Pico.m.hardware; break; // Hardware value (Version register)\r
339 case 1: d=PadRead(0); d|=Pico.ioports[1]&0x80; break;\r
340 case 2: d=PadRead(1); d|=Pico.ioports[2]&0x80; break;\r
341 default: d=Pico.ioports[a]; break; // IO ports can be used as RAM\r
342 }\r
343 d|=d<<8;\r
344 goto end;\r
345 }\r
346 // |=0x80 for Shadow of the Beast & Super Offroad; rotate fakes next fetched instruction for Time Killers\r
347 if (a==0xa11100) { d=((Pico.m.z80Run&1)<<8)|0x8000|Pico.m.rotate++; goto end; }\r
348\r
349 if ((a&0xe700e0)==0xc00000) { d=PicoVideoRead(a); goto end; }\r
350\r
672ad671 351 if ((a&0xffffc0)==0xa12000) {\r
352 d=m68k_reg_read16(a, realsize);\r
353 goto end;\r
354 }\r
cc68a136 355\r
356 d = UnusualRead16(a, realsize);\r
357\r
358end:\r
359 return d;\r
360}\r
361\r
362//extern UINT32 mz80GetRegisterValue(void *, UINT32);\r
363\r
364static void OtherWrite8(u32 a,u32 d,int realsize)\r
365{\r
366 if ((a&0xe700f9)==0xc00011||(a&0xff7ff9)==0xa07f11) { if(PicoOpt&2) SN76496Write(d); return; } // PSG Sound\r
367 if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)d; return; } // Z80 ram\r
368 if ((a&0xff6000)==0xa04000) { if(PicoOpt&1) emustatus|=YM2612Write(a&3, d); return; } // FM Sound\r
369 if ((a&0xffffe0)==0xa10000) { // I/O ports\r
370 a=(a>>1)&0xf;\r
371 // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
372 if(PicoOpt&0x20) {\r
373 if(a==1) {\r
374 Pico.m.padDelay[0] = 0;\r
375 if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;\r
376 }\r
377 else if(a==2) {\r
378 Pico.m.padDelay[1] = 0;\r
379 if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;\r
380 }\r
381 }\r
382 Pico.ioports[a]=(u8)d; // IO ports can be used as RAM\r
383 return;\r
384 }\r
385 if (a==0xa11100) {\r
386 extern int z80startCycle, z80stopCycle;\r
387 //int lineCycles=(488-SekCyclesLeft)&0x1ff;\r
388 d&=1; d^=1;\r
389 if(!d) {\r
390 // hack: detect a nasty situation where Z80 was enabled and disabled in the same 68k timeslice (Golden Axe III)\r
391 if((PicoOpt&4) && Pico.m.z80Run==1) z80_run(20);\r
392 z80stopCycle = SekCyclesDone();\r
393 //z80ExtraCycles += (lineCycles>>1)-(lineCycles>>5); // only meaningful in PicoFrameHints()\r
394 } else {\r
395 z80startCycle = SekCyclesDone();\r
396 //if(Pico.m.scanline != -1)\r
397 //z80ExtraCycles -= (lineCycles>>1)-(lineCycles>>5)+16;\r
398 }\r
399 //dprintf("set_zrun: %i [%i|%i] zPC=%04x @%06x", d, Pico.m.scanline, SekCyclesDone(), mz80GetRegisterValue(NULL, 0), SekPc);\r
400 Pico.m.z80Run=(u8)d; return;\r
401 }\r
402 if (a==0xa11200) { if(!(d&1)) z80_reset(); return; }\r
403\r
404 if ((a&0xff7f00)==0xa06000) // Z80 BANK register\r
405 {\r
406 Pico.m.z80_bank68k>>=1;\r
407 Pico.m.z80_bank68k|=(d&1)<<8;\r
408 Pico.m.z80_bank68k&=0x1ff; // 9 bits and filled in the new top one\r
409 return;\r
410 }\r
411\r
412 if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)(d|(d<<8))); return; } // Byte access gets mirrored\r
413\r
414 if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d, realsize); return; }\r
415\r
416 dprintf("strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
417}\r
418\r
419static void OtherWrite16(u32 a,u32 d)\r
420{\r
421 if ((a&0xe700e0)==0xc00000) { PicoVideoWrite(a,(u16)d); return; }\r
422 if ((a&0xff4000)==0xa00000) { if(!(Pico.m.z80Run&1)) Pico.zram[a&0x1fff]=(u8)(d>>8); return; } // Z80 ram (MSB only)\r
423\r
424 if ((a&0xffffe0)==0xa10000) { // I/O ports\r
425 a=(a>>1)&0xf;\r
426 // 6 button gamepad: if TH went from 0 to 1, gamepad changes state\r
427 if(PicoOpt&0x20) {\r
428 if(a==1) {\r
429 Pico.m.padDelay[0] = 0;\r
430 if(!(Pico.ioports[1]&0x40) && (d&0x40)) Pico.m.padTHPhase[0]++;\r
431 }\r
432 else if(a==2) {\r
433 Pico.m.padDelay[1] = 0;\r
434 if(!(Pico.ioports[2]&0x40) && (d&0x40)) Pico.m.padTHPhase[1]++;\r
435 }\r
436 }\r
437 Pico.ioports[a]=(u8)d; // IO ports can be used as RAM\r
438 return;\r
439 }\r
440 if (a==0xa11100) { OtherWrite8(a, d>>8, 16); return; }\r
441 if (a==0xa11200) { if(!(d&0x100)) z80_reset(); return; }\r
442\r
443 OtherWrite8(a, d>>8, 16);\r
444 OtherWrite8(a+1,d&0xff, 16);\r
445}\r
446\r
447// -----------------------------------------------------------------\r
448// Read Rom and read Ram\r
449\r
450u8 PicoReadM68k8(u32 a)\r
451{\r
452 u32 d=0;\r
453\r
454 if ((a&0xe00000)==0xe00000) { d = *(u8 *)(Pico.ram+((a^1)&0xffff)); goto end; } // Ram\r
455\r
456 a&=0xffffff;\r
457\r
458 if (a < 0x20000) { d = *(u8 *)(Pico_mcd->bios+(a^1)); goto end; } // bios\r
459\r
460 // prg RAM\r
461 if ((a&0xfe0000)==0x020000) {\r
672ad671 462 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 463 d = *(prg_bank+((a^1)&0x1ffff));\r
464 goto end;\r
465 }\r
466\r
d0d47c5b 467 // word RAM\r
468 if ((a&0xfc0000)==0x200000) {\r
469 dprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
470 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
bf098bc5 471 if (a >= 0x220000) {\r
472 dprintf("cell");\r
473 } else {\r
474 a=((a&0x1fffe)<<1)|(a&1);\r
475 if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
476 d = Pico_mcd->word_ram[a^1];\r
477 }\r
d0d47c5b 478 } else {\r
479 // allow access in any mode, like Gens does\r
480 d = Pico_mcd->word_ram[(a^1)&0x3ffff];\r
481 }\r
482 dprintf("ret = %02x", (u8)d);\r
483 goto end;\r
484 }\r
485\r
cc68a136 486 if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
487\r
c459aefd 488 if ((a&0xffffc0)==0xa12000)\r
489 rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 490\r
cc68a136 491 d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
492\r
c459aefd 493 if ((a&0xffffc0)==0xa12000)\r
494 rdprintf("ret = %02x", (u8)d);\r
672ad671 495\r
cc68a136 496 end:\r
497\r
498#ifdef __debug_io\r
499 dprintf("r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPc);\r
500#endif\r
501 return (u8)d;\r
502}\r
503\r
504u16 PicoReadM68k16(u32 a)\r
505{\r
506 u16 d=0;\r
507\r
508 if ((a&0xe00000)==0xe00000) { d=*(u16 *)(Pico.ram+(a&0xfffe)); goto end; } // Ram\r
509\r
510 a&=0xfffffe;\r
511\r
512 if (a < 0x20000) { d = *(u16 *)(Pico_mcd->bios+a); goto end; } // bios\r
513\r
514 // prg RAM\r
515 if ((a&0xfe0000)==0x020000) {\r
672ad671 516 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 517 d = *(u16 *)(prg_bank+(a&0x1fffe));\r
518 goto end;\r
519 }\r
520\r
d0d47c5b 521 // word RAM\r
522 if ((a&0xfc0000)==0x200000) {\r
523 dprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
524 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
bf098bc5 525 if (a >= 0x220000) {\r
526 dprintf("cell");\r
527 } else {\r
528 a=((a&0x1fffe)<<1);\r
529 if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
530 d = *(u16 *)(Pico_mcd->word_ram+a);\r
531 }\r
d0d47c5b 532 } else {\r
533 // allow access in any mode, like Gens does\r
534 d = *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
535 }\r
536 dprintf("ret = %04x", d);\r
537 goto end;\r
538 }\r
539\r
c459aefd 540 if ((a&0xffffc0)==0xa12000)\r
541 rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 542\r
cc68a136 543 d = (u16)OtherRead16(a, 16);\r
544\r
c459aefd 545 if ((a&0xffffc0)==0xa12000)\r
546 rdprintf("ret = %04x", d);\r
672ad671 547\r
cc68a136 548 end:\r
549\r
550#ifdef __debug_io\r
551 dprintf("r16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
552#endif\r
553 return d;\r
554}\r
555\r
556u32 PicoReadM68k32(u32 a)\r
557{\r
558 u32 d=0;\r
559\r
560 if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); d = (pm[0]<<16)|pm[1]; goto end; } // Ram\r
561\r
562 a&=0xfffffe;\r
563\r
564 if (a < 0x20000) { u16 *pm=(u16 *)(Pico_mcd->bios+a); d = (pm[0]<<16)|pm[1]; goto end; } // bios\r
565\r
566 // prg RAM\r
567 if ((a&0xfe0000)==0x020000) {\r
672ad671 568 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 569 u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
570 d = (pm[0]<<16)|pm[1];\r
571 goto end;\r
572 }\r
573\r
d0d47c5b 574 // word RAM\r
575 if ((a&0xfc0000)==0x200000) {\r
576 dprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
577 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
bf098bc5 578 if (a >= 0x220000) {\r
579 dprintf("cell");\r
580 } else {\r
581 u16 *pm;\r
582 a=((a&0x1fffe)<<1);\r
583 if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
584 pm=(u16 *)(Pico_mcd->word_ram+a);\r
585 d = (pm[0]<<16)|pm[1];\r
586 }\r
d0d47c5b 587 } else {\r
588 // allow access in any mode, like Gens does\r
589 u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
590 }\r
591 dprintf("ret = %08x", d);\r
592 goto end;\r
593 }\r
594\r
c459aefd 595 if ((a&0xffffc0)==0xa12000)\r
596 rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 597\r
cc68a136 598 d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
599\r
c459aefd 600 if ((a&0xffffc0)==0xa12000)\r
601 rdprintf("ret = %08x", d);\r
672ad671 602\r
cc68a136 603 end:\r
604#ifdef __debug_io\r
605 dprintf("r32: %06x, %08x @%06x", a&0xffffff, d, SekPc);\r
606#endif\r
607 return d;\r
608}\r
609\r
610// -----------------------------------------------------------------\r
611// Write Ram\r
612\r
613void PicoWriteM68k8(u32 a,u8 d)\r
614{\r
615#ifdef __debug_io\r
616 dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);\r
617#endif\r
618 //if ((a&0xe0ffff)==0xe0a9ba+0x69c)\r
619 // dprintf("w8 : %06x, %02x @%06x", a&0xffffff, d, SekPc);\r
620\r
621\r
622 if ((a&0xe00000)==0xe00000) { u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram\r
623\r
624 a&=0xffffff;\r
625\r
626 // prg RAM\r
627 if ((a&0xfe0000)==0x020000) {\r
672ad671 628 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
bf098bc5 629 *(u8 *)(prg_bank+((a^1)&0x1ffff))=d;\r
cc68a136 630 return;\r
631 }\r
632\r
d0d47c5b 633 // word RAM\r
634 if ((a&0xfc0000)==0x200000) {\r
635 dprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
636 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
bf098bc5 637 if (a >= 0x220000) {\r
638 dprintf("cell");\r
639 } else {\r
640 a=((a&0x1fffe)<<1)|(a&1);\r
641 if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
642 *(u8 *)(Pico_mcd->word_ram+(a^1))=d;\r
643 }\r
d0d47c5b 644 } else {\r
645 // allow access in any mode, like Gens does\r
bf098bc5 646 *(u8 *)(Pico_mcd->word_ram+((a^1)&0x3ffff))=d;\r
d0d47c5b 647 }\r
648 return;\r
649 }\r
650\r
c459aefd 651 if ((a&0xffffc0)==0xa12000)\r
652 rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
672ad671 653\r
cc68a136 654 OtherWrite8(a,d,8);\r
655}\r
656\r
657void PicoWriteM68k16(u32 a,u16 d)\r
658{\r
659#ifdef __debug_io\r
660 dprintf("w16: %06x, %04x", a&0xffffff, d);\r
661#endif\r
cc68a136 662 // dprintf("w16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
663\r
664 if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram\r
665\r
666 a&=0xfffffe;\r
667\r
668 // prg RAM\r
669 if ((a&0xfe0000)==0x020000) {\r
672ad671 670 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 671 *(u16 *)(prg_bank+(a&0x1fffe))=d;\r
672 return;\r
673 }\r
674\r
d0d47c5b 675 // word RAM\r
676 if ((a&0xfc0000)==0x200000) {\r
677 dprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
678 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
bf098bc5 679 if (a >= 0x220000) {\r
680 dprintf("cell");\r
681 } else {\r
682 a=((a&0x1fffe)<<1);\r
683 if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
684 *(u16 *)(Pico_mcd->word_ram+a)=d;\r
685 }\r
d0d47c5b 686 } else {\r
687 // allow access in any mode, like Gens does\r
688 *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe))=d;\r
689 }\r
690 return;\r
691 }\r
692\r
c459aefd 693 if ((a&0xffffc0)==0xa12000)\r
694 rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
cc68a136 695\r
696 OtherWrite16(a,d);\r
697}\r
698\r
699void PicoWriteM68k32(u32 a,u32 d)\r
700{\r
701#ifdef __debug_io\r
702 dprintf("w32: %06x, %08x", a&0xffffff, d);\r
703#endif\r
704\r
705 if ((a&0xe00000)==0xe00000)\r
706 {\r
707 // Ram:\r
708 u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
709 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
710 return;\r
711 }\r
712\r
713 a&=0xfffffe;\r
714\r
715 // prg RAM\r
716 if ((a&0xfe0000)==0x020000) {\r
672ad671 717 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 718 u16 *pm=(u16 *)(prg_bank+(a&0x1fffe));\r
719 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
720 return;\r
721 }\r
722\r
672ad671 723 // word RAM\r
d0d47c5b 724 if ((a&0xfc0000)==0x200000) {\r
725 if (d != 0) // don't log clears\r
726 dprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc);\r
727 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
bf098bc5 728 if (a >= 0x220000) {\r
729 dprintf("cell");\r
730 } else {\r
731 u16 *pm;\r
732 a=((a&0x1fffe)<<1);\r
733 if (Pico_mcd->s68k_regs[3]&1) a+=2;\r
734 pm=(u16 *)(Pico_mcd->word_ram+a);\r
735 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
736 }\r
d0d47c5b 737 } else {\r
738 // allow access in any mode, like Gens does\r
739 u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
740 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
741 }\r
672ad671 742 return;\r
d0d47c5b 743 }\r
672ad671 744\r
c459aefd 745 if ((a&0xffffc0)==0xa12000)\r
746 rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
cc68a136 747\r
748 OtherWrite16(a, (u16)(d>>16));\r
749 OtherWrite16(a+2,(u16)d);\r
750}\r
751\r
752\r
753// -----------------------------------------------------------------\r
754\r
755\r
756u8 PicoReadS68k8(u32 a)\r
757{\r
758 u32 d=0;\r
759\r
760 a&=0xffffff;\r
761\r
762 // prg RAM\r
763 if (a < 0x80000) {\r
764 d = *(Pico_mcd->prg_ram+(a^1));\r
765 goto end;\r
766 }\r
767\r
768 // regs\r
769 if ((a&0xfffe00) == 0xff8000) {\r
c459aefd 770 rdprintf("s68k_regs r8: [%02x] @ %06x", a&0x1ff, SekPcS68k);\r
cc68a136 771 d = s68k_reg_read16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
c459aefd 772 rdprintf("ret = %02x", (u8)d);\r
cc68a136 773 goto end;\r
774 }\r
775\r
d0d47c5b 776 // word RAM (2M area)\r
777 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
778 dprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPc);\r
779 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
780 // TODO (decode)\r
781 dprintf("(decode)");\r
782 } else {\r
783 // allow access in any mode, like Gens does\r
784 d = Pico_mcd->word_ram[(a^1)&0x3ffff];\r
785 }\r
786 dprintf("ret = %02x", (u8)d);\r
787 goto end;\r
788 }\r
789\r
790 // word RAM (1M area)\r
791 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
792 dprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPc);\r
bf098bc5 793 a=((a&0x1fffe)<<1)|(a&1);\r
794 if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
795 d = Pico_mcd->word_ram[a^1];\r
796 dprintf("ret = %02x", (u8)d);\r
d0d47c5b 797 goto end;\r
798 }\r
799\r
cc68a136 800 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
801\r
802 end:\r
803\r
804#ifdef __debug_io2\r
805 dprintf("s68k r8 : %06x, %02x @%06x", a&0xffffff, (u8)d, SekPcS68k);\r
806#endif\r
807 return (u8)d;\r
808}\r
809\r
810u16 PicoReadS68k16(u32 a)\r
811{\r
812 u16 d=0;\r
813\r
814 a&=0xfffffe;\r
815\r
816 // prg RAM\r
817 if (a < 0x80000) {\r
818 d = *(u16 *)(Pico_mcd->prg_ram+a);\r
819 goto end;\r
820 }\r
821\r
822 // regs\r
823 if ((a&0xfffe00) == 0xff8000) {\r
c459aefd 824 rdprintf("s68k_regs r16: [%02x] @ %06x", a&0x1fe, SekPcS68k);\r
cc68a136 825 d = s68k_reg_read16(a, 16);\r
c459aefd 826 rdprintf("ret = %04x", d);\r
cc68a136 827 goto end;\r
828 }\r
829\r
d0d47c5b 830 // word RAM (2M area)\r
831 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
832 dprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPc);\r
833 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
834 // TODO (decode)\r
835 dprintf("(decode)");\r
836 } else {\r
837 // allow access in any mode, like Gens does\r
838 d = *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
839 }\r
840 dprintf("ret = %04x", (u8)d);\r
841 goto end;\r
842 }\r
843\r
844 // word RAM (1M area)\r
845 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
846 dprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPc);\r
bf098bc5 847 a=((a&0x1fffe)<<1);\r
848 if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
849 d = *(u16 *)(Pico_mcd->word_ram+a);\r
850 dprintf("ret = %04x", (u8)d);\r
d0d47c5b 851 goto end;\r
852 }\r
853\r
cc68a136 854 dprintf("s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
855\r
856 end:\r
857\r
858#ifdef __debug_io2\r
859 dprintf("s68k r16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
860#endif\r
861 return d;\r
862}\r
863\r
864u32 PicoReadS68k32(u32 a)\r
865{\r
866 u32 d=0;\r
867\r
868 a&=0xfffffe;\r
869\r
870 // prg RAM\r
871 if (a < 0x80000) {\r
872 u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
873 d = (pm[0]<<16)|pm[1];\r
874 goto end;\r
875 }\r
876\r
877 // regs\r
878 if ((a&0xfffe00) == 0xff8000) {\r
c459aefd 879 rdprintf("s68k_regs r32: [%02x] @ %06x", a&0x1fe, SekPcS68k);\r
cc68a136 880 d = (s68k_reg_read16(a, 32)<<16)|s68k_reg_read16(a+2, 32);\r
c459aefd 881 rdprintf("ret = %08x", d);\r
cc68a136 882 goto end;\r
883 }\r
884\r
d0d47c5b 885 // word RAM (2M area)\r
886 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
887 dprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPc);\r
888 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
889 // TODO (decode)\r
890 dprintf("(decode)");\r
891 } else {\r
892 // allow access in any mode, like Gens does\r
893 u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
894 }\r
895 dprintf("ret = %08x", (u8)d);\r
896 goto end;\r
897 }\r
898\r
899 // word RAM (1M area)\r
900 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
bf098bc5 901 u16 *pm;\r
d0d47c5b 902 dprintf("s68k_wram1M 32: [%06x] @%06x", a, SekPc);\r
bf098bc5 903 a=((a&0x1fffe)<<1);\r
904 if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
905 pm=(u16 *)(Pico_mcd->word_ram+a);\r
906 d = (pm[0]<<16)|pm[1];\r
907 dprintf("ret = %08x", (u8)d);\r
d0d47c5b 908 goto end;\r
909 }\r
910\r
cc68a136 911 dprintf("s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
912\r
913 end:\r
914\r
915#ifdef __debug_io2\r
916 dprintf("s68k r32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
917#endif\r
918 return d;\r
919}\r
920\r
921// -----------------------------------------------------------------\r
922\r
923void PicoWriteS68k8(u32 a,u8 d)\r
924{\r
925#ifdef __debug_io2\r
926 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
927#endif\r
928\r
929 a&=0xffffff;\r
930\r
931 // prg RAM\r
932 if (a < 0x80000) {\r
933 u8 *pm=(u8 *)(Pico_mcd->prg_ram+(a^1));\r
934 *pm=d;\r
935 return;\r
936 }\r
937\r
672ad671 938 if (a != 0xff0011 && (a&0xff8000) == 0xff0000) // PCM hack\r
939 return;\r
940\r
cc68a136 941 // regs\r
942 if ((a&0xfffe00) == 0xff8000) {\r
c459aefd 943 rdprintf("s68k_regs w8: [%02x] %02x @ %06x", a&0x1ff, d, SekPcS68k);\r
cc68a136 944 s68k_reg_write8(a,d,8);\r
945 return;\r
946 }\r
947\r
d0d47c5b 948 // word RAM (2M area)\r
949 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
950 dprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPc);\r
951 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
952 // TODO (decode)\r
953 dprintf("(decode)");\r
954 } else {\r
955 // allow access in any mode, like Gens does\r
bf098bc5 956 *(u8 *)(Pico_mcd->word_ram+((a^1)&0x3ffff))=d;\r
d0d47c5b 957 }\r
958 return;\r
959 }\r
960\r
961 // word RAM (1M area)\r
962 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
963 if (d)\r
964 dprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPc);\r
bf098bc5 965 a=((a&0x1fffe)<<1)|(a&1);\r
966 if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
967 *(u8 *)(Pico_mcd->word_ram+(a^1))=d;\r
d0d47c5b 968 return;\r
969 }\r
970\r
cc68a136 971 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
972}\r
973\r
974void PicoWriteS68k16(u32 a,u16 d)\r
975{\r
976#ifdef __debug_io2\r
977 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
978#endif\r
979\r
980 a&=0xfffffe;\r
981\r
982 // prg RAM\r
983 if (a < 0x80000) {\r
984 *(u16 *)(Pico_mcd->prg_ram+a)=d;\r
985 return;\r
986 }\r
987\r
988 // regs\r
989 if ((a&0xfffe00) == 0xff8000) {\r
c459aefd 990 rdprintf("s68k_regs w16: [%02x] %04x @ %06x", a&0x1ff, d, SekPcS68k);\r
cc68a136 991 s68k_reg_write8(a, d>>8, 16);\r
992 s68k_reg_write8(a+1,d&0xff, 16);\r
993 return;\r
994 }\r
995\r
d0d47c5b 996 // word RAM (2M area)\r
997 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
998 dprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPc);\r
999 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
1000 // TODO (decode)\r
1001 dprintf("(decode)");\r
1002 } else {\r
1003 // allow access in any mode, like Gens does\r
1004 *(u16 *)(Pico_mcd->word_ram+(a&0x3fffe))=d;\r
1005 }\r
1006 return;\r
1007 }\r
1008\r
1009 // word RAM (1M area)\r
1010 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
1011 if (d)\r
1012 dprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPc);\r
bf098bc5 1013 a=((a&0x1fffe)<<1);\r
1014 if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
1015 *(u16 *)(Pico_mcd->word_ram+a)=d;\r
d0d47c5b 1016 return;\r
1017 }\r
1018\r
cc68a136 1019 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1020}\r
1021\r
1022void PicoWriteS68k32(u32 a,u32 d)\r
1023{\r
1024#ifdef __debug_io2\r
1025 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1026#endif\r
1027\r
1028 a&=0xfffffe;\r
1029\r
1030 // prg RAM\r
1031 if (a < 0x80000) {\r
1032 u16 *pm=(u16 *)(Pico_mcd->prg_ram+a);\r
1033 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
1034 return;\r
1035 }\r
1036\r
1037 // regs\r
1038 if ((a&0xfffe00) == 0xff8000) {\r
c459aefd 1039 rdprintf("s68k_regs w32: [%02x] %08x @ %06x", a&0x1ff, d, SekPcS68k);\r
cc68a136 1040 s68k_reg_write8(a, d>>24, 32);\r
1041 s68k_reg_write8(a+1,(d>>16)&0xff, 32);\r
1042 s68k_reg_write8(a+2,(d>>8) &0xff, 32);\r
1043 s68k_reg_write8(a+3, d &0xff, 32);\r
1044 return;\r
1045 }\r
1046\r
d0d47c5b 1047 // word RAM (2M area)\r
1048 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
1049 dprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPc);\r
1050 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
1051 // TODO (decode)\r
1052 dprintf("(decode)");\r
1053 } else {\r
1054 // allow access in any mode, like Gens does\r
1055 u16 *pm=(u16 *)(Pico_mcd->word_ram+(a&0x3fffe));\r
1056 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
1057 }\r
1058 return;\r
1059 }\r
1060\r
1061 // word RAM (1M area)\r
1062 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
bf098bc5 1063 u16 *pm;\r
d0d47c5b 1064 if (d)\r
1065 dprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPc);\r
bf098bc5 1066 a=((a&0x1fffe)<<1);\r
1067 if (!(Pico_mcd->s68k_regs[3]&1)) a+=2;\r
1068 pm=(u16 *)(Pico_mcd->word_ram+a);\r
1069 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
d0d47c5b 1070 return;\r
1071 }\r
cc68a136 1072 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1073}\r
1074\r
1075\r
1076\r
1077// -----------------------------------------------------------------\r
1078\r
1079#ifdef EMU_M68K\r
1080unsigned char PicoReadCD8w (unsigned int a) {\r
1081 return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k8(a) : PicoReadM68k8(a);\r
1082}\r
1083unsigned short PicoReadCD16w(unsigned int a) {\r
1084 return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k16(a) : PicoReadM68k16(a);\r
1085}\r
1086unsigned int PicoReadCD32w(unsigned int a) {\r
1087 return m68ki_cpu_p == &PicoS68kCPU ? PicoReadS68k32(a) : PicoReadM68k32(a);\r
1088}\r
1089void PicoWriteCD8w (unsigned int a, unsigned char d) {\r
1090 if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k8(a, d); else PicoWriteM68k8(a, d);\r
1091}\r
1092void PicoWriteCD16w(unsigned int a, unsigned short d) {\r
1093 if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k16(a, d); else PicoWriteM68k16(a, d);\r
1094}\r
1095void PicoWriteCD32w(unsigned int a, unsigned int d) {\r
1096 if (m68ki_cpu_p == &PicoS68kCPU) PicoWriteS68k32(a, d); else PicoWriteM68k32(a, d);\r
1097}\r
1098\r
1099// these are allowed to access RAM\r
1100unsigned int m68k_read_pcrelative_CD8 (unsigned int a) {\r
1101 a&=0xffffff;\r
1102 if(m68ki_cpu_p == &PicoS68kCPU) {\r
1103 if (a < 0x80000) return *(u8 *)(Pico_mcd->prg_ram+(a^1)); // PRG Ram\r
1104 else dprintf("s68k read_pcrel8 @ %06x", a);\r
1105 } else {\r
1106 if(a<Pico.romsize) return *(u8 *)(Pico.rom+(a^1)); // Rom\r
1107 if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
1108 }\r
1109 return 0;//(u8) lastread_d;\r
1110}\r
1111unsigned int m68k_read_pcrelative_CD16(unsigned int a) {\r
1112 a&=0xffffff;\r
1113 if(m68ki_cpu_p == &PicoS68kCPU) {\r
1114 if (a < 0x80000) return *(u16 *)(Pico_mcd->prg_ram+(a&~1)); // PRG Ram\r
1115 else dprintf("s68k read_pcrel16 @ %06x", a);\r
1116 } else {\r
1117 if(a<Pico.romsize) return *(u16 *)(Pico.rom+(a&~1)); // Rom\r
1118 if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram\r
1119 }\r
1120 return 0;//(u16) lastread_d;\r
1121}\r
1122unsigned int m68k_read_pcrelative_CD32(unsigned int a) {\r
1123 a&=0xffffff;\r
1124 if(m68ki_cpu_p == &PicoS68kCPU) {\r
1125 if (a < 0x80000) { u16 *pm=(u16 *)(Pico_mcd->prg_ram+(a&~1)); return (pm[0]<<16)|pm[1]; } // PRG Ram\r
1126 else dprintf("s68k read_pcrel32 @ %06x", a);\r
1127 } else {\r
1128 if(a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+(a&~1)); return (pm[0]<<16)|pm[1]; }\r
1129 if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram\r
1130 }\r
1131 return 0; //lastread_d;\r
1132}\r
1133#endif // EMU_M68K\r
1134\r