1 /* Copyright 2005-2006 Guillaume Duhamel
2 Copyright 2005 Theo Berkau
3
4 This file is part of Yabause.
5
6 Yabause is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Yabause is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Yabause; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #ifndef MEMORY_H
22 #define MEMORY_H
23
24 #include <stdlib.h>
25 #include "core.h"
26
27 typedef struct SH2_struct SH2_struct;
28
29 /* Type 1 Memory, faster for byte (8 bits) accesses */
30
31 u8 * T1MemoryInit(u32);
32 void T1MemoryDeInit(u8 *);
33
T1ReadByte(u8 * mem,u32 addr)34 static INLINE u8 T1ReadByte(u8 * mem, u32 addr)
35 {
36 return mem[addr];
37 }
38
T1ReadWord(u8 * mem,u32 addr)39 static INLINE u16 T1ReadWord(u8 * mem, u32 addr)
40 {
41 #ifdef WORDS_BIGENDIAN
42 return *((u16 *) (mem + addr));
43 #else
44 return BSWAP16L(*((u16 *) (mem + addr)));
45 #endif
46 }
47
T1ReadLong(u8 * mem,u32 addr)48 static INLINE u32 T1ReadLong(u8 * mem, u32 addr)
49 {
50 #ifdef WORDS_BIGENDIAN
51 return *((u32 *) (mem + addr));
52 #else
53 return BSWAP32(*((u32 *) (mem + addr)));
54 #endif
55 }
56
T1WriteByte(u8 * mem,u32 addr,u8 val)57 static INLINE void T1WriteByte(u8 * mem, u32 addr, u8 val)
58 {
59 mem[addr] = val;
60 }
61
T1WriteWord(u8 * mem,u32 addr,u16 val)62 static INLINE void T1WriteWord(u8 * mem, u32 addr, u16 val)
63 {
64 #ifdef WORDS_BIGENDIAN
65 *((u16 *) (mem + addr)) = val;
66 #else
67 *((u16 *) (mem + addr)) = BSWAP16L(val);
68 #endif
69 }
70
T1WriteLong(u8 * mem,u32 addr,u32 val)71 static INLINE void T1WriteLong(u8 * mem, u32 addr, u32 val)
72 {
73 #ifdef WORDS_BIGENDIAN
74 *((u32 *) (mem + addr)) = val;
75 #else
76 *((u32 *) (mem + addr)) = BSWAP32(val);
77 #endif
78 }
79
80 /* Type 2 Memory, faster for word (16 bits) accesses */
81
82 #define T2MemoryInit(x) (T1MemoryInit(x))
83 #define T2MemoryDeInit(x) (T1MemoryDeInit(x))
84
T2ReadByte(u8 * mem,u32 addr)85 static INLINE u8 T2ReadByte(u8 * mem, u32 addr)
86 {
87 #ifdef WORDS_BIGENDIAN
88 return mem[addr];
89 #else
90 return mem[addr ^ 1];
91 #endif
92 }
93
T2ReadWord(u8 * mem,u32 addr)94 static INLINE u16 T2ReadWord(u8 * mem, u32 addr)
95 {
96 return *((u16 *) (mem + addr));
97 }
98
T2ReadLong(u8 * mem,u32 addr)99 static INLINE u32 T2ReadLong(u8 * mem, u32 addr)
100 {
101 #ifdef WORDS_BIGENDIAN
102 return *((u32 *) (mem + addr));
103 #else
104 return WSWAP32(*((u32 *) (mem + addr)));
105 #endif
106 }
107
T2WriteByte(u8 * mem,u32 addr,u8 val)108 static INLINE void T2WriteByte(u8 * mem, u32 addr, u8 val)
109 {
110 #ifdef WORDS_BIGENDIAN
111 mem[addr] = val;
112 #else
113 mem[addr ^ 1] = val;
114 #endif
115 }
116
T2WriteWord(u8 * mem,u32 addr,u16 val)117 static INLINE void T2WriteWord(u8 * mem, u32 addr, u16 val)
118 {
119 *((u16 *) (mem + addr)) = val;
120 }
121
T2WriteLong(u8 * mem,u32 addr,u32 val)122 static INLINE void T2WriteLong(u8 * mem, u32 addr, u32 val)
123 {
124 #ifdef WORDS_BIGENDIAN
125 *((u32 *) (mem + addr)) = val;
126 #else
127 *((u32 *) (mem + addr)) = WSWAP32(val);
128 #endif
129 }
130
131 /* Type 3 Memory, faster for long (32 bits) accesses */
132
133 typedef struct
134 {
135 u8 * base_mem;
136 u8 * mem;
137 } T3Memory;
138
139 T3Memory * T3MemoryInit(u32);
140 void T3MemoryDeInit(T3Memory *);
141
T3ReadByte(T3Memory * mem,u32 addr)142 static INLINE u8 T3ReadByte(T3Memory * mem, u32 addr)
143 {
144 #ifdef WORDS_BIGENDIAN
145 return mem->mem[addr];
146 #else
147 return (mem->mem - addr - 1)[0];
148 #endif
149 }
150
T3ReadWord(T3Memory * mem,u32 addr)151 static INLINE u16 T3ReadWord(T3Memory * mem, u32 addr)
152 {
153 #ifdef WORDS_BIGENDIAN
154 return *((u16 *) (mem->mem + addr));
155 #else
156 return ((u16 *) (mem->mem - addr - 2))[0];
157 #endif
158 }
159
T3ReadLong(T3Memory * mem,u32 addr)160 static INLINE u32 T3ReadLong(T3Memory * mem, u32 addr)
161 {
162 #ifdef WORDS_BIGENDIAN
163 return *((u32 *) (mem->mem + addr));
164 #else
165 return ((u32 *) (mem->mem - addr - 4))[0];
166 #endif
167 }
168
T3WriteByte(T3Memory * mem,u32 addr,u8 val)169 static INLINE void T3WriteByte(T3Memory * mem, u32 addr, u8 val)
170 {
171 #ifdef WORDS_BIGENDIAN
172 mem->mem[addr] = val;
173 #else
174 (mem->mem - addr - 1)[0] = val;
175 #endif
176 }
177
T3WriteWord(T3Memory * mem,u32 addr,u16 val)178 static INLINE void T3WriteWord(T3Memory * mem, u32 addr, u16 val)
179 {
180 #ifdef WORDS_BIGENDIAN
181 *((u16 *) (mem->mem + addr)) = val;
182 #else
183 ((u16 *) (mem->mem - addr - 2))[0] = val;
184 #endif
185 }
186
T3WriteLong(T3Memory * mem,u32 addr,u32 val)187 static INLINE void T3WriteLong(T3Memory * mem, u32 addr, u32 val)
188 {
189 #ifdef WORDS_BIGENDIAN
190 *((u32 *) (mem->mem + addr)) = val;
191 #else
192 ((u32 *) (mem->mem - addr - 4))[0] = val;
193 #endif
194 }
195
T123Load(void * mem,u32 size,int type,const char * filename)196 static INLINE int T123Load(void * mem, u32 size, int type, const char *filename)
197 {
198 FILE *fp;
199 u32 filesize, filesizecheck;
200 u8 *buffer;
201 u32 i;
202
203 if (!filename)
204 return -1;
205
206 if ((fp = fopen(filename, "rb")) == NULL)
207 return -1;
208
209 // Calculate file size
210 fseek(fp, 0, SEEK_END);
211 filesize = ftell(fp);
212 fseek(fp, 0, SEEK_SET);
213
214 if (filesize > size)
215 {
216 fclose(fp);
217 return -1;
218 }
219
220 if ((buffer = (u8 *)malloc(filesize)) == NULL)
221 {
222 fclose(fp);
223 return -1;
224 }
225
226 filesizecheck = (u32)fread((void *)buffer, 1, filesize, fp);
227 fclose(fp);
228
229 if (filesizecheck != filesize)
230 {
231 free(buffer);
232 return -1;
233 }
234
235 switch (type)
236 {
237 case 1:
238 {
239 for (i = 0; i < filesize; i++)
240 T1WriteByte((u8 *) mem, i, buffer[i]);
241 break;
242 }
243 case 2:
244 {
245 for (i = 0; i < filesize; i++)
246 T2WriteByte((u8 *) mem, i, buffer[i]);
247 break;
248 }
249 case 3:
250 {
251 for (i = 0; i < filesize; i++)
252 T3WriteByte((T3Memory *) mem, i, buffer[i]);
253 break;
254 }
255 default:
256 {
257 free(buffer);
258 return -1;
259 }
260 }
261
262 free(buffer);
263
264 return 0;
265 }
266
T123Save(void * mem,u32 size,int type,const char * filename)267 static INLINE int T123Save(void * mem, u32 size, int type, const char *filename)
268 {
269 FILE *fp;
270 u8 *buffer;
271 u32 i;
272 u32 sizecheck;
273
274 if (filename == NULL)
275 return 0;
276
277 if (filename[0] == 0x00)
278 return 0;
279
280 if ((buffer = (u8 *)malloc(size)) == NULL)
281 return -1;
282
283 switch (type)
284 {
285 case 1:
286 {
287 for (i = 0; i < size; i++)
288 buffer[i] = T1ReadByte((u8 *) mem, i);
289 break;
290 }
291 case 2:
292 {
293 for (i = 0; i < size; i++)
294 buffer[i] = T2ReadByte((u8 *) mem, i);
295 break;
296 }
297 case 3:
298 {
299 for (i = 0; i < size; i++)
300 buffer[i] = T3ReadByte((T3Memory *) mem, i);
301 break;
302 }
303 default:
304 {
305 free(buffer);
306 return -1;
307 }
308 }
309
310 if ((fp = fopen(filename, "wb")) == NULL)
311 {
312 free(buffer);
313 return -1;
314 }
315
316 sizecheck = (u32)fwrite((void *)buffer, 1, size, fp);
317 fclose(fp);
318 free(buffer);
319
320 if (sizecheck != size) return -1;
321
322 return 0;
323 }
324
325 /* Dummy memory, always returns 0 */
326
327 typedef void Dummy;
328
329 Dummy * DummyInit(u32);
330 void DummyDeInit(Dummy *);
331
DummyReadByte(Dummy UNUSED * d,u32 UNUSED a)332 static INLINE u8 DummyReadByte(Dummy UNUSED * d, u32 UNUSED a) { return 0; }
DummyReadWord(Dummy UNUSED * d,u32 UNUSED a)333 static INLINE u16 DummyReadWord(Dummy UNUSED * d, u32 UNUSED a) { return 0; }
DummyReadLong(Dummy UNUSED * d,u32 UNUSED a)334 static INLINE u32 DummyReadLong(Dummy UNUSED * d, u32 UNUSED a) { return 0; }
335
DummyWriteByte(Dummy UNUSED * d,u32 UNUSED a,u8 UNUSED v)336 static INLINE void DummyWriteByte(Dummy UNUSED * d, u32 UNUSED a, u8 UNUSED v) {}
DummyWriteWord(Dummy UNUSED * d,u32 UNUSED a,u16 UNUSED v)337 static INLINE void DummyWriteWord(Dummy UNUSED * d, u32 UNUSED a, u16 UNUSED v) {}
DummyWriteLong(Dummy UNUSED * d,u32 UNUSED a,u32 UNUSED v)338 static INLINE void DummyWriteLong(Dummy UNUSED * d, u32 UNUSED a, u32 UNUSED v) {}
339
340 #ifdef __cplusplus
341 extern "C" {
342 #endif
343 void MappedMemoryInit(SH2_struct *msh1, SH2_struct *ssh2, SH2_struct *sh1);
344
345 u8 FASTCALL MappedMemoryReadByteCacheEnabled(SH2_struct *sh, u32 addr);
346 u16 FASTCALL MappedMemoryReadWordCacheEnabled(SH2_struct *sh, u32 addr);
347 u32 FASTCALL MappedMemoryReadLongCacheEnabled(SH2_struct *sh, u32 addr);
348 void FASTCALL MappedMemoryWriteByteCacheEnabled(SH2_struct *sh, u32 addr, u8 val);
349 void FASTCALL MappedMemoryWriteWordCacheEnabled(SH2_struct *sh, u32 addr, u16 val);
350 void FASTCALL MappedMemoryWriteLongCacheEnabled(SH2_struct *sh, u32 addr, u32 val);
351
352 u8 FASTCALL MappedMemoryReadByteNocache(SH2_struct *sh, u32 addr);
353 u16 FASTCALL MappedMemoryReadWordNocache(SH2_struct *sh, u32 addr);
354 u32 FASTCALL MappedMemoryReadLongNocache(SH2_struct *sh, u32 addr);
355 void FASTCALL MappedMemoryWriteByteNocache(SH2_struct *sh, u32 addr, u8 val);
356 void FASTCALL MappedMemoryWriteWordNocache(SH2_struct *sh, u32 addr, u16 val);
357 void FASTCALL MappedMemoryWriteLongNocache(SH2_struct *sh, u32 addr, u32 val);
358 #ifdef __cplusplus
359 }
360 #endif
361
362 extern u8 *SH1Rom;
363 extern u8 *SH1Dram;
364 extern u8 *SH1MpegRom;
365 #ifdef __cplusplus
366 extern "C" {
367 #endif
368 extern u8 *HighWram;
369 #ifdef __cplusplus
370 }
371 #endif
372 extern u8 *LowWram;
373 extern u8 *BiosRom;
374 extern u8 *BupRam;
375 extern u8 BupRamWritten;
376
377 typedef void (FASTCALL *writebytefunc)(SH2_struct *, u32, u8);
378 typedef void (FASTCALL *writewordfunc)(SH2_struct *, u32, u16);
379 typedef void (FASTCALL *writelongfunc)(SH2_struct *, u32, u32);
380
381 typedef u8 (FASTCALL *readbytefunc)(SH2_struct *, u32);
382 typedef u16 (FASTCALL *readwordfunc)(SH2_struct *, u32);
383 typedef u32 (FASTCALL *readlongfunc)(SH2_struct *, u32);
384
385 typedef struct {
386 u32 addr;
387 u32 val;
388 } result_struct;
389
390 #define SEARCHBYTE 0
391 #define SEARCHWORD 1
392 #define SEARCHLONG 2
393
394 #define SEARCHEXACT (0 << 2)
395 #define SEARCHLESSTHAN (1 << 2)
396 #define SEARCHGREATERTHAN (2 << 2)
397
398 #define SEARCHUNSIGNED (0 << 4)
399 #define SEARCHSIGNED (1 << 4)
400 #define SEARCHHEX (2 << 4)
401 #define SEARCHSTRING (3 << 4)
402 #define SEARCHREL8BIT (6 << 4)
403 #define SEARCHREL16BIT (7 << 4)
404
405 result_struct *MappedMemorySearch(u32 startaddr, u32 endaddr, int searchtype,
406 const char *searchstr,
407 result_struct *prevresults, u32 *maxresults);
408
409 int MappedMemoryLoad(SH2_struct *sh, const char *filename, u32 addr);
410 int MappedMemorySave(SH2_struct *sh, const char *filename, u32 addr, u32 size);
411 void MappedMemoryLoadExec(const char *filename, u32 pc);
412
413 int LoadSH1Rom(const char *filename);
414 int LoadMpegRom(const char *filename);
415 int LoadBios(const char *filename);
416 int LoadBackupRam(const char *filename);
417 void FormatBackupRam(void *mem, u32 size);
418
419 int YabSaveState(const char *filename);
420 int YabLoadState(const char *filename);
421 int YabSaveStateSlot(const char *dirpath, u8 slot);
422 int YabLoadStateSlot(const char *dirpath, u8 slot);
423 int YabSaveStateStream(FILE *stream);
424 int YabLoadStateStream(FILE *stream);
425 int YabSaveStateBuffer(void **buffer, size_t *size);
426 int YabLoadStateBuffer(const void *buffer, size_t size);
427
428
429 u8 FASTCALL UnhandledMemoryReadByte(USED_IF_DEBUG u32 addr);
430 u16 FASTCALL UnhandledMemoryReadWord(USED_IF_DEBUG u32 addr);
431 u32 FASTCALL UnhandledMemoryReadLong(USED_IF_DEBUG u32 addr);
432 void FASTCALL UnhandledMemoryWriteByte(USED_IF_DEBUG u32 addr, UNUSED u8 val);
433 void FASTCALL UnhandledMemoryWriteWord(USED_IF_DEBUG u32 addr, UNUSED u16 val);
434 void FASTCALL UnhandledMemoryWriteLong(USED_IF_DEBUG u32 addr, UNUSED u32 val);
435 u8 FASTCALL HighWramMemoryReadByte(u32 addr);
436 u16 FASTCALL HighWramMemoryReadWord(u32 addr);
437 u32 FASTCALL HighWramMemoryReadLong(u32 addr);
438 void FASTCALL HighWramMemoryWriteByte(u32 addr, u8 val);
439 void FASTCALL HighWramMemoryWriteWord(u32 addr, u16 val);
440 void FASTCALL HighWramMemoryWriteLong(u32 addr, u32 val);
441 u8 FASTCALL LowWramMemoryReadByte(u32 addr);
442 u16 FASTCALL LowWramMemoryReadWord(u32 addr);
443 u32 FASTCALL LowWramMemoryReadLong(u32 addr);
444 void FASTCALL LowWramMemoryWriteByte(u32 addr, u8 val);
445 void FASTCALL LowWramMemoryWriteWord(u32 addr, u16 val);
446 void FASTCALL LowWramMemoryWriteLong(u32 addr, u32 val);
447 u8 FASTCALL BiosRomMemoryReadByte(u32 addr);
448 u16 FASTCALL BiosRomMemoryReadWord(u32 addr);
449 u32 FASTCALL BiosRomMemoryReadLong(u32 addr);
450 void FASTCALL BiosRomMemoryWriteByte(UNUSED u32 addr, UNUSED u8 val);
451 void FASTCALL BiosRomMemoryWriteWord(UNUSED u32 addr, UNUSED u16 val);
452 void FASTCALL BiosRomMemoryWriteLong(UNUSED u32 addr, UNUSED u32 val);
453 u8 FASTCALL BupRamMemoryReadByte(u32 addr);
454 u16 FASTCALL BupRamMemoryReadWord(USED_IF_DEBUG u32 addr);
455 u32 FASTCALL BupRamMemoryReadLong(USED_IF_DEBUG u32 addr);
456 void FASTCALL BupRamMemoryWriteByte(u32 addr, u8 val);
457 void FASTCALL BupRamMemoryWriteWord(USED_IF_DEBUG u32 addr, UNUSED u16 val);
458 void FASTCALL BupRamMemoryWriteLong(USED_IF_DEBUG u32 addr, UNUSED u32 val);
459
460 #if 0
461 u8 FASTCALL UnhandledMemoryReadByte(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr);
462 u16 FASTCALL UnhandledMemoryReadWord(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr);
463 u32 FASTCALL UnhandledMemoryReadLong(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr);
464 void FASTCALL UnhandledMemoryWriteByte(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr, UNUSED u8 val);
465 void FASTCALL UnhandledMemoryWriteWord(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr, UNUSED u16 val);
466 void FASTCALL UnhandledMemoryWriteLong(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr, UNUSED u32 val);
467 u8 FASTCALL HighWramMemoryReadByte(SH2_struct *sh, u32 addr);
468 u16 FASTCALL HighWramMemoryReadWord(SH2_struct *sh, u32 addr);
469 u32 FASTCALL HighWramMemoryReadLong(SH2_struct *sh, u32 addr);
470 void FASTCALL HighWramMemoryWriteByte(SH2_struct *sh, u32 addr, u8 val);
471 void FASTCALL HighWramMemoryWriteWord(SH2_struct *sh, u32 addr, u16 val);
472 void FASTCALL HighWramMemoryWriteLong(SH2_struct *sh, u32 addr, u32 val);
473 u8 FASTCALL LowWramMemoryReadByte(SH2_struct *sh, u32 addr);
474 u16 FASTCALL LowWramMemoryReadWord(SH2_struct *sh, u32 addr);
475 u32 FASTCALL LowWramMemoryReadLong(SH2_struct *sh, u32 addr);
476 void FASTCALL LowWramMemoryWriteByte(SH2_struct *sh, u32 addr, u8 val);
477 void FASTCALL LowWramMemoryWriteWord(SH2_struct *sh, u32 addr, u16 val);
478 void FASTCALL LowWramMemoryWriteLong(SH2_struct *sh, u32 addr, u32 val);
479 u8 FASTCALL BiosRomMemoryReadByte(SH2_struct *sh, u32 addr);
480 u16 FASTCALL BiosRomMemoryReadWord(SH2_struct *sh, u32 addr);
481 u32 FASTCALL BiosRomMemoryReadLong(SH2_struct *sh, u32 addr);
482 static void FASTCALL BiosRomMemoryWriteByte(UNUSED SH2_struct *sh, UNUSED u32 addr, UNUSED u8 val);
483 static void FASTCALL BiosRomMemoryWriteWord(UNUSED SH2_struct *sh, UNUSED u32 addr, UNUSED u16 val);
484 void FASTCALL BiosRomMemoryWriteLong(UNUSED SH2_struct *sh, UNUSED u32 addr, UNUSED u32 val);
485 static u8 FASTCALL BupRamMemoryReadByte(SH2_struct *sh, u32 addr);
486 u16 FASTCALL BupRamMemoryReadWord(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr);
487 u32 FASTCALL BupRamMemoryReadLong(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr);
488 void FASTCALL BupRamMemoryWriteByte(SH2_struct *sh, u32 addr, u8 val);
489 void FASTCALL BupRamMemoryWriteWord(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr, UNUSED u16 val);
490 void FASTCALL BupRamMemoryWriteLong(UNUSED SH2_struct *sh, USED_IF_DEBUG u32 addr, UNUSED u32 val);
491 #endif
492
493
494 #endif
495