1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * memory management
5 *
6 * Copyright 1995 Bernd Schmidt
7 */
8
9 extern void memory_reset (void);
10 extern void a1000_reset (void);
11
12 typedef uae_u32 (*mem_get_func)(uaecptr) REGPARAM;
13 typedef void (*mem_put_func)(uaecptr, uae_u32) REGPARAM;
14 typedef uae_u8 *(*xlate_func)(uaecptr) REGPARAM;
15 typedef int (*check_func)(uaecptr, uae_u32) REGPARAM;
16
17 extern char *address_space, *good_address_map;
18 extern uae_u8 *chipmemory;
19
20 extern uae_u32 allocated_chipmem;
21 extern uae_u32 allocated_fastmem;
22 extern uae_u32 allocated_bogomem;
23 extern uae_u32 allocated_gfxmem;
24 extern uae_u32 allocated_z3fastmem;
25 extern uae_u32 allocated_a3000mem;
26
27 #undef DIRECT_MEMFUNCS_SUCCESSFUL
28 #include "machdep/maccess.h"
29
30 #ifndef CAN_MAP_MEMORY
31 #undef USE_COMPILER
32 #endif
33
34 #if defined(USE_COMPILER) && !defined(USE_MAPPED_MEMORY)
35 #define USE_MAPPED_MEMORY
36 #endif
37
38 #define kickmem_size 0x080000
39
40 #define chipmem_start 0x00000000
41 #define bogomem_start 0x00C00000
42 #define a3000mem_start 0x07000000
43 #define kickmem_start 0x00F80000
44
45 extern int ersatzkickfile;
46 extern int cloanto_rom;
47 extern uae_u16 kickstart_version;
48 extern int uae_boot_rom, uae_boot_rom_size;
49
50 extern uae_u8* baseaddr[];
51
52 typedef struct {
53 /* These ones should be self-explanatory... */
54 mem_get_func lget, wget, bget;
55 mem_put_func lput, wput, bput;
56 /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can
57 * be used to address memory without calling the wget/wput functions.
58 * This doesn't work for all memory banks, so this function may call
59 * abort(). */
60 xlate_func xlateaddr;
61 /* To prevent calls to abort(), use check before calling xlateaddr.
62 * It checks not only that the memory bank can do xlateaddr, but also
63 * that the pointer points to an area of at least the specified size.
64 * This is used for example to translate bitplane pointers in custom.c */
65 check_func check;
66 /* For those banks that refer to real memory, we can save the whole trouble
67 of going through function calls, and instead simply grab the memory
68 ourselves. This holds the memory address where the start of memory is
69 for this particular bank. */
70 uae_u8 *baseaddr;
71 const char *name;
72 } addrbank;
73
74 extern uae_u8 *filesysory;
75 extern uae_u8 *rtarea;
76
77 extern addrbank chipmem_bank;
78 extern addrbank kickmem_bank;
79 extern addrbank custom_bank;
80 extern addrbank clock_bank;
81 extern addrbank cia_bank;
82 extern addrbank rtarea_bank;
83 extern addrbank expamem_bank;
84 extern addrbank fastmem_bank;
85 extern addrbank gfxmem_bank;
86 extern addrbank gayle_bank;
87 extern addrbank gayle2_bank;
88 extern addrbank gayle_attr_bank;
89 extern addrbank mbres_bank;
90
91 extern void rtarea_init (void);
92 extern void rtarea_setup (void);
93 extern void expamem_init (void);
94 extern void expamem_reset (void);
95
96 extern uae_u32 gfxmem_start;
97 extern uae_u8 *gfxmemory;
98 extern uae_u32 gfxmem_mask;
99 extern int address_space_24;
100
101 /* Default memory access functions */
102
103 extern int default_check(uaecptr addr, uae_u32 size) REGPARAM;
104 extern uae_u8 *default_xlate(uaecptr addr) REGPARAM;
105
106 #define bankindex(addr) (((uaecptr)(addr)) >> 16)
107
108 extern addrbank *mem_banks[65536];
109 extern uae_u8 *baseaddr[65536];
110 #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
111 #define put_mem_bank(addr, b, realstart) do { \
112 (mem_banks[bankindex(addr)] = (b)); \
113 if ((b)->baseaddr) \
114 baseaddr[bankindex(addr)] = (b)->baseaddr - (realstart); \
115 else \
116 baseaddr[bankindex(addr)] = (uae_u8*)(((long)b)+1); \
117 } while (0)
118
119 extern void memory_init (void);
120 extern void memory_cleanup (void);
121 extern void map_banks (addrbank *bank, int first, int count, int realsize);
122 extern void map_overlay (int chip);
123
124 #ifndef NO_INLINE_MEMORY_ACCESS
125
126 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
127 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
128 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
129 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
130 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
131 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
132
133 #else
134
135 extern uae_u32 alongget(uaecptr addr);
136 extern uae_u32 awordget(uaecptr addr);
137 extern uae_u32 longget(uaecptr addr);
138 extern uae_u32 wordget(uaecptr addr);
139 extern uae_u32 byteget(uaecptr addr);
140 extern void longput(uaecptr addr, uae_u32 l);
141 extern void wordput(uaecptr addr, uae_u32 w);
142 extern void byteput(uaecptr addr, uae_u32 b);
143
144 #endif
145
146 #ifndef MD_HAVE_MEM_1_FUNCS
147
148 #define longget_1 longget
149 #define wordget_1 wordget
150 #define byteget_1 byteget
151 #define longput_1 longput
152 #define wordput_1 wordput
153 #define byteput_1 byteput
154
155 #endif
156
get_long(uaecptr addr)157 STATIC_INLINE uae_u32 get_long (uaecptr addr)
158 {
159 return longget_1(addr);
160 }
get_word(uaecptr addr)161 STATIC_INLINE uae_u32 get_word (uaecptr addr)
162 {
163 return wordget_1(addr);
164 }
get_byte(uaecptr addr)165 STATIC_INLINE uae_u32 get_byte (uaecptr addr)
166 {
167 return byteget_1(addr);
168 }
169
170 /*
171 * Read a host pointer from addr
172 */
173 #if SIZEOF_VOID_P == 4
174 # define get_pointer(addr) ((void *)get_long (addr))
175 #else
176 # if SIZEOF_VOID_P == 8
get_pointer(uaecptr addr)177 STATIC_INLINE void *get_pointer (uaecptr addr)
178 {
179 const unsigned int n = SIZEOF_VOID_P / 4;
180 union {
181 void *ptr;
182 uae_u32 longs[SIZEOF_VOID_P / 4];
183 } p;
184 unsigned int i;
185
186 for (i = 0; i < n; i++) {
187 #ifdef WORDS_BIGENDIAN
188 p.longs[i] = get_long (addr + i * 4);
189 #else
190 p.longs[n - 1 - i] = get_long (addr + i * 4);
191 #endif
192 }
193 return p.ptr;
194 }
195 # else
196 # error "Unknown or unsupported pointer size."
197 # endif
198 #endif
199
put_long(uaecptr addr,uae_u32 l)200 STATIC_INLINE void put_long (uaecptr addr, uae_u32 l)
201 {
202 longput_1(addr, l);
203 }
put_word(uaecptr addr,uae_u32 w)204 STATIC_INLINE void put_word (uaecptr addr, uae_u32 w)
205 {
206 wordput_1(addr, w);
207 }
put_byte(uaecptr addr,uae_u32 b)208 STATIC_INLINE void put_byte (uaecptr addr, uae_u32 b)
209 {
210 byteput_1(addr, b);
211 }
212
213 /*
214 * Store host pointer v at addr
215 */
216 #if SIZEOF_VOID_P == 4
217 # define put_pointer(addr, p) (put_long ((addr), (uae_u32)(p)))
218 #else
219 # if SIZEOF_VOID_P == 8
put_pointer(uaecptr addr,void * v)220 STATIC_INLINE void put_pointer (uaecptr addr, void *v)
221 {
222 const unsigned int n = SIZEOF_VOID_P / 4;
223 union {
224 void *ptr;
225 uae_u32 longs[SIZEOF_VOID_P / 4];
226 } p;
227 unsigned int i;
228
229 p.ptr = v;
230
231 for (i = 0; i < n; i++) {
232 #ifdef WORDS_BIGENDIAN
233 put_long (addr + i * 4, p.longs[i]);
234 #else
235 put_long (addr + i * 4, p.longs[n - 1 - i]);
236 #endif
237 }
238 }
239 # endif
240 #endif
241
get_real_address(uaecptr addr)242 STATIC_INLINE uae_u8 *get_real_address (uaecptr addr)
243 {
244 return get_mem_bank(addr).xlateaddr(addr);
245 }
246
valid_address(uaecptr addr,uae_u32 size)247 STATIC_INLINE int valid_address(uaecptr addr, uae_u32 size)
248 {
249 return get_mem_bank(addr).check(addr, size);
250 }
251
252 /* For faster access in custom chip emulation. */
253 extern uae_u32 chipmem_lget (uaecptr) REGPARAM;
254 extern uae_u32 chipmem_wget (uaecptr) REGPARAM;
255 extern uae_u32 chipmem_bget (uaecptr) REGPARAM;
256 extern void chipmem_lput (uaecptr, uae_u32) REGPARAM;
257 extern void chipmem_wput (uaecptr, uae_u32) REGPARAM;
258 extern void chipmem_bput (uaecptr, uae_u32) REGPARAM;
259
260 extern uae_u32 chipmem_agnus_wget (uaecptr) REGPARAM;
261 extern void chipmem_agnus_wput (uaecptr, uae_u32) REGPARAM;
262
263 #ifdef NATMEM_OFFSET
264
265 typedef struct shmpiece_reg {
266 uae_u8 *native_address;
267 int id;
268 uae_u32 size;
269 struct shmpiece_reg *next;
270 struct shmpiece_reg *prev;
271 } shmpiece;
272
273 extern shmpiece *shm_start;
274 extern int canbang;
275
276 #endif
277
278 extern uae_u8 *mapped_malloc (size_t, char *);
279 extern void mapped_free (uae_u8 *);
280 extern void memory_hardreset (void);
281
282 uaecptr strcpyha_safe (uaecptr dst, const char *src);
283 uaecptr strncpyha_safe (uaecptr dst, const char *src, int size);
284 extern char *strcpyah_safe (char *dst, uaecptr src);
285 extern void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size);
286 extern void memcpyha (uaecptr dst, const uae_u8 *src, int size);
287 extern void memcpyah_safe (uae_u8 *dst, uaecptr src, int size);
288 extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
289