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