1  /*
2   * UAE - The Un*x Amiga Emulator
3   *
4   * memory management
5   *
6   * Copyright 1995 Bernd Schmidt
7   *
8   * Adaptation to Hatari by Thomas Huth
9   *
10   * This file is distributed under the GNU General Public License, version 2
11   * or at your option any later version. Read the file gpl.txt for details.
12   */
13 
14 #ifndef UAE_MEMORY_H
15 #define UAE_MEMORY_H
16 
17 #include "maccess.h"
18 
19 #ifdef JIT
20 extern int special_mem;
21 #define S_READ 1
22 #define S_WRITE 2
23 
24 extern uae_u8 *cache_alloc (int);
25 extern void cache_free (uae_u8*);
26 #endif
27 
28 #define call_mem_get_func(func, addr) ((*func)(addr))
29 #define call_mem_put_func(func, addr, v) ((*func)(addr, v))
30 
31 
32 /* Enabling this adds one additional native memory reference per 68k memory
33  * access, but saves one shift (on the x86). Enabling this is probably
34  * better for the cache. My favourite benchmark (PP2) doesn't show a
35  * difference, so I leave this enabled. */
36 #if 1 || defined SAVE_MEMORY
37 #define SAVE_MEMORY_BANKS
38 #endif
39 
40 extern void memory_hardreset (void);
41 
42 typedef uae_u32 (*mem_get_func)(uaecptr) REGPARAM;
43 typedef void (*mem_put_func)(uaecptr, uae_u32) REGPARAM;
44 typedef uae_u8 *(*xlate_func)(uaecptr) REGPARAM;
45 typedef int (*check_func)(uaecptr, uae_u32) REGPARAM;
46 
47 extern char *address_space, *good_address_map;
48 
49 enum { ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8, ABFLAG_NONE = 16, ABFLAG_SAFE = 32 };
50 typedef struct {
51 	/* These ones should be self-explanatory... */
52 	mem_get_func lget, wget, bget;
53 	mem_put_func lput, wput, bput;
54 	/* Use xlateaddr to translate an Amiga address to a uae_u8 * that can
55 	* be used to address memory without calling the wget/wput functions.
56 	* This doesn't work for all memory banks, so this function may call
57 	* abort(). */
58 	xlate_func xlateaddr;
59 	/* To prevent calls to abort(), use check before calling xlateaddr.
60 	* It checks not only that the memory bank can do xlateaddr, but also
61 	* that the pointer points to an area of at least the specified size.
62 	* This is used for example to translate bitplane pointers in custom.c */
63 	check_func check;
64 	/* For those banks that refer to real memory, we can save the whole trouble
65 	of going through function calls, and instead simply grab the memory
66 	ourselves. This holds the memory address where the start of memory is
67 	for this particular bank. */
68 	uae_u8 *baseaddr;
69 	const TCHAR *name;
70 	/* for instruction opcode/operand fetches */
71 	mem_get_func lgeti, wgeti;
72 	int flags;
73 } addrbank;
74 
75 #define CE_MEMBANK_FAST 0
76 #define CE_MEMBANK_CHIP 1
77 #define CE_MEMBANK_CIA 2
78 #define CE_MEMBANK_FAST16BIT 3
79 extern uae_u8 ce_banktype[65536], ce_cachable[65536];
80 
81 
82 #define bankindex(addr) (((uaecptr)(addr)) >> 16)
83 
84 #ifdef SAVE_MEMORY_BANKS
85 extern addrbank *mem_banks[65536];
86 #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
87 #define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = (b))
88 #else
89 extern addrbank mem_banks[65536];
90 #define get_mem_bank(addr) (mem_banks[bankindex(addr)])
91 #define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = *(b))
92 #endif
93 
94 extern void memory_init(uae_u32 nNewSTMemSize, uae_u32 nNewTTMemSize, uae_u32 nNewRomMemStart);
95 extern void memory_uninit (void);
96 extern void map_banks(addrbank *bank, int first, int count);
97 
98 #ifndef NO_INLINE_MEMORY_ACCESS
99 
100 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
101 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
102 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
103 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
104 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
105 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
106 
107 #else
108 
109 extern uae_u32 alongget(uaecptr addr);
110 extern uae_u32 awordget(uaecptr addr);
111 extern uae_u32 longget(uaecptr addr);
112 extern uae_u32 wordget(uaecptr addr);
113 extern uae_u32 byteget(uaecptr addr);
114 extern void longput(uaecptr addr, uae_u32 l);
115 extern void wordput(uaecptr addr, uae_u32 w);
116 extern void byteput(uaecptr addr, uae_u32 b);
117 
118 #endif
119 
120 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
121 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
122 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
123 #define longgeti(addr) (call_mem_get_func(get_mem_bank(addr).lgeti, addr))
124 #define wordgeti(addr) (call_mem_get_func(get_mem_bank(addr).wgeti, addr))
125 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
126 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
127 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
128 
get_long(uaecptr addr)129 static inline uae_u32 get_long(uaecptr addr)
130 {
131     return longget(addr);
132 }
133 
get_word(uaecptr addr)134 static inline uae_u32 get_word(uaecptr addr)
135 {
136     return wordget(addr);
137 }
138 
get_byte(uaecptr addr)139 static inline uae_u32 get_byte(uaecptr addr)
140 {
141     return byteget(addr);
142 }
143 
put_long(uaecptr addr,uae_u32 l)144 static inline void put_long(uaecptr addr, uae_u32 l)
145 {
146     longput(addr, l);
147 }
148 
put_word(uaecptr addr,uae_u32 w)149 static inline void put_word(uaecptr addr, uae_u32 w)
150 {
151     wordput(addr, w);
152 }
153 
put_byte(uaecptr addr,uae_u32 b)154 static inline void put_byte(uaecptr addr, uae_u32 b)
155 {
156     byteput(addr, b);
157 }
158 
get_real_address(uaecptr addr)159 static inline uae_u8 *get_real_address(uaecptr addr)
160 {
161     return get_mem_bank(addr).xlateaddr(addr);
162 }
163 
valid_address(uaecptr addr,uae_u32 size)164 static inline int valid_address(uaecptr addr, uae_u32 size)
165 {
166     return get_mem_bank(addr).check(addr, size);
167 }
168 
get_longi(uaecptr addr)169 static inline uae_u32 get_longi(uaecptr addr)
170 {
171 	return longgeti (addr);
172 }
173 
get_wordi(uaecptr addr)174 static inline uae_u32 get_wordi(uaecptr addr)
175 {
176 	return wordgeti (addr);
177 }
178 
179 #endif /* UAE_MEMORY_H */
180