license info at top of Cyclone source files
[cyclone68000.git] / Pico / Memory.cpp
CommitLineData
15eb0001 1\r
2#include "PicoInt.h"\r
3\r
4typedef unsigned char u8;\r
5typedef unsigned short u16;\r
6typedef unsigned int u32;\r
7\r
8static 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
30extern "C" u8 *OP_ROM=NULL,*OP_RAM=NULL;\r
31\r
32static 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
42static 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
54static u32 PicoCheckPc(u32) { return 0; }\r
55#endif\r
56\r
57\r
58int PicoInitPc(u32 pc)\r
59{\r
60 PicoCheckPc(pc);\r
61 return 0;\r
62}\r
63\r
64// -----------------------------------------------------------------\r
65static 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
76static 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
106end:\r
107 return d;\r
108}\r
109\r
110static 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
122static 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
134static 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
146u16 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
156u32 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
169static 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
177static 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
185static 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
202int 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
218struct 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
235extern "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