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