|
|
1.1.1.2 root 1: /*
2: * cpummu.h - MMU emulation
3: *
4: * Copyright (c) 2001-2004 Milan Jurik of ARAnyM dev team (see AUTHORS)
5: *
6: * Inspired by UAE MMU patch
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:
1.1.1.4 root 26:
1.1.1.5 root 27: #ifndef UAE_CPUMMU_H
28: #define UAE_CPUMMU_H
29:
30: //#include "uae/types.h"
1.1.1.2 root 31:
1.1.1.3 root 32: #include "mmu_common.h"
1.1.1.2 root 33:
34: #ifndef FULLMMU
35: #define FULLMMU
36: #endif
37:
38: #define DUNUSED(x)
39: #define D
40: #if DEBUG
41: #define bug write_log
42: #else
43: #define bug
44: #endif
45:
46: static __inline void flush_internals (void) { }
47:
1.1.1.4 root 48: extern int mmu060_state;
49:
50: extern int mmu040_movem;
51: extern uaecptr mmu040_movem_ea;
52: extern uae_u32 mmu040_move16[4];
53:
54: extern bool mmu_pagesize_8k;
55: extern uae_u16 mmu_opcode;
56: extern bool mmu_restart;
57: extern bool mmu_ttr_enabled;
58:
1.1.1.2 root 59: //typedef uae_u8 flagtype;
60:
61: //static m68k_exception except;
62:
63: struct xttrx {
64: uae_u32 log_addr_base : 8;
65: uae_u32 log_addr_mask : 8;
66: uae_u32 enable : 1;
67: uae_u32 s_field : 2;
68: uae_u32 : 3;
69: uae_u32 usr1 : 1;
70: uae_u32 usr0 : 1;
71: uae_u32 : 1;
72: uae_u32 cmode : 2;
73: uae_u32 : 2;
74: uae_u32 write : 1;
75: uae_u32 : 2;
76: };
77:
78: struct mmusr_t {
79: uae_u32 phys_addr : 20;
80: uae_u32 bus_err : 1;
81: uae_u32 global : 1;
82: uae_u32 usr1 : 1;
83: uae_u32 usr0 : 1;
84: uae_u32 super : 1;
85: uae_u32 cmode : 2;
86: uae_u32 modif : 1;
87: uae_u32 : 1;
88: uae_u32 write : 1;
89: uae_u32 ttrhit : 1;
90: uae_u32 resident : 1;
91: };
92:
93: struct log_addr4 {
94: uae_u32 rif : 7;
95: uae_u32 pif : 7;
96: uae_u32 paif : 6;
97: uae_u32 poff : 12;
98: };
99:
100: struct log_addr8 {
101: uae_u32 rif : 7;
102: uae_u32 pif : 7;
103: uae_u32 paif : 5;
104: uae_u32 poff : 13;
105: };
106:
107: #define MMU_TEST_PTEST 1
108: #define MMU_TEST_VERBOSE 2
109: #define MMU_TEST_FORCE_TABLE_SEARCH 4
110: #define MMU_TEST_NO_BUSERR 8
111:
112: extern void mmu_dump_tables(void);
113:
114: #define MMU_TTR_LOGICAL_BASE 0xff000000
115: #define MMU_TTR_LOGICAL_MASK 0x00ff0000
116: #define MMU_TTR_BIT_ENABLED (1 << 15)
117: #define MMU_TTR_BIT_SFIELD_ENABLED (1 << 14)
118: #define MMU_TTR_BIT_SFIELD_SUPER (1 << 13)
119: #define MMU_TTR_SFIELD_SHIFT 13
120: #define MMU_TTR_UX_MASK ((1 << 9) | (1 << 8))
121: #define MMU_TTR_UX_SHIFT 8
122: #define MMU_TTR_CACHE_MASK ((1 << 6) | (1 << 5))
123: #define MMU_TTR_CACHE_SHIFT 5
124: #define MMU_TTR_BIT_WRITE_PROTECT (1 << 2)
125:
126: #define MMU_UDT_MASK 3
127: #define MMU_PDT_MASK 3
128:
129: #define MMU_DES_WP 4
130: #define MMU_DES_USED 8
131:
132: /* page descriptors only */
133: #define MMU_DES_MODIFIED 16
134: #define MMU_DES_SUPER (1 << 7)
135: #define MMU_DES_GLOBAL (1 << 10)
136:
137: #define MMU_ROOT_PTR_ADDR_MASK 0xfffffe00
138: #define MMU_PTR_PAGE_ADDR_MASK_8 0xffffff80
139: #define MMU_PTR_PAGE_ADDR_MASK_4 0xffffff00
140:
141: #define MMU_PAGE_INDIRECT_MASK 0xfffffffc
142: #define MMU_PAGE_ADDR_MASK_8 0xffffe000
143: #define MMU_PAGE_ADDR_MASK_4 0xfffff000
144: #define MMU_PAGE_UR_MASK_8 ((1 << 12) | (1 << 11))
145: #define MMU_PAGE_UR_MASK_4 (1 << 11)
146: #define MMU_PAGE_UR_SHIFT 11
147:
148: #define MMU_MMUSR_ADDR_MASK 0xfffff000
149: #define MMU_MMUSR_B (1 << 11)
150: #define MMU_MMUSR_G (1 << 10)
151: #define MMU_MMUSR_U1 (1 << 9)
152: #define MMU_MMUSR_U0 (1 << 8)
153: #define MMU_MMUSR_Ux (MMU_MMUSR_U1 | MMU_MMUSR_U0)
154: #define MMU_MMUSR_S (1 << 7)
155: #define MMU_MMUSR_CM ((1 << 6) | ( 1 << 5))
156: #define MMU_MMUSR_M (1 << 4)
157: #define MMU_MMUSR_W (1 << 2)
158: #define MMU_MMUSR_T (1 << 1)
159: #define MMU_MMUSR_R (1 << 0)
160:
161: #define TTR_I0 4
162: #define TTR_I1 5
163: #define TTR_D0 6
164: #define TTR_D1 7
165:
166: #define TTR_NO_MATCH 0
167: #define TTR_NO_WRITE 1
168: #define TTR_OK_MATCH 2
169:
170: struct mmu_atc_line {
171: uaecptr tag; // tag is 16 or 17 bits S+logical
1.1.1.5 root 172: uae_u32 valid;
173: uae_u32 status;
1.1.1.2 root 174: uaecptr phys; // phys base address
175: };
176:
177: /*
178: * 68040 ATC is a 4 way 16 slot associative address translation cache
179: * the 68040 has a DATA and an INSTRUCTION ATC.
180: * an ATC lookup may result in : a hit, a miss and a modified state.
181: * the 68060 can disable ATC allocation
182: * we must take care of 8k and 4k page size, index position is relative to page size
183: */
184:
185: #define ATC_WAYS 4
186: #define ATC_SLOTS 16
187: #define ATC_TYPE 2
188:
1.1.1.4 root 189: extern uae_u32 mmu_is_super;
190: extern uae_u32 mmu_tagmask, mmu_pagemask;
1.1.1.2 root 191: extern struct mmu_atc_line mmu_atc_array[ATC_TYPE][ATC_WAYS][ATC_SLOTS];
192:
1.1.1.5 root 193: extern void mmu_tt_modified(void);
194: extern uaecptr mmu_translate(uaecptr addr, uae_u32 val, bool super, bool data, bool write, int size);
1.1.1.2 root 195:
1.1.1.4 root 196: extern uae_u32 REGPARAM3 mmu060_get_rmw_bitfield (uae_u32 src, uae_u32 bdata[2], uae_s32 offset, int width) REGPARAM;
197: extern void REGPARAM3 mmu060_put_rmw_bitfield (uae_u32 dst, uae_u32 bdata[2], uae_u32 val, uae_s32 offset, int width) REGPARAM;
198:
1.1.1.5 root 199: extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr) REGPARAM;
200: extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr) REGPARAM;
1.1.1.2 root 201:
1.1.1.5 root 202: extern uae_u32 REGPARAM3 mmu_get_ilong_unaligned(uaecptr addr) REGPARAM;
203:
204: extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val) REGPARAM;
205: extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val) REGPARAM;
1.1.1.2 root 206:
207: extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode);
208:
209: #define FC_DATA (regs.s ? 5 : 1)
210: #define FC_INST (regs.s ? 6 : 2)
211:
1.1.1.5 root 212: extern void mmu_bus_error(uaecptr addr, uae_u32 val, int fc, bool write, int size, bool nonmmu);
1.1.1.2 root 213:
214: extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM;
215: extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM;
216: extern uae_u8 REGPARAM3 sfc_get_byte(uaecptr addr) REGPARAM;
217: extern void REGPARAM3 dfc_put_long(uaecptr addr, uae_u32 val) REGPARAM;
218: extern void REGPARAM3 dfc_put_word(uaecptr addr, uae_u16 val) REGPARAM;
219: extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM;
220:
1.1.1.4 root 221: #define sfc040_get_long sfc_get_long
222: #define sfc040_get_word sfc_get_word
223: #define sfc040_get_byte sfc_get_byte
224: #define dfc040_put_long dfc_put_long
225: #define dfc040_put_word dfc_put_word
226: #define dfc040_put_byte dfc_put_byte
227:
228: #define sfc060_get_long sfc_get_long
229: #define sfc060_get_word sfc_get_word
230: #define sfc060_get_byte sfc_get_byte
231: #define dfc060_put_long dfc_put_long
232: #define dfc060_put_word dfc_put_word
233: #define dfc060_put_byte dfc_put_byte
234:
235: extern void uae_mmu_put_lrmw (uaecptr addr, uae_u32 v, int size, int type);
236: extern uae_u32 uae_mmu_get_lrmw (uaecptr addr, int size, int type);
1.1.1.2 root 237:
238: extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM;
239: extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM;
240: extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM;
241:
242: extern void REGPARAM3 mmu_reset(void) REGPARAM;
1.1.1.5 root 243: extern void REGPARAM3 mmu_set_funcs(void) REGPARAM;
1.1.1.2 root 244: extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM;
245: extern void REGPARAM3 mmu_set_super(bool super) REGPARAM;
246:
1.1.1.6 ! root 247: static ALWAYS_INLINE int mmu_get_fc(bool super, bool data)
! 248: {
! 249: return (super ? 4 : 0) | (data ? 1 : 2);
! 250: }
! 251:
! 252: /*
! 253: * mmu access is a 4 step process:
! 254: * if mmu is not enabled just read physical
! 255: * check transparent region, if transparent, read physical
! 256: * check ATC (address translation cache), read immediatly if HIT
! 257: * read from mmu with the long path (and allocate ATC entry if needed)
! 258: */
! 259:
! 260: /* check if an address matches a ttr */
! 261: static ALWAYS_INLINE int mmu_do_match_ttr(uae_u32 ttr, uaecptr addr, bool super)
! 262: {
! 263: if (ttr & MMU_TTR_BIT_ENABLED) { /* TTR enabled */
! 264: uae_u8 msb, mask;
! 265:
! 266: msb = ((addr ^ ttr) & MMU_TTR_LOGICAL_BASE) >> 24;
! 267: mask = (ttr & MMU_TTR_LOGICAL_MASK) >> 16;
! 268:
! 269: if (!(msb & ~mask)) {
! 270:
! 271: if ((ttr & MMU_TTR_BIT_SFIELD_ENABLED) == 0) {
! 272: if (((ttr & MMU_TTR_BIT_SFIELD_SUPER) == 0) != (super == 0)) {
! 273: return TTR_NO_MATCH;
! 274: }
! 275: }
! 276:
! 277: return (ttr & MMU_TTR_BIT_WRITE_PROTECT) ? TTR_NO_WRITE : TTR_OK_MATCH;
! 278: }
! 279: }
! 280: return TTR_NO_MATCH;
! 281: }
! 282:
! 283: static ALWAYS_INLINE int mmu_match_ttr(uaecptr addr, bool super, bool data)
! 284: {
! 285: int res;
! 286:
! 287: if (!mmu_ttr_enabled)
! 288: return TTR_NO_MATCH;
! 289: if (data) {
! 290: res = mmu_do_match_ttr(regs.dtt0, addr, super);
! 291: if (res == TTR_NO_MATCH)
! 292: res = mmu_do_match_ttr(regs.dtt1, addr, super);
! 293: } else {
! 294: res = mmu_do_match_ttr(regs.itt0, addr, super);
! 295: if (res == TTR_NO_MATCH)
! 296: res = mmu_do_match_ttr(regs.itt1, addr, super);
! 297: }
! 298: return res;
! 299: }
! 300:
! 301: static ALWAYS_INLINE int mmu_match_ttr_write(uaecptr addr, bool super, bool data, uae_u32 val, int size, bool write)
! 302: {
! 303: if (!mmu_ttr_enabled)
! 304: return TTR_NO_MATCH;
! 305: int res = mmu_match_ttr(addr, super, data);
! 306: if (res == TTR_NO_WRITE && write)
! 307: mmu_bus_error(addr, val, mmu_get_fc (super, data), true, size, false);
! 308: return res;
! 309: }
! 310:
1.1.1.2 root 311: static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl)
312: {
1.1.1.4 root 313: return cl->phys | (addr & mmu_pagemask);
1.1.1.2 root 314: }
315:
1.1.1.5 root 316: static ALWAYS_INLINE void mmu_get_move16(uaecptr addr, uae_u32 *v, int size)
1.1.1.2 root 317: {
1.1.1.5 root 318: int i;
319: bool super = regs.s != 0;
320: addr &= ~15;
321:
322: if (mmu_match_ttr(addr,super,true) == TTR_NO_MATCH && regs.mmu_enabled) {
323: addr = mmu_translate(addr, 0, super, true, false, size);
324: }
325:
326: for (i = 0; i < 4; i++) {
327: v[i] = phys_get_long(addr + i * 4);
328: }
1.1.1.2 root 329: }
330:
1.1.1.5 root 331: static ALWAYS_INLINE void mmu_put_move16(uaecptr addr, uae_u32 *v, int size)
1.1.1.2 root 332: {
1.1.1.5 root 333: int i;
334: bool super = regs.s != 0;
335: addr &= ~15;
336:
337: if (mmu_match_ttr_write(addr,super,true,v[0],size,false) == TTR_NO_MATCH && regs.mmu_enabled) {
338: addr = mmu_translate(addr, v[0], super, true, true, size);
339: }
340:
341: for (i = 0; i < 4; i++) {
342: phys_put_long(addr + i * 4, v[i]);
343: }
1.1.1.2 root 344: }
345:
1.1.1.5 root 346: static ALWAYS_INLINE uae_u32 mmu_get_ilong(uaecptr addr, int size)
1.1.1.2 root 347: {
1.1.1.5 root 348: if (mmu_match_ttr(addr,regs.s!=0,false) == TTR_NO_MATCH && regs.mmu_enabled) {
349: addr = mmu_translate(addr, 0, regs.s!=0, false, false, size);
350: }
351: return phys_get_long(addr);
1.1.1.2 root 352: }
353:
1.1.1.5 root 354: static ALWAYS_INLINE uae_u16 mmu_get_iword(uaecptr addr, int size)
1.1.1.2 root 355: {
1.1.1.5 root 356: if (mmu_match_ttr(addr,regs.s!=0,false) == TTR_NO_MATCH && regs.mmu_enabled) {
357: addr = mmu_translate(addr, 0, regs.s!=0, false, false, size);
358: }
359: return phys_get_word(addr);
1.1.1.2 root 360: }
361:
1.1.1.5 root 362: static ALWAYS_INLINE uae_u8 mmu_get_ibyte(uaecptr addr, int size)
1.1.1.2 root 363: {
1.1.1.5 root 364: if (mmu_match_ttr(addr,regs.s!=0,false) == TTR_NO_MATCH && regs.mmu_enabled) {
365: addr = mmu_translate(addr, 0, regs.s!=0, false, false, size);
366: }
367: return phys_get_byte(addr);
1.1.1.2 root 368: }
369:
1.1.1.5 root 370: static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, int size)
1.1.1.2 root 371: {
1.1.1.5 root 372: if (mmu_match_ttr(addr,regs.s!=0,true) == TTR_NO_MATCH && regs.mmu_enabled) {
373: addr = mmu_translate(addr, 0, regs.s!=0, true, false, size);
374: }
375: return phys_get_long(addr);
1.1.1.2 root 376: }
377:
1.1.1.5 root 378: static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, int size)
1.1.1.2 root 379: {
1.1.1.5 root 380: if (mmu_match_ttr(addr,regs.s!=0,true) == TTR_NO_MATCH && regs.mmu_enabled) {
381: addr = mmu_translate(addr, 0, regs.s!=0, true, false, size);
382: }
383: return phys_get_word(addr);
1.1.1.2 root 384: }
385:
1.1.1.5 root 386: static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, int size)
1.1.1.2 root 387: {
1.1.1.5 root 388: if (mmu_match_ttr(addr,regs.s!=0,true) == TTR_NO_MATCH && regs.mmu_enabled) {
389: addr = mmu_translate(addr, 0, regs.s!=0, true, false, size);
390: }
391: return phys_get_byte(addr);
392: }
1.1.1.2 root 393:
1.1.1.5 root 394: static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, int size)
395: {
396: if (mmu_match_ttr_write(addr,regs.s!=0,true,val,size,true) == TTR_NO_MATCH && regs.mmu_enabled) {
397: addr = mmu_translate(addr, val, regs.s!=0, true, true, size);
398: }
399: phys_put_long(addr, val);
1.1.1.2 root 400: }
401:
1.1.1.5 root 402: static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, int size)
1.1.1.2 root 403: {
1.1.1.5 root 404: if (mmu_match_ttr_write(addr,regs.s!=0,true,val,size,true) == TTR_NO_MATCH && regs.mmu_enabled) {
405: addr = mmu_translate(addr, val, regs.s!=0, true, true, size);
406: }
407: phys_put_word(addr, val);
408: }
1.1.1.2 root 409:
1.1.1.5 root 410: static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, int size)
411: {
412: if (mmu_match_ttr_write(addr,regs.s!=0,true,val,size,true) == TTR_NO_MATCH && regs.mmu_enabled) {
413: addr = mmu_translate(addr, val, regs.s!=0, true, true, size);
414: }
415: phys_put_byte(addr, val);
1.1.1.2 root 416: }
417:
1.1.1.5 root 418: static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool write, int size)
1.1.1.2 root 419: {
1.1.1.5 root 420: if (mmu_match_ttr_write(addr,super,true,0,size,write) == TTR_NO_MATCH && regs.mmu_enabled) {
421: addr = mmu_translate(addr, 0, super, true, write, size);
422: }
423: return phys_get_long(addr);
424: }
1.1.1.2 root 425:
1.1.1.5 root 426: static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool write, int size)
427: {
428: if (mmu_match_ttr_write(addr,super,true,0,size,write) == TTR_NO_MATCH && regs.mmu_enabled) {
429: addr = mmu_translate(addr, 0, super, true, write, size);
430: }
431: return phys_get_word(addr);
1.1.1.2 root 432: }
433:
1.1.1.5 root 434: static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool write, int size)
1.1.1.2 root 435: {
1.1.1.5 root 436: if (mmu_match_ttr_write(addr,super,true,0,size,write) == TTR_NO_MATCH && regs.mmu_enabled) {
437: addr = mmu_translate(addr, 0, super, true, write, size);
438: }
439: return phys_get_byte(addr);
440: }
1.1.1.2 root 441:
1.1.1.5 root 442: static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, int size)
443: {
444: if (mmu_match_ttr_write(addr,super,true,val,size,true) == TTR_NO_MATCH && regs.mmu_enabled) {
445: addr = mmu_translate(addr, val, super, true, true, size);
446: }
447: phys_put_long(addr, val);
1.1.1.2 root 448: }
449:
1.1.1.5 root 450: static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, int size)
1.1.1.2 root 451: {
1.1.1.5 root 452: if (mmu_match_ttr_write(addr,super,true,val,size,true) == TTR_NO_MATCH && regs.mmu_enabled) {
453: addr = mmu_translate(addr, val, super, true, true, size);
454: }
455: phys_put_word(addr, val);
456: }
1.1.1.2 root 457:
1.1.1.5 root 458: static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, int size)
459: {
460: if (mmu_match_ttr_write(addr,super,true,val,size,true) == TTR_NO_MATCH && regs.mmu_enabled) {
461: addr = mmu_translate(addr, val, super, true, true, size);
462: }
463: phys_put_byte(addr, val);
1.1.1.2 root 464: }
465:
466:
467: static ALWAYS_INLINE void HWput_l(uaecptr addr, uae_u32 l)
468: {
469: put_long (addr, l);
470: }
471: static ALWAYS_INLINE void HWput_w(uaecptr addr, uae_u32 w)
472: {
473: put_word (addr, w);
474: }
475: static ALWAYS_INLINE void HWput_b(uaecptr addr, uae_u32 b)
476: {
477: put_byte (addr, b);
478: }
479: static ALWAYS_INLINE uae_u32 HWget_l(uaecptr addr)
480: {
481: return get_long (addr);
482: }
483: static ALWAYS_INLINE uae_u32 HWget_w(uaecptr addr)
484: {
485: return get_word (addr);
486: }
487: static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr)
488: {
489: return get_byte (addr);
490: }
491:
1.1.1.4 root 492: static ALWAYS_INLINE uae_u32 uae_mmu040_get_ilong(uaecptr addr)
493: {
494: if (unlikely(is_unaligned(addr, 4)))
1.1.1.5 root 495: return mmu_get_ilong_unaligned(addr);
496: return mmu_get_ilong(addr, sz_long);
1.1.1.4 root 497: }
498: static ALWAYS_INLINE uae_u16 uae_mmu040_get_iword(uaecptr addr)
499: {
1.1.1.5 root 500: return mmu_get_iword(addr, sz_word);
1.1.1.4 root 501: }
502: static ALWAYS_INLINE uae_u16 uae_mmu040_get_ibyte(uaecptr addr)
503: {
1.1.1.5 root 504: return mmu_get_ibyte(addr, sz_byte);
1.1.1.4 root 505: }
506: static ALWAYS_INLINE uae_u32 uae_mmu040_get_long(uaecptr addr)
507: {
508: if (unlikely(is_unaligned(addr, 4)))
1.1.1.5 root 509: return mmu_get_long_unaligned(addr);
510: return mmu_get_long(addr, sz_long);
1.1.1.4 root 511: }
512: static ALWAYS_INLINE uae_u16 uae_mmu040_get_word(uaecptr addr)
513: {
514: if (unlikely(is_unaligned(addr, 2)))
1.1.1.5 root 515: return mmu_get_word_unaligned(addr);
516: return mmu_get_word(addr, sz_word);
1.1.1.4 root 517: }
518: static ALWAYS_INLINE uae_u8 uae_mmu040_get_byte(uaecptr addr)
519: {
1.1.1.5 root 520: return mmu_get_byte(addr, sz_byte);
1.1.1.4 root 521: }
522:
523: static ALWAYS_INLINE void uae_mmu040_put_word(uaecptr addr, uae_u16 val)
524: {
525: if (unlikely(is_unaligned(addr, 2)))
1.1.1.5 root 526: mmu_put_word_unaligned(addr, val);
1.1.1.4 root 527: else
1.1.1.5 root 528: mmu_put_word(addr, val, sz_word);
1.1.1.4 root 529: }
530: static ALWAYS_INLINE void uae_mmu040_put_byte(uaecptr addr, uae_u8 val)
531: {
1.1.1.5 root 532: mmu_put_byte(addr, val, sz_byte);
1.1.1.4 root 533: }
534: static ALWAYS_INLINE void uae_mmu040_put_long(uaecptr addr, uae_u32 val)
535: {
536: if (unlikely(is_unaligned(addr, 4)))
1.1.1.5 root 537: mmu_put_long_unaligned(addr, val);
1.1.1.4 root 538: else
1.1.1.5 root 539: mmu_put_long(addr, val, sz_long);
1.1.1.4 root 540: }
541:
542:
543: static ALWAYS_INLINE void uae_mmu_get_move16(uaecptr addr, uae_u32 *val)
544: {
545: // move16 is always aligned
1.1.1.5 root 546: mmu_get_move16(addr, val, 16);
1.1.1.2 root 547: }
1.1.1.4 root 548: static ALWAYS_INLINE void uae_mmu_put_move16(uaecptr addr, uae_u32 *val)
1.1.1.2 root 549: {
1.1.1.4 root 550: // move16 is always aligned
1.1.1.5 root 551: mmu_put_move16(addr, val, 16);
1.1.1.2 root 552: }
553:
1.1.1.4 root 554: // normal 040
555: STATIC_INLINE void put_byte_mmu040 (uaecptr addr, uae_u32 v)
556: {
557: uae_mmu040_put_byte (addr, v);
558: }
559: STATIC_INLINE void put_word_mmu040 (uaecptr addr, uae_u32 v)
560: {
561: uae_mmu040_put_word (addr, v);
562: }
563: STATIC_INLINE void put_long_mmu040 (uaecptr addr, uae_u32 v)
564: {
565: uae_mmu040_put_long (addr, v);
566: }
567: STATIC_INLINE uae_u32 get_byte_mmu040 (uaecptr addr)
1.1.1.2 root 568: {
1.1.1.4 root 569: return uae_mmu040_get_byte (addr);
1.1.1.2 root 570: }
1.1.1.4 root 571: STATIC_INLINE uae_u32 get_word_mmu040 (uaecptr addr)
1.1.1.2 root 572: {
1.1.1.4 root 573: return uae_mmu040_get_word (addr);
1.1.1.2 root 574: }
1.1.1.4 root 575: STATIC_INLINE uae_u32 get_long_mmu040 (uaecptr addr)
1.1.1.2 root 576: {
1.1.1.4 root 577: return uae_mmu040_get_long (addr);
1.1.1.2 root 578: }
1.1.1.4 root 579: STATIC_INLINE void get_move16_mmu (uaecptr addr, uae_u32 *v)
580: {
581: uae_mmu_get_move16 (addr, v);
582: }
583: STATIC_INLINE void put_move16_mmu (uaecptr addr, uae_u32 *v)
584: {
585: uae_mmu_put_move16 (addr, v);
586: }
587:
588: // locked rmw 060
589: STATIC_INLINE void put_lrmw_byte_mmu060 (uaecptr addr, uae_u32 v)
590: {
591: uae_mmu_put_lrmw (addr, v, sz_byte, 1);
592: }
593: STATIC_INLINE void put_lrmw_word_mmu060 (uaecptr addr, uae_u32 v)
594: {
595: uae_mmu_put_lrmw (addr, v, sz_word, 1);
596: }
597: STATIC_INLINE void put_lrmw_long_mmu060 (uaecptr addr, uae_u32 v)
598: {
599: uae_mmu_put_lrmw (addr, v, sz_long, 1);
600: }
601: STATIC_INLINE uae_u32 get_lrmw_byte_mmu060 (uaecptr addr)
602: {
603: return uae_mmu_get_lrmw (addr, sz_byte, 1);
604: }
605: STATIC_INLINE uae_u32 get_lrmw_word_mmu060 (uaecptr addr)
606: {
607: return uae_mmu_get_lrmw (addr, sz_word, 1);
608: }
609: STATIC_INLINE uae_u32 get_lrmw_long_mmu060 (uaecptr addr)
610: {
611: return uae_mmu_get_lrmw (addr, sz_long, 1);
612: }
1.1.1.5 root 613:
1.1.1.4 root 614: // locked rmw 040
615: STATIC_INLINE void put_lrmw_byte_mmu040 (uaecptr addr, uae_u32 v)
616: {
617: uae_mmu_put_lrmw (addr, v, sz_byte, 0);
618: }
619: STATIC_INLINE void put_lrmw_word_mmu040 (uaecptr addr, uae_u32 v)
620: {
621: uae_mmu_put_lrmw (addr, v, sz_word, 0);
622: }
623: STATIC_INLINE void put_lrmw_long_mmu040 (uaecptr addr, uae_u32 v)
624: {
625: uae_mmu_put_lrmw (addr, v, sz_long, 0);
626: }
627: STATIC_INLINE uae_u32 get_lrmw_byte_mmu040 (uaecptr addr)
628: {
629: return uae_mmu_get_lrmw (addr, sz_byte, 0);
630: }
631: STATIC_INLINE uae_u32 get_lrmw_word_mmu040 (uaecptr addr)
632: {
633: return uae_mmu_get_lrmw (addr, sz_word, 0);
634: }
635: STATIC_INLINE uae_u32 get_lrmw_long_mmu040 (uaecptr addr)
636: {
637: return uae_mmu_get_lrmw (addr, sz_long, 0);
638: }
639:
640: STATIC_INLINE uae_u32 get_ibyte_mmu040 (int o)
641: {
1.1.1.5 root 642: uae_u32 pc = m68k_getpci () + o;
1.1.1.4 root 643: return uae_mmu040_get_iword (pc);
644: }
645: STATIC_INLINE uae_u32 get_iword_mmu040 (int o)
646: {
1.1.1.5 root 647: uae_u32 pc = m68k_getpci () + o;
1.1.1.4 root 648: return uae_mmu040_get_iword (pc);
649: }
650: STATIC_INLINE uae_u32 get_ilong_mmu040 (int o)
651: {
1.1.1.5 root 652: uae_u32 pc = m68k_getpci () + o;
1.1.1.4 root 653: return uae_mmu040_get_ilong (pc);
654: }
655: STATIC_INLINE uae_u32 next_iword_mmu040 (void)
656: {
1.1.1.5 root 657: uae_u32 pc = m68k_getpci ();
1.1.1.4 root 658: m68k_incpci (2);
659: return uae_mmu040_get_iword (pc);
660: }
661: STATIC_INLINE uae_u32 next_ilong_mmu040 (void)
662: {
1.1.1.5 root 663: uae_u32 pc = m68k_getpci ();
1.1.1.4 root 664: m68k_incpci (4);
665: return uae_mmu040_get_ilong (pc);
666: }
667:
668: extern void flush_mmu040 (uaecptr, int);
669: extern void m68k_do_rts_mmu040 (void);
670: extern void m68k_do_rte_mmu040 (uaecptr a7);
671: extern void m68k_do_bsr_mmu040 (uaecptr oldpc, uae_s32 offset);
672:
673: extern void flush_mmu060 (uaecptr, int);
674: extern void m68k_do_rts_mmu060 (void);
675: extern void m68k_do_rte_mmu060 (uaecptr a7);
676: extern void m68k_do_bsr_mmu060 (uaecptr oldpc, uae_s32 offset);
1.1.1.2 root 677:
1.1.1.5 root 678: #endif /* UAE_CPUMMU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.