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