1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * memory management
5 *
6 * Copyright 1995 Bernd Schmidt
7 */
8
9 #ifndef HAS_UAE_PREFS_STRUCT
10 struct uae_prefs;
11 #endif // HAS_UAEPREFS_STRUCT
12
13 extern void memory_reset (void);
14 extern void a1000_reset (void);
15
16 #ifdef JIT
17 extern int special_mem;
18 #define S_READ 1
19 #define S_WRITE 2
20
21 extern uae_u8 *cache_alloc (int);
22 extern void cache_free (uae_u8*);
23
24 #ifdef NATMEM_OFFSET
25 bool init_shm (void);
26 void free_shm (void);
27 bool preinit_shm (void);
28 #endif
29
30 extern bool canbang;
31 extern int candirect;
32 #endif
33
34 #ifdef ADDRESS_SPACE_24BIT
35 #define MEMORY_BANKS 256
36 #define MEMORY_RANGE_MASK ((1<<24)-1)
37 #else
38 #define MEMORY_BANKS 65536
39 #define MEMORY_RANGE_MASK (~0)
40 #endif
41
42 typedef uae_u32 (REGPARAM3 *mem_get_func)(uaecptr) REGPARAM;
43 typedef void (REGPARAM3 *mem_put_func)(uaecptr, uae_u32) REGPARAM;
44 typedef uae_u8 *(REGPARAM3 *xlate_func)(uaecptr) REGPARAM;
45 typedef int (REGPARAM3 *check_func)(uaecptr, uae_u32) REGPARAM;
46
47 extern uae_u8 *address_space, *good_address_map;
48 extern uae_u8 *chipmemory;
49
50 extern uae_u32 allocated_chipmem;
51 extern uae_u32 allocated_fastmem;
52 extern uae_u32 allocated_bogomem;
53 extern uae_u32 allocated_gfxmem;
54 extern uae_u32 allocated_z3fastmem, allocated_z3fastmem2, allocated_z3chipmem;
55 extern uae_u32 max_z3fastmem;
56 extern uae_u32 allocated_a3000mem;
57 extern uae_u32 allocated_cardmem;
58
59 extern uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode);
60 extern void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v);
61 extern uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode);
62 extern void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v);
63
64 #undef DIRECT_MEMFUNCS_SUCCESSFUL
65 #if !defined(ANDROID) && !defined(ARM)
66 #include "machdep/maccess.h"
67 #else
68 #include "machdep/maccess-generic.h"
69 #endif
70
71 #include "retrodep/memory_uae.h"
72
73 #define chipmem_start 0x00000000
74 #define bogomem_start 0x00C00000
75 #define cardmem_start 0x00E00000
76 #define kickmem_start 0x00F80000
77 extern uaecptr z3fastmem_start, z3fastmem2_start, z3chipmem_start;
78 extern uaecptr p96ram_start;
79 extern uaecptr fastmem_start;
80 extern uaecptr a3000lmem_start, a3000hmem_start;
81
82 extern bool ersatzkickfile;
83 extern bool cloanto_rom, kickstart_rom;
84 extern uae_u16 kickstart_version;
85 extern bool uae_boot_rom;
86 extern int uae_boot_rom_size;
87 extern uaecptr rtarea_base;
88
89 extern uae_u8* baseaddr[];
90
91 enum { ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8, ABFLAG_NONE = 16, ABFLAG_SAFE = 32 };
92 typedef struct {
93 /* These ones should be self-explanatory... */
94 mem_get_func lget, wget, bget;
95 mem_put_func lput, wput, bput;
96 /* Use xlateaddr to translate an Amiga address to a uae_u8 * that can
97 * be used to address memory without calling the wget/wput functions.
98 * This doesn't work for all memory banks, so this function may call
99 * abort(). */
100 xlate_func xlateaddr;
101 /* To prevent calls to abort(), use check before calling xlateaddr.
102 * It checks not only that the memory bank can do xlateaddr, but also
103 * that the pointer points to an area of at least the specified size.
104 * This is used for example to translate bitplane pointers in custom.c */
105 check_func check;
106 /* For those banks that refer to real memory, we can save the whole trouble
107 of going through function calls, and instead simply grab the memory
108 ourselves. This holds the memory address where the start of memory is
109 for this particular bank. */
110 uae_u8 *baseaddr;
111 TCHAR *name;
112 /* for instruction opcode/operand fetches */
113 mem_get_func lgeti, wgeti;
114 int flags;
115 } addrbank;
116
117 #define CE_MEMBANK_FAST 0
118 #define CE_MEMBANK_CHIP 1
119 #define CE_MEMBANK_CIA 2
120 #define CE_MEMBANK_FAST16BIT 3
121 extern uae_u8 ce_banktype[65536], ce_cachable[65536];
122
123 extern uae_u8 *filesysory;
124 extern uae_u8 *rtarea;
125
126 extern addrbank chipmem_bank;
127 extern addrbank chipmem_agnus_bank;
128 extern addrbank chipmem_bank_ce2;
129 extern addrbank kickmem_bank;
130 extern addrbank custom_bank;
131 extern addrbank clock_bank;
132 extern addrbank cia_bank;
133 extern addrbank rtarea_bank;
134 extern addrbank expamem_bank;
135 extern addrbank fastmem_bank;
136 extern addrbank gfxmem_bank;
137 #ifdef GAYLE
138 extern addrbank gayle_bank;
139 extern addrbank gayle2_bank;
140 #endif // GAYLE
141 extern addrbank mbres_bank;
142 extern addrbank akiko_bank;
143 extern addrbank cardmem_bank;
144
145 extern void rtarea_init (void);
146 extern void rtarea_init_mem (void);
147 extern void rtarea_setup (void);
148 extern void expamem_init (void);
149 extern void expamem_reset (void);
150 extern void expamem_next (void);
151
152 extern uae_u32 gfxmem_start;
153 extern uae_u8 *gfxmemory;
154 extern uae_u32 gfxmem_mask;
155 extern uae_u16 last_custom_value1;
156
157 /* Default memory access functions */
158
159 extern int REGPARAM3 default_check(uaecptr addr, uae_u32 size) REGPARAM;
160 extern uae_u8 *REGPARAM3 default_xlate(uaecptr addr) REGPARAM;
161 /* 680x0 opcode fetches */
162 extern uae_u32 REGPARAM3 dummy_lgeti (uaecptr addr) REGPARAM;
163 extern uae_u32 REGPARAM3 dummy_wgeti (uaecptr addr) REGPARAM;
164
165 #define bankindex(addr) (((uaecptr)(addr)) >> 16)
166
167 extern addrbank *mem_banks[MEMORY_BANKS];
168
169 #ifdef JIT
170 extern uae_u8 *baseaddr[MEMORY_BANKS];
171 #endif
172
173 #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
174
175 #ifdef JIT
176 #define put_mem_bank(addr, b, realstart) { \
177 uaecptr idx = bankindex((uae_u32)(addr)); \
178 (mem_banks[idx] = (b)); \
179 if ((b)->baseaddr) \
180 baseaddr[idx] = (b)->baseaddr - (realstart); \
181 else \
182 baseaddr[idx] = (uae_u8*)(((uae_u8*)b)+1); \
183 }
184 #else
185 #define put_mem_bank(addr, b, realstart) \
186 (mem_banks[bankindex(addr)] = (b));
187 #endif
188
189 extern void memory_init (void);
190 extern void memory_cleanup (void);
191 extern void map_banks (addrbank *bank, int first, int count, int realsize);
192 extern void map_banks_cond (addrbank *bank, int first, int count, int realsize);
193 extern void map_overlay (int chip);
194 extern void memory_hardreset (int);
195 extern void memory_clear (void);
196 extern void free_fastmemory (void);
197
198 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
199 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
200 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
201 #define longgeti(addr) (call_mem_get_func(get_mem_bank(addr).lgeti, addr))
202 #define wordgeti(addr) (call_mem_get_func(get_mem_bank(addr).wgeti, addr))
203 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
204 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
205 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
206
get_long(uaecptr addr)207 STATIC_INLINE uae_u32 get_long (uaecptr addr)
208 {
209 return longget (addr);
210 }
get_word(uaecptr addr)211 STATIC_INLINE uae_u32 get_word (uaecptr addr)
212 {
213 return wordget (addr);
214 }
get_byte(uaecptr addr)215 STATIC_INLINE uae_u32 get_byte (uaecptr addr)
216 {
217 return byteget (addr);
218 }
get_longi(uaecptr addr)219 STATIC_INLINE uae_u32 get_longi(uaecptr addr)
220 {
221 return longgeti (addr);
222 }
get_wordi(uaecptr addr)223 STATIC_INLINE uae_u32 get_wordi(uaecptr addr)
224 {
225 return wordgeti (addr);
226 }
227
228 /*
229 * Read a host pointer from addr
230 */
231 #if SIZEOF_VOID_P == 4
232 # define get_pointer(addr) ((void *)get_long (addr))
233 #else
234 # if SIZEOF_VOID_P == 8
get_pointer(uaecptr addr)235 STATIC_INLINE void *get_pointer (uaecptr addr)
236 {
237 const unsigned int n = SIZEOF_VOID_P / 4;
238 union {
239 void *ptr;
240 uae_u32 longs[SIZEOF_VOID_P / 4];
241 } p;
242 unsigned int i;
243
244 for (i = 0; i < n; i++) {
245 #ifdef WORDS_BIGENDIAN
246 p.longs[i] = get_long (addr + i * 4);
247 #else
248 p.longs[n - 1 - i] = get_long (addr + i * 4);
249 #endif
250 }
251 return p.ptr;
252 }
253 # else
254 # error "Unknown or unsupported pointer size."
255 # endif
256 #endif
257
put_long(uaecptr addr,uae_u32 l)258 STATIC_INLINE void put_long (uaecptr addr, uae_u32 l)
259 {
260 longput(addr, l);
261 }
put_word(uaecptr addr,uae_u32 w)262 STATIC_INLINE void put_word (uaecptr addr, uae_u32 w)
263 {
264 wordput(addr, w);
265 }
put_byte(uaecptr addr,uae_u32 b)266 STATIC_INLINE void put_byte (uaecptr addr, uae_u32 b)
267 {
268 byteput(addr, b);
269 }
270
271 extern void put_long_slow (uaecptr addr, uae_u32 v);
272 extern void put_word_slow (uaecptr addr, uae_u32 v);
273 extern void put_byte_slow (uaecptr addr, uae_u32 v);
274 extern uae_u32 get_long_slow (uaecptr addr);
275 extern uae_u32 get_word_slow (uaecptr addr);
276 extern uae_u32 get_byte_slow (uaecptr addr);
277
278
279 /*
280 * Store host pointer v at addr
281 */
282 #if SIZEOF_VOID_P == 4
283 # define put_pointer(addr, p) (put_long ((addr), (uae_u32)(p)))
284 #else
285 # if SIZEOF_VOID_P == 8
put_pointer(uaecptr addr,void * v)286 STATIC_INLINE void put_pointer (uaecptr addr, void *v)
287 {
288 const unsigned int n = SIZEOF_VOID_P / 4;
289 union {
290 void *ptr;
291 uae_u32 longs[SIZEOF_VOID_P / 4];
292 } p;
293 unsigned int i;
294
295 p.ptr = v;
296
297 for (i = 0; i < n; i++) {
298 #ifdef WORDS_BIGENDIAN
299 put_long (addr + i * 4, p.longs[i]);
300 #else
301 put_long (addr + i * 4, p.longs[n - 1 - i]);
302 #endif
303 }
304 }
305 # endif
306 #endif
307
get_real_address(uaecptr addr)308 STATIC_INLINE uae_u8 *get_real_address (uaecptr addr)
309 {
310 return get_mem_bank (addr).xlateaddr(addr);
311 }
312
valid_address(uaecptr addr,uae_u32 size)313 STATIC_INLINE int valid_address (uaecptr addr, uae_u32 size)
314 {
315 return get_mem_bank (addr).check(addr, size);
316 }
317
318 extern int addr_valid (const TCHAR*, uaecptr,uae_u32);
319
320 /* For faster access in custom chip emulation. */
321 extern void REGPARAM3 chipmem_lput (uaecptr, uae_u32) REGPARAM;
322 extern void REGPARAM3 chipmem_wput (uaecptr, uae_u32) REGPARAM;
323 extern void REGPARAM3 chipmem_bput (uaecptr, uae_u32) REGPARAM;
324
325 extern uae_u32 REGPARAM3 chipmem_agnus_wget (uaecptr) REGPARAM;
326 extern void REGPARAM3 chipmem_agnus_wput (uaecptr, uae_u32) REGPARAM;
327
328 extern uae_u32 chipmem_mask, kickmem_mask;
329 extern uae_u8 *kickmemory;
330 extern uae_u32 kickmem_size;
331 extern addrbank dummy_bank;
332
333 /* 68020+ Chip RAM DMA contention emulation */
334 extern void REGPARAM3 chipmem_bput_c2 (uaecptr, uae_u32) REGPARAM;
335
336 extern uae_u32 (REGPARAM3 *chipmem_lget_indirect)(uaecptr) REGPARAM;
337 extern uae_u32 (REGPARAM3 *chipmem_wget_indirect)(uaecptr) REGPARAM;
338 extern uae_u32 (REGPARAM3 *chipmem_bget_indirect)(uaecptr) REGPARAM;
339 extern void (REGPARAM3 *chipmem_lput_indirect)(uaecptr, uae_u32) REGPARAM;
340 extern void (REGPARAM3 *chipmem_wput_indirect)(uaecptr, uae_u32) REGPARAM;
341 extern void (REGPARAM3 *chipmem_bput_indirect)(uaecptr, uae_u32) REGPARAM;
342 extern int (REGPARAM3 *chipmem_check_indirect)(uaecptr, uae_u32) REGPARAM;
343 extern uae_u8 *(REGPARAM3 *chipmem_xlate_indirect)(uaecptr) REGPARAM;
344
345 #ifdef NATMEM_OFFSET
346
347 #ifdef HAVE_SYS_TYPES_H
348 # include <sys/types.h>
349 #endif // HAVE_SYS_TYPES_H
350 #ifndef __key_t_defined
351 typedef int key_t;
352 #endif // __key_t_defined
353
354 typedef struct shmpiece_reg {
355 uae_u8 *native_address;
356 int id;
357 uae_u32 size;
358 const TCHAR *name;
359 struct shmpiece_reg *next;
360 struct shmpiece_reg *prev;
361 } shmpiece;
362
363 extern shmpiece *shm_start;
364
365 struct shmid_ds;
366
367 /* Prototypes from src/memory.c used elsewhere, too */
368 int my_shmdt (const void *shmaddr);
369 void *my_shmat (int shmid, void *shmaddr, int shmflg);
370 int my_shmget (key_t key, size_t size, int shmflg, const TCHAR *name);
371 int my_shmctl (int shmid, int cmd, struct shmid_ds *buf);
372
373 #endif
374
375 extern uae_u8 *mapped_malloc (size_t, const TCHAR*);
376 extern void mapped_free (uae_u8 *);
377 extern void clearexec (void);
378 extern void mapkick (void);
379 extern void a3000_fakekick (int);
380
381 extern uaecptr strcpyha_safe (uaecptr dst, const uae_char *src);
382 extern uae_char *strcpyah_safe (uae_char *dst, uaecptr src, int maxsize);
383 extern void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size);
384 //extern void memcpyha (uaecptr dst, const uae_u8 *src, int size);
385 extern void memcpyah_safe (uae_u8 *dst, uaecptr src, int size);
386 extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
387
388 extern uae_s32 getz2size (struct uae_prefs *p);
389 extern ULONG getz2endaddr (void);
390
391 #if 0
392 void *arm_memset(void *s, int c, size_t n);
393 void *arm_memcpy(void *dest, const void *src, size_t n);
394 #define uae4all_memclr(p,l) arm_memset(p,0,l)
395 #define uae4all_memcpy arm_memcpy
396 #else
397 #define uae4all_memcpy memcpy
398 #define uae4all_memclr(p,l) memset(p, 0, l)
399 #endif
400
401