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