32x: more memhandler improvements
[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 extern u32 m68k_read8(u32 a);
30 extern u32 m68k_read16(u32 a);
31 extern void m68k_write8(u32 a, u8 d);
32 extern void m68k_write16(u32 a, u16 d);
33
34 // z80
35 #define Z80_MEM_SHIFT 13
36 extern uptr z80_read_map [0x10000 >> Z80_MEM_SHIFT];
37 extern uptr z80_write_map[0x10000 >> Z80_MEM_SHIFT];
38 typedef unsigned char (z80_read_f)(unsigned short a);
39 typedef void (z80_write_f)(unsigned int a, unsigned char data);
40
41 void z80_map_set(uptr *map, int start_addr, int end_addr,
42     const void *func_or_mh, int is_func);
43 void cpu68k_map_set(uptr *map, int start_addr, int end_addr,
44     const void *func_or_mh, int is_func);
45 void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub);
46 void m68k_map_unmap(int start_addr, int end_addr);
47
48 #define map_flag_set(x) ((x) & ((uptr)1 << (sizeof(uptr) * 8 - 1)))
49
50 #define MAKE_68K_READ8(name, map)               \
51 u32 name(u32 a)                                 \
52 {                                               \
53   uptr v;                                       \
54   a &= 0x00ffffff;                              \
55   v = map[a >> M68K_MEM_SHIFT];                 \
56   if (map_flag_set(v))                          \
57     return ((cpu68k_read_f *)(v << 1))(a);      \
58   else                                          \
59     return *(u8 *)((v << 1) + (a ^ 1));         \
60 }
61
62 #define MAKE_68K_READ16(name, map)              \
63 u32 name(u32 a)                                 \
64 {                                               \
65   uptr v;                                       \
66   a &= 0x00fffffe;                              \
67   v = map[a >> M68K_MEM_SHIFT];                 \
68   if (map_flag_set(v))                          \
69     return ((cpu68k_read_f *)(v << 1))(a);      \
70   else                                          \
71     return *(u16 *)((v << 1) + a);              \
72 }
73
74 #define MAKE_68K_READ32(name, map)              \
75 u32 name(u32 a)                                 \
76 {                                               \
77   uptr v, vs;                                   \
78   u32 d;                                        \
79   a &= 0x00fffffe;                              \
80   v = map[a >> M68K_MEM_SHIFT];                 \
81   vs = v << 1;                                  \
82   if (map_flag_set(v)) {                        \
83     d  = ((cpu68k_read_f *)vs)(a) << 16;        \
84     d |= ((cpu68k_read_f *)vs)(a + 2);          \
85   }                                             \
86   else {                                        \
87     u16 *m = (u16 *)(vs + a);                   \
88     d = (m[0] << 16) | m[1];                    \
89   }                                             \
90   return d;                                     \
91 }
92
93 #define MAKE_68K_WRITE8(name, map)              \
94 void name(u32 a, u8 d)                          \
95 {                                               \
96   uptr v;                                       \
97   a &= 0x00ffffff;                              \
98   v = map[a >> M68K_MEM_SHIFT];                 \
99   if (map_flag_set(v))                          \
100     ((cpu68k_write_f *)(v << 1))(a, d);         \
101   else                                          \
102     *(u8 *)((v << 1) + (a ^ 1)) = d;            \
103 }
104
105 #define MAKE_68K_WRITE16(name, map)             \
106 void name(u32 a, u16 d)                         \
107 {                                               \
108   uptr v;                                       \
109   a &= 0x00fffffe;                              \
110   v = map[a >> M68K_MEM_SHIFT];                 \
111   if (map_flag_set(v))                          \
112     ((cpu68k_write_f *)(v << 1))(a, d);         \
113   else                                          \
114     *(u16 *)((v << 1) + a) = d;                 \
115 }
116
117 #define MAKE_68K_WRITE32(name, map)             \
118 void name(u32 a, u32 d)                         \
119 {                                               \
120   uptr v, vs;                                   \
121   a &= 0x00fffffe;                              \
122   v = map[a >> M68K_MEM_SHIFT];                 \
123   vs = v << 1;                                  \
124   if (map_flag_set(v)) {                        \
125     ((cpu68k_write_f *)vs)(a, d >> 16);         \
126     ((cpu68k_write_f *)vs)(a + 2, d);           \
127   }                                             \
128   else {                                        \
129     u16 *m = (u16 *)(vs + a);                   \
130     m[0] = d >> 16;                             \
131     m[1] = d;                                   \
132   }                                             \
133 }
134
135 // 32x
136 typedef struct {
137   uptr addr; // stores (membase >> 1) or ((handler >> 1) | (1<<31))
138   u32 mask;
139 } sh2_memmap;