Added 0.030 of PicoDrive and moved license files into root
[cyclone68000.git] / Pico / Memory.cpp
1 \r
2 #include "PicoInt.h"\r
3 \r
4 typedef unsigned char  u8;\r
5 typedef unsigned short u16;\r
6 typedef unsigned int   u32;\r
7 \r
8 static int PicoMemBase(u32 pc)\r
9 {\r
10   int membase=0;\r
11 \r
12   if (pc<Pico.romsize)\r
13   {\r
14     membase=(int)Pico.rom; // Program Counter in Rom\r
15   }\r
16   else if ((pc&0xe00000)==0xe00000)\r
17   {\r
18     membase=(int)Pico.ram-(pc&0xff0000); // Program Counter in Ram\r
19   }\r
20   else\r
21   {\r
22     // Error - Program Counter is invalid\r
23     membase=(int)Pico.rom;\r
24   }\r
25 \r
26   return membase;\r
27 }\r
28 \r
29 #ifdef EMU_A68K\r
30 extern "C" u8 *OP_ROM=NULL,*OP_RAM=NULL;\r
31 \r
32 static void CPU_CALL PicoCheckPc(u32 pc)\r
33 {\r
34   OP_ROM=(u8 *)PicoMemBase(pc);\r
35 \r
36   // don't bother calling us back unless it's outside the 64k segment\r
37   M68000_regs.AsmBank=(pc>>16);\r
38 }\r
39 #endif\r
40 \r
41 #ifdef EMU_C68K\r
42 static u32 PicoCheckPc(u32 pc)\r
43 {\r
44   pc-=PicoCpu.membase; // Get real pc\r
45   pc&=0xffffff;\r
46 \r
47   PicoCpu.membase=PicoMemBase(pc);\r
48 \r
49   return PicoCpu.membase+pc;\r
50 }\r
51 #endif\r
52 \r
53 #ifdef EMU_NULL\r
54 static u32 PicoCheckPc(u32) { return 0; }\r
55 #endif\r
56 \r
57 \r
58 int PicoInitPc(u32 pc)\r
59 {\r
60   PicoCheckPc(pc);\r
61   return 0;\r
62 }\r
63 \r
64 // -----------------------------------------------------------------\r
65 static int PadRead(int i)\r
66 {\r
67   int pad=0,value=0;\r
68   pad=~PicoPad[i]; // Get inverse of pad\r
69 \r
70   if (Pico.m.padSelect[i]) value=0x40|(pad&0x3f); // 01CB RLDU\r
71   else value=((pad&0xc0)>>2)|(pad&3); // 00SA 00DU\r
72 \r
73   return (value<<8)|value; // Mirror bytes\r
74 }\r
75 \r
76 static u32 OtherRead16(u32 a)\r
77 {\r
78   u32 d=0;\r
79 \r
80   if ((a&0xffe000)==0xa00000)\r
81   {\r
82     // Z80 ram\r
83     d=*(u16 *)(Pico.zram+(a&0x1fff));\r
84 \r
85     if (Pico.m.rotate&2) { d=(Pico.m.rotate>>2)&0xff; d|=d<<8; } // Fake z80\r
86     Pico.m.rotate++;\r
87 \r
88     goto end;\r
89   }\r
90 \r
91   if ((a&0xffe000)==0xa00000)\r
92   {\r
93     // Fake Z80 ram\r
94     d=((Pico.m.rotate++)>>2)&0xff; d|=d<<8;\r
95     goto end;\r
96   }\r
97   \r
98   if (a==0xa04000) { d=Pico.m.rotate&3; Pico.m.rotate++; goto end; } // Fudge\r
99   if (a==0xa10000) { d=Pico.m.hardware; goto end; }  // Hardware value\r
100   if (a==0xa10002) { d=PadRead(0); goto end; }\r
101   if (a==0xa10004) { d=PadRead(1); goto end; }\r
102   if (a==0xa11100) { d=((Pico.m.rotate++)&4)<<6; goto end; } // Fudge z80 reset\r
103 \r
104   if ((a&0xffffe0)==0xc00000) { d=PicoVideoRead(a); goto end; }\r
105 \r
106 end:\r
107   return d;\r
108 }\r
109 \r
110 static void OtherWrite8(u32 a,u32 d)\r
111 {\r
112   if ((a&0xffe000)==0xa00000) { Pico.zram[(a^1)&0x1fff]=(u8)d; return; } // Z80 ram\r
113   if ((a&0xfffffc)==0xa04000) { PsndFm(a,d); return; } // FM Sound\r
114 \r
115   if (a==0xa11100) { Pico.m.z80Run=(u8)(d^1); return; }\r
116   if (a==0xa10003) { Pico.m.padSelect[0]=(u8)((d>>6)&1); return; } // Joypad 1 select\r
117   if (a==0xa10005) { Pico.m.padSelect[1]=(u8)((d>>6)&1); return; } // Joypad 2 select\r
118 \r
119   if ((a&0xffffe0)==0xc00000) { PicoVideoWrite(a,d|(d<<8)); return; } // Byte access gets mirrored\r
120 }\r
121 \r
122 static void OtherWrite16(u32 a,u32 d)\r
123 {\r
124   if ((a&0xffffe0)==0xc00000) { PicoVideoWrite(a,d); return; }\r
125   if ((a&0xffe000)==0xa00000) { *(u16 *)(Pico.zram+(a&0x1ffe))=(u16)d; return; } // Z80 ram\r
126 \r
127   OtherWrite8(a,  d>>8);\r
128   OtherWrite8(a+1,d&0xff);\r
129 }\r
130 \r
131 // -----------------------------------------------------------------\r
132 //                     Read Rom and read Ram\r
133 \r
134 static u8 CPU_CALL PicoRead8(u32 a)\r
135 {\r
136   u32 d=0;\r
137   a&=0xffffff;\r
138 \r
139   if (a<Pico.romsize) return *(u8 *)(Pico.rom+(a^1)); // Rom\r
140   if ((a&0xe00000)==0xe00000) return *(u8 *)(Pico.ram+((a^1)&0xffff)); // Ram\r
141 \r
142   d=OtherRead16(a&~1); if ((a&1)==0) d>>=8;\r
143   return (u8)d;\r
144 }\r
145 \r
146 u16 CPU_CALL PicoRead16(u32 a)\r
147 {\r
148   a&=0xfffffe;\r
149 \r
150   if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); return pm[0]; } // Rom\r
151   if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xffff)); return pm[0]; } // Ram\r
152 \r
153   return (u16)OtherRead16(a);\r
154 }\r
155 \r
156 u32 CPU_CALL PicoRead32(u32 a)\r
157 {\r
158   a&=0xfffffe;\r
159 \r
160   if (a<Pico.romsize) { u16 *pm=(u16 *)(Pico.rom+a); return (pm[0]<<16)|pm[1]; } // Rom\r
161   if ((a&0xe00000)==0xe00000) { u16 *pm=(u16 *)(Pico.ram+(a&0xffff)); return (pm[0]<<16)|pm[1]; } // Ram\r
162 \r
163   return (OtherRead16(a)<<16)|OtherRead16(a+2);\r
164 }\r
165 \r
166 // -----------------------------------------------------------------\r
167 //                            Write Ram\r
168 \r
169 static void CPU_CALL PicoWrite8(u32 a,u8 d)\r
170 {\r
171   if ((a&0xe00000)==0xe00000) { u8 *pm=(u8 *)(Pico.ram+((a^1)&0xffff)); pm[0]=d; return; } // Ram\r
172 \r
173   a&=0xffffff;\r
174   OtherWrite8(a,d);\r
175 }\r
176 \r
177 static void CPU_CALL PicoWrite16(u32 a,u16 d)\r
178 {\r
179   if ((a&0xe00000)==0xe00000) { *(u16 *)(Pico.ram+(a&0xfffe))=d; return; } // Ram\r
180 \r
181   a&=0xfffffe;\r
182   OtherWrite16(a,d);\r
183 }\r
184 \r
185 static void CPU_CALL PicoWrite32(u32 a,u32 d)\r
186 {\r
187   if ((a&0xe00000)==0xe00000)\r
188   {\r
189     // Ram:\r
190     u16 *pm=(u16 *)(Pico.ram+(a&0xfffe));\r
191     pm[0]=(u16)(d>>16); pm[1]=(u16)d;\r
192     return;\r
193   }\r
194 \r
195   a&=0xfffffe;\r
196   OtherWrite16(a,  (u16)(d>>16));\r
197   OtherWrite16(a+2,(u16)d);\r
198 }\r
199 \r
200 \r
201 // -----------------------------------------------------------------\r
202 int PicoMemInit()\r
203 {\r
204 #ifdef EMU_C68K\r
205   // Setup memory callbacks:\r
206   PicoCpu.checkpc=PicoCheckPc;\r
207   PicoCpu.fetch8 =PicoCpu.read8 =PicoRead8;\r
208   PicoCpu.fetch16=PicoCpu.read16=PicoRead16;\r
209   PicoCpu.fetch32=PicoCpu.read32=PicoRead32;\r
210   PicoCpu.write8 =PicoWrite8;\r
211   PicoCpu.write16=PicoWrite16;\r
212   PicoCpu.write32=PicoWrite32;\r
213 #endif\r
214   return 0;\r
215 }\r
216 \r
217 #ifdef EMU_A68K\r
218 struct A68KInter\r
219 {\r
220   u32 unknown;\r
221   u8  (__fastcall *Read8) (u32 a);\r
222   u16 (__fastcall *Read16)(u32 a);\r
223   u32 (__fastcall *Read32)(u32 a);\r
224   void (__fastcall *Write8)  (u32 a,u8 d);\r
225   void (__fastcall *Write16) (u32 a,u16 d);\r
226   void (__fastcall *Write32) (u32 a,u32 d);\r
227   void (__fastcall *ChangePc)(u32 a);\r
228   u8  (__fastcall *PcRel8) (u32 a);\r
229   u16 (__fastcall *PcRel16)(u32 a);\r
230   u32 (__fastcall *PcRel32)(u32 a);\r
231   u16 (__fastcall *Dir16)(u32 a);\r
232   u32 (__fastcall *Dir32)(u32 a);\r
233 };\r
234 \r
235 extern "C" struct A68KInter a68k_memory_intf=\r
236 {\r
237   0,\r
238   PicoRead8,\r
239   PicoRead16,\r
240   PicoRead32,\r
241   PicoWrite8,\r
242   PicoWrite16,\r
243   PicoWrite32,\r
244   PicoCheckPc,\r
245   PicoRead8,\r
246   PicoRead16,\r
247   PicoRead32,\r
248   PicoRead16, // unused\r
249   PicoRead32, // unused\r
250 };\r
251 #endif\r