libretro: add savestate support
[picodrive.git] / pico / memory.h
1 // memory map related stuff
2
3 typedef unsigned char  u8;
4 typedef unsigned short u16;
5 typedef unsigned int   u32;
6 typedef unsigned long  uptr; // unsigned pointer-sized int
7
8 #define M68K_MEM_SHIFT 16
9 // minimum size we can map
10 #define M68K_BANK_SIZE (1 << M68K_MEM_SHIFT)
11 #define M68K_BANK_MASK (M68K_BANK_SIZE - 1)
12
13 extern uptr m68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
14 extern uptr m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
15 extern uptr m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
16 extern uptr m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
17
18 extern uptr s68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
19 extern uptr s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
20 extern uptr s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
21 extern uptr s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
22
23 // top-level handlers that cores can use
24 // (or alternatively build them into themselves)
25 // XXX: unhandled: *16 and *32 might cross the bank boundaries
26 typedef u32  (cpu68k_read_f)(u32 a);
27 typedef void (cpu68k_write_f)(u32 a, u32 d);
28
29 // z80
30 #define Z80_MEM_SHIFT 13
31 extern uptr z80_read_map [0x10000 >> Z80_MEM_SHIFT];
32 extern uptr z80_write_map[0x10000 >> Z80_MEM_SHIFT];
33 typedef unsigned char (z80_read_f)(unsigned short a);
34 typedef void (z80_write_f)(unsigned int a, unsigned char data);
35
36 void z80_map_set(uptr *map, int start_addr, int end_addr,
37     const void *func_or_mh, int is_func);
38 void cpu68k_map_set(uptr *map, int start_addr, int end_addr,
39     const void *func_or_mh, int is_func);
40 void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub);
41 void m68k_map_unmap(int start_addr, int end_addr);
42
43 #define map_flag_set(x) ((x) & ((uptr)1 << (sizeof(uptr) * 8 - 1)))
44
45 #define MAKE_68K_READ8(name, map)               \
46 u32 name(u32 a)                                 \
47 {                                               \
48   uptr v;                                       \
49   a &= 0x00ffffff;                              \
50   v = map[a >> M68K_MEM_SHIFT];                 \
51   if (map_flag_set(v))                          \
52     return ((cpu68k_read_f *)(v << 1))(a);      \
53   else                                          \
54     return *(u8 *)((v << 1) + (a ^ 1));         \
55 }
56
57 #define MAKE_68K_READ16(name, map)              \
58 u32 name(u32 a)                                 \
59 {                                               \
60   uptr v;                                       \
61   a &= 0x00fffffe;                              \
62   v = map[a >> M68K_MEM_SHIFT];                 \
63   if (map_flag_set(v))                          \
64     return ((cpu68k_read_f *)(v << 1))(a);      \
65   else                                          \
66     return *(u16 *)((v << 1) + a);              \
67 }
68
69 #define MAKE_68K_READ32(name, map)              \
70 u32 name(u32 a)                                 \
71 {                                               \
72   uptr v, vs;                                   \
73   u32 d;                                        \
74   a &= 0x00fffffe;                              \
75   v = map[a >> M68K_MEM_SHIFT];                 \
76   vs = v << 1;                                  \
77   if (map_flag_set(v)) {                        \
78     d  = ((cpu68k_read_f *)vs)(a) << 16;        \
79     d |= ((cpu68k_read_f *)vs)(a + 2);          \
80   }                                             \
81   else {                                        \
82     u16 *m = (u16 *)(vs + a);                   \
83     d = (m[0] << 16) | m[1];                    \
84   }                                             \
85   return d;                                     \
86 }
87
88 #define MAKE_68K_WRITE8(name, map)              \
89 void name(u32 a, u8 d)                          \
90 {                                               \
91   uptr v;                                       \
92   a &= 0x00ffffff;                              \
93   v = map[a >> M68K_MEM_SHIFT];                 \
94   if (map_flag_set(v))                          \
95     ((cpu68k_write_f *)(v << 1))(a, d);         \
96   else                                          \
97     *(u8 *)((v << 1) + (a ^ 1)) = d;            \
98 }
99
100 #define MAKE_68K_WRITE16(name, map)             \
101 void name(u32 a, u16 d)                         \
102 {                                               \
103   uptr v;                                       \
104   a &= 0x00fffffe;                              \
105   v = map[a >> M68K_MEM_SHIFT];                 \
106   if (map_flag_set(v))                          \
107     ((cpu68k_write_f *)(v << 1))(a, d);         \
108   else                                          \
109     *(u16 *)((v << 1) + a) = d;                 \
110 }
111
112 #define MAKE_68K_WRITE32(name, map)             \
113 void name(u32 a, u32 d)                         \
114 {                                               \
115   uptr v, vs;                                   \
116   a &= 0x00fffffe;                              \
117   v = map[a >> M68K_MEM_SHIFT];                 \
118   vs = v << 1;                                  \
119   if (map_flag_set(v)) {                        \
120     ((cpu68k_write_f *)vs)(a, d >> 16);         \
121     ((cpu68k_write_f *)vs)(a + 2, d);           \
122   }                                             \
123   else {                                        \
124     u16 *m = (u16 *)(vs + a);                   \
125     m[0] = d >> 16;                             \
126     m[1] = d;                                   \
127   }                                             \
128 }
129
130 // 32x
131 typedef struct {
132   uptr addr; // stores (membase >> 1) or ((handler >> 1) | (1<<31))
133   u32 mask;
134 } sh2_memmap;