new memory handling, but asm and mappers need update.
[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
7 #define M68K_MEM_SHIFT 16
8
9 extern unsigned long m68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
10 extern unsigned long m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
11 extern unsigned long m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
12 extern unsigned long m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
13
14 extern unsigned long s68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
15 extern unsigned long s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
16 extern unsigned long s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
17 extern unsigned long s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
18
19 void z80_map_set(unsigned long *map, int start_addr, int end_addr,
20     void *func_or_mh, int is_func);
21 void cpu68k_map_set(unsigned long *map, int start_addr, int end_addr,
22     void *func_or_mh, int is_func);
23 void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub);
24 void m68k_map_unmap(int start_addr, int end_addr);
25
26 // top-level handlers that cores can use
27 // (or alternatively build them into themselves)
28 // XXX: unhandled: *16 and *32 might cross the bank boundaries
29 typedef u32  (cpu68k_read_f)(u32 a);
30 typedef void (cpu68k_write_f)(u32 a, u32 d);
31
32 #define MAKE_68K_READ8(name, map)               \
33 u32 name(u32 a)                                 \
34 {                                               \
35   unsigned long v;                              \
36   a &= 0x00ffffff;                              \
37   v = map[a >> M68K_MEM_SHIFT];                 \
38   if (v & 0x80000000)                           \
39     return ((cpu68k_read_f *)(v << 1))(a);      \
40   else                                          \
41     return *(u8 *)((v << 1) + (a ^ 1));         \
42 }
43
44 #define MAKE_68K_READ16(name, map)              \
45 u32 name(u32 a)                                 \
46 {                                               \
47   unsigned long v;                              \
48   a &= 0x00fffffe;                              \
49   v = map[a >> M68K_MEM_SHIFT];                 \
50   if (v & 0x80000000)                           \
51     return ((cpu68k_read_f *)(v << 1))(a);      \
52   else                                          \
53     return *(u16 *)((v << 1) + a);              \
54 }
55
56 #define MAKE_68K_READ32(name, map)              \
57 u32 name(u32 a)                                 \
58 {                                               \
59   unsigned long v, vs;                          \
60   u32 d;                                        \
61   a &= 0x00fffffe;                              \
62   v = map[a >> M68K_MEM_SHIFT];                 \
63   vs = v << 1;                                  \
64   if (v & 0x80000000) {                         \
65     d  = ((cpu68k_read_f *)vs)(a) << 16;        \
66     d |= ((cpu68k_read_f *)vs)(a + 2);          \
67   }                                             \
68   else {                                        \
69     u16 *m = (u16 *)(vs + a);                   \
70     d = (m[0] << 16) | m[1];                    \
71   }                                             \
72   return d;                                     \
73 }
74
75 #define MAKE_68K_WRITE8(name, map)              \
76 void name(u32 a, u8 d)                          \
77 {                                               \
78   unsigned long v;                              \
79   a &= 0x00ffffff;                              \
80   v = map[a >> M68K_MEM_SHIFT];                 \
81   if (v & 0x80000000)                           \
82     ((cpu68k_write_f *)(v << 1))(a, d);         \
83   else                                          \
84     *(u8 *)((v << 1) + (a ^ 1)) = d;            \
85 }
86
87 #define MAKE_68K_WRITE16(name, map)             \
88 void name(u32 a, u16 d)                         \
89 {                                               \
90   unsigned long v;                              \
91   a &= 0x00fffffe;                              \
92   v = map[a >> M68K_MEM_SHIFT];                 \
93   if (v & 0x80000000)                           \
94     ((cpu68k_write_f *)(v << 1))(a, d);         \
95   else                                          \
96     *(u16 *)((v << 1) + a) = d;                 \
97 }
98
99 #define MAKE_68K_WRITE32(name, map)             \
100 void name(u32 a, u32 d)                         \
101 {                                               \
102   unsigned long v, vs;                          \
103   a &= 0x00fffffe;                              \
104   v = map[a >> M68K_MEM_SHIFT];                 \
105   vs = v << 1;                                  \
106   if (v & 0x80000000) {                         \
107     ((cpu68k_write_f *)vs)(a, d >> 16);         \
108     ((cpu68k_write_f *)vs)(a + 2, d);           \
109   }                                             \
110   else {                                        \
111     u16 *m = (u16 *)(vs + a);                   \
112     m[0] = d >> 16;                             \
113     m[1] = d;                                   \
114   }                                             \
115 }
116