1 // memory map related stuff
2 
3 #include "pico_port.h"
4 
5 #define M68K_MEM_SHIFT 16
6 // minimum size we can map
7 #define M68K_BANK_SIZE (1 << M68K_MEM_SHIFT)
8 #define M68K_BANK_MASK (M68K_BANK_SIZE - 1)
9 
10 extern uptr m68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
11 extern uptr m68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
12 extern uptr m68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
13 extern uptr m68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
14 
15 extern uptr s68k_read8_map  [0x1000000 >> M68K_MEM_SHIFT];
16 extern uptr s68k_read16_map [0x1000000 >> M68K_MEM_SHIFT];
17 extern uptr s68k_write8_map [0x1000000 >> M68K_MEM_SHIFT];
18 extern uptr s68k_write16_map[0x1000000 >> M68K_MEM_SHIFT];
19 
20 // top-level handlers that cores can use
21 // (or alternatively build them into themselves)
22 // XXX: unhandled: *16 and *32 might cross the bank boundaries
23 typedef u32  (cpu68k_read_f)(u32 a);
24 typedef void (cpu68k_write_f)(u32 a, u32 d);
25 
26 extern u32 m68k_read8(u32 a);
27 extern u32 m68k_read16(u32 a);
28 extern u32 m68k_read32(u32 a);
29 extern void m68k_write8(u32 a, u8 d);
30 extern void m68k_write16(u32 a, u16 d);
31 extern void m68k_write32(u32 a, u32 d);
32 
33 extern u32 s68k_read8(u32 a);
34 extern u32 s68k_read16(u32 a);
35 extern u32 s68k_read32(u32 a);
36 extern void s68k_write8(u32 a, u8 d);
37 extern void s68k_write16(u32 a, u16 d);
38 extern void s68k_write32(u32 a, u32 d);
39 
40 // z80
41 #define Z80_MEM_SHIFT 13
42 extern uptr z80_read_map [0x10000 >> Z80_MEM_SHIFT];
43 extern uptr z80_write_map[0x10000 >> Z80_MEM_SHIFT];
44 typedef unsigned char (z80_read_f)(unsigned short a);
45 typedef void (z80_write_f)(unsigned int a, unsigned char data);
46 
47 void z80_map_set(uptr *map, int start_addr, int end_addr,
48     const void *func_or_mh, int is_func);
49 void cpu68k_map_set(uptr *map, int start_addr, int end_addr,
50     const void *func_or_mh, int is_func);
51 void cpu68k_map_all_ram(int start_addr, int end_addr, void *ptr, int is_sub);
52 void m68k_map_unmap(int start_addr, int end_addr);
53 
54 #define MAP_FLAG ((uptr)1 << (sizeof(uptr) * 8 - 1))
55 #define map_flag_set(x) ((x) & MAP_FLAG)
56 
57 #define MAKE_68K_READ8(name, map)               \
58 u32 name(u32 a)                                 \
59 {                                               \
60   uptr v;                                       \
61   a &= 0x00ffffff;                              \
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 *(u8 *)((v << 1) + (a ^ 1));         \
67 }
68 
69 #define MAKE_68K_READ16(name, map)              \
70 u32 name(u32 a)                                 \
71 {                                               \
72   uptr v;                                       \
73   a &= 0x00fffffe;                              \
74   v = map[a >> M68K_MEM_SHIFT];                 \
75   if (map_flag_set(v))                          \
76     return ((cpu68k_read_f *)(v << 1))(a);      \
77   else                                          \
78     return *(u16 *)((v << 1) + a);              \
79 }
80 
81 #define MAKE_68K_READ32(name, map)              \
82 u32 name(u32 a)                                 \
83 {                                               \
84   uptr v, vs;                                   \
85   u32 d;                                        \
86   a &= 0x00fffffe;                              \
87   v = map[a >> M68K_MEM_SHIFT];                 \
88   vs = v << 1;                                  \
89   if (map_flag_set(v)) {                        \
90     d  = ((cpu68k_read_f *)vs)(a) << 16;        \
91     d |= ((cpu68k_read_f *)vs)(a + 2);          \
92   }                                             \
93   else {                                        \
94     u16 *m = (u16 *)(vs + a);                   \
95     d = (m[0] << 16) | m[1];                    \
96   }                                             \
97   return d;                                     \
98 }
99 
100 #define MAKE_68K_WRITE8(name, map)              \
101 void name(u32 a, u8 d)                          \
102 {                                               \
103   uptr v;                                       \
104   a &= 0x00ffffff;                              \
105   v = map[a >> M68K_MEM_SHIFT];                 \
106   if (map_flag_set(v))                          \
107     ((cpu68k_write_f *)(v << 1))(a, d);         \
108   else                                          \
109     *(u8 *)((v << 1) + (a ^ 1)) = d;            \
110 }
111 
112 #define MAKE_68K_WRITE16(name, map)             \
113 void name(u32 a, u16 d)                         \
114 {                                               \
115   uptr v;                                       \
116   a &= 0x00fffffe;                              \
117   v = map[a >> M68K_MEM_SHIFT];                 \
118   if (map_flag_set(v))                          \
119     ((cpu68k_write_f *)(v << 1))(a, d);         \
120   else                                          \
121     *(u16 *)((v << 1) + a) = d;                 \
122 }
123 
124 #define MAKE_68K_WRITE32(name, map)             \
125 void name(u32 a, u32 d)                         \
126 {                                               \
127   uptr v, vs;                                   \
128   a &= 0x00fffffe;                              \
129   v = map[a >> M68K_MEM_SHIFT];                 \
130   vs = v << 1;                                  \
131   if (map_flag_set(v)) {                        \
132     ((cpu68k_write_f *)vs)(a, d >> 16);         \
133     ((cpu68k_write_f *)vs)(a + 2, d);           \
134   }                                             \
135   else {                                        \
136     u16 *m = (u16 *)(vs + a);                   \
137     m[0] = d >> 16;                             \
138     m[1] = d;                                   \
139   }                                             \
140 }
141 
142 #ifdef NEED_DMA_SOURCE // meh
143 
m68k_dma_source(u32 a)144 static __inline void *m68k_dma_source(u32 a)
145 {
146   u8 *base;
147   uptr v;
148   v = m68k_read16_map[a >> M68K_MEM_SHIFT];
149   if (map_flag_set(v)) {
150     if (a >= Pico.romsize) // Rom
151       return NULL;
152     base = Pico.rom;
153   }
154   else
155     base = (void *)(v << 1);
156   return base + (a & 0xfe0000);
157 }
158 
159 #endif
160 
161 // 32x
162 typedef struct {
163   uptr addr; // stores (membase >> 1) or ((handler >> 1) | (1<<31))
164   u32 mask;
165 } sh2_memmap;
166