Annotation of nono/m680x0/m680x0.h, revision 1.1.1.1

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: #pragma once
                      8: 
                      9: #include "bus.h"
                     10: 
                     11: // どこ?
                     12: __BEGIN_DECLS
                     13: #include "fpu_emulate.h"
                     14: __END_DECLS
                     15: 
                     16: // MPU 種別
                     17: enum class m680x0MPUType
                     18: {
                     19:        NONE = 0,
                     20:        M68030 = (1U << 1),
                     21:        M68040 = (1U << 2),
                     22: };
                     23: 
                     24: // FPU 種別
                     25: struct m680x0FPUType
                     26: {
                     27:        enum m680x0FPUType_ {
                     28:                M68030_NOFPU    = 0,                    // 68030 without 6888x
                     29:                M68LC040                = (1U << 0),
                     30:                M68LC060                = (1U << 1),    // (reserved)
                     31:                M68040                  = (1U << 2),
                     32:                M68060                  = (1U << 3),    // (reserved)
                     33:                M68881                  = (1U << 4),
                     34:                M68882                  = (1U << 5),
                     35: 
                     36:                M68LC0x0                = (M68LC040 | M68LC060),
                     37:                M680x0                  = (M68040 | M68060),
                     38:                M6888x                  = (M68881 | M68882),
                     39:        } type {};
                     40: 
                     41:        // コンストラクタ
                     42:        m680x0FPUType() {
                     43:        }
                     44:        m680x0FPUType(m680x0FPUType_ type_)
                     45:                : type(type_)
                     46:        {
                     47:        }
                     48: 
                     49:        bool IsNoFPU() const noexcept   { return (type == M68030_NOFPU); }
                     50:        bool Is4060LC() const noexcept  { return (type & M68LC0x0) != 0; }
                     51:        bool Is40FPU() const noexcept   { return (type & M68040) != 0; }
                     52:        bool Is4060FPU() const noexcept { return (type & M680x0) != 0; }
                     53:        bool Is6888x() const noexcept   { return (type & M6888x) != 0; }
                     54: };
                     55: static inline bool operator==(const m680x0FPUType& a, const m680x0FPUType& b) {
                     56:        return (a.type == b.type);
                     57: }
                     58: static inline bool operator!=(const m680x0FPUType& a, const m680x0FPUType& b) {
                     59:        return !(a == b);
                     60: }
                     61: 
                     62: // 定数
                     63: struct M68K
                     64: {
                     65:        // SR(CCR)
                     66:        static const uint32 SR_T                        = 0xc000;
                     67:        static const uint32 SR_S                        = 0x2000;
                     68:        static const uint32 SR_M                        = 0x1000;
                     69:        static const uint32 SR_IMASK            = 0x0700;
                     70:        static const uint32 CCR_X                       = 0x0010;
                     71:        static const uint32 CCR_N                       = 0x0008;
                     72:        static const uint32 CCR_Z                       = 0x0004;
                     73:        static const uint32 CCR_V                       = 0x0002;
                     74:        static const uint32 CCR_C                       = 0x0001;
                     75: 
                     76:        // FC
                     77:        static const uint32 FC_DATA                     = 1;
                     78:        static const uint32 FC_PROG                     = 2;
                     79:        static const uint32 FC_USER                     = 0;
                     80:        static const uint32 FC_SUPER            = 4;
                     81:        static const uint32 FC_UD                       = (FC_USER  | FC_DATA);
                     82:        static const uint32 FC_UP                       = (FC_USER  | FC_PROG);
                     83:        static const uint32 FC_SD                       = (FC_SUPER | FC_DATA);
                     84:        static const uint32 FC_SP                       = (FC_SUPER | FC_PROG);
                     85: 
                     86:        // FP
                     87:        static const uint32 FPCR_MASK           = 0x0000fff0;
                     88:        static const uint32 FPSR_MASK           = 0x0ffffff8;
                     89: 
                     90:        // 例外 (型は core.cpp の try-catch と揃えること)。
                     91:        // FPU_NOIMPL (浮動小数点未実装命令例外) はベクタ番号が 11 ($b) で
                     92:        // F ラインと同じだが処理が色々違うので帯域外のビットで判別する。
                     93:        static const uint EXCEP_RESET                   = 0;
                     94:        static const uint EXCEP_BUSERR                  = 2;
                     95:        static const uint EXCEP_ADDRERR                 = 3;
                     96:        static const uint EXCEP_ILLEGAL                 = 4;
                     97:        static const uint EXCEP_ZERODIV                 = 5;
                     98:        static const uint EXCEP_CHK                             = 6;
                     99:        static const uint EXCEP_TRAPV                   = 7;
                    100:        static const uint EXCEP_PRIV                    = 8;
                    101:        static const uint EXCEP_TRACE                   = 9;
                    102:        static const uint EXCEP_ALINE                   = 10;
                    103:        static const uint EXCEP_FLINE                   = 11;
                    104:        static const uint EXCEP_FP_UNIMPL               = (11 | 0x100);
                    105:        static const uint EXCEP_COPRO                   = 13;
                    106:        static const uint EXCEP_FORMAT                  = 14;
                    107:        static const uint EXCEP_UNINIT_INTR             = 16;
                    108:        static const uint EXCEP_SPURIOUS                = 24;
                    109:        static const uint EXCEP_LEVEL_BASE              = 24;   // オートベクタ演算用
                    110:        static const uint EXCEP_LEVEL1                  = 25;
                    111:        static const uint EXCEP_LEVEL7                  = 31;
                    112:        static const uint EXCEP_TRAP0                   = 32;
                    113:        static const uint EXCEP_TRAP15                  = 47;
                    114:        static const uint EXCEP_FP_BSUN                 = 48;
                    115:        static const uint EXCEP_FP_INEX                 = 49;
                    116:        static const uint EXCEP_FP_ZERODIV              = 50;
                    117:        static const uint EXCEP_FP_UNFL                 = 51;
                    118:        static const uint EXCEP_FP_OPERR                = 52;
                    119:        static const uint EXCEP_FP_OVFL                 = 53;
                    120:        static const uint EXCEP_FP_SNAN                 = 54;
                    121:        static const uint EXCEP_FP_UNSUPP               = 55;
                    122:        static const uint EXCEP_MMU_CONFIG              = 56;
                    123: };
                    124: 
                    125: // 定数
                    126: struct M68030
                    127: {
                    128:        // SSW
                    129:        static constexpr uint32 SSW_SIZE(uint32 x) { return ((x) & 0x03) << 4; }
                    130:        static const uint32 SSW_SIZE_LONG       = (0 << 4);
                    131:        static const uint32 SSW_SIZE_BYTE       = (1 << 4);
                    132:        static const uint32 SSW_SIZE_WORD       = (2 << 4);
                    133:        static const uint32 SSW_SIZE_3BYTES     = (3 << 4);
                    134:        static const uint32 SSW_SIZE_MASK       = (0x03 << 4);
                    135: 
                    136:        static const uint32 SSW_FC_MASK         = 0x0007;       // FC_*
                    137:        static const uint32 SSW_RW                      = 0x0040;       // SSW_BUS_{R,W}
                    138:        static const uint32 SSW_RM                      = 0x0080;
                    139:        static const uint32 SSW_DF                      = 0x0100;       // Data Fault
                    140:        static const uint32 SSW_RB                      = 0x1000;
                    141:        static const uint32 SSW_RC                      = 0x2000;
                    142:        static const uint32 SSW_FB                      = 0x4000;
                    143:        static const uint32 SSW_FC                      = 0x8000;
                    144: 
                    145:        static const uint32 SSW_BUS_R           = 0x0040;
                    146:        static const uint32 SSW_BUS_W           = 0x0000;
                    147: 
                    148:        // CACR
                    149:        static const uint32 CACR_EI                     = 0x0001;
                    150:        static const uint32 CACR_FI                     = 0x0002;
                    151:        static const uint32 CACR_CEI            = 0x0004;
                    152:        static const uint32 CACR_CI                     = 0x0008;
                    153:        static const uint32 CACR_IBE            = 0x0010;
                    154:        static const uint32 CACR_ED                     = 0x0100;
                    155:        static const uint32 CACR_FD                     = 0x0200;
                    156:        static const uint32 CACR_CED            = 0x0400;
                    157:        static const uint32 CACR_CD                     = 0x0800;
                    158:        static const uint32 CACR_DBE            = 0x1000;
                    159:        static const uint32 CACR_WA                     = 0x2000;
                    160:        static const uint32 CACR_MASK           = 0x3f1f;
                    161: };
                    162: 
                    163: // 定数
                    164: struct M68040
                    165: {
                    166:        // SSW
                    167:        static const uint32 SSW_TM_MASK         = 0x0007;
                    168:        static const uint32 SSW_TT_MASK         = 0x0018;
                    169:        static const uint32 SSW_SIZE_MASK       = 0x0060;       // (0x03 << 5)
                    170:        static const uint32 SSW_RW                      = 0x0100;
                    171:        static const uint32 SSW_LK                      = 0x0200;
                    172:        static const uint32 SSW_ATC                     = 0x0400;
                    173:        static const uint32 SSW_MA                      = 0x0800;
                    174:        static const uint32 SSW_CM                      = 0x1000;
                    175:        static const uint32 SSW_CT                      = 0x2000;
                    176:        static const uint32 SSW_CU                      = 0x4000;
                    177:        static const uint32 SSW_CP                      = 0x8000;
                    178: 
                    179:        static const uint32 SSW_SIZE_LONG       = (0x00 << 5);
                    180:        static const uint32 SSW_SIZE_BYTE       = (0x01 << 5);
                    181:        static const uint32 SSW_SIZE_WORD       = (0x02 << 5);
                    182:        static const uint32 SSW_SIZE_LINE       = (0x03 << 5);
                    183:        // バイトサイズから SSW_SIZE フィールドを作成する。1, 2, 4 バイトのみ。
                    184:        static constexpr uint32 SSW_SIZE(uint32 x) { return ((x) & 0x03) << 5; }
                    185: 
                    186:        // CACR
                    187:        static const uint32 CACR_MASK           = 0x80008000;
                    188:        static const uint32 CACR_DE                     = 0x80000000;
                    189:        static const uint32 CACR_IE                     = 0x00008000;
                    190: };
                    191: 
                    192: struct m680x0CCR
                    193: {
                    194:  protected:
                    195:        // X フラグは、X の X_BIT が立っていれば 1
                    196:        // N フラグは、N の N_BIT が立っていれば 1
                    197:        // Z フラグは、Z == 0 なら 1
                    198:        // V フラグは、V の V_BIT が立っていれば 1
                    199:        // C フラグは、C の C_BIT が立っていれば 1
                    200:        static const uint32 X_BIT = 0x00000001;
                    201:        static const uint32 N_BIT = 0x80000000;
                    202:        static const uint32 V_BIT = 0x80000000;
                    203:        static const uint32 C_BIT = 0x00000001;
                    204: 
                    205:        uint32 X;
                    206:        uint32 V;
                    207:        uint32 N;
                    208:        DEF_UNION64(, CZ, C, Z);
                    209: 
                    210:  public:
                    211:        // value をフラグにセットする
                    212:        void SetX(bool value) { X = (value) ? X_BIT : 0; }
                    213:        void SetN(bool value) { N = (value) ? N_BIT : 0; }
                    214:        void SetZ(bool value) { Z = (value) ? 0 : 1; }
                    215:        void SetV(bool value) { V = (value) ? V_BIT : 0; }
                    216:        void SetC(bool value) { C = (value) ? C_BIT : 0; }
                    217: 
                    218:        // フラグが立っていれば真を返す
                    219:        bool IsX() const { return ((X & X_BIT) != 0); }
                    220:        bool IsN() const { return ((N & N_BIT) != 0); }
                    221:        bool IsZ() const { return (Z == 0); }
                    222:        bool IsV() const { return ((V & V_BIT) != 0); }
                    223:        bool IsC() const { return ((C & C_BIT) != 0); }
                    224: 
                    225:        // CCR レジスタの内容を作って返す
                    226:        uint8 Get() const {
                    227:                return (IsX() ? M68K::CCR_X : 0)
                    228:                     | (IsN() ? M68K::CCR_N : 0)
                    229:                     | (IsZ() ? M68K::CCR_Z : 0)
                    230:                     | (IsV() ? M68K::CCR_V : 0)
                    231:                     | (IsC() ? M68K::CCR_C : 0);
                    232:        }
                    233: 
                    234:        // CCR レジスタに val をセットする
                    235:        void Set(uint8 val) {
                    236:                SetX((val) & M68K::CCR_X);
                    237:                SetN((val) & M68K::CCR_N);
                    238:                SetZ((val) & M68K::CCR_Z);
                    239:                SetV((val) & M68K::CCR_V);
                    240:                SetC((val) & M68K::CCR_C);
                    241:        }
                    242: 
                    243:        bool CondT()  const { return true; }
                    244:        bool CondF()  const { return false; }
                    245:        bool CondHI() const { return !IsC() && !IsZ(); }
                    246:        bool CondLS() const { return IsC() || IsZ(); }
                    247:        bool CondCC() const { return !IsC(); }
                    248:        bool CondCS() const { return IsC(); }
                    249:        bool CondNE() const { return !IsZ(); }
                    250:        bool CondEQ() const { return IsZ(); }
                    251:        bool CondVC() const { return !IsV(); }
                    252:        bool CondVS() const { return IsV(); }
                    253:        bool CondPL() const { return !IsN(); }
                    254:        bool CondMI() const { return IsN(); }
                    255:        bool CondGE() const { return (IsN() && IsV()) || (!IsN() && !IsV()); }
                    256:        bool CondLT() const { return (IsN() && !IsV()) || (!IsN() && IsV()); }
                    257:        bool CondGT() const {
                    258:                return (IsN() && IsV() && !IsZ()) || (!IsN() && !IsV() && !IsZ());
                    259:        }
                    260:        bool CondLE() const {
                    261:                return IsZ() || (IsN() && !IsV()) || (!IsN() && IsV());
                    262:        }
                    263: 
                    264:        // cond で示される条件が成立すれば true を返す。
                    265:        inline bool Cond(uint cond) const {
                    266:                switch (cond) {
                    267:                 case 0:        // T
                    268:                        return CondT();
                    269:                 case 1:        // F
                    270:                        return CondF();
                    271:                 case 2:
                    272:                        return CondHI();
                    273:                 case 3:
                    274:                        return CondLS();
                    275:                 case 4:
                    276:                        return CondCC();
                    277:                 case 5:
                    278:                        return CondCS();
                    279:                 case 6:
                    280:                        return CondNE();
                    281:                 case 7:
                    282:                        return CondEQ();
                    283:                 case 8:
                    284:                        return CondVC();
                    285:                 case 9:
                    286:                        return CondVS();
                    287:                 case 10:
                    288:                        return CondPL();
                    289:                 case 11:
                    290:                        return CondMI();
                    291:                 case 12:
                    292:                        return CondGE();
                    293:                 case 13:
                    294:                        return CondLT();
                    295:                 case 14:
                    296:                        return CondGT();
                    297:                 case 15:
                    298:                        return CondLE();
                    299:                }
                    300:                __unreachable();
                    301:        }
                    302: };
                    303: 
                    304: // レジスタイメージを保持する構造体。
                    305: // この構造体はコピーとか比較をするのでポインタとかは置かないこと。
                    306: struct m68kreg
                    307: {
                    308:        uint32 pc;
                    309:        union {
                    310:                uint32 R[16] {};
                    311:                struct {
                    312:                        uint32 D[8];
                    313:                        uint32 A[8];
                    314:                };
                    315:        };
                    316: 
                    317:        m680x0CCR ccr;
                    318:        bool s;                         // SR の S ビット
                    319:        bool m;                         // SR の M ビット
                    320:        int  intr_mask;         // SR の割り込みマスク (0-7)
                    321: 
                    322:        // 現在の SP は常に A[7]。A[7] が示しているときは対応する変数の
                    323:        // ほうは更新されないため無効 (図中 'x')。
                    324:        //
                    325:        //                                              A[7]    usp             isp             msp
                    326:        //                      ----    ---             ---             ---
                    327:        // ユーザ                            USP             x               ISP             MSP
                    328:        // スーパーバイザ(I)     ISP             USP             x               MSP
                    329:        // スーパーバイザ(M)     MSP             USP             ISP             x
                    330:        uint32 usp;
                    331:        uint32 isp;
                    332:        uint32 msp;
                    333: 
                    334:        uint32 vbr;
                    335:        busaddr sfc;            // (R/W も含む)
                    336:        busaddr dfc;            // (R/W も含む)
                    337: 
                    338:        uint32 cacr;
                    339:        uint32 caar;
                    340: 
                    341:        // 68030 MMU
                    342:        union64 srp;
                    343:        union64 crp;
                    344:        uint32 tt[2];
                    345:        uint32 tc;
                    346:        uint16 mmusr;
                    347: 
                    348:        // 68040 MMU
                    349:        uint32 itt[2];
                    350:        uint32 dtt[2];
                    351:        uint32 srp40;
                    352:        uint32 urp40;
                    353:        uint16 tc40;
                    354:        uint32 mmusr40;
                    355: 
                    356:        struct fpframe fpframe;
                    357: 
                    358:        // SR レジスタ全体を返す
                    359:        uint16 GetSR() const {
                    360:                return (s ? M68K::SR_S : 0)
                    361:                     | (m ? M68K::SR_M : 0)
                    362:                     | (intr_mask << 8)
                    363:                     | ccr.Get();
                    364:        }
                    365:        // SFC, DFC レジスタの値を返す
                    366:        uint32 GetSFC() const { return sfc.GetFC(); }
                    367:        uint32 GetDFC() const { return dfc.GetFC(); }
                    368: };
                    369: 
                    370: // バス状態
                    371: struct m68kbus
                    372: {
                    373:        // 論理アドレス。(R/W, FC2-0, Addr すべて使用)
                    374:        busaddr laddr;
                    375: 
                    376:        // 対応する物理アドレス (FC2, Addr のみ使用)
                    377:        busaddr paddr;
                    378: 
                    379:        // アクセスサイズ (バイト数で表す)
                    380:        uint32 size;
                    381: 
                    382:        // データバス。
                    383:        // 今の所書き込みだけで使う。読み込みデータは戻り値のみ。
                    384:        uint32 data;
                    385: 
                    386:        // キャッシュ禁止。/CIIN
                    387:        bool ci;
                    388: 
                    389:        // ATC フォールト (68040 only)
                    390:        bool atcfault;
                    391: 
                    392:        // ATC フォールトが2ページ目で起きたら true (68040 only)
                    393:        bool atcfault2;
                    394: 
                    395:        // Supervisor アクセスなら true を返す
                    396:        bool IsSuper() const { return laddr.IsSuper(); }
                    397: 
                    398:        // バスが Write なら true を返す
                    399:        bool IsWrite() const { return laddr.IsWrite(); }
                    400: };
                    401: 
                    402: // 仮
                    403: #define RegFP(n)       (reg.fpframe.fpf_regs[(n) * 3])
                    404: #define RegFPCR                (reg.fpframe.fpf_fpcr)
                    405: #define RegFPSR                (reg.fpframe.fpf_fpsr)
                    406: #define RegFPIAR       (reg.fpframe.fpf_fpiar)

unix.superglobalmegacorp.com

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