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