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