|
|
1.1 ! 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: ! 26: #ifndef CPUMMU_H ! 27: #define CPUMMU_H ! 28: ! 29: #include "compat.h" ! 30: ! 31: #ifndef FULLMMU ! 32: #define FULLMMU ! 33: #endif ! 34: ! 35: #define DUNUSED(x) ! 36: #define D ! 37: #if DEBUG ! 38: #define bug write_log ! 39: #else ! 40: #define bug ! 41: #endif ! 42: ! 43: /*struct m68k_exception { ! 44: int prb; ! 45: m68k_exception (int exc) : prb (exc) {} ! 46: operator int() { return prb; } ! 47: };*/ ! 48: typedef int m68k_exception; ! 49: ! 50: #define SAVE_EXCEPTION ! 51: #define RESTORE_EXCEPTION ! 52: //#define TRY(var) try ! 53: //#define CATCH(var) catch(m68k_exception var) ! 54: #define CATCH(var) if (except != 0) ! 55: //#define THROW(n) except=n ! 56: //#define THROW_AGAIN(var) except=var ! 57: #define VOLATILE ! 58: #define ALWAYS_INLINE __inline ! 59: ! 60: static __inline void flush_internals (void) { } ! 61: ! 62: //typedef uae_u8 flagtype; ! 63: ! 64: static m68k_exception except; ! 65: ! 66: struct xttrx { ! 67: uae_u32 log_addr_base : 8; ! 68: uae_u32 log_addr_mask : 8; ! 69: uae_u32 enable : 1; ! 70: uae_u32 s_field : 2; ! 71: uae_u32 : 3; ! 72: uae_u32 usr1 : 1; ! 73: uae_u32 usr0 : 1; ! 74: uae_u32 : 1; ! 75: uae_u32 cmode : 2; ! 76: uae_u32 : 2; ! 77: uae_u32 write : 1; ! 78: uae_u32 : 2; ! 79: }; ! 80: ! 81: struct mmusr_t { ! 82: uae_u32 phys_addr : 20; ! 83: uae_u32 bus_err : 1; ! 84: uae_u32 global : 1; ! 85: uae_u32 usr1 : 1; ! 86: uae_u32 usr0 : 1; ! 87: uae_u32 super : 1; ! 88: uae_u32 cmode : 2; ! 89: uae_u32 modif : 1; ! 90: uae_u32 : 1; ! 91: uae_u32 write : 1; ! 92: uae_u32 ttrhit : 1; ! 93: uae_u32 resident : 1; ! 94: }; ! 95: ! 96: struct log_addr4 { ! 97: uae_u32 rif : 7; ! 98: uae_u32 pif : 7; ! 99: uae_u32 paif : 6; ! 100: uae_u32 poff : 12; ! 101: }; ! 102: ! 103: struct log_addr8 { ! 104: uae_u32 rif : 7; ! 105: uae_u32 pif : 7; ! 106: uae_u32 paif : 5; ! 107: uae_u32 poff : 13; ! 108: }; ! 109: ! 110: #define MMU_TEST_PTEST 1 ! 111: #define MMU_TEST_VERBOSE 2 ! 112: #define MMU_TEST_FORCE_TABLE_SEARCH 4 ! 113: #define MMU_TEST_NO_BUSERR 8 ! 114: ! 115: extern void mmu_dump_tables(void); ! 116: ! 117: #define MMU_TTR_LOGICAL_BASE 0xff000000 ! 118: #define MMU_TTR_LOGICAL_MASK 0x00ff0000 ! 119: #define MMU_TTR_BIT_ENABLED (1 << 15) ! 120: #define MMU_TTR_BIT_SFIELD_ENABLED (1 << 14) ! 121: #define MMU_TTR_BIT_SFIELD_SUPER (1 << 13) ! 122: #define MMU_TTR_SFIELD_SHIFT 13 ! 123: #define MMU_TTR_UX_MASK ((1 << 9) | (1 << 8)) ! 124: #define MMU_TTR_UX_SHIFT 8 ! 125: #define MMU_TTR_CACHE_MASK ((1 << 6) | (1 << 5)) ! 126: #define MMU_TTR_CACHE_SHIFT 5 ! 127: #define MMU_TTR_BIT_WRITE_PROTECT (1 << 2) ! 128: ! 129: #define MMU_UDT_MASK 3 ! 130: #define MMU_PDT_MASK 3 ! 131: ! 132: #define MMU_DES_WP 4 ! 133: #define MMU_DES_USED 8 ! 134: ! 135: /* page descriptors only */ ! 136: #define MMU_DES_MODIFIED 16 ! 137: #define MMU_DES_SUPER (1 << 7) ! 138: #define MMU_DES_GLOBAL (1 << 10) ! 139: ! 140: #define MMU_ROOT_PTR_ADDR_MASK 0xfffffe00 ! 141: #define MMU_PTR_PAGE_ADDR_MASK_8 0xffffff80 ! 142: #define MMU_PTR_PAGE_ADDR_MASK_4 0xffffff00 ! 143: ! 144: #define MMU_PAGE_INDIRECT_MASK 0xfffffffc ! 145: #define MMU_PAGE_ADDR_MASK_8 0xffffe000 ! 146: #define MMU_PAGE_ADDR_MASK_4 0xfffff000 ! 147: #define MMU_PAGE_UR_MASK_8 ((1 << 12) | (1 << 11)) ! 148: #define MMU_PAGE_UR_MASK_4 (1 << 11) ! 149: #define MMU_PAGE_UR_SHIFT 11 ! 150: ! 151: #define MMU_MMUSR_ADDR_MASK 0xfffff000 ! 152: #define MMU_MMUSR_B (1 << 11) ! 153: #define MMU_MMUSR_G (1 << 10) ! 154: #define MMU_MMUSR_U1 (1 << 9) ! 155: #define MMU_MMUSR_U0 (1 << 8) ! 156: #define MMU_MMUSR_Ux (MMU_MMUSR_U1 | MMU_MMUSR_U0) ! 157: #define MMU_MMUSR_S (1 << 7) ! 158: #define MMU_MMUSR_CM ((1 << 6) | ( 1 << 5)) ! 159: #define MMU_MMUSR_M (1 << 4) ! 160: #define MMU_MMUSR_W (1 << 2) ! 161: #define MMU_MMUSR_T (1 << 1) ! 162: #define MMU_MMUSR_R (1 << 0) ! 163: ! 164: /* special status word (access error stack frame) */ ! 165: #define MMU_SSW_TM 0x0007 ! 166: #define MMU_SSW_TT 0x0018 ! 167: #define MMU_SSW_SIZE 0x0060 ! 168: #define MMU_SSW_SIZE_B 0x0020 ! 169: #define MMU_SSW_SIZE_W 0x0040 ! 170: #define MMU_SSW_SIZE_L 0x0000 ! 171: #define MMU_SSW_RW 0x0100 ! 172: #define MMU_SSW_LK 0x0200 ! 173: #define MMU_SSW_ATC 0x0400 ! 174: #define MMU_SSW_MA 0x0800 ! 175: #define MMU_SSW_CM 0x1000 ! 176: #define MMU_SSW_CT 0x2000 ! 177: #define MMU_SSW_CU 0x4000 ! 178: #define MMU_SSW_CP 0x8000 ! 179: ! 180: #define TTR_I0 4 ! 181: #define TTR_I1 5 ! 182: #define TTR_D0 6 ! 183: #define TTR_D1 7 ! 184: ! 185: #define TTR_NO_MATCH 0 ! 186: #define TTR_NO_WRITE 1 ! 187: #define TTR_OK_MATCH 2 ! 188: ! 189: struct mmu_atc_line { ! 190: uae_u16 tag; ! 191: unsigned tt : 1; ! 192: unsigned valid_data : 1; ! 193: unsigned valid_inst : 1; ! 194: unsigned global : 1; ! 195: unsigned modified : 1; ! 196: unsigned write_protect : 1; ! 197: unsigned hw : 1; ! 198: unsigned bus_fault : 1; ! 199: uaecptr phys; ! 200: }; ! 201: ! 202: /* ! 203: * We don't need to store the whole logical address in the atc cache, as part of ! 204: * it is encoded as index into the cache. 14 bits of the address are stored in ! 205: * the tag, this means at least 6 bits must go into the index. The upper two ! 206: * bits of the tag define the type of data in the atc line: ! 207: * - 00: a normal memory address ! 208: * - 11: invalid memory address or hardware access ! 209: * (generated via ~ATC_TAG(addr) in the slow path) ! 210: * - 10: empty atc line ! 211: */ ! 212: ! 213: #define ATC_TAG_SHIFT 18 ! 214: #define ATC_TAG(addr) ((uae_u32)(addr) >> ATC_TAG_SHIFT) ! 215: ! 216: ! 217: #define ATC_L1_SIZE_LOG 8 ! 218: #define ATC_L1_SIZE (1 << ATC_L1_SIZE_LOG) ! 219: ! 220: #define ATC_L1_INDEX(addr) (((addr) >> 12) % ATC_L1_SIZE) ! 221: ! 222: /* ! 223: * first level atc cache ! 224: * indexed by [super][data][rw][idx] ! 225: */ ! 226: ! 227: typedef struct mmu_atc_line mmu_atc_l1_array[2][2][ATC_L1_SIZE]; ! 228: extern mmu_atc_l1_array atc_l1[2]; ! 229: extern mmu_atc_l1_array *current_atc; ! 230: ! 231: #define ATC_L2_SIZE_LOG 12 ! 232: #define ATC_L2_SIZE (1 << ATC_L2_SIZE_LOG) ! 233: ! 234: #define ATC_L2_INDEX(addr) ((((addr) >> 12) ^ ((addr) >> (32 - ATC_L2_SIZE_LOG))) % ATC_L2_SIZE) ! 235: ! 236: extern struct mmu_atc_line atc_l2[2][ATC_L2_SIZE]; ! 237: ! 238: /* ! 239: * lookup address in the level 1 atc cache, ! 240: * the data and write arguments are constant in the common, ! 241: * thus allows gcc to generate a constant offset. ! 242: */ ! 243: static ALWAYS_INLINE bool mmu_lookup(uaecptr addr, bool data, bool write, ! 244: struct mmu_atc_line **cl) ! 245: { ! 246: addr >>= 12; ! 247: *cl = &(*current_atc)[data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE]; ! 248: return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12); ! 249: } ! 250: ! 251: /* ! 252: * similiar to mmu_user_lookup, but for the use of the moves instruction ! 253: */ ! 254: static ALWAYS_INLINE bool mmu_user_lookup(uaecptr addr, bool super, bool data, ! 255: bool write, struct mmu_atc_line **cl) ! 256: { ! 257: addr >>= 12; ! 258: *cl = &atc_l1[super ? 1 : 0][data ? 1 : 0][write ? 1 : 0][addr % ATC_L1_SIZE]; ! 259: return (*cl)->tag == addr >> (ATC_TAG_SHIFT - 12); ! 260: } ! 261: ! 262: extern uae_u16 REGPARAM3 mmu_get_word_unaligned(uaecptr addr, bool data) REGPARAM; ! 263: extern uae_u32 REGPARAM3 mmu_get_long_unaligned(uaecptr addr, bool data) REGPARAM; ! 264: ! 265: extern uae_u8 REGPARAM3 mmu_get_byte_slow(uaecptr addr, bool super, bool data, ! 266: int size, struct mmu_atc_line *cl) REGPARAM; ! 267: extern uae_u16 REGPARAM3 mmu_get_word_slow(uaecptr addr, bool super, bool data, ! 268: int size, struct mmu_atc_line *cl) REGPARAM; ! 269: extern uae_u32 REGPARAM3 mmu_get_long_slow(uaecptr addr, bool super, bool data, ! 270: int size, struct mmu_atc_line *cl) REGPARAM; ! 271: ! 272: extern void REGPARAM3 mmu_put_word_unaligned(uaecptr addr, uae_u16 val, bool data) REGPARAM; ! 273: extern void REGPARAM3 mmu_put_long_unaligned(uaecptr addr, uae_u32 val, bool data) REGPARAM; ! 274: ! 275: extern void REGPARAM3 mmu_put_byte_slow(uaecptr addr, uae_u8 val, bool super, bool data, ! 276: int size, struct mmu_atc_line *cl) REGPARAM; ! 277: extern void REGPARAM3 mmu_put_word_slow(uaecptr addr, uae_u16 val, bool super, bool data, ! 278: int size, struct mmu_atc_line *cl) REGPARAM; ! 279: extern void REGPARAM3 mmu_put_long_slow(uaecptr addr, uae_u32 val, bool super, bool data, ! 280: int size, struct mmu_atc_line *cl) REGPARAM; ! 281: ! 282: extern void mmu_make_transparent_region(uaecptr baseaddr, uae_u32 size, int datamode); ! 283: ! 284: #define FC_DATA (regs.s ? 5 : 1) ! 285: #define FC_INST (regs.s ? 6 : 2) ! 286: ! 287: extern uaecptr REGPARAM3 mmu_translate(uaecptr addr, bool super, bool data, bool write) REGPARAM; ! 288: ! 289: extern uae_u32 REGPARAM3 sfc_get_long(uaecptr addr) REGPARAM; ! 290: extern uae_u16 REGPARAM3 sfc_get_word(uaecptr addr) REGPARAM; ! 291: extern uae_u8 REGPARAM3 sfc_get_byte(uaecptr addr) REGPARAM; ! 292: extern void REGPARAM3 dfc_put_long(uaecptr addr, uae_u32 val) REGPARAM; ! 293: extern void REGPARAM3 dfc_put_word(uaecptr addr, uae_u16 val) REGPARAM; ! 294: extern void REGPARAM3 dfc_put_byte(uaecptr addr, uae_u8 val) REGPARAM; ! 295: ! 296: ! 297: extern void REGPARAM3 mmu_flush_atc(uaecptr addr, bool super, bool global) REGPARAM; ! 298: extern void REGPARAM3 mmu_flush_atc_all(bool global) REGPARAM; ! 299: extern void REGPARAM3 mmu_op_real(uae_u32 opcode, uae_u16 extra) REGPARAM; ! 300: ! 301: extern void REGPARAM3 mmu_reset(void) REGPARAM; ! 302: extern void REGPARAM3 mmu_set_tc(uae_u16 tc) REGPARAM; ! 303: extern void REGPARAM3 mmu_set_super(bool super) REGPARAM; ! 304: ! 305: static ALWAYS_INLINE bool is_unaligned(uaecptr addr, int size) ! 306: { ! 307: return unlikely((addr & (size - 1)) && (addr ^ (addr + size - 1)) & 0x1000); ! 308: } ! 309: ! 310: static ALWAYS_INLINE uaecptr mmu_get_real_address(uaecptr addr, struct mmu_atc_line *cl) ! 311: { ! 312: return cl->phys + addr; ! 313: } ! 314: ! 315: static ALWAYS_INLINE void phys_put_long(uaecptr addr, uae_u32 l) ! 316: { ! 317: longput(addr, l); ! 318: } ! 319: static ALWAYS_INLINE void phys_put_word(uaecptr addr, uae_u32 w) ! 320: { ! 321: wordput(addr, w); ! 322: } ! 323: static ALWAYS_INLINE void phys_put_byte(uaecptr addr, uae_u32 b) ! 324: { ! 325: byteput(addr, b); ! 326: } ! 327: static ALWAYS_INLINE uae_u32 phys_get_long(uaecptr addr) ! 328: { ! 329: return longget (addr); ! 330: } ! 331: static ALWAYS_INLINE uae_u32 phys_get_word(uaecptr addr) ! 332: { ! 333: return wordget (addr); ! 334: } ! 335: static ALWAYS_INLINE uae_u32 phys_get_byte(uaecptr addr) ! 336: { ! 337: return byteget (addr); ! 338: } ! 339: ! 340: static ALWAYS_INLINE uae_u32 mmu_get_long(uaecptr addr, bool data, int size) ! 341: { ! 342: struct mmu_atc_line *cl; ! 343: ! 344: if (likely(mmu_lookup(addr, data, false, &cl))) ! 345: return phys_get_long(mmu_get_real_address(addr, cl)); ! 346: return mmu_get_long_slow(addr, regs.s != 0, data, size, cl); ! 347: } ! 348: ! 349: static ALWAYS_INLINE uae_u16 mmu_get_word(uaecptr addr, bool data, int size) ! 350: { ! 351: struct mmu_atc_line *cl; ! 352: ! 353: if (likely(mmu_lookup(addr, data, false, &cl))) ! 354: return phys_get_word(mmu_get_real_address(addr, cl)); ! 355: return mmu_get_word_slow(addr, regs.s != 0, data, size, cl); ! 356: } ! 357: ! 358: static ALWAYS_INLINE uae_u8 mmu_get_byte(uaecptr addr, bool data, int size) ! 359: { ! 360: struct mmu_atc_line *cl; ! 361: ! 362: if (likely(mmu_lookup(addr, data, false, &cl))) ! 363: return phys_get_byte(mmu_get_real_address(addr, cl)); ! 364: return mmu_get_byte_slow(addr, regs.s != 0, data, size, cl); ! 365: } ! 366: ! 367: ! 368: static ALWAYS_INLINE void mmu_put_long(uaecptr addr, uae_u32 val, bool data, int size) ! 369: { ! 370: struct mmu_atc_line *cl; ! 371: ! 372: if (likely(mmu_lookup(addr, data, true, &cl))) ! 373: phys_put_long(mmu_get_real_address(addr, cl), val); ! 374: else ! 375: mmu_put_long_slow(addr, val, regs.s != 0, data, size, cl); ! 376: } ! 377: ! 378: static ALWAYS_INLINE void mmu_put_word(uaecptr addr, uae_u16 val, bool data, int size) ! 379: { ! 380: struct mmu_atc_line *cl; ! 381: ! 382: if (likely(mmu_lookup(addr, data, true, &cl))) ! 383: phys_put_word(mmu_get_real_address(addr, cl), val); ! 384: else ! 385: mmu_put_word_slow(addr, val, regs.s != 0, data, size, cl); ! 386: } ! 387: ! 388: static ALWAYS_INLINE void mmu_put_byte(uaecptr addr, uae_u8 val, bool data, int size) ! 389: { ! 390: struct mmu_atc_line *cl; ! 391: ! 392: if (likely(mmu_lookup(addr, data, true, &cl))) ! 393: phys_put_byte(mmu_get_real_address(addr, cl), val); ! 394: else ! 395: mmu_put_byte_slow(addr, val, regs.s != 0, data, size, cl); ! 396: } ! 397: ! 398: static ALWAYS_INLINE uae_u32 mmu_get_user_long(uaecptr addr, bool super, bool data, int size) ! 399: { ! 400: struct mmu_atc_line *cl; ! 401: ! 402: if (likely(mmu_user_lookup(addr, super, data, false, &cl))) ! 403: return phys_get_long(mmu_get_real_address(addr, cl)); ! 404: return mmu_get_long_slow(addr, super, data, size, cl); ! 405: } ! 406: ! 407: static ALWAYS_INLINE uae_u16 mmu_get_user_word(uaecptr addr, bool super, bool data, int size) ! 408: { ! 409: struct mmu_atc_line *cl; ! 410: ! 411: if (likely(mmu_user_lookup(addr, super, data, false, &cl))) ! 412: return phys_get_word(mmu_get_real_address(addr, cl)); ! 413: return mmu_get_word_slow(addr, super, data, size, cl); ! 414: } ! 415: ! 416: static ALWAYS_INLINE uae_u8 mmu_get_user_byte(uaecptr addr, bool super, bool data, int size) ! 417: { ! 418: struct mmu_atc_line *cl; ! 419: ! 420: if (likely(mmu_user_lookup(addr, super, data, false, &cl))) ! 421: return phys_get_byte(mmu_get_real_address(addr, cl)); ! 422: return mmu_get_byte_slow(addr, super, data, size, cl); ! 423: } ! 424: ! 425: static ALWAYS_INLINE void mmu_put_user_long(uaecptr addr, uae_u32 val, bool super, bool data, int size) ! 426: { ! 427: struct mmu_atc_line *cl; ! 428: ! 429: if (likely(mmu_user_lookup(addr, super, data, true, &cl))) ! 430: phys_put_long(mmu_get_real_address(addr, cl), val); ! 431: else ! 432: mmu_put_long_slow(addr, val, super, data, size, cl); ! 433: } ! 434: ! 435: static ALWAYS_INLINE void mmu_put_user_word(uaecptr addr, uae_u16 val, bool super, bool data, int size) ! 436: { ! 437: struct mmu_atc_line *cl; ! 438: ! 439: if (likely(mmu_user_lookup(addr, super, data, true, &cl))) ! 440: phys_put_word(mmu_get_real_address(addr, cl), val); ! 441: else ! 442: mmu_put_word_slow(addr, val, super, data, size, cl); ! 443: } ! 444: ! 445: static ALWAYS_INLINE void mmu_put_user_byte(uaecptr addr, uae_u8 val, bool super, bool data, int size) ! 446: { ! 447: struct mmu_atc_line *cl; ! 448: ! 449: if (likely(mmu_user_lookup(addr, super, data, true, &cl))) ! 450: phys_put_byte(mmu_get_real_address(addr, cl), val); ! 451: else ! 452: mmu_put_byte_slow(addr, val, super, data, size, cl); ! 453: } ! 454: ! 455: ! 456: static ALWAYS_INLINE void HWput_l(uaecptr addr, uae_u32 l) ! 457: { ! 458: put_long (addr, l); ! 459: } ! 460: static ALWAYS_INLINE void HWput_w(uaecptr addr, uae_u32 w) ! 461: { ! 462: put_word (addr, w); ! 463: } ! 464: static ALWAYS_INLINE void HWput_b(uaecptr addr, uae_u32 b) ! 465: { ! 466: put_byte (addr, b); ! 467: } ! 468: static ALWAYS_INLINE uae_u32 HWget_l(uaecptr addr) ! 469: { ! 470: return get_long (addr); ! 471: } ! 472: static ALWAYS_INLINE uae_u32 HWget_w(uaecptr addr) ! 473: { ! 474: return get_word (addr); ! 475: } ! 476: static ALWAYS_INLINE uae_u32 HWget_b(uaecptr addr) ! 477: { ! 478: return get_byte (addr); ! 479: } ! 480: ! 481: static ALWAYS_INLINE uae_u32 uae_mmu_get_ilong(uaecptr addr) ! 482: { ! 483: if (unlikely(is_unaligned(addr, 4))) ! 484: return mmu_get_long_unaligned(addr, false); ! 485: return mmu_get_long(addr, false, sz_long); ! 486: } ! 487: static ALWAYS_INLINE uae_u16 uae_mmu_get_iword(uaecptr addr) ! 488: { ! 489: if (unlikely(is_unaligned(addr, 2))) ! 490: return mmu_get_word_unaligned(addr, false); ! 491: return mmu_get_word(addr, false, sz_word); ! 492: } ! 493: static ALWAYS_INLINE uae_u16 uae_mmu_get_ibyte(uaecptr addr) ! 494: { ! 495: return mmu_get_byte(addr, false, sz_byte); ! 496: } ! 497: static ALWAYS_INLINE uae_u32 uae_mmu_get_long(uaecptr addr) ! 498: { ! 499: if (unlikely(is_unaligned(addr, 4))) ! 500: return mmu_get_long_unaligned(addr, true); ! 501: return mmu_get_long(addr, true, sz_long); ! 502: } ! 503: static ALWAYS_INLINE uae_u16 uae_mmu_get_word(uaecptr addr) ! 504: { ! 505: if (unlikely(is_unaligned(addr, 2))) ! 506: return mmu_get_word_unaligned(addr, true); ! 507: return mmu_get_word(addr, true, sz_word); ! 508: } ! 509: static ALWAYS_INLINE uae_u8 uae_mmu_get_byte(uaecptr addr) ! 510: { ! 511: return mmu_get_byte(addr, true, sz_byte); ! 512: } ! 513: static ALWAYS_INLINE void uae_mmu_put_long(uaecptr addr, uae_u32 val) ! 514: { ! 515: if (unlikely(is_unaligned(addr, 4))) ! 516: mmu_put_long_unaligned(addr, val, true); ! 517: else ! 518: mmu_put_long(addr, val, true, sz_long); ! 519: } ! 520: static ALWAYS_INLINE void uae_mmu_put_word(uaecptr addr, uae_u16 val) ! 521: { ! 522: if (unlikely(is_unaligned(addr, 2))) ! 523: mmu_put_word_unaligned(addr, val, true); ! 524: else ! 525: mmu_put_word(addr, val, true, sz_word); ! 526: } ! 527: static ALWAYS_INLINE void uae_mmu_put_byte(uaecptr addr, uae_u8 val) ! 528: { ! 529: mmu_put_byte(addr, val, true, sz_byte); ! 530: } ! 531: ! 532: STATIC_INLINE void put_byte_mmu (uaecptr addr, uae_u32 v) ! 533: { ! 534: uae_mmu_put_byte (addr, v); ! 535: } ! 536: STATIC_INLINE void put_word_mmu (uaecptr addr, uae_u32 v) ! 537: { ! 538: uae_mmu_put_word (addr, v); ! 539: } ! 540: STATIC_INLINE void put_long_mmu (uaecptr addr, uae_u32 v) ! 541: { ! 542: uae_mmu_put_long (addr, v); ! 543: } ! 544: STATIC_INLINE uae_u32 get_byte_mmu (uaecptr addr) ! 545: { ! 546: return uae_mmu_get_byte (addr); ! 547: } ! 548: STATIC_INLINE uae_u32 get_word_mmu (uaecptr addr) ! 549: { ! 550: return uae_mmu_get_word (addr); ! 551: } ! 552: STATIC_INLINE uae_u32 get_long_mmu (uaecptr addr) ! 553: { ! 554: return uae_mmu_get_long (addr); ! 555: } ! 556: STATIC_INLINE uae_u32 get_ibyte_mmu (int o) ! 557: { ! 558: uae_u32 pc = m68k_getpc () + o; ! 559: return uae_mmu_get_iword (pc); ! 560: } ! 561: STATIC_INLINE uae_u32 get_iword_mmu (int o) ! 562: { ! 563: uae_u32 pc = m68k_getpc () + o; ! 564: return uae_mmu_get_iword (pc); ! 565: } ! 566: STATIC_INLINE uae_u32 get_ilong_mmu (int o) ! 567: { ! 568: uae_u32 pc = m68k_getpc () + o; ! 569: return uae_mmu_get_ilong (pc); ! 570: } ! 571: STATIC_INLINE uae_u32 next_iword_mmu (void) ! 572: { ! 573: uae_u32 pc = m68k_getpc (); ! 574: m68k_incpci (2); ! 575: return uae_mmu_get_iword (pc); ! 576: } ! 577: STATIC_INLINE uae_u32 next_ilong_mmu (void) ! 578: { ! 579: uae_u32 pc = m68k_getpc (); ! 580: m68k_incpci (4); ! 581: return uae_mmu_get_ilong (pc); ! 582: } ! 583: ! 584: extern void m68k_do_rts_mmu (void); ! 585: extern void m68k_do_rte_mmu (uaecptr a7); ! 586: extern void m68k_do_bsr_mmu (uaecptr oldpc, uae_s32 offset); ! 587: ! 588: struct mmufixup ! 589: { ! 590: int reg; ! 591: uae_u32 value; ! 592: }; ! 593: extern struct mmufixup mmufixup[2]; ! 594: ! 595: #endif /* CPUMMU_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.