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