1 /*
2 * memory.h - memory management
3 *
4 * Copyright (c) 2001-2006 Milan Jurik of ARAnyM dev team (see AUTHORS)
5 *
6 * Inspired by Christian Bauer's Basilisk II
7 *
8 * This file is part of the ARAnyM project which builds a new and powerful
9 * TOS/FreeMiNT compatible virtual machine running on almost any hardware.
10 *
11 * ARAnyM is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * ARAnyM is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ARAnyM; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25 /*
26 * UAE - The Un*x Amiga Emulator
27 *
28 * memory management
29 *
30 * Copyright 1995 Bernd Schmidt
31 */
32
33 #ifndef UAE_MEMORY_H
34 #define UAE_MEMORY_H
35
36 #include "sysdeps.h"
37 #include "string.h"
38 #include "hardware.h"
39 #include "parameters.h"
40 #include "registers.h"
41 #include "cpummu.h"
42 #include "readcpu.h"
43
44 # include <csetjmp>
45
46 // newcpu.h
47 extern void Exception (int, uaecptr);
48 #ifdef EXCEPTIONS_VIA_LONGJMP
49 extern JMP_BUF excep_env;
50 #define SAVE_EXCEPTION \
51 JMP_BUF excep_env_old; \
52 memcpy(excep_env_old, excep_env, sizeof(JMP_BUF))
53 #define RESTORE_EXCEPTION \
54 memcpy(excep_env, excep_env_old, sizeof(JMP_BUF))
55 #define TRY(var) int var = SETJMP(excep_env); if (!var)
56 #define CATCH(var) else
57 #define THROW(n) LONGJMP(excep_env, n)
58 #define THROW_AGAIN(var) LONGJMP(excep_env, var)
59 #define VOLATILE volatile
60 #else
61 struct m68k_exception {
62 int prb;
m68k_exceptionm68k_exception63 m68k_exception (int exc) : prb (exc) {}
64 operator int() { return prb; }
65 };
66 #define SAVE_EXCEPTION
67 #define RESTORE_EXCEPTION
68 #define TRY(var) try
69 #define CATCH(var) catch(m68k_exception var)
70 #define THROW(n) throw m68k_exception(n)
71 #define THROW_AGAIN(var) throw
72 #define VOLATILE
73 #endif /* EXCEPTIONS_VIA_LONGJMP */
74 extern int in_exception_2;
75
76 #define STRAM_END 0x0e00000UL // should be replaced by global ROMBase as soon as ROMBase will be a constant
77 #define ROM_END 0x0e80000UL // should be replaced by ROMBase + RealROMSize if we are going to work with larger TOS ROMs than 512 kilobytes
78 #define FastRAM_BEGIN 0x1000000UL // should be replaced by global FastRAMBase as soon as FastRAMBase will be a constant
79 #ifdef FixedSizeFastRAM
80 #define FastRAM_SIZE (FixedSizeFastRAM * 1024 * 1024)
81 #else
82 #define FastRAM_SIZE FastRAMSize
83 #endif
84
85 #ifdef FIXED_VIDEORAM
86 #define ARANYMVRAMSTART 0xf0000000UL
87 #endif
88
89 #define ARANYMVRAMSIZE 0x00100000 // should be a variable to protect VGA card offscreen memory
90
91 #ifdef FIXED_VIDEORAM
92 extern uintptr VMEMBaseDiff;
93 #else
94 extern uae_u32 VideoRAMBase;
95 #endif
96
97 #ifdef ARAM_PAGE_CHECK
98 extern uaecptr pc_page, read_page, write_page;
99 extern uintptr pc_offset, read_offset, write_offset;
100 # ifdef PROTECT2K
101 # define ARAM_PAGE_MASK 0x7ff
102 # else
103 # ifdef FULLMMU
104 # define ARAM_PAGE_MASK 0xfff
105 # else
106 # define ARAM_PAGE_MASK 0xfffff
107 # endif
108 # endif
109 #endif
110
111 extern uintptr MEMBaseDiff;
112 extern uintptr ROMBaseDiff;
113 extern uintptr FastRAMBaseDiff;
114 # define InitMEMBaseDiff(va, ra) (MEMBaseDiff = (uintptr)(va) - (uintptr)(ra))
115 # define InitROMBaseDiff(va, ra) (ROMBaseDiff = (uintptr)(va) - (uintptr)(ra))
116 # define InitFastRAMBaseDiff(va, ra) (FastRAMBaseDiff = (uintptr)(va) - (uintptr)(ra))
117
118 #ifdef FIXED_VIDEORAM
119 #define InitVMEMBaseDiff(va, ra) (VMEMBaseDiff = (uintptr)(va) - (uintptr)(ra))
120 #else
121 #define InitVMEMBaseDiff(va, ra) (ra = (uintptr)(va) + MEMBaseDiff)
122 #endif
123
124 extern "C" void breakpt(void);
125
126
do_get_mem_quad(uae_u64 * a)127 static inline uae_u64 do_get_mem_quad(uae_u64 *a) {return SDL_SwapBE64(*a);}
do_put_mem_quad(uae_u64 * a,uae_u64 v)128 static inline void do_put_mem_quad(uae_u64 *a, uae_u64 v) {*a = SDL_SwapBE64(v);}
129
130
131 #ifndef NOCHECKBOUNDARY
test_ram_boundary(uaecptr addr,int size,bool super,bool write)132 static ALWAYS_INLINE bool test_ram_boundary(uaecptr addr, int size, bool super, bool write)
133 {
134 if (addr <= (FastRAM_BEGIN + FastRAM_SIZE - size)) {
135 #ifdef PROTECT2K
136 // protect first 2kB of RAM - access in supervisor mode only
137 if (!super && addr < 0x00000800UL)
138 return false;
139 #endif
140 // check for write access to protected areas:
141 // - first two longwords of ST-RAM are non-writable (ROM shadow)
142 // - non-writable area between end of ST-RAM and begin of FastRAM
143 if (!write || addr >= FastRAM_BEGIN || (addr >= 8 && addr <= (STRAM_END - size)))
144 return true;
145 }
146 #ifdef FIXED_VIDEORAM
147 return addr >= ARANYMVRAMSTART && addr <= (ARANYMVRAMSTART + ARANYMVRAMSIZE - size);
148 #else
149 return addr >= VideoRAMBase && addr <= (VideoRAMBase + ARANYMVRAMSIZE - size);
150 #endif
151 }
152 /*
153 * "size" is the size of the memory access (byte = 1, word = 2, long = 4)
154 */
check_ram_boundary(uaecptr addr,int size,bool write)155 static ALWAYS_INLINE void check_ram_boundary(uaecptr addr, int size, bool write)
156 {
157 if (test_ram_boundary(addr, size, regs.s, write))
158 return;
159
160 // D(bug("BUS ERROR %s at $%x\n", (write ? "writing" : "reading"), addr));
161 regs.mmu_fault_addr = addr;
162 regs.mmu_ssw = ((size & 3) << 5) | (write ? 0 : (1 << 8));
163 breakpt();
164 THROW(2);
165 }
166
167 #else
test_ram_boundary(uaecptr,int,bool,bool)168 static inline bool test_ram_boundary(uaecptr, int, bool, bool) { return 1; }
check_ram_boundary(uaecptr,int,bool)169 static inline void check_ram_boundary(uaecptr, int, bool) { }
170 #endif
171
172 #ifdef FIXED_VIDEORAM
173 # define do_get_real_address(a) ((uae_u8 *)(((uaecptr)(a) < ARANYMVRAMSTART) ? ((uaecptr)(a) + MEMBaseDiff) : ((uaecptr)(a) + VMEMBaseDiff)))
174 #else
175 # define do_get_real_address(a) ((uae_u8 *)((uintptr)(a) + MEMBaseDiff))
176 #endif
177
phys_get_real_address(uaecptr addr)178 static inline uae_u8 *phys_get_real_address(uaecptr addr)
179 {
180 return do_get_real_address(addr);
181 }
182
183 #ifndef NOCHECKBOUNDARY
phys_valid_address(uaecptr addr,bool write,int sz)184 static inline bool phys_valid_address(uaecptr addr, bool write, int sz)
185 {
186 return test_ram_boundary(addr, sz, regs.s, write);
187 }
188 #else
phys_valid_address(uaecptr,bool,int)189 static inline bool phys_valid_address(uaecptr, bool, int) { return true; }
190 #endif
191
phys_get_quad(uaecptr addr)192 static inline uae_u64 phys_get_quad(uaecptr addr)
193 {
194 #ifdef ARAM_PAGE_CHECK
195 if (((addr ^ read_page) <= ARAM_PAGE_MASK))
196 return do_get_mem_quad((uae_u64*)(addr + read_offset));
197 #endif
198 #ifndef HW_SIGSEGV
199 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
200 if ((addr & 0xfff00000) == 0x00f00000) return HWget_l(addr); /* TODO: must be HWget_q */
201 #endif
202 check_ram_boundary(addr, 8, false);
203 uae_u64 * const m = (uae_u64 *)phys_get_real_address(addr);
204 #ifdef ARAM_PAGE_CHECK
205 read_page = addr;
206 read_offset = (uintptr)m - (uintptr)addr;
207 #endif
208 return do_get_mem_quad(m);
209 }
210
phys_get_long(uaecptr addr)211 static inline uae_u32 phys_get_long(uaecptr addr)
212 {
213 #ifdef ARAM_PAGE_CHECK
214 if (((addr ^ read_page) <= ARAM_PAGE_MASK))
215 return do_get_mem_long((uae_u32*)(addr + read_offset));
216 #endif
217 #ifndef HW_SIGSEGV
218 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
219 if ((addr & 0xfff00000) == 0x00f00000) return HWget_l(addr);
220 #endif
221 check_ram_boundary(addr, 4, false);
222 uae_u32 * const m = (uae_u32 *)phys_get_real_address(addr);
223 #ifdef ARAM_PAGE_CHECK
224 read_page = addr;
225 read_offset = (uintptr)m - (uintptr)addr;
226 #endif
227 return do_get_mem_long(m);
228 }
229
phys_get_word(uaecptr addr)230 static inline uae_u32 phys_get_word(uaecptr addr)
231 {
232 #ifdef ARAM_PAGE_CHECK
233 if (((addr ^ read_page) <= ARAM_PAGE_MASK))
234 return do_get_mem_word((uae_u16*)(addr + read_offset));
235 #endif
236 #ifndef HW_SIGSEGV
237 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
238 if ((addr & 0xfff00000) == 0x00f00000) return HWget_w(addr);
239 #endif
240 check_ram_boundary(addr, 2, false);
241 uae_u16 * const m = (uae_u16 *)phys_get_real_address(addr);
242 #ifdef ARAM_PAGE_CHECK
243 read_page = addr;
244 read_offset = (uintptr)m - (uintptr)addr;
245 #endif
246 return do_get_mem_word(m);
247 }
248
phys_get_byte(uaecptr addr)249 static inline uae_u32 phys_get_byte(uaecptr addr)
250 {
251 #ifdef ARAM_PAGE_CHECK
252 if (((addr ^ read_page) <= ARAM_PAGE_MASK))
253 return do_get_mem_byte((uae_u8*)(addr + read_offset));
254 #endif
255 #ifndef HW_SIGSEGV
256 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
257 if ((addr & 0xfff00000) == 0x00f00000) return HWget_b(addr);
258 #endif
259 check_ram_boundary(addr, 1, false);
260 uae_u8 * const m = (uae_u8 *)phys_get_real_address(addr);
261 #ifdef ARAM_PAGE_CHECK
262 read_page = addr;
263 read_offset = (uintptr)m - (uintptr)addr;
264 #endif
265 return do_get_mem_byte(m);
266 }
267
phys_put_quad(uaecptr addr,uae_u64 l)268 static inline void phys_put_quad(uaecptr addr, uae_u64 l)
269 {
270 #ifdef ARAM_PAGE_CHECK
271 if (((addr ^ write_page) <= ARAM_PAGE_MASK)) {
272 do_put_mem_quad((uae_u64*)(addr + write_offset), l);
273 return;
274 }
275 #endif
276 #ifndef HW_SIGSEGV
277 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
278 if ((addr & 0xfff00000) == 0x00f00000) {
279 HWput_l(addr, l); /* TODO: must be HWput_q */
280 return;
281 }
282 #endif
283 check_ram_boundary(addr, 8, true);
284 uae_u64 * const m = (uae_u64 *)phys_get_real_address(addr);
285 #ifdef ARAM_PAGE_CHECK
286 write_page = addr;
287 write_offset = (uintptr)m - (uintptr)addr;
288 #endif
289 do_put_mem_quad(m, l);
290 }
291
phys_put_long(uaecptr addr,uae_u32 l)292 static inline void phys_put_long(uaecptr addr, uae_u32 l)
293 {
294 #ifdef ARAM_PAGE_CHECK
295 if (((addr ^ write_page) <= ARAM_PAGE_MASK)) {
296 do_put_mem_long((uae_u32*)(addr + write_offset), l);
297 return;
298 }
299 #endif
300 #ifndef HW_SIGSEGV
301 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
302 if ((addr & 0xfff00000) == 0x00f00000) {
303 HWput_l(addr, l);
304 return;
305 }
306 #endif
307 check_ram_boundary(addr, 4, true);
308 uae_u32 * const m = (uae_u32 *)phys_get_real_address(addr);
309 #ifdef ARAM_PAGE_CHECK
310 write_page = addr;
311 write_offset = (uintptr)m - (uintptr)addr;
312 #endif
313 do_put_mem_long(m, l);
314 }
315
phys_put_word(uaecptr addr,uae_u32 w)316 static inline void phys_put_word(uaecptr addr, uae_u32 w)
317 {
318 #ifdef ARAM_PAGE_CHECK
319 if (((addr ^ write_page) <= ARAM_PAGE_MASK)) {
320 do_put_mem_word((uae_u16*)(addr + write_offset), w);
321 return;
322 }
323 #endif
324 #ifndef HW_SIGSEGV
325 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
326 if ((addr & 0xfff00000) == 0x00f00000) {
327 HWput_w(addr, w);
328 return;
329 }
330 #endif
331 check_ram_boundary(addr, 2, true);
332 uae_u16 * const m = (uae_u16 *)phys_get_real_address(addr);
333 #ifdef ARAM_PAGE_CHECK
334 write_page = addr;
335 write_offset = (uintptr)m - (uintptr)addr;
336 #endif
337 do_put_mem_word(m, w);
338 }
339
phys_put_byte(uaecptr addr,uae_u32 b)340 static inline void phys_put_byte(uaecptr addr, uae_u32 b)
341 {
342 #ifdef ARAM_PAGE_CHECK
343 if (((addr ^ write_page) <= ARAM_PAGE_MASK)) {
344 do_put_mem_byte((uae_u8*)(addr + write_offset), b);
345 return;
346 }
347 #endif
348 #ifndef HW_SIGSEGV
349 addr = addr < 0xff000000 ? addr : addr & 0x00ffffff;
350 if ((addr & 0xfff00000) == 0x00f00000) {
351 HWput_b(addr, b);
352 return;
353 }
354 #endif
355 check_ram_boundary(addr, 1, true);
356 uae_u8 * const m = (uae_u8 *)phys_get_real_address(addr);
357 #ifdef ARAM_PAGE_CHECK
358 write_page = addr;
359 write_offset = (uintptr)m - (uintptr)addr;
360 #endif
361 do_put_mem_byte(m, b);
362 }
363
364 #ifdef FULLMMU
is_unaligned(uaecptr addr,int size)365 static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size)
366 {
367 return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & 0x1000);
368 }
369
mmu_get_real_address(uaecptr addr,struct mmu_atc_line * cl)370 static ALWAYS_INLINE uae_u8 *mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
371 {
372 return do_get_real_address(cl->phys + addr);
373 }
374
mmu_get_quad(uaecptr addr,int data)375 static ALWAYS_INLINE uae_u32 mmu_get_quad(uaecptr addr, int data)
376 {
377 struct mmu_atc_line *cl;
378
379 if (likely(mmu_lookup(addr, data, 0, &cl)))
380 return do_get_mem_quad((uae_u64 *)mmu_get_real_address(addr, cl));
381 return mmu_get_quad_slow(addr, regs.s, data, cl);
382 }
383
get_quad(uaecptr addr)384 static ALWAYS_INLINE uae_u64 get_quad(uaecptr addr)
385 {
386 return mmu_get_quad(addr, 1);
387 }
388
mmu_get_long(uaecptr addr,int data,int size)389 static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, int data, int size)
390 {
391 struct mmu_atc_line *cl;
392
393 if (likely(mmu_lookup(addr, data, 0, &cl)))
394 return do_get_mem_long((uae_u32 *)mmu_get_real_address(addr, cl));
395 return mmu_get_long_slow(addr, regs.s, data, size, cl);
396 }
397
get_long(uaecptr addr)398 static ALWAYS_INLINE uae_u32 get_long(uaecptr addr)
399 {
400 if (unlikely(is_unaligned(addr, 4)))
401 return mmu_get_long_unaligned(addr, 1);
402 return mmu_get_long(addr, 1, sz_long);
403 }
404
mmu_get_word(uaecptr addr,int data,int size)405 static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, int data, int size)
406 {
407 struct mmu_atc_line *cl;
408
409 if (likely(mmu_lookup(addr, data, 0, &cl)))
410 return do_get_mem_word((uae_u16 *)mmu_get_real_address(addr, cl));
411 return mmu_get_word_slow(addr, regs.s, data, size, cl);
412 }
413
get_word(uaecptr addr)414 static ALWAYS_INLINE uae_u16 get_word(uaecptr addr)
415 {
416 if (unlikely(is_unaligned(addr, 2)))
417 return mmu_get_word_unaligned(addr, 1);
418 return mmu_get_word(addr, 1, sz_word);
419 }
420
mmu_get_byte(uaecptr addr,int data,int size)421 static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, int data, int size)
422 {
423 struct mmu_atc_line *cl;
424
425 if (likely(mmu_lookup(addr, data, 0, &cl)))
426 return do_get_mem_byte((uae_u8 *)mmu_get_real_address(addr, cl));
427 return mmu_get_byte_slow(addr, regs.s, data, size, cl);
428 }
429
get_byte(uaecptr addr)430 static ALWAYS_INLINE uae_u8 get_byte(uaecptr addr)
431 {
432 return mmu_get_byte(addr, 1, sz_byte);
433 }
434
mmu_put_quad(uaecptr addr,uae_u64 val,int data)435 static ALWAYS_INLINE void mmu_put_quad(uaecptr addr, uae_u64 val, int data)
436 {
437 struct mmu_atc_line *cl;
438
439 if (likely(mmu_lookup(addr, data, 1, &cl)))
440 do_put_mem_quad((uae_u64 *)mmu_get_real_address(addr, cl), val);
441 else
442 mmu_put_quad_slow(addr, val, regs.s, data, cl);
443 }
444
put_quad(uaecptr addr,uae_u32 val)445 static ALWAYS_INLINE void put_quad(uaecptr addr, uae_u32 val)
446 {
447 mmu_put_quad(addr, val, 1);
448 }
449
mmu_put_long(uaecptr addr,uae_u32 val,int data,int size)450 static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, int data, int size)
451 {
452 struct mmu_atc_line *cl;
453
454 if (likely(mmu_lookup(addr, data, 1, &cl)))
455 do_put_mem_long((uae_u32 *)mmu_get_real_address(addr, cl), val);
456 else
457 mmu_put_long_slow(addr, val, regs.s, data, size, cl);
458 }
459
put_long(uaecptr addr,uae_u32 val)460 static ALWAYS_INLINE void put_long(uaecptr addr, uae_u32 val)
461 {
462 if (unlikely(is_unaligned(addr, 4)))
463 mmu_put_long_unaligned(addr, val, 1);
464 else
465 mmu_put_long(addr, val, 1, sz_long);
466 }
467
mmu_put_word(uaecptr addr,uae_u16 val,int data,int size)468 static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, int data, int size)
469 {
470 struct mmu_atc_line *cl;
471
472 if (likely(mmu_lookup(addr, data, 1, &cl)))
473 do_put_mem_word((uae_u16 *)mmu_get_real_address(addr, cl), val);
474 else
475 mmu_put_word_slow(addr, val, regs.s, data, size, cl);
476 }
477
put_word(uaecptr addr,uae_u16 val)478 static ALWAYS_INLINE void put_word(uaecptr addr, uae_u16 val)
479 {
480 if (unlikely(is_unaligned(addr, 2)))
481 mmu_put_word_unaligned(addr, val, 1);
482 else
483 mmu_put_word(addr, val, 1, sz_word);
484 }
485
mmu_put_byte(uaecptr addr,uae_u8 val,int data,int size)486 static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, int data, int size)
487 {
488 struct mmu_atc_line *cl;
489
490 if (likely(mmu_lookup(addr, data, 1, &cl)))
491 do_put_mem_byte((uae_u8 *)mmu_get_real_address(addr, cl), val);
492 else
493 mmu_put_byte_slow(addr, val, regs.s, data, size, cl);
494 }
495
put_byte(uaecptr addr,uae_u8 val)496 static ALWAYS_INLINE void put_byte(uaecptr addr, uae_u8 val)
497 {
498 mmu_put_byte(addr, val, 1, sz_byte);
499 }
500
get_real_address(uaecptr addr,int write,int sz)501 static inline uae_u8 *get_real_address(uaecptr addr, int write, int sz)
502 {
503 (void)sz;
504 return phys_get_real_address(mmu_translate(addr, regs.s, 1, write));
505 }
506
mmu_get_user_long(uaecptr addr,int super,int data,int size)507 static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, int super, int data, int size)
508 {
509 struct mmu_atc_line *cl;
510
511 if (likely(mmu_user_lookup(addr, super, data, 0, &cl)))
512 return do_get_mem_long((uae_u32 *)mmu_get_real_address(addr, cl));
513 return mmu_get_long_slow(addr, super, data, size, cl);
514 }
515
mmu_get_user_word(uaecptr addr,int super,int data,int size)516 static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, int super, int data, int size)
517 {
518 struct mmu_atc_line *cl;
519
520 if (likely(mmu_user_lookup(addr, super, data, 0, &cl)))
521 return do_get_mem_word((uae_u16 *)mmu_get_real_address(addr, cl));
522 return mmu_get_word_slow(addr, super, data, size, cl);
523 }
524
mmu_get_user_byte(uaecptr addr,int super,int data,int size)525 static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, int super, int data, int size)
526 {
527 struct mmu_atc_line *cl;
528
529 if (likely(mmu_user_lookup(addr, super, data, 0, &cl)))
530 return do_get_mem_byte((uae_u8 *)mmu_get_real_address(addr, cl));
531 return mmu_get_byte_slow(addr, super, data, size, cl);
532 }
533
mmu_put_user_long(uaecptr addr,uae_u32 val,int super,int data,int size)534 static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, int super, int data, int size)
535 {
536 struct mmu_atc_line *cl;
537
538 if (likely(mmu_user_lookup(addr, super, data, 1, &cl)))
539 do_put_mem_long((uae_u32 *)mmu_get_real_address(addr, cl), val);
540 else
541 mmu_put_long_slow(addr, val, super, data, size, cl);
542 }
543
mmu_put_user_word(uaecptr addr,uae_u16 val,int super,int data,int size)544 static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, int super, int data, int size)
545 {
546 struct mmu_atc_line *cl;
547
548 if (likely(mmu_user_lookup(addr, super, data, 1, &cl)))
549 do_put_mem_word((uae_u16 *)mmu_get_real_address(addr, cl), val);
550 else
551 mmu_put_word_slow(addr, val, super, data, size, cl);
552 }
553
mmu_put_user_byte(uaecptr addr,uae_u8 val,int super,int data,int size)554 static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, int super, int data, int size)
555 {
556 struct mmu_atc_line *cl;
557
558 if (likely(mmu_user_lookup(addr, super, data, 1, &cl)))
559 do_put_mem_byte((uae_u8 *)mmu_get_real_address(addr, cl), val);
560 else
561 mmu_put_byte_slow(addr, val, super, data, size, cl);
562 }
563
valid_address(uaecptr addr,bool write,int sz)564 static inline bool valid_address(uaecptr addr, bool write, int sz)
565 {
566 SAVE_EXCEPTION;
567 TRY(prb) {
568 (void)sz;
569 check_ram_boundary(mmu_translate(addr, regs.s, 1, (write ? 1 : 0)), sz, write);
570 RESTORE_EXCEPTION;
571 return true;
572 }
573 CATCH(prb) {
574 RESTORE_EXCEPTION;
575 return false;
576 }
577 }
578
579 #else
580
581 # define get_quad(a) phys_get_quad(a)
582 # define get_long(a) phys_get_long(a)
583 # define get_word(a) phys_get_word(a)
584 # define get_byte(a) phys_get_byte(a)
585 # define put_quad(a,b) phys_put_quad(a,b)
586 # define put_long(a,b) phys_put_long(a,b)
587 # define put_word(a,b) phys_put_word(a,b)
588 # define put_byte(a,b) phys_put_byte(a,b)
589 # define get_real_address(a,w,s) phys_get_real_address(a)
590
591 #define valid_address(a,w,s) phys_valid_address(a,w,s)
592 #endif
593
flush_internals()594 static inline void flush_internals() {
595 #ifdef ARAM_PAGE_CHECK
596 pc_page = 0xeeeeeeee;
597 read_page = 0xeeeeeeee;
598 write_page = 0xeeeeeeee;
599 #endif
600 }
601
602 #endif /* MEMORY_H */
603
604 /*
605 vim:ts=4:sw=4:
606 */
607