Annotation of hatari/src/cpu/cpummu.h, revision 1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.