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 #define call_mem_get_func(func, addr) ((*func)(addr))
20 #define call_mem_put_func(func, addr, v) ((*func)(addr, v))
21
22
23 /* Enabling this adds one additional native memory reference per 68k memory
24 * access, but saves one shift (on the x86). Enabling this is probably
25 * better for the cache. My favourite benchmark (PP2) doesn't show a
26 * difference, so I leave this enabled. */
27 #if 1 || defined SAVE_MEMORY
28 #define SAVE_MEMORY_BANKS
29 #endif
30
31
32 typedef uae_u32 (*mem_get_func)(uaecptr) REGPARAM;
33 typedef void (*mem_put_func)(uaecptr, uae_u32) REGPARAM;
34 typedef uae_u8 *(*xlate_func)(uaecptr) REGPARAM;
35 typedef int (*check_func)(uaecptr, uae_u32) REGPARAM;
36
37 extern char *address_space, *good_address_map;
38
39
40 typedef struct {
41 /* These ones should be self-explanatory... */
42 mem_get_func lget, wget, bget;
43 mem_put_func lput, wput, bput;
44 /* Use xlateaddr to translate an Atari address to a uae_u8 * that can
45 * be used to address memory without calling the wget/wput functions.
46 * This doesn't work for all memory banks, so this function may call
47 * abort(). */
48 xlate_func xlateaddr;
49 /* To prevent calls to abort(), use check before calling xlateaddr.
50 * It checks not only that the memory bank can do xlateaddr, but also
51 * that the pointer points to an area of at least the specified size.
52 * This is used for example to translate bitplane pointers in custom.c */
53 check_func check;
54 } addrbank;
55
56
57 #define bankindex(addr) (((uaecptr)(addr)) >> 16)
58
59 #ifdef SAVE_MEMORY_BANKS
60 extern addrbank *mem_banks[65536];
61 #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
62 #define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = (b))
63 #else
64 extern addrbank mem_banks[65536];
65 #define get_mem_bank(addr) (mem_banks[bankindex(addr)])
66 #define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = *(b))
67 #endif
68
69 extern void memory_init(uae_u32 nNewSTMemSize, uae_u32 nNewTTMemSize, uae_u32 nNewRomMemStart);
70 extern void memory_uninit (void);
71 extern void map_banks(addrbank *bank, int first, int count);
72
73 #ifndef NO_INLINE_MEMORY_ACCESS
74
75 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
76 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
77 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
78 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
79 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
80 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
81
82 #else
83
84 extern uae_u32 alongget(uaecptr addr);
85 extern uae_u32 awordget(uaecptr addr);
86 extern uae_u32 longget(uaecptr addr);
87 extern uae_u32 wordget(uaecptr addr);
88 extern uae_u32 byteget(uaecptr addr);
89 extern void longput(uaecptr addr, uae_u32 l);
90 extern void wordput(uaecptr addr, uae_u32 w);
91 extern void byteput(uaecptr addr, uae_u32 b);
92
93 #endif
94
95
get_long(uaecptr addr)96 static inline uae_u32 get_long(uaecptr addr)
97 {
98 return longget(addr);
99 }
100
get_word(uaecptr addr)101 static inline uae_u32 get_word(uaecptr addr)
102 {
103 return wordget(addr);
104 }
105
get_byte(uaecptr addr)106 static inline uae_u32 get_byte(uaecptr addr)
107 {
108 return byteget(addr);
109 }
110
put_long(uaecptr addr,uae_u32 l)111 static inline void put_long(uaecptr addr, uae_u32 l)
112 {
113 longput(addr, l);
114 }
115
put_word(uaecptr addr,uae_u32 w)116 static inline void put_word(uaecptr addr, uae_u32 w)
117 {
118 wordput(addr, w);
119 }
120
put_byte(uaecptr addr,uae_u32 b)121 static inline void put_byte(uaecptr addr, uae_u32 b)
122 {
123 byteput(addr, b);
124 }
125
get_real_address(uaecptr addr)126 static inline uae_u8 *get_real_address(uaecptr addr)
127 {
128 return get_mem_bank(addr).xlateaddr(addr);
129 }
130
valid_address(uaecptr addr,uae_u32 size)131 static inline int valid_address(uaecptr addr, uae_u32 size)
132 {
133 return get_mem_bank(addr).check(addr, size);
134 }
135
136
137 #endif /* UAE_MEMORY_H */
138