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 enum
41 {
42 ABFLAG_UNK = 0, ABFLAG_RAM = 1, ABFLAG_ROM = 2, ABFLAG_ROMIN = 4, ABFLAG_IO = 8,
43 ABFLAG_NONE = 16, ABFLAG_SAFE = 32, ABFLAG_INDIRECT = 64, ABFLAG_NOALLOC = 128,
44 ABFLAG_RTG = 256, ABFLAG_THREADSAFE = 512, ABFLAG_DIRECTMAP = 1024
45 };
46 typedef struct {
47 /* These ones should be self-explanatory... */
48 mem_get_func lget, wget, bget;
49 mem_put_func lput, wput, bput;
50 /* Use xlateaddr to translate an Atari address to a uae_u8 * that can
51 * be used to address memory without calling the wget/wput functions.
52 * This doesn't work for all memory banks, so this function may call
53 * abort(). */
54 xlate_func xlateaddr;
55 /* To prevent calls to abort(), use check before calling xlateaddr.
56 * It checks not only that the memory bank can do xlateaddr, but also
57 * that the pointer points to an area of at least the specified size.
58 * This is used for example to translate bitplane pointers in custom.c */
59 check_func check;
60 /* For those banks that refer to real memory, we can save the whole trouble
61 of going through function calls, and instead simply grab the memory
62 ourselves. This holds the memory address where the start of memory is
63 for this particular bank. */
64 uae_u8 *baseaddr;
65 int flags;
66 uae_u32 mask;
67 uae_u32 start;
68 } addrbank;
69
70
71 #define bankindex(addr) (((uaecptr)(addr)) >> 16)
72
73 #ifdef SAVE_MEMORY_BANKS
74 extern addrbank *mem_banks[65536];
75 #define get_mem_bank(addr) (*mem_banks[bankindex(addr)])
76 #define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = (b))
77 #else
78 extern addrbank mem_banks[65536];
79 #define get_mem_bank(addr) (mem_banks[bankindex(addr)])
80 #define put_mem_bank(addr, b) (mem_banks[bankindex(addr)] = *(b))
81 #endif
82
83 extern bool memory_region_bus_error ( uaecptr addr );
84 extern void memory_map_Standard_RAM ( Uint32 MMU_Bank0_Size , Uint32 MMU_Bank1_Size );
85 extern void memory_init(uae_u32 nNewSTMemSize, uae_u32 nNewTTMemSize, uae_u32 nNewRomMemStart);
86 extern void memory_uninit (void);
87 extern void map_banks(addrbank *bank, int first, int count);
88
89 #ifndef NO_INLINE_MEMORY_ACCESS
90
91 #define longget(addr) (call_mem_get_func(get_mem_bank(addr).lget, addr))
92 #define wordget(addr) (call_mem_get_func(get_mem_bank(addr).wget, addr))
93 #define byteget(addr) (call_mem_get_func(get_mem_bank(addr).bget, addr))
94 #define longput(addr,l) (call_mem_put_func(get_mem_bank(addr).lput, addr, l))
95 #define wordput(addr,w) (call_mem_put_func(get_mem_bank(addr).wput, addr, w))
96 #define byteput(addr,b) (call_mem_put_func(get_mem_bank(addr).bput, addr, b))
97
98 #else
99
100 extern uae_u32 alongget(uaecptr addr);
101 extern uae_u32 awordget(uaecptr addr);
102 extern uae_u32 longget(uaecptr addr);
103 extern uae_u32 wordget(uaecptr addr);
104 extern uae_u32 byteget(uaecptr addr);
105 extern void longput(uaecptr addr, uae_u32 l);
106 extern void wordput(uaecptr addr, uae_u32 w);
107 extern void byteput(uaecptr addr, uae_u32 b);
108
109 #endif
110
111
get_long(uaecptr addr)112 static inline uae_u32 get_long(uaecptr addr)
113 {
114 return longget(addr);
115 }
116
get_word(uaecptr addr)117 static inline uae_u32 get_word(uaecptr addr)
118 {
119 return wordget(addr);
120 }
121
get_byte(uaecptr addr)122 static inline uae_u32 get_byte(uaecptr addr)
123 {
124 return byteget(addr);
125 }
126
put_long(uaecptr addr,uae_u32 l)127 static inline void put_long(uaecptr addr, uae_u32 l)
128 {
129 longput(addr, l);
130 }
131
put_word(uaecptr addr,uae_u32 w)132 static inline void put_word(uaecptr addr, uae_u32 w)
133 {
134 wordput(addr, w);
135 }
136
put_byte(uaecptr addr,uae_u32 b)137 static inline void put_byte(uaecptr addr, uae_u32 b)
138 {
139 byteput(addr, b);
140 }
141
get_real_address(uaecptr addr)142 static inline uae_u8 *get_real_address(uaecptr addr)
143 {
144 return get_mem_bank(addr).xlateaddr(addr);
145 }
146
valid_address(uaecptr addr,uae_u32 size)147 static inline int valid_address(uaecptr addr, uae_u32 size)
148 {
149 return get_mem_bank(addr).check(addr, size);
150 }
151
152
153 #endif /* UAE_MEMORY_H */
154