1 /*
2 * UAE - The Un*x Amiga Emulator
3 *
4 * memory management
5 *
6 * Copyright 1995 Bernd Schmidt
7 */
8 
9 #ifndef UAE_MEMORY_H
10 #define UAE_MEMORY_H
11 
12 extern void memory_reset (void);
13 
14 #ifdef JIT
15 extern int special_mem;
16 #endif
17 
18 #define S_READ 1
19 #define S_WRITE 2
20 
21 bool init_shm (void);
22 void free_shm (void);
23 bool preinit_shm (void);
24 extern bool canbang;
25 extern bool jit_direct_compatible_memory;
26 
27 #define Z3BASE_UAE 0x10000000
28 #define Z3BASE_REAL 0x40000000
29 
30 #define AUTOCONFIG_Z2 0x00e80000
31 #define AUTOCONFIG_Z2_MEM 0x00200000
32 #define AUTOCONFIG_Z3 0xff000000
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_u32 max_z3fastmem;
48 
49 extern uae_u32 wait_cpu_cycle_read (uaecptr addr, int mode);
50 extern void wait_cpu_cycle_write (uaecptr addr, int mode, uae_u32 v);
51 extern uae_u32 wait_cpu_cycle_read_ce020 (uaecptr addr, int mode);
52 extern void wait_cpu_cycle_write_ce020 (uaecptr addr, int mode, uae_u32 v);
53 
54 #undef DIRECT_MEMFUNCS_SUCCESSFUL
55 #include "maccess.h"
56 
57 #define chipmem_start_addr 0x00000000
58 #define bogomem_start_addr 0x00C00000
59 
60 #define ROM_SIZE_512 524288
61 #define ROM_SIZE_256 262144
62 #define ROM_SIZE_128 131072
63 
64 extern bool ersatzkickfile;
65 extern bool cloanto_rom, kickstart_rom;
66 extern uae_u16 kickstart_version;
67 extern int uae_boot_rom_type;
68 extern int uae_boot_rom_size;
69 extern uaecptr rtarea_base;
70 extern uaecptr uaeboard_base;
71 
72 extern uae_u8* baseaddr[];
73 
74 #define CACHE_ENABLE_DATA 0x01
75 #define CACHE_ENABLE_DATA_BURST 0x02
76 #define CACHE_ENABLE_COPYBACK 0x020
77 #define CACHE_ENABLE_INS 0x80
78 #define CACHE_ENABLE_INS_BURST 0x40
79 #define CACHE_ENABLE_BOTH (CACHE_ENABLE_DATA | CACHE_ENABLE_INS)
80 #define CACHE_ENABLE_ALL (CACHE_ENABLE_BOTH | CACHE_ENABLE_INS_BURST | CACHE_ENABLE_DATA_BURST)
81 #define CACHE_DISABLE_ALLOCATE 0x08
82 #define CACHE_DISABLE_MMU 0x10
83 extern uae_u8 ce_banktype[65536], ce_cachable[65536];
84 
85 #define ABFLAG_CACHE_SHIFT 16
86 enum
87 {
88 	ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8,
89 	ABFLAG_NONE = 16, ABFLAG_SAFE = 32, ABFLAG_INDIRECT = 64, ABFLAG_NOALLOC = 128,
90 	ABFLAG_RTG = 256, ABFLAG_THREADSAFE = 512, ABFLAG_DIRECTMAP = 1024, ABFLAG_ALLOCINDIRECT = 2048,
91 	ABFLAG_CHIPRAM = 4096, ABFLAG_CIA = 8192, ABFLAG_PPCIOSPACE = 16384,
92 	ABFLAG_MAPPED = 32768,
93 	ABFLAG_CACHE_ENABLE_DATA = CACHE_ENABLE_DATA << ABFLAG_CACHE_SHIFT,
94 	ABFLAG_CACHE_ENABLE_DATA_BURST = CACHE_ENABLE_DATA_BURST << ABFLAG_CACHE_SHIFT,
95 	ABFLAG_CACHE_ENABLE_INS = CACHE_ENABLE_INS << ABFLAG_CACHE_SHIFT,
96 	ABFLAG_CACHE_ENABLE_INS_BURST = CACHE_ENABLE_INS_BURST << ABFLAG_CACHE_SHIFT,
97 };
98 
99 #define ABFLAG_CACHE_ENABLE_BOTH (ABFLAG_CACHE_ENABLE_DATA | ABFLAG_CACHE_ENABLE_INS)
100 #define ABFLAG_CACHE_ENABLE_ALL (ABFLAG_CACHE_ENABLE_BOTH | ABFLAG_CACHE_ENABLE_INS_BURST | ABFLAG_CACHE_ENABLE_DATA_BURST)
101 
102 typedef struct {
103 	/* These ones should be self-explanatory... */
104 	mem_get_func lget, wget, bget;
105 	mem_put_func lput, wput, bput;
106 	/* Use xlateaddr to translate an Amiga address to a uae_u8 * that can
107 	* be used to address memory without calling the wget/wput functions.
108 	* This doesn't work for all memory banks, so this function may call
109 	* abort(). */
110 	xlate_func xlateaddr;
111 	/* To prevent calls to abort(), use check before calling xlateaddr.
112 	* It checks not only that the memory bank can do xlateaddr, but also
113 	* that the pointer points to an area of at least the specified size.
114 	* This is used for example to translate bitplane pointers in custom.c */
115 	check_func check;
116 	/* For those banks that refer to real memory, we can save the whole trouble
117 	of going through function calls, and instead simply grab the memory
118 	ourselves. This holds the memory address where the start of memory is
119 	for this particular bank. */
120 	uae_u8 *baseaddr;
121 	const TCHAR *label;
122 	const TCHAR *name;
123 	/* for instruction opcode/operand fetches */
124 	mem_get_func lgeti, wgeti;
125 	int flags;
126 	int jit_read_flag, jit_write_flag;
127 	struct addrbank_sub *sub_banks;
128 	uae_u32 mask;
129 	uae_u32 startmask;
130 	uae_u32 start;
131 	// if RAM: size of allocated RAM. Zero if failed.
132 	uae_u32 allocated_size;
133 	// size of bank (if IO or before RAM allocation)
134 	uae_u32 reserved_size;
135 } addrbank;
136 
137 #define MEMORY_MIN_SUBBANK 1024
138 struct addrbank_sub
139 {
140 	addrbank *bank;
141 	uae_u32 offset;
142 	uae_u32 suboffset;
143 	uae_u32 mask;
144 	uae_u32 maskval;
145 };
146 
147 #ifndef WINUAE_FOR_HATARI
148 struct autoconfig_info
149 {
150 	struct uae_prefs *prefs;
151 	bool doinit;
152 	bool postinit;
153 	int devnum;
154 	uae_u8 autoconfig_raw[128];
155 	uae_u8 autoconfig_bytes[16];
156 	TCHAR name[128];
157 	const uae_u8 *autoconfigp;
158 	bool autoconfig_automatic;
159 	uae_u32 start;
160 	uae_u32 size;
161 	int zorro;
162 	const TCHAR *label;
163 	addrbank *addrbank;
164 	uaecptr write_bank_address;
165 	struct romconfig *rc;
166 	uae_u32 last_high_ram;
167 	const struct cpuboardsubtype *cst;
168 	const struct expansionromtype *ert;
169 	struct autoconfig_info *parent;
170 	const int *parent_romtype;
171 	bool parent_of_previous;
172 	bool parent_address_space;
173 	bool direct_vram;
174 	const TCHAR *parent_name;
175 	bool can_sort;
176 	bool hardwired;
177 	bool (*get_params)(struct uae_prefs*, struct expansion_params*);
178 	bool (*set_params)(struct uae_prefs*, struct expansion_params*);
179 	void *userdata;
180 };
181 #endif
182 
183 #define CE_MEMBANK_FAST32 0
184 #define CE_MEMBANK_CHIP16 1
185 #define CE_MEMBANK_CHIP32 2
186 #define CE_MEMBANK_CIA 3
187 #define CE_MEMBANK_FAST16 4
188 //#define CE_MEMBANK_FAST16_EXTRA_ACCURACY 5
189 
190 #ifdef WINUAE_FOR_HATARI
191 #define CE_MEMBANK_NOT_CACHABLE		CACHE_DISABLE_ALLOCATE
192 #endif
193 
194 #define MEMORY_LGETI(name) \
195 static uae_u32 REGPARAM3 name ## _lgeti (uaecptr) REGPARAM; \
196 static uae_u32 REGPARAM2 name ## _lgeti (uaecptr addr) \
197 { \
198 	uae_u8 *m; \
199 	addr -= name ## _bank.start & name ## _bank.mask; \
200 	addr &= name ## _bank.mask; \
201 	m = name ## _bank.baseaddr + addr; \
202 	return do_get_mem_long ((uae_u32 *)m); \
203 }
204 #define MEMORY_WGETI(name) \
205 static uae_u32 REGPARAM3 name ## _wgeti (uaecptr) REGPARAM; \
206 static uae_u32 REGPARAM2 name ## _wgeti (uaecptr addr) \
207 { \
208 	uae_u8 *m; \
209 	addr -= name ## _bank.start & name ## _bank.mask; \
210 	addr &= name ## _bank.mask; \
211 	m = name ## _bank.baseaddr + addr; \
212 	return do_get_mem_word ((uae_u16 *)m); \
213 }
214 #define MEMORY_LGET(name) \
215 static uae_u32 REGPARAM3 name ## _lget (uaecptr) REGPARAM; \
216 static uae_u32 REGPARAM2 name ## _lget (uaecptr addr) \
217 { \
218 	uae_u8 *m; \
219 	addr -= name ## _bank.start & name ## _bank.mask; \
220 	addr &= name ## _bank.mask; \
221 	m = name ## _bank.baseaddr + addr; \
222 	return do_get_mem_long ((uae_u32 *)m); \
223 }
224 #define MEMORY_WGET(name) \
225 static uae_u32 REGPARAM3 name ## _wget (uaecptr) REGPARAM; \
226 static uae_u32 REGPARAM2 name ## _wget (uaecptr addr) \
227 { \
228 	uae_u8 *m; \
229 	addr -= name ## _bank.start & name ## _bank.mask; \
230 	addr &= name ## _bank.mask; \
231 	m = name ## _bank.baseaddr + addr; \
232 	return do_get_mem_word ((uae_u16 *)m); \
233 }
234 #define MEMORY_BGET(name) \
235 static uae_u32 REGPARAM3 name ## _bget (uaecptr) REGPARAM; \
236 static uae_u32 REGPARAM2 name ## _bget (uaecptr addr) \
237 { \
238 	addr -= name ## _bank.start & name ## _bank.mask; \
239 	addr &= name ## _bank.mask; \
240 	return name ## _bank.baseaddr[addr]; \
241 }
242 #define MEMORY_LPUT(name) \
243 static void REGPARAM3 name ## _lput (uaecptr, uae_u32) REGPARAM; \
244 static void REGPARAM2 name ## _lput (uaecptr addr, uae_u32 l) \
245 { \
246 	uae_u8 *m;  \
247 	addr -= name ## _bank.start & name ## _bank.mask; \
248 	addr &= name ## _bank.mask; \
249 	m = name ## _bank.baseaddr + addr; \
250 	do_put_mem_long ((uae_u32 *)m, l); \
251 }
252 #define MEMORY_WPUT(name) \
253 static void REGPARAM3 name ## _wput (uaecptr, uae_u32) REGPARAM; \
254 static void REGPARAM2 name ## _wput (uaecptr addr, uae_u32 w) \
255 { \
256 	uae_u8 *m;  \
257 	addr -= name ## _bank.start & name ## _bank.mask; \
258 	addr &= name ## _bank.mask; \
259 	m = name ## _bank.baseaddr + addr; \
260 	do_put_mem_word ((uae_u16 *)m, w); \
261 }
262 #define MEMORY_BPUT(name) \
263 static void REGPARAM3 name ## _bput (uaecptr, uae_u32) REGPARAM; \
264 static void REGPARAM2 name ## _bput (uaecptr addr, uae_u32 b) \
265 { \
266 	addr -= name ## _bank.start & name ## _bank.mask; \
267 	addr &= name ## _bank.mask; \
268 	name ## _bank.baseaddr[addr] = b; \
269 }
270 #define MEMORY_CHECK(name) \
271 static int REGPARAM3 name ## _check (uaecptr addr, uae_u32 size) REGPARAM; \
272 static int REGPARAM2 name ## _check (uaecptr addr, uae_u32 size) \
273 { \
274 	addr -= name ## _bank.start & name ## _bank.mask; \
275 	addr &= name ## _bank.mask; \
276 	return (addr + size) <= name ## _bank.allocated_size; \
277 }
278 #define MEMORY_XLATE(name) \
279 static uae_u8 *REGPARAM3 name ## _xlate (uaecptr addr) REGPARAM; \
280 static uae_u8 *REGPARAM2 name ## _xlate (uaecptr addr) \
281 { \
282 	addr -= name ## _bank.start & name ## _bank.mask; \
283 	addr &= name ## _bank.mask; \
284 	return name ## _bank.baseaddr + addr; \
285 }
286 
287 #define DECLARE_MEMORY_FUNCTIONS(name) \
288 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lget) (uaecptr) REGPARAM; \
289 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lgeti) (uaecptr) REGPARAM; \
290 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wget) (uaecptr) REGPARAM; \
291 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wgeti) (uaecptr) REGPARAM; \
292 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _bget) (uaecptr) REGPARAM; \
293 static void REGPARAM3 NOWARN_UNUSED(name ## _lput) (uaecptr, uae_u32) REGPARAM; \
294 static void REGPARAM3 NOWARN_UNUSED(name ## _wput) (uaecptr, uae_u32) REGPARAM; \
295 static void REGPARAM3 NOWARN_UNUSED(name ## _bput) (uaecptr, uae_u32) REGPARAM; \
296 static int REGPARAM3 NOWARN_UNUSED(name ## _check) (uaecptr addr, uae_u32 size) REGPARAM; \
297 static uae_u8 *REGPARAM3 NOWARN_UNUSED(name ## _xlate) (uaecptr addr) REGPARAM;
298 
299 #define DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(name, suffix) \
300 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lget_ ## suffix) (uaecptr) REGPARAM; \
301 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _lgeti_ ## suffix) (uaecptr) REGPARAM; \
302 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wget_ ## suffix) (uaecptr) REGPARAM; \
303 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _wgeti_ ## suffix) (uaecptr) REGPARAM; \
304 static uae_u32 REGPARAM3 NOWARN_UNUSED(name ## _bget_ ## suffix) (uaecptr) REGPARAM; \
305 static void REGPARAM3 NOWARN_UNUSED(name ## _lput_ ## suffix) (uaecptr, uae_u32) REGPARAM; \
306 static void REGPARAM3 NOWARN_UNUSED(name ## _wput_ ## suffix) (uaecptr, uae_u32) REGPARAM; \
307 static void REGPARAM3 NOWARN_UNUSED(name ## _bput_ ## suffix) (uaecptr, uae_u32) REGPARAM; \
308 static int REGPARAM3 NOWARN_UNUSED(name ## _check_ ## suffix) (uaecptr addr, uae_u32 size) REGPARAM; \
309 static uae_u8 *REGPARAM3 NOWARN_UNUSED(name ## _xlate_ ## suffix) (uaecptr addr) REGPARAM;
310 
311 #define MEMORY_FUNCTIONS(name) \
312 MEMORY_LGET(name); \
313 MEMORY_WGET(name); \
314 MEMORY_BGET(name); \
315 MEMORY_LPUT(name); \
316 MEMORY_WPUT(name); \
317 MEMORY_BPUT(name); \
318 MEMORY_CHECK(name); \
319 MEMORY_XLATE(name);
320 
321 
322 #define MEMORY_ARRAY_LGET(name, index) \
323 static uae_u32 REGPARAM3 name ## index ## _lget (uaecptr) REGPARAM; \
324 static uae_u32 REGPARAM2 name ## index ## _lget (uaecptr addr) \
325 { \
326 	uae_u8 *m; \
327 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
328 	addr &= name ## _bank[index].mask; \
329 	m = name ## _bank[index].baseaddr + addr; \
330 	return do_get_mem_long ((uae_u32 *)m); \
331 }
332 #define MEMORY_ARRAY_WGET(name, index) \
333 static uae_u32 REGPARAM3 name ## index ## _wget (uaecptr) REGPARAM; \
334 static uae_u32 REGPARAM2 name ## index ## _wget (uaecptr addr) \
335 { \
336 	uae_u8 *m; \
337 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
338 	addr &= name ## _bank[index].mask; \
339 	m = name ## _bank[index].baseaddr + addr; \
340 	return do_get_mem_word ((uae_u16 *)m); \
341 }
342 #define MEMORY_ARRAY_BGET(name, index) \
343 static uae_u32 REGPARAM3 name ## index ## _bget (uaecptr) REGPARAM; \
344 static uae_u32 REGPARAM2 name ## index ## _bget (uaecptr addr) \
345 { \
346 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
347 	addr &= name ## _bank[index].mask; \
348 	return name ## _bank[index].baseaddr[addr]; \
349 }
350 #define MEMORY_ARRAY_LPUT(name, index) \
351 static void REGPARAM3 name ## index ## _lput (uaecptr, uae_u32) REGPARAM; \
352 static void REGPARAM2 name ## index ## _lput (uaecptr addr, uae_u32 l) \
353 { \
354 	uae_u8 *m;  \
355 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
356 	addr &= name ## _bank[index].mask; \
357 	m = name ## _bank[index].baseaddr + addr; \
358 	do_put_mem_long ((uae_u32 *)m, l); \
359 }
360 #define MEMORY_ARRAY_WPUT(name, index) \
361 static void REGPARAM3 name ## index ## _wput (uaecptr, uae_u32) REGPARAM; \
362 static void REGPARAM2 name ## index ## _wput (uaecptr addr, uae_u32 w) \
363 { \
364 	uae_u8 *m;  \
365 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
366 	addr &= name ## _bank[index].mask; \
367 	m = name ## _bank[index].baseaddr + addr; \
368 	do_put_mem_word ((uae_u16 *)m, w); \
369 }
370 #define MEMORY_ARRAY_BPUT(name, index) \
371 static void REGPARAM3 name ## index ## _bput (uaecptr, uae_u32) REGPARAM; \
372 static void REGPARAM2 name ## index ## _bput (uaecptr addr, uae_u32 b) \
373 { \
374 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
375 	addr &= name ## _bank[index].mask; \
376 	name ## _bank[index].baseaddr[addr] = b; \
377 }
378 #define MEMORY_ARRAY_CHECK(name, index) \
379 static int REGPARAM3 name ## index ## _check (uaecptr addr, uae_u32 size) REGPARAM; \
380 static int REGPARAM2 name ## index ## _check (uaecptr addr, uae_u32 size) \
381 { \
382 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
383 	addr &= name ## _bank[index].mask; \
384 	return (addr + size) <= name ## _bank[index].allocated_size; \
385 }
386 #define MEMORY_ARRAY_XLATE(name, index) \
387 static uae_u8 *REGPARAM3 name ## index ## _xlate (uaecptr addr) REGPARAM; \
388 static uae_u8 *REGPARAM2 name ## index ## _xlate (uaecptr addr) \
389 { \
390 	addr -= name ## _bank[index].start & name ## _bank[index].mask; \
391 	addr &= name ## _bank[index].mask; \
392 	return name ## _bank[index].baseaddr + addr; \
393 }
394 
395 #define MEMORY_ARRAY_FUNCTIONS(name, index) \
396 MEMORY_ARRAY_LGET(name, index); \
397 MEMORY_ARRAY_WGET(name, index); \
398 MEMORY_ARRAY_BGET(name, index); \
399 MEMORY_ARRAY_LPUT(name, index); \
400 MEMORY_ARRAY_WPUT(name, index); \
401 MEMORY_ARRAY_BPUT(name, index); \
402 MEMORY_ARRAY_CHECK(name, index); \
403 MEMORY_ARRAY_XLATE(name, index);
404 
405 #ifndef WINUAE_FOR_HATARI
406 extern addrbank chipmem_bank;
407 extern addrbank chipmem_agnus_bank;
408 extern addrbank chipmem_bank_ce2;
409 extern addrbank kickmem_bank;
410 extern addrbank custom_bank;
411 extern addrbank clock_bank;
412 extern addrbank cia_bank;
413 extern addrbank rtarea_bank;
414 extern addrbank filesys_bank;
415 extern addrbank uaeboard_bank;
416 extern addrbank expamem_bank;
417 extern addrbank expamem_null, expamem_none;
418 extern addrbank fastmem_bank[MAX_RAM_BOARDS];
419 extern addrbank fastmem_nojit_bank[MAX_RAM_BOARDS];
420 extern addrbank *gfxmem_banks[MAX_RTG_BOARDS];
421 extern addrbank gayle_bank;
422 extern addrbank gayle2_bank;
423 extern addrbank mbres_bank;
424 extern addrbank akiko_bank;
425 extern addrbank cardmem_bank;
426 extern addrbank bogomem_bank;
427 extern addrbank z3fastmem_bank[MAX_RAM_BOARDS];
428 extern addrbank z3chipmem_bank;
429 extern addrbank mem25bit_bank;
430 extern addrbank debugmem_bank;
431 extern addrbank a3000lmem_bank;
432 extern addrbank a3000hmem_bank;
433 extern addrbank extendedkickmem_bank;
434 extern addrbank extendedkickmem2_bank;
435 extern addrbank custmem1_bank;
436 extern addrbank custmem2_bank;
437 
438 extern void rtarea_init(void);
439 extern void rtarea_free(void);
440 extern void rtarea_init_mem(void);
441 extern void rtarea_setup(void);
442 extern void expamem_reset (void);
443 extern void expamem_next (addrbank *mapped, addrbank *next);
444 extern void expamem_shutup (addrbank *mapped);
445 extern bool expamem_z3hack(struct uae_prefs*);
446 extern void expansion_cpu_fallback(void);
447 extern void set_expamem_z3_hack_mode(int);
448 extern uaecptr expamem_board_pointer, expamem_highmem_pointer;
449 extern uaecptr expamem_z3_pointer_real, expamem_z3_pointer_uae;
450 extern uae_u32 expamem_z3_highram_real, expamem_z3_highram_uae;
451 extern uae_u32 expamem_board_size;
452 
453 extern uae_u32 last_custom_value1;
454 #endif
455 
456 /* Default memory access functions */
457 
458 extern void dummy_put (uaecptr addr, int size, uae_u32 val);
459 extern uae_u32 dummy_get (uaecptr addr, int size, bool inst, uae_u32 defvalue);
460 extern uae_u32 dummy_get_safe(uaecptr addr, int size, bool inst, uae_u32 defvalue);
461 
462 extern int REGPARAM3 default_check(uaecptr addr, uae_u32 size) REGPARAM;
463 extern uae_u8 *REGPARAM3 default_xlate(uaecptr addr) REGPARAM;
464 /* 680x0 opcode fetches */
465 extern uae_u32 REGPARAM3 dummy_lgeti (uaecptr addr) REGPARAM;
466 extern uae_u32 REGPARAM3 dummy_wgeti (uaecptr addr) REGPARAM;
467 
468 /* sub bank support */
469 extern uae_u32 REGPARAM3 sub_bank_lget (uaecptr) REGPARAM;
470 extern uae_u32 REGPARAM3 sub_bank_wget(uaecptr) REGPARAM;
471 extern uae_u32 REGPARAM3 sub_bank_bget(uaecptr) REGPARAM;
472 extern void REGPARAM3 sub_bank_lput(uaecptr, uae_u32) REGPARAM;
473 extern void REGPARAM3 sub_bank_wput(uaecptr, uae_u32) REGPARAM;
474 extern void REGPARAM3 sub_bank_bput(uaecptr, uae_u32) REGPARAM;
475 extern uae_u32 REGPARAM3 sub_bank_lgeti(uaecptr) REGPARAM;
476 extern uae_u32 REGPARAM3 sub_bank_wgeti(uaecptr) REGPARAM;
477 extern int REGPARAM3 sub_bank_check(uaecptr addr, uae_u32 size) REGPARAM;
478 extern uae_u8 *REGPARAM3 sub_bank_xlate(uaecptr addr) REGPARAM;
479 extern addrbank *get_sub_bank(uaecptr *addr);
480 
481 #define bankindex(addr) (((uaecptr)(addr)) >> 16)
482 
483 extern addrbank *mem_banks[MEMORY_BANKS];
484 
485 #ifdef JIT
486 extern uae_u8 *baseaddr[MEMORY_BANKS];
487 #endif
488 
489 #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
490 extern addrbank *get_mem_bank_real(uaecptr);
491 
492 #ifdef JIT
493 #define put_mem_bank(addr, b, realstart) do { \
494 	(mem_banks[bankindex(addr)] = (b)); \
495 	if ((b)->baseaddr) \
496 		baseaddr[bankindex(addr)] = (b)->baseaddr - (realstart); \
497 	else \
498 		baseaddr[bankindex(addr)] = (uae_u8*)(((uae_u8*)b)+1); \
499 } while (0)
500 #else
501 #define put_mem_bank(addr, b, realstart) \
502 	(mem_banks[bankindex(addr)] = (b));
503 #endif
504 
505 #ifdef WINUAE_FOR_HATARI
506 extern bool memory_region_bus_error ( uaecptr addr );
507 extern void memory_map_Standard_RAM ( Uint32 MMU_Bank0_Size , Uint32 MMU_Bank1_Size );
508 #endif
509 extern void memory_init(uae_u32 NewSTMemSize, uae_u32 NewTTMemSize, uae_u32 NewRomMemStart);
510 extern void memory_uninit (void);
511 extern void map_banks (addrbank *bank, int first, int count, int realsize);
512 extern void map_banks_z2(addrbank *bank, int first, int count);
513 extern uae_u32 map_banks_z2_autosize(addrbank *bank, int first);
514 extern void map_banks_z3(addrbank *bank, int first, int count);
515 extern bool validate_banks_z2(addrbank *bank, int start, int size);
516 extern bool validate_banks_z3(addrbank *bank, int start, int size);
517 extern void map_banks_quick (addrbank *bank, int first, int count, int realsize);
518 extern void map_banks_nojitdirect (addrbank *bank, int first, int count, int realsize);
519 extern void map_banks_cond (addrbank *bank, int first, int count, int realsize);
520 extern void map_overlay (int chip);
521 #ifdef WINUAE_FOR_HATARI
522 extern void map_banks_ce (addrbank *bank, int first, int count, int realsize, int banktype, int cachable);
523 #endif
524 extern void memory_hardreset (void);
525 extern void memory_clear (void);
526 #ifndef WINUAE_FOR_HATARI
527 extern void free_fastmemory (int);
528 extern void set_roms_modified (void);
529 extern void reload_roms(void);
530 extern bool read_kickstart_version(struct uae_prefs *p);
531 extern void chipmem_setindirect(void);
532 #endif
533 
534 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
535 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
536 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
537 #define longgeti(addr) (call_mem_get_func(get_mem_bank(addr).lgeti, addr))
538 #define wordgeti(addr) (call_mem_get_func(get_mem_bank(addr).wgeti, addr))
539 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
540 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
541 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
542 
get_long(uaecptr addr)543 STATIC_INLINE uae_u32 get_long (uaecptr addr)
544 {
545 	return longget (addr);
546 }
get_word(uaecptr addr)547 STATIC_INLINE uae_u32 get_word (uaecptr addr)
548 {
549 	return wordget (addr);
550 }
get_byte(uaecptr addr)551 STATIC_INLINE uae_u32 get_byte (uaecptr addr)
552 {
553 	return byteget (addr);
554 }
get_longi(uaecptr addr)555 STATIC_INLINE uae_u32 get_longi(uaecptr addr)
556 {
557 	return longgeti (addr);
558 }
get_wordi(uaecptr addr)559 STATIC_INLINE uae_u32 get_wordi(uaecptr addr)
560 {
561 	return wordgeti (addr);
562 }
563 
get_long_jit(uaecptr addr)564 STATIC_INLINE uae_u32 get_long_jit(uaecptr addr)
565 {
566 	addrbank *bank = &get_mem_bank(addr);
567 #ifdef JIT
568 	special_mem |= bank->jit_read_flag;
569 #endif
570 	return bank->lget(addr);
571 }
get_word_jit(uaecptr addr)572 STATIC_INLINE uae_u32 get_word_jit(uaecptr addr)
573 {
574 	addrbank *bank = &get_mem_bank(addr);
575 #ifdef JIT
576 	special_mem |= bank->jit_read_flag;
577 #endif
578 	return bank->wget(addr);
579 }
get_byte_jit(uaecptr addr)580 STATIC_INLINE uae_u32 get_byte_jit(uaecptr addr)
581 {
582 	addrbank *bank = &get_mem_bank(addr);
583 #ifdef JIT
584 	special_mem |= bank->jit_read_flag;
585 #endif
586 	return bank->bget(addr);
587 }
get_longi_jit(uaecptr addr)588 STATIC_INLINE uae_u32 get_longi_jit(uaecptr addr)
589 {
590 	addrbank *bank = &get_mem_bank(addr);
591 #ifdef JIT
592 	special_mem |= bank->jit_read_flag;
593 #endif
594 	return bank->lgeti(addr);
595 }
get_wordi_jit(uaecptr addr)596 STATIC_INLINE uae_u32 get_wordi_jit(uaecptr addr)
597 {
598 	addrbank *bank = &get_mem_bank(addr);
599 #ifdef JIT
600 	special_mem |= bank->jit_read_flag;
601 #endif
602 	return bank->wgeti(addr);
603 }
604 
605 /*
606 * Read a host pointer from addr
607 */
608 #if SIZEOF_VOID_P == 4
609 # define get_pointer(addr) ((void *)get_long (addr))
610 #else
611 # if SIZEOF_VOID_P == 8
get_pointer(uaecptr addr)612 STATIC_INLINE void *get_pointer (uaecptr addr)
613 {
614 	const unsigned int n = SIZEOF_VOID_P / 4;
615 	union {
616 		void    *ptr;
617 		uae_u32  longs[SIZEOF_VOID_P / 4];
618 	} p;
619 	unsigned int i;
620 
621 	for (i = 0; i < n; i++) {
622 #ifdef WORDS_BIGENDIAN
623 		p.longs[i]     = get_long (addr + i * 4);
624 #else
625 		p.longs[n - 1 - i] = get_long (addr + i * 4);
626 #endif
627 	}
628 	return p.ptr;
629 }
630 # else
631 #  error "Unknown or unsupported pointer size."
632 # endif
633 #endif
634 
put_long(uaecptr addr,uae_u32 l)635 STATIC_INLINE void put_long (uaecptr addr, uae_u32 l)
636 {
637 	longput(addr, l);
638 }
put_word(uaecptr addr,uae_u32 w)639 STATIC_INLINE void put_word (uaecptr addr, uae_u32 w)
640 {
641 	wordput(addr, w);
642 }
put_byte(uaecptr addr,uae_u32 b)643 STATIC_INLINE void put_byte (uaecptr addr, uae_u32 b)
644 {
645 	byteput(addr, b);
646 }
647 
put_long_jit(uaecptr addr,uae_u32 l)648 STATIC_INLINE void put_long_jit(uaecptr addr, uae_u32 l)
649 {
650 	addrbank *bank = &get_mem_bank(addr);
651 #ifdef JIT
652 	special_mem |= bank->jit_write_flag;
653 #endif
654 	bank->lput(addr, l);
655 }
put_word_jit(uaecptr addr,uae_u32 l)656 STATIC_INLINE void put_word_jit(uaecptr addr, uae_u32 l)
657 {
658 	addrbank *bank = &get_mem_bank(addr);
659 #ifdef JIT
660 	special_mem |= bank->jit_write_flag;
661 #endif
662 	bank->wput(addr, l);
663 }
put_byte_jit(uaecptr addr,uae_u32 l)664 STATIC_INLINE void put_byte_jit(uaecptr addr, uae_u32 l)
665 {
666 	addrbank *bank = &get_mem_bank(addr);
667 #ifdef JIT
668 	special_mem |= bank->jit_write_flag;
669 #endif
670 	bank->bput(addr, l);
671 }
672 
673 /*
674 * Store host pointer v at addr
675 */
676 #if SIZEOF_VOID_P == 4
677 # define put_pointer(addr, p) (put_long ((addr), (uae_u32)(p)))
678 #else
679 # if SIZEOF_VOID_P == 8
put_pointer(uaecptr addr,void * v)680 STATIC_INLINE void put_pointer (uaecptr addr, void *v)
681 {
682 	const unsigned int n = SIZEOF_VOID_P / 4;
683 	union {
684 		void    *ptr;
685 		uae_u32  longs[SIZEOF_VOID_P / 4];
686 	} p;
687 	unsigned int i;
688 
689 	p.ptr = v;
690 
691 	for (i = 0; i < n; i++) {
692 #ifdef WORDS_BIGENDIAN
693 		put_long (addr + i * 4, p.longs[i]);
694 #else
695 		put_long (addr + i * 4, p.longs[n - 1 - i]);
696 #endif
697 	}
698 }
699 # endif
700 #endif
701 
get_real_address(uaecptr addr)702 STATIC_INLINE uae_u8 *get_real_address (uaecptr addr)
703 {
704 	return get_mem_bank (addr).xlateaddr(addr);
705 }
706 
valid_address(uaecptr addr,uae_u32 size)707 STATIC_INLINE int valid_address (uaecptr addr, uae_u32 size)
708 {
709 	return get_mem_bank (addr).check(addr, size);
710 }
711 
put_quad_host(void * addr,uae_u64 v)712 STATIC_INLINE void put_quad_host(void *addr, uae_u64 v)
713 {
714 	do_put_mem_long((uae_u32*)addr, v >> 32);
715 	do_put_mem_long(((uae_u32*)addr) + 1, (uae_u32)v);
716 }
put_long_host(void * addr,uae_u32 v)717 STATIC_INLINE void put_long_host(void *addr, uae_u32 v)
718 {
719 	do_put_mem_long((uae_u32*)addr, v);
720 }
put_word_host(void * addr,uae_u16 v)721 STATIC_INLINE void put_word_host(void *addr, uae_u16 v)
722 {
723 	do_put_mem_word((uae_u16*)addr, v);
724 }
put_byte_host(void * addr,uae_u8 v)725 STATIC_INLINE void put_byte_host(void *addr, uae_u8 v)
726 {
727 	*((uae_u8*)addr) = v;
728 }
get_quad_host(void * addr)729 STATIC_INLINE uae_u64 get_quad_host(void *addr)
730 {
731 	uae_u64 v = ((uae_u64)do_get_mem_long((uae_u32*)addr)) << 32;
732 	v |= do_get_mem_long(((uae_u32*)addr) + 1);
733 	return v;
734 }
get_long_host(void * addr)735 STATIC_INLINE uae_u32 get_long_host(void *addr)
736 {
737 	return do_get_mem_long((uae_u32*)addr);
738 }
get_word_host(void * addr)739 STATIC_INLINE uae_u16 get_word_host(void *addr)
740 {
741 	return do_get_mem_word((uae_u16*)addr);
742 }
get_byte_host(void * addr)743 STATIC_INLINE uae_u32 get_byte_host(void *addr)
744 {
745 	return *((uae_u8*)addr);
746 }
747 
748 extern int addr_valid (const TCHAR*, uaecptr,uae_u32);
749 
750 /* For faster access in custom chip emulation.  */
751 extern void REGPARAM3 chipmem_lput (uaecptr, uae_u32) REGPARAM;
752 extern void REGPARAM3 chipmem_wput (uaecptr, uae_u32) REGPARAM;
753 extern void REGPARAM3 chipmem_bput (uaecptr, uae_u32) REGPARAM;
754 
755 extern uae_u32 REGPARAM3 chipmem_agnus_wget (uaecptr) REGPARAM;
756 extern void REGPARAM3 chipmem_agnus_wput (uaecptr, uae_u32) REGPARAM;
757 
758 extern addrbank dummy_bank;
759 
760 /* 68020+ Chip RAM DMA contention emulation */
761 extern void REGPARAM3 chipmem_bput_c2 (uaecptr, uae_u32) REGPARAM;
762 
763 extern uae_u32 (REGPARAM3 *chipmem_lget_indirect)(uaecptr) REGPARAM;
764 extern uae_u32 (REGPARAM3 *chipmem_wget_indirect)(uaecptr) REGPARAM;
765 extern uae_u32 (REGPARAM3 *chipmem_bget_indirect)(uaecptr) REGPARAM;
766 extern void (REGPARAM3 *chipmem_lput_indirect)(uaecptr, uae_u32) REGPARAM;
767 extern void (REGPARAM3 *chipmem_wput_indirect)(uaecptr, uae_u32) REGPARAM;
768 extern void (REGPARAM3 *chipmem_bput_indirect)(uaecptr, uae_u32) REGPARAM;
769 extern int (REGPARAM3 *chipmem_check_indirect)(uaecptr, uae_u32) REGPARAM;
770 extern uae_u8 *(REGPARAM3 *chipmem_xlate_indirect)(uaecptr) REGPARAM;
771 
772 #ifdef NATMEM_OFFSET
773 
774 typedef struct shmpiece_reg {
775 	uae_u8 *native_address;
776 	int id;
777 	uae_u32 size;
778 	const TCHAR *name;
779 	struct shmpiece_reg *next;
780 	struct shmpiece_reg *prev;
781 } shmpiece;
782 
783 extern shmpiece *shm_start;
784 
785 extern uae_u8* natmem_offset;
786 extern uae_u8 *natmem_reserved;
787 extern uae_u32 natmem_reserved_size;
788 
789 #endif
790 
791 extern bool mapped_malloc (addrbank*);
792 extern void mapped_free (addrbank*);
793 extern void a3000_fakekick (int);
794 
795 extern uaecptr strcpyha_safe (uaecptr dst, const uae_char *src);
796 extern uae_char *strcpyah_safe (uae_char *dst, uaecptr src, int maxsize);
797 extern void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size);
798 extern void memcpyha (uaecptr dst, const uae_u8 *src, int size);
799 extern void memcpyah_safe (uae_u8 *dst, uaecptr src, int size);
800 extern void memcpyah (uae_u8 *dst, uaecptr src, int size);
801 
802 #define UAE_MEMORY_REGIONS_MAX 64
803 #define UAE_MEMORY_REGION_NAME_LENGTH 64
804 
805 #define UAE_MEMORY_REGION_RAM (1 << 0)
806 #define UAE_MEMORY_REGION_ALIAS (1 << 1)
807 #define UAE_MEMORY_REGION_MIRROR (1 << 2)
808 
809 /* Get a list of memory regions in the Amiga address space */
810 
811 typedef struct UaeMemoryRegion {
812 	uaecptr start;
813 	uae_u32 size;
814 	TCHAR name[UAE_MEMORY_REGION_NAME_LENGTH];
815 	TCHAR rom_name[UAE_MEMORY_REGION_NAME_LENGTH];
816 	uaecptr alias;
817 	int flags;
818 	uae_u8 *memory;
819 } UaeMemoryRegion;
820 
821 typedef struct UaeMemoryMap {
822 	UaeMemoryRegion regions[UAE_MEMORY_REGIONS_MAX];
823 	int num_regions;
824 } UaeMemoryMap;
825 
826 void uae_memory_map(UaeMemoryMap *map);
827 
828 #endif /* UAE_MEMORY_H */
829