added software scaler
[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
7a1f6e45 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
cc68a136 41\r
4ff2d527 42#ifndef _ASM_CD_MEMORY_C\r
cb4a513a 43static u32 m68k_reg_read16(u32 a)\r
cc68a136 44{\r
45 u32 d=0;\r
46 a &= 0x3e;\r
672ad671 47 // dprintf("m68k_regs r%2i: [%02x] @%06x", realsize&~1, a+(realsize&1), SekPc);\r
cc68a136 48\r
49 switch (a) {\r
672ad671 50 case 0:\r
c459aefd 51 d = ((Pico_mcd->s68k_regs[0x33]<<13)&0x8000) | Pico_mcd->m.busreq; // here IFL2 is always 0, just like in Gens\r
672ad671 52 goto end;\r
cc68a136 53 case 2:\r
672ad671 54 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0xc7);\r
c008977e 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
cc68a136 58 goto end;\r
c459aefd 59 case 4:\r
60 d = Pico_mcd->s68k_regs[4]<<8;\r
61 goto end;\r
62 case 6:\r
913ef4b7 63 d = *(u16 *)(Pico_mcd->bios + 0x72);\r
c459aefd 64 goto end;\r
cc68a136 65 case 8:\r
cc68a136 66 d = Read_CDC_Host(0);\r
67 goto end;\r
c459aefd 68 case 0xA:\r
fa1e5e29 69 dprintf("m68k FIXME: reserved read");\r
c459aefd 70 goto end;\r
cc68a136 71 case 0xC:\r
1cd356a3 72 d = Pico_mcd->m.timer_stopwatch >> 16;\r
4ff2d527 73 dprintf("m68k stopwatch timer read (%04x)", d);\r
1cd356a3 74 goto end;\r
cc68a136 75 }\r
76\r
cc68a136 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
fa1e5e29 83 dprintf("m68k_regs FIXME invalid read @ %02x", a);\r
cc68a136 84\r
85end:\r
86\r
672ad671 87 // dprintf("ret = %04x", d);\r
cc68a136 88 return d;\r
89}\r
4ff2d527 90#endif\r
cc68a136 91\r
4ff2d527 92#ifndef _ASM_CD_MEMORY_C\r
93static\r
94#endif\r
95void m68k_reg_write8(u32 a, u32 d)\r
cc68a136 96{\r
97 a &= 0x3f;\r
672ad671 98 // dprintf("m68k_regs w%2i: [%02x] %02x @%06x", realsize, a, d, SekPc);\r
cc68a136 99\r
100 switch (a) {\r
101 case 0:\r
672ad671 102 d &= 1;\r
cc68a136 103 if ((d&1) && (Pico_mcd->s68k_regs[0x33]&(1<<2))) { dprintf("m68k: s68k irq 2"); SekInterruptS68k(2); }\r
c459aefd 104 return;\r
cc68a136 105 case 1:\r
672ad671 106 d &= 3;\r
51a902ae 107 if (!(d&1)) Pico_mcd->m.state_flags |= 1; // reset pending, needed to be sure we fetch the right vectors on reset\r
c459aefd 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
51a902ae 110 if ((Pico_mcd->m.state_flags&1) && (d&3)==1) {\r
cc68a136 111 SekResetS68k(); // S68k comes out of RESET or BRQ state\r
4ff2d527 112 Pico_mcd->m.state_flags&=~1;\r
113 dprintf("m68k: resetting s68k, cycles=%i", SekCyclesLeft);\r
cc68a136 114 }\r
c459aefd 115 Pico_mcd->m.busreq = d;\r
116 return;\r
672ad671 117 case 2:\r
118 Pico_mcd->s68k_regs[2] = d; // really use s68k side register\r
119 return;\r
66fdc0f0 120 case 3: {\r
121 u32 dold = Pico_mcd->s68k_regs[3]&0x1f;\r
c008977e 122 //printf("m68k_regs w3: %02x @%06x\n", (u8)d, SekPc);\r
672ad671 123 d &= 0xc2;\r
66fdc0f0 124 if ((dold>>6) != ((d>>6)&3))\r
672ad671 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
66fdc0f0 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
89fa852d 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
66fdc0f0 139 if (d & 2) dold &= ~1; // return word RAM to s68k in 2M mode\r
89fa852d 140#endif\r
66fdc0f0 141 }\r
142 Pico_mcd->s68k_regs[3] = d | dold; // really use s68k side register\r
7a1f6e45 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
672ad671 149 return;\r
66fdc0f0 150 }\r
c459aefd 151 case 6:\r
d1df8786 152 Pico_mcd->bios[0x72 + 1] = d; // simple hint vector changer\r
c459aefd 153 return;\r
154 case 7:\r
d1df8786 155 Pico_mcd->bios[0x72] = d;\r
913ef4b7 156 dprintf("hint vector set to %08x", PicoRead32(0x70));\r
c459aefd 157 return;\r
7a1f6e45 158 case 0xf:\r
159 d = (d << 1) | ((d >> 7) & 1); // rol8 1 (special case)\r
cc68a136 160 case 0xe:\r
672ad671 161 //dprintf("m68k: comm flag: %02x", d);\r
cc68a136 162 Pico_mcd->s68k_regs[0xe] = d;\r
7a1f6e45 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
c459aefd 169 return;\r
672ad671 170 }\r
171\r
172 if ((a&0xf0) == 0x10) {\r
cc68a136 173 Pico_mcd->s68k_regs[a] = d;\r
7a1f6e45 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
672ad671 180 return;\r
cc68a136 181 }\r
182\r
fa1e5e29 183 dprintf("m68k FIXME: invalid write? [%02x] %02x", a, d);\r
cc68a136 184}\r
185\r
186\r
913ef4b7 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
cc68a136 197\r
4ff2d527 198#ifndef _ASM_CD_MEMORY_C\r
199static\r
200#endif\r
201u32 s68k_reg_read16(u32 a)\r
cc68a136 202{\r
203 u32 d=0;\r
cc68a136 204\r
672ad671 205 // dprintf("s68k_regs r%2i: [%02x] @ %06x", realsize&~1, a+(realsize&1), SekPcS68k);\r
cc68a136 206\r
207 switch (a) {\r
208 case 0:\r
7a1f6e45 209 return ((Pico_mcd->s68k_regs[0]&3)<<8) | 1; // ver = 0, not in reset state\r
672ad671 210 case 2:\r
211 d = (Pico_mcd->s68k_regs[a]<<8) | (Pico_mcd->s68k_regs[a+1]&0x1f);\r
c008977e 212 //printf("s68k_regs r3: %02x @%06x\n", (u8)d, SekPcS68k);\r
7a1f6e45 213 goto poll_detect;\r
cc68a136 214 case 6:\r
7a1f6e45 215 return CDC_Read_Reg();\r
cc68a136 216 case 8:\r
7a1f6e45 217 return Read_CDC_Host(1); // Gens returns 0 here on byte reads\r
cc68a136 218 case 0xC:\r
4f265db7 219 d = Pico_mcd->m.timer_stopwatch >> 16;\r
4ff2d527 220 dprintf("s68k stopwatch timer read (%04x)", d);\r
7a1f6e45 221 return d;\r
d1df8786 222 case 0x30:\r
7a1f6e45 223 dprintf("s68k int3 timer read (%02x)", Pico_mcd->s68k_regs[31]);\r
224 return Pico_mcd->s68k_regs[31];\r
cc68a136 225 case 0x34: // fader\r
7a1f6e45 226 return 0; // no busy bit\r
913ef4b7 227 case 0x50: // font data (check: Lunar 2, Silpheed)\r
228 READ_FONT_DATA(0x00100000);\r
7a1f6e45 229 return d;\r
913ef4b7 230 case 0x52:\r
231 READ_FONT_DATA(0x00010000);\r
7a1f6e45 232 return d;\r
913ef4b7 233 case 0x54:\r
234 READ_FONT_DATA(0x10000000);\r
7a1f6e45 235 return d;\r
913ef4b7 236 case 0x56:\r
237 READ_FONT_DATA(0x01000000);\r
7a1f6e45 238 return d;\r
cc68a136 239 }\r
240\r
241 d = (Pico_mcd->s68k_regs[a]<<8) | Pico_mcd->s68k_regs[a+1];\r
242\r
7a1f6e45 243 if (a >= 0x0e && a < 0x30) goto poll_detect;\r
cc68a136 244\r
7a1f6e45 245 return d;\r
cc68a136 246\r
7a1f6e45 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
cc68a136 267 return d;\r
268}\r
269\r
4ff2d527 270#ifndef _ASM_CD_MEMORY_C\r
271static\r
272#endif\r
273void s68k_reg_write8(u32 a, u32 d)\r
cc68a136 274{\r
672ad671 275 //dprintf("s68k_regs w%2i: [%02x] %02x @ %06x", realsize, a, d, SekPcS68k);\r
cc68a136 276\r
277 // TODO: review against Gens\r
48e8482f 278 // Warning: d might have upper bits set\r
cc68a136 279 switch (a) {\r
672ad671 280 case 2:\r
281 return; // only m68k can change WP\r
fa1e5e29 282 case 3: {\r
283 int dold = Pico_mcd->s68k_regs[3];\r
c008977e 284 //printf("s68k_regs w3: %02x @%06x\n", (u8)d, SekPcS68k);\r
672ad671 285 d &= 0x1d;\r
4ff2d527 286 d |= dold&0xc2;\r
d0d47c5b 287 if (d&4) {\r
4ff2d527 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
48e8482f 294#ifdef _ASM_CD_MEMORY_C\r
295 if ((d ^ dold) & 0x1d)\r
296 PicoMemResetCDdecode(d);\r
297#endif\r
fa1e5e29 298 if (!(dold & 4)) {\r
299 dprintf("wram mode 2M->1M");\r
300 wram_2M_to_1M(Pico_mcd->word_ram2M);\r
4ff2d527 301 }\r
d0d47c5b 302 } else {\r
fa1e5e29 303 if (dold & 4) {\r
304 dprintf("wram mode 1M->2M");\r
4ff2d527 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
fa1e5e29 309 wram_1M_to_2M(Pico_mcd->word_ram2M);\r
4ff2d527 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
d0d47c5b 317 }\r
672ad671 318 break;\r
fa1e5e29 319 }\r
cc68a136 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
c459aefd 325 //dprintf("s68k CDC reg addr: %x", d&0xf);\r
cc68a136 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
d1df8786 333 case 0xc:\r
4f265db7 334 case 0xd:\r
d1df8786 335 dprintf("s68k set stopwatch timer");\r
4f265db7 336 Pico_mcd->m.timer_stopwatch = 0;\r
337 return;\r
1cd356a3 338 case 0xe:\r
7a1f6e45 339 Pico_mcd->s68k_regs[0xf] = (d>>1) | (d<<7); // ror8 1, Gens note: Dragons lair\r
1cd356a3 340 return;\r
d1df8786 341 case 0x31:\r
4f265db7 342 dprintf("s68k set int3 timer: %02x", d);\r
48e8482f 343 Pico_mcd->m.timer_int3 = (d & 0xff) << 16;\r
d1df8786 344 break;\r
cc68a136 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
cc68a136 349 }\r
350 break;\r
351 case 0x34: // fader\r
352 Pico_mcd->s68k_regs[a] = (u8) d & 0x7f;\r
353 return;\r
672ad671 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
cc68a136 360 CDD_Export_Status();\r
cc68a136 361 }\r
672ad671 362 return;\r
363 }\r
cc68a136 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
1cd356a3 370 if ((a&0x1f0) == 0x10 || (a >= 0x38 && a < 0x42))\r
cc68a136 371 {\r
fa1e5e29 372 dprintf("s68k FIXME: invalid write @ %02x?", a);\r
cc68a136 373 return;\r
374 }\r
375\r
376 Pico_mcd->s68k_regs[a] = (u8) d;\r
377}\r
378\r
379\r
4ff2d527 380#ifndef _ASM_CD_MEMORY_C\r
fa1e5e29 381static u32 OtherRead16End(u32 a, int realsize)\r
cc68a136 382{\r
383 u32 d=0;\r
384\r
672ad671 385 if ((a&0xffffc0)==0xa12000) {\r
cb4a513a 386 d=m68k_reg_read16(a);\r
672ad671 387 goto end;\r
388 }\r
cc68a136 389\r
fa1e5e29 390 dprintf("m68k FIXME: unusual r%i: %06x @%06x", realsize&~1, (a&0xfffffe)+(realsize&1), SekPc);\r
cc68a136 391\r
392end:\r
393 return d;\r
394}\r
395\r
cc68a136 396\r
fa1e5e29 397static void OtherWrite8End(u32 a, u32 d, int realsize)\r
cc68a136 398{\r
cb4a513a 399 if ((a&0xffffc0)==0xa12000) { m68k_reg_write8(a, d); return; }\r
cc68a136 400\r
fa1e5e29 401 dprintf("m68k FIXME: strange w%i: %06x, %08x @%06x", realsize, a&0xffffff, d, SekPc);\r
cc68a136 402}\r
403\r
cc68a136 404\r
fa1e5e29 405#undef _ASM_MEMORY_C\r
406#include "../MemoryCmn.c"\r
4ff2d527 407#include "cell_map.c"\r
408#endif // !def _ASM_CD_MEMORY_C\r
cc68a136 409\r
410// -----------------------------------------------------------------\r
411// Read Rom and read Ram\r
412\r
4ff2d527 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
cc68a136 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
4ff2d527 428 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
672ad671 429 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 430 d = *(prg_bank+((a^1)&0x1ffff));\r
431 goto end;\r
432 }\r
433\r
d0d47c5b 434 // word RAM\r
435 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 436 wrdprintf("m68k_wram r8: [%06x] @%06x", a, SekPc);\r
d0d47c5b 437 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 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
d0d47c5b 443 } else {\r
444 // allow access in any mode, like Gens does\r
fa1e5e29 445 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
d0d47c5b 446 }\r
913ef4b7 447 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 448 goto end;\r
449 }\r
450\r
cc68a136 451 if ((a&0xff4000)==0xa00000) { d=z80Read8(a); goto end; } // Z80 Ram\r
452\r
c459aefd 453 if ((a&0xffffc0)==0xa12000)\r
454 rdprintf("m68k_regs r8: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 455\r
cc68a136 456 d=OtherRead16(a&~1, 8|(a&1)); if ((a&1)==0) d>>=8;\r
457\r
c459aefd 458 if ((a&0xffffc0)==0xa12000)\r
459 rdprintf("ret = %02x", (u8)d);\r
672ad671 460\r
cc68a136 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
4ff2d527 468#endif\r
cc68a136 469\r
ab0607f7 470\r
4ff2d527 471#ifdef _ASM_CD_MEMORY_C\r
472u16 PicoReadM68k16(u32 a);\r
473#else\r
474static u16 PicoReadM68k16(u32 a)\r
cc68a136 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
4ff2d527 485 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
672ad671 486 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
c008977e 487 wrdprintf("m68k_prgram r16: [%i,%06x] @%06x", Pico_mcd->s68k_regs[3]>>6, a, SekPc);\r
cc68a136 488 d = *(u16 *)(prg_bank+(a&0x1fffe));\r
c008977e 489 wrdprintf("ret = %04x", d);\r
cc68a136 490 goto end;\r
491 }\r
492\r
d0d47c5b 493 // word RAM\r
494 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 495 wrdprintf("m68k_wram r16: [%06x] @%06x", a, SekPc);\r
d0d47c5b 496 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 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
d0d47c5b 502 } else {\r
503 // allow access in any mode, like Gens does\r
fa1e5e29 504 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 505 }\r
913ef4b7 506 wrdprintf("ret = %04x", d);\r
d0d47c5b 507 goto end;\r
508 }\r
509\r
c459aefd 510 if ((a&0xffffc0)==0xa12000)\r
511 rdprintf("m68k_regs r16: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 512\r
cc68a136 513 d = (u16)OtherRead16(a, 16);\r
514\r
c459aefd 515 if ((a&0xffffc0)==0xa12000)\r
516 rdprintf("ret = %04x", d);\r
672ad671 517\r
cc68a136 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
4ff2d527 525#endif\r
cc68a136 526\r
ab0607f7 527\r
4ff2d527 528#ifdef _ASM_CD_MEMORY_C\r
529u32 PicoReadM68k32(u32 a);\r
530#else\r
531static u32 PicoReadM68k32(u32 a)\r
cc68a136 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
4ff2d527 542 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
672ad671 543 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 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
d0d47c5b 549 // word RAM\r
550 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 551 wrdprintf("m68k_wram r32: [%06x] @%06x", a, SekPc);\r
d0d47c5b 552 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 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
4ff2d527 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
bf098bc5 561 } else {\r
fa1e5e29 562 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe)); d = (pm[0]<<16)|pm[1];\r
bf098bc5 563 }\r
d0d47c5b 564 } else {\r
565 // allow access in any mode, like Gens does\r
fa1e5e29 566 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d0d47c5b 567 }\r
913ef4b7 568 wrdprintf("ret = %08x", d);\r
d0d47c5b 569 goto end;\r
570 }\r
571\r
c459aefd 572 if ((a&0xffffc0)==0xa12000)\r
573 rdprintf("m68k_regs r32: [%02x] @%06x", a&0x3f, SekPc);\r
672ad671 574\r
cc68a136 575 d = (OtherRead16(a, 32)<<16)|OtherRead16(a+2, 32);\r
576\r
c459aefd 577 if ((a&0xffffc0)==0xa12000)\r
578 rdprintf("ret = %08x", d);\r
672ad671 579\r
cc68a136 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
4ff2d527 586#endif\r
cc68a136 587\r
ab0607f7 588\r
cc68a136 589// -----------------------------------------------------------------\r
590// Write Ram\r
591\r
4ff2d527 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
cc68a136 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
ab0607f7 604 if ((a&0xe00000)==0xe00000) { // Ram\r
605 *(u8 *)(Pico.ram+((a^1)&0xffff)) = d;\r
606 return;\r
607 }\r
cc68a136 608\r
609 a&=0xffffff;\r
610\r
611 // prg RAM\r
4ff2d527 612 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
672ad671 613 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
bf098bc5 614 *(u8 *)(prg_bank+((a^1)&0x1ffff))=d;\r
cc68a136 615 return;\r
616 }\r
617\r
d0d47c5b 618 // word RAM\r
619 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 620 wrdprintf("m68k_wram w8: [%06x] %02x @%06x", a, d, SekPc);\r
d0d47c5b 621 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 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
d0d47c5b 627 } else {\r
628 // allow access in any mode, like Gens does\r
fa1e5e29 629 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
d0d47c5b 630 }\r
631 return;\r
632 }\r
633\r
c459aefd 634 if ((a&0xffffc0)==0xa12000)\r
635 rdprintf("m68k_regs w8: [%02x] %02x @%06x", a&0x3f, d, SekPc);\r
672ad671 636\r
cc68a136 637 OtherWrite8(a,d,8);\r
638}\r
4ff2d527 639#endif\r
cc68a136 640\r
ab0607f7 641\r
4ff2d527 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
cc68a136 646{\r
647#ifdef __debug_io\r
648 dprintf("w16: %06x, %04x", a&0xffffff, d);\r
649#endif\r
cc68a136 650 // dprintf("w16: %06x, %04x @%06x", a&0xffffff, d, SekPc);\r
651\r
ab0607f7 652 if ((a&0xe00000)==0xe00000) { // Ram\r
653 *(u16 *)(Pico.ram+(a&0xfffe))=d;\r
654 return;\r
655 }\r
cc68a136 656\r
657 a&=0xfffffe;\r
658\r
659 // prg RAM\r
4ff2d527 660 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
672ad671 661 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
c008977e 662 wrdprintf("m68k_prgram w16: [%i,%06x] %04x @%06x", Pico_mcd->s68k_regs[3]>>6, a, d, SekPc);\r
cc68a136 663 *(u16 *)(prg_bank+(a&0x1fffe))=d;\r
664 return;\r
665 }\r
666\r
d0d47c5b 667 // word RAM\r
668 if ((a&0xfc0000)==0x200000) {\r
913ef4b7 669 wrdprintf("m68k_wram w16: [%06x] %04x @%06x", a, d, SekPc);\r
d0d47c5b 670 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 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
d0d47c5b 676 } else {\r
677 // allow access in any mode, like Gens does\r
fa1e5e29 678 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
d0d47c5b 679 }\r
680 return;\r
681 }\r
682\r
7a1f6e45 683 // regs\r
684 if ((a&0xffffc0)==0xa12000) {\r
c459aefd 685 rdprintf("m68k_regs w16: [%02x] %04x @%06x", a&0x3f, d, SekPc);\r
7a1f6e45 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
cc68a136 700\r
701 OtherWrite16(a,d);\r
702}\r
4ff2d527 703#endif\r
cc68a136 704\r
ab0607f7 705\r
4ff2d527 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
cc68a136 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
4ff2d527 726 if ((a&0xfe0000)==0x020000 && (Pico_mcd->m.busreq&2)) {\r
672ad671 727 u8 *prg_bank = Pico_mcd->prg_ram_b[Pico_mcd->s68k_regs[3]>>6];\r
cc68a136 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
672ad671 733 // word RAM\r
d0d47c5b 734 if ((a&0xfc0000)==0x200000) {\r
735 if (d != 0) // don't log clears\r
913ef4b7 736 wrdprintf("m68k_wram w32: [%06x] %08x @%06x", a, d, SekPc);\r
d0d47c5b 737 if (Pico_mcd->s68k_regs[3]&4) { // 1M mode?\r
fa1e5e29 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
4ff2d527 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
bf098bc5 746 } else {\r
fa1e5e29 747 u16 *pm=(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
748 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
bf098bc5 749 }\r
d0d47c5b 750 } else {\r
751 // allow access in any mode, like Gens does\r
fa1e5e29 752 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 753 pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
754 }\r
672ad671 755 return;\r
d0d47c5b 756 }\r
672ad671 757\r
c459aefd 758 if ((a&0xffffc0)==0xa12000)\r
759 rdprintf("m68k_regs w32: [%02x] %08x @%06x", a&0x3f, d, SekPc);\r
cc68a136 760\r
761 OtherWrite16(a, (u16)(d>>16));\r
762 OtherWrite16(a+2,(u16)d);\r
763}\r
4ff2d527 764#endif\r
cc68a136 765\r
766\r
767// -----------------------------------------------------------------\r
768\r
4ff2d527 769#ifdef _ASM_CD_MEMORY_C\r
770u8 PicoReadS68k8(u32 a);\r
771#else\r
772static u8 PicoReadS68k8(u32 a)\r
cc68a136 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
cb4a513a 786 a &= 0x1ff;\r
787 rdprintf("s68k_regs r8: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 788 if (a >= 0x58 && a < 0x68)\r
cb4a513a 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
c459aefd 792 rdprintf("ret = %02x", (u8)d);\r
cc68a136 793 goto end;\r
794 }\r
795\r
d0d47c5b 796 // word RAM (2M area)\r
797 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
fa1e5e29 798 // test: batman returns\r
913ef4b7 799 wrdprintf("s68k_wram2M r8: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 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
d0d47c5b 806 } else {\r
807 // allow access in any mode, like Gens does\r
fa1e5e29 808 d = Pico_mcd->word_ram2M[(a^1)&0x3ffff];\r
d0d47c5b 809 }\r
913ef4b7 810 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 811 goto end;\r
812 }\r
813\r
814 // word RAM (1M area)\r
68cba51e 815 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 816 int bank;\r
913ef4b7 817 wrdprintf("s68k_wram1M r8: [%06x] @%06x", a, SekPcS68k);\r
68cba51e 818// if (!(Pico_mcd->s68k_regs[3]&4))\r
819// dprintf("s68k_wram1M FIXME: wrong mode");\r
fa1e5e29 820 bank = !(Pico_mcd->s68k_regs[3]&1);\r
821 d = Pico_mcd->word_ram1M[bank][(a^1)&0x1ffff];\r
913ef4b7 822 wrdprintf("ret = %02x", (u8)d);\r
d0d47c5b 823 goto end;\r
824 }\r
825\r
4f265db7 826 // PCM\r
827 if ((a&0xff8000)==0xff0000) {\r
1cd356a3 828 dprintf("s68k_pcm r8: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 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
ab0607f7 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
cc68a136 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
4ff2d527 856#endif\r
cc68a136 857\r
ab0607f7 858\r
4ff2d527 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
cc68a136 864{\r
4f265db7 865 u32 d=0;\r
cc68a136 866\r
867 a&=0xfffffe;\r
868\r
869 // prg RAM\r
870 if (a < 0x80000) {\r
c008977e 871 wrdprintf("s68k_prgram r16: [%06x] @%06x", a, SekPcS68k);\r
cc68a136 872 d = *(u16 *)(Pico_mcd->prg_ram+a);\r
c008977e 873 wrdprintf("ret = %04x", d);\r
cc68a136 874 goto end;\r
875 }\r
876\r
877 // regs\r
878 if ((a&0xfffe00) == 0xff8000) {\r
cb4a513a 879 a &= 0x1fe;\r
880 rdprintf("s68k_regs r16: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 881 if (a >= 0x58 && a < 0x68)\r
cb4a513a 882 d = gfx_cd_read(a);\r
883 else d = s68k_reg_read16(a);\r
c459aefd 884 rdprintf("ret = %04x", d);\r
cc68a136 885 goto end;\r
886 }\r
887\r
d0d47c5b 888 // word RAM (2M area)\r
889 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 890 wrdprintf("s68k_wram2M r16: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 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
d0d47c5b 896 } else {\r
897 // allow access in any mode, like Gens does\r
fa1e5e29 898 d = *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 899 }\r
913ef4b7 900 wrdprintf("ret = %04x", d);\r
d0d47c5b 901 goto end;\r
902 }\r
903\r
904 // word RAM (1M area)\r
68cba51e 905 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 906 int bank;\r
913ef4b7 907 wrdprintf("s68k_wram1M r16: [%06x] @%06x", a, SekPcS68k);\r
68cba51e 908// if (!(Pico_mcd->s68k_regs[3]&4))\r
909// dprintf("s68k_wram1M FIXME: wrong mode");\r
fa1e5e29 910 bank = !(Pico_mcd->s68k_regs[3]&1);\r
911 d = *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe));\r
913ef4b7 912 wrdprintf("ret = %04x", d);\r
ab0607f7 913 goto end;\r
914 }\r
915\r
916 // bram\r
917 if ((a&0xff0000)==0xfe0000) {\r
4ff2d527 918 dprintf("FIXME: s68k_bram r16: [%06x] @%06x", a, SekPcS68k);\r
ab0607f7 919 a = (a>>1)&0x1fff;\r
4f265db7 920 d = Pico_mcd->bram[a++]; // Gens does little endian here, and so do we..\r
4ff2d527 921 d|= Pico_mcd->bram[a++] << 8; // This is most likely wrong\r
ab0607f7 922 dprintf("ret = %04x", d);\r
d0d47c5b 923 goto end;\r
924 }\r
925\r
4f265db7 926 // PCM\r
927 if ((a&0xff8000)==0xff0000) {\r
4ff2d527 928 dprintf("FIXME: s68k_pcm r16: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 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
cc68a136 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
4ff2d527 950#endif\r
cc68a136 951\r
ab0607f7 952\r
4ff2d527 953#ifdef _ASM_CD_MEMORY_C\r
954u32 PicoReadS68k32(u32 a);\r
955#else\r
956static u32 PicoReadS68k32(u32 a)\r
cc68a136 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
cb4a513a 971 a &= 0x1fe;\r
972 rdprintf("s68k_regs r32: [%02x] @ %06x", a, SekPcS68k);\r
913ef4b7 973 if (a >= 0x58 && a < 0x68)\r
cb4a513a 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
c459aefd 976 rdprintf("ret = %08x", d);\r
cc68a136 977 goto end;\r
978 }\r
979\r
d0d47c5b 980 // word RAM (2M area)\r
981 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
913ef4b7 982 wrdprintf("s68k_wram2M r32: [%06x] @%06x", a, SekPcS68k);\r
fa1e5e29 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
d0d47c5b 989 } else {\r
990 // allow access in any mode, like Gens does\r
fa1e5e29 991 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe)); d = (pm[0]<<16)|pm[1];\r
d0d47c5b 992 }\r
913ef4b7 993 wrdprintf("ret = %08x", d);\r
d0d47c5b 994 goto end;\r
995 }\r
996\r
997 // word RAM (1M area)\r
68cba51e 998 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 999 int bank;\r
913ef4b7 1000 wrdprintf("s68k_wram1M r32: [%06x] @%06x", a, SekPcS68k);\r
68cba51e 1001// if (!(Pico_mcd->s68k_regs[3]&4))\r
1002// dprintf("s68k_wram1M FIXME: wrong mode");\r
fa1e5e29 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
913ef4b7 1005 wrdprintf("ret = %08x", d);\r
ab0607f7 1006 goto end;\r
1007 }\r
1008\r
4f265db7 1009 // PCM\r
1010 if ((a&0xff8000)==0xff0000) {\r
4ff2d527 1011 dprintf("FIXME: s68k_pcm r32: [%06x] @%06x", a, SekPcS68k);\r
4f265db7 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
ab0607f7 1032 // bram\r
1033 if ((a&0xff0000)==0xfe0000) {\r
4ff2d527 1034 dprintf("FIXME: s68k_bram r32: [%06x] @%06x", a, SekPcS68k);\r
ab0607f7 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
d0d47c5b 1041 goto end;\r
1042 }\r
1043\r
cc68a136 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
4ff2d527 1053#endif\r
cc68a136 1054\r
ab0607f7 1055\r
a4030801 1056#ifndef _ASM_CD_MEMORY_C\r
0a051f55 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
0a051f55 1063 r3 &= 0x18;\r
1064 d &= 0x0f;\r
1065 if (!(a&1)) d <<= 4;\r
1066\r
0a051f55 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
0a051f55 1104}\r
a4030801 1105#endif\r
0a051f55 1106\r
cc68a136 1107// -----------------------------------------------------------------\r
1108\r
4ff2d527 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
cc68a136 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
cb4a513a 1129 a &= 0x1ff;\r
1130 rdprintf("s68k_regs w8: [%02x] %02x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1131 if (a >= 0x58 && a < 0x68)\r
48e8482f 1132 gfx_cd_write16(a&~1, (d<<8)|d);\r
cb4a513a 1133 else s68k_reg_write8(a,d);\r
cc68a136 1134 return;\r
1135 }\r
1136\r
d0d47c5b 1137 // word RAM (2M area)\r
1138 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
0a051f55 1139 int r3 = Pico_mcd->s68k_regs[3];\r
913ef4b7 1140 wrdprintf("s68k_wram2M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
0a051f55 1141 if (r3 & 4) { // 1M decode mode?\r
1142 decode_write8(a, d, r3);\r
d0d47c5b 1143 } else {\r
1144 // allow access in any mode, like Gens does\r
fa1e5e29 1145 *(u8 *)(Pico_mcd->word_ram2M+((a^1)&0x3ffff))=d;\r
d0d47c5b 1146 }\r
1147 return;\r
1148 }\r
1149\r
1150 // word RAM (1M area)\r
68cba51e 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
fa1e5e29 1153 int bank;\r
d0d47c5b 1154 if (d)\r
913ef4b7 1155 wrdprintf("s68k_wram1M w8: [%06x] %02x @%06x", a, d, SekPcS68k);\r
68cba51e 1156// if (!(Pico_mcd->s68k_regs[3]&4))\r
1157// dprintf("s68k_wram1M FIXME: wrong mode");\r
fa1e5e29 1158 bank = !(Pico_mcd->s68k_regs[3]&1);\r
1159 *(u8 *)(Pico_mcd->word_ram1M[bank]+((a^1)&0x1ffff))=d;\r
d0d47c5b 1160 return;\r
1161 }\r
1162\r
4f265db7 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
ab0607f7 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
cc68a136 1180 dprintf("s68k w8 : %06x, %02x @%06x", a&0xffffff, d, SekPcS68k);\r
1181}\r
4ff2d527 1182#endif\r
cc68a136 1183\r
ab0607f7 1184\r
4ff2d527 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
cc68a136 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
c008977e 1198 wrdprintf("s68k_prgram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
cc68a136 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
cb4a513a 1205 a &= 0x1fe;\r
1206 rdprintf("s68k_regs w16: [%02x] %04x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1207 if (a >= 0x58 && a < 0x68)\r
48e8482f 1208 gfx_cd_write16(a, d);\r
cb4a513a 1209 else {\r
1cd356a3 1210 if (a == 0xe) { // special case, 2 byte writes would be handled differently\r
1211 Pico_mcd->s68k_regs[0xf] = d;\r
4ff2d527 1212 return;\r
1cd356a3 1213 }\r
cb4a513a 1214 s68k_reg_write8(a, d>>8);\r
1215 s68k_reg_write8(a+1,d&0xff);\r
1216 }\r
cc68a136 1217 return;\r
1218 }\r
1219\r
d0d47c5b 1220 // word RAM (2M area)\r
1221 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
0a051f55 1222 int r3 = Pico_mcd->s68k_regs[3];\r
913ef4b7 1223 wrdprintf("s68k_wram2M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
0a051f55 1224 if (r3 & 4) { // 1M decode mode?\r
1225 decode_write16(a, d, r3);\r
d0d47c5b 1226 } else {\r
1227 // allow access in any mode, like Gens does\r
fa1e5e29 1228 *(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe))=d;\r
d0d47c5b 1229 }\r
1230 return;\r
1231 }\r
1232\r
1233 // word RAM (1M area)\r
68cba51e 1234 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 1235 int bank;\r
d0d47c5b 1236 if (d)\r
913ef4b7 1237 wrdprintf("s68k_wram1M w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
68cba51e 1238// if (!(Pico_mcd->s68k_regs[3]&4))\r
1239// dprintf("s68k_wram1M FIXME: wrong mode");\r
fa1e5e29 1240 bank = !(Pico_mcd->s68k_regs[3]&1);\r
1241 *(u16 *)(Pico_mcd->word_ram1M[bank]+(a&0x1fffe))=d;\r
d0d47c5b 1242 return;\r
1243 }\r
1244\r
4f265db7 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
ab0607f7 1255 // bram\r
1256 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 1257 dprintf("s68k_bram w16: [%06x] %04x @%06x", a, d, SekPcS68k);\r
ab0607f7 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
cc68a136 1265 dprintf("s68k w16: %06x, %04x @%06x", a&0xffffff, d, SekPcS68k);\r
1266}\r
4ff2d527 1267#endif\r
cc68a136 1268\r
ab0607f7 1269\r
4ff2d527 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
cc68a136 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
cb4a513a 1290 a &= 0x1fe;\r
1291 rdprintf("s68k_regs w32: [%02x] %08x @ %06x", a, d, SekPcS68k);\r
913ef4b7 1292 if (a >= 0x58 && a < 0x68) {\r
48e8482f 1293 gfx_cd_write16(a, d>>16);\r
1294 gfx_cd_write16(a+2, d&0xffff);\r
cb4a513a 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
cc68a136 1301 return;\r
1302 }\r
1303\r
d0d47c5b 1304 // word RAM (2M area)\r
1305 if ((a&0xfc0000)==0x080000) { // 080000-0bffff\r
0a051f55 1306 int r3 = Pico_mcd->s68k_regs[3];\r
913ef4b7 1307 wrdprintf("s68k_wram2M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
0a051f55 1308 if (r3 & 4) { // 1M decode mode?\r
1309 decode_write16(a , d >> 16, r3);\r
1310 decode_write16(a+2, d , r3);\r
d0d47c5b 1311 } else {\r
1312 // allow access in any mode, like Gens does\r
fa1e5e29 1313 u16 *pm=(u16 *)(Pico_mcd->word_ram2M+(a&0x3fffe));\r
d0d47c5b 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
68cba51e 1320 if ((a&0xfe0000)==0x0c0000 && (Pico_mcd->s68k_regs[3]&4)) { // 0c0000-0dffff\r
fa1e5e29 1321 int bank;\r
1322 u16 *pm;\r
d0d47c5b 1323 if (d)\r
913ef4b7 1324 wrdprintf("s68k_wram1M w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
68cba51e 1325// if (!(Pico_mcd->s68k_regs[3]&4))\r
1326// dprintf("s68k_wram1M FIXME: wrong mode");\r
fa1e5e29 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
d0d47c5b 1330 return;\r
1331 }\r
ab0607f7 1332\r
4f265db7 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
ab0607f7 1348 // bram\r
1349 if ((a&0xff0000)==0xfe0000) {\r
1cd356a3 1350 dprintf("s68k_bram w32: [%06x] %08x @%06x", a, d, SekPcS68k);\r
ab0607f7 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
cc68a136 1360 dprintf("s68k w32: %06x, %08x @%06x", a&0xffffff, d, SekPcS68k);\r
1361}\r
4ff2d527 1362#endif\r
cc68a136 1363\r
1364\r
1365// -----------------------------------------------------------------\r
1366\r
b837b69b 1367\r
1368#if defined(EMU_C68K)\r
1369static __inline int PicoMemBaseM68k(u32 pc)\r
1370{\r
fa1e5e29 1371 if ((pc&0xe00000)==0xe00000)\r
1372 return (int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
b837b69b 1373\r
1374 if (pc < 0x20000)\r
fa1e5e29 1375 return (int)Pico_mcd->bios; // Program Counter in BIOS\r
1376\r
1377 if ((pc&0xfc0000)==0x200000)\r
b837b69b 1378 {\r
fa1e5e29 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
b837b69b 1385 }\r
1386\r
fa1e5e29 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
b837b69b 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
fa1e5e29 1407 if (pc < 0x80000) // PRG RAM\r
1408 return (int)Pico_mcd->prg_ram;\r
b837b69b 1409\r
fa1e5e29 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
b837b69b 1416 }\r
1417\r
fa1e5e29 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
b837b69b 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
7a1f6e45 1458 // m68k_poll_addr = m68k_poll_cnt = 0;\r
1459 s68k_poll_adclk = s68k_poll_cnt = 0;\r
b837b69b 1460}\r
1461\r
1462\r
cc68a136 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
fa1e5e29 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
cc68a136 1495 } else {\r
cc68a136 1496 if((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
fa1e5e29 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
cc68a136 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
fa1e5e29 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
cc68a136 1521 } else {\r
cc68a136 1522 if((a&0xe00000)==0xe00000) return *(u16 *)(Pico.ram+(a&0xfffe)); // Ram\r
fa1e5e29 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
cc68a136 1533 }\r
b837b69b 1534 return 0;\r
cc68a136 1535}\r
1536unsigned int m68k_read_pcrelative_CD32(unsigned int a) {\r
fa1e5e29 1537 u16 *pm;\r
cc68a136 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
fa1e5e29 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
cc68a136 1549 } else {\r
cc68a136 1550 if((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xfffe)); return (pm[0]<<16)|pm[1]; } // Ram\r
fa1e5e29 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
cc68a136 1562 }\r
b837b69b 1563 return 0;\r
cc68a136 1564}\r
1565#endif // EMU_M68K\r
1566\r