Annotation of nono/m680x0/m68030.h, revision 1.1.1.14

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
1.1.1.13  root        9: #include "bus.h"
1.1       root       10: 
1.1.1.12  root       11: // どこ?
1.1       root       12: __BEGIN_DECLS
                     13: #include "fpu_emulate.h"
                     14: __END_DECLS
                     15: 
1.1.1.12  root       16: // 定数
                     17: struct M68K
                     18: {
                     19:        // SR(CCR)
                     20:        static const uint32 SR_T                        = 0xc000;
                     21:        static const uint32 SR_S                        = 0x2000;
                     22:        static const uint32 SR_M                        = 0x1000;
                     23:        static const uint32 SR_IMASK            = 0x0700;
                     24:        static const uint32 CCR_X                       = 0x0010;
                     25:        static const uint32 CCR_N                       = 0x0008;
                     26:        static const uint32 CCR_Z                       = 0x0004;
                     27:        static const uint32 CCR_V                       = 0x0002;
                     28:        static const uint32 CCR_C                       = 0x0001;
                     29: 
                     30:        // SSW
                     31:        static constexpr uint32 SSW_SIZE(uint32 x) { return ((x) & 0x03) << 4; }
                     32:        static const uint32 SSW_SIZE_LONG       = (0 << 4);
                     33:        static const uint32 SSW_SIZE_BYTE       = (1 << 4);
                     34:        static const uint32 SSW_SIZE_WORD       = (2 << 4);
                     35:        static const uint32 SSW_SIZE_3BYTES     = (3 << 4);
                     36:        static const uint32 SSW_SIZE_MASK       = (0x03 << 4);
                     37: 
                     38:        static const uint32 SSW_FC_MASK         = 0x0007;       // FC_*
                     39:        static const uint32 SSW_RW                      = 0x0040;       // SSW_BUS_{R,W}
                     40:        static const uint32 SSW_RM                      = 0x0080;
                     41:        static const uint32 SSW_DF                      = 0x0100;       // Data Fault
                     42:        static const uint32 SSW_RB                      = 0x1000;
                     43:        static const uint32 SSW_RC                      = 0x2000;
                     44:        static const uint32 SSW_FB                      = 0x4000;
                     45:        static const uint32 SSW_FC                      = 0x8000;
                     46: 
                     47:        static const uint32 SSW_BUS_R           = 0x0040;
                     48:        static const uint32 SSW_BUS_W           = 0x0000;
                     49: 
                     50:        // FC
                     51:        static const uint32 FC_DATA                     = 1;
                     52:        static const uint32 FC_PROG                     = 2;
                     53:        static const uint32 FC_USER                     = 0;
                     54:        static const uint32 FC_SUPER            = 4;
                     55:        static const uint32 FC_UD                       = (FC_USER  | FC_DATA);
                     56:        static const uint32 FC_UP                       = (FC_USER  | FC_PROG);
                     57:        static const uint32 FC_SD                       = (FC_SUPER | FC_DATA);
                     58:        static const uint32 FC_SP                       = (FC_SUPER | FC_PROG);
                     59: 
                     60:        // CACR
                     61:        static const uint32 CACR_EI                     = 0x0001;
                     62:        static const uint32 CACR_FI                     = 0x0002;
                     63:        static const uint32 CACR_CEI            = 0x0004;
                     64:        static const uint32 CACR_CI                     = 0x0008;
                     65:        static const uint32 CACR_IBE            = 0x0010;
                     66:        static const uint32 CACR_ED                     = 0x0100;
                     67:        static const uint32 CACR_FD                     = 0x0200;
                     68:        static const uint32 CACR_CED            = 0x0400;
                     69:        static const uint32 CACR_CD                     = 0x0800;
                     70:        static const uint32 CACR_DBE            = 0x1000;
                     71:        static const uint32 CACR_WA                     = 0x2000;
1.1.1.13  root       72:        static const uint32 CACR_MASK           = 0x3f1f;
1.1.1.12  root       73: 
                     74:        // FP
                     75:        static const uint32 FPCR_MASK           = 0x0000fff0;
                     76:        static const uint32 FPSR_MASK           = 0x0ffffff8;
                     77: 
                     78:        // 例外
                     79:        // (型は core.cpp の try-catch と揃えること)
1.1.1.14! root       80:        static const uint EXCEP_RESET                   = 0;
        !            81:        static const uint EXCEP_BUSERR                  = 2;
        !            82:        static const uint EXCEP_ADDRERR                 = 3;
        !            83:        static const uint EXCEP_ILLEGAL                 = 4;
        !            84:        static const uint EXCEP_ZERODIV                 = 5;
        !            85:        static const uint EXCEP_CHK                             = 6;
        !            86:        static const uint EXCEP_TRAPV                   = 7;
        !            87:        static const uint EXCEP_PRIV                    = 8;
        !            88:        static const uint EXCEP_TRACE                   = 9;
        !            89:        static const uint EXCEP_ALINE                   = 10;
        !            90:        static const uint EXCEP_FLINE                   = 11;
        !            91:        static const uint EXCEP_COPRO                   = 13;
        !            92:        static const uint EXCEP_FORMAT                  = 14;
        !            93:        static const uint EXCEP_UNINIT_INTR             = 16;
        !            94:        static const uint EXCEP_SPURIOUS                = 24;
        !            95:        static const uint EXCEP_LEVEL_BASE              = 24;   // オートベクタ演算用
        !            96:        static const uint EXCEP_LEVEL1                  = 25;
        !            97:        static const uint EXCEP_LEVEL7                  = 31;
        !            98:        static const uint EXCEP_TRAP0                   = 32;
        !            99:        static const uint EXCEP_TRAP15                  = 47;
        !           100:        static const uint EXCEP_FPCP_BRANCH             = 48;
        !           101:        static const uint EXCEP_FPCP_INEXACT    = 49;
        !           102:        static const uint EXCEP_FPCP_ZERODIV    = 50;
        !           103:        static const uint EXCEP_FPCP_UNFL               = 51;
        !           104:        static const uint EXCEP_FPCP_OPERR              = 52;
        !           105:        static const uint EXCEP_FPCP_OVFL               = 53;
        !           106:        static const uint EXCEP_FPCP_SNAN               = 54;
        !           107:        static const uint EXCEP_MMU_CONFIG              = 56;
1.1.1.12  root      108: };
                    109: 
                    110: struct m68030ccr
                    111: {
                    112:  protected:
                    113:        // X フラグは、X の X_BIT が立っていれば 1
                    114:        // N フラグは、N の N_BIT が立っていれば 1
                    115:        // Z フラグは、Z == 0 なら 1
                    116:        // V フラグは、V の V_BIT が立っていれば 1
                    117:        // C フラグは、C の C_BIT が立っていれば 1
                    118:        static const uint32 X_BIT = 0x00000001;
                    119:        static const uint32 N_BIT = 0x80000000;
                    120:        static const uint32 V_BIT = 0x80000000;
                    121:        static const uint32 C_BIT = 0x00000001;
                    122: 
                    123:        uint32 X;
                    124:        uint32 V;
                    125:        uint32 N;
1.1.1.14! root      126:        DEF_UNION64(, CZ, C, Z);
1.1       root      127: 
1.1.1.12  root      128:  public:
                    129:        // value をフラグにセットする
                    130:        void SetX(bool value) { X = (value) ? X_BIT : 0; }
                    131:        void SetN(bool value) { N = (value) ? N_BIT : 0; }
                    132:        void SetZ(bool value) { Z = (value) ? 0 : 1; }
                    133:        void SetV(bool value) { V = (value) ? V_BIT : 0; }
                    134:        void SetC(bool value) { C = (value) ? C_BIT : 0; }
                    135: 
                    136:        // フラグが立っていれば真を返す
                    137:        bool IsX() const { return ((X & X_BIT) != 0); }
                    138:        bool IsN() const { return ((N & N_BIT) != 0); }
                    139:        bool IsZ() const { return (Z == 0); }
                    140:        bool IsV() const { return ((V & V_BIT) != 0); }
                    141:        bool IsC() const { return ((C & C_BIT) != 0); }
                    142: 
                    143:        // CCR レジスタの内容を作って返す
                    144:        uint8 Get() const {
                    145:                return (IsX() ? M68K::CCR_X : 0)
                    146:                     | (IsN() ? M68K::CCR_N : 0)
                    147:                     | (IsZ() ? M68K::CCR_Z : 0)
                    148:                     | (IsV() ? M68K::CCR_V : 0)
                    149:                     | (IsC() ? M68K::CCR_C : 0);
                    150:        }
1.1.1.10  root      151: 
1.1.1.12  root      152:        // CCR レジスタに val をセットする
                    153:        void Set(uint8 val) {
                    154:                SetX((val) & M68K::CCR_X);
                    155:                SetN((val) & M68K::CCR_N);
                    156:                SetZ((val) & M68K::CCR_Z);
                    157:                SetV((val) & M68K::CCR_V);
                    158:                SetC((val) & M68K::CCR_C);
                    159:        }
1.1       root      160: 
1.1.1.12  root      161:        bool CondT()  const { return true; }
                    162:        bool CondF()  const { return false; }
                    163:        bool CondHI() const { return !IsC() && !IsZ(); }
                    164:        bool CondLS() const { return IsC() || IsZ(); }
                    165:        bool CondCC() const { return !IsC(); }
                    166:        bool CondCS() const { return IsC(); }
                    167:        bool CondNE() const { return !IsZ(); }
                    168:        bool CondEQ() const { return IsZ(); }
                    169:        bool CondVC() const { return !IsV(); }
                    170:        bool CondVS() const { return IsV(); }
                    171:        bool CondPL() const { return !IsN(); }
                    172:        bool CondMI() const { return IsN(); }
                    173:        bool CondGE() const { return (IsN() && IsV()) || (!IsN() && !IsV()); }
                    174:        bool CondLT() const { return (IsN() && !IsV()) || (!IsN() && IsV()); }
                    175:        bool CondGT() const {
                    176:                return (IsN() && IsV() && !IsZ()) || (!IsN() && !IsV() && !IsZ());
                    177:        }
                    178:        bool CondLE() const {
                    179:                return IsZ() || (IsN() && !IsV()) || (!IsN() && IsV());
                    180:        }
                    181: 
                    182:        // cond で示される条件が成立すれば true を返す。
1.1.1.14! root      183:        inline bool Cond(uint cond) const {
1.1.1.12  root      184:                switch (cond) {
                    185:                 case 0:        // T
                    186:                        return CondT();
                    187:                 case 1:        // F
                    188:                        return CondF();
                    189:                 case 2:
                    190:                        return CondHI();
                    191:                 case 3:
                    192:                        return CondLS();
                    193:                 case 4:
                    194:                        return CondCC();
                    195:                 case 5:
                    196:                        return CondCS();
                    197:                 case 6:
                    198:                        return CondNE();
                    199:                 case 7:
                    200:                        return CondEQ();
                    201:                 case 8:
                    202:                        return CondVC();
                    203:                 case 9:
                    204:                        return CondVS();
                    205:                 case 10:
                    206:                        return CondPL();
                    207:                 case 11:
                    208:                        return CondMI();
                    209:                 case 12:
                    210:                        return CondGE();
                    211:                 case 13:
                    212:                        return CondLT();
                    213:                 case 14:
                    214:                        return CondGT();
                    215:                 case 15:
                    216:                        return CondLE();
                    217:                }
                    218:                __unreachable();
                    219:        }
                    220: };
1.1       root      221: 
                    222: // レジスタイメージを保持する構造体。
                    223: // この構造体はコピーとか比較をするのでポインタとかは置かないこと。
1.1.1.12  root      224: struct m68kreg
                    225: {
1.1       root      226:        uint32 pc;
1.1.1.12  root      227:        union {
                    228:                uint32 R[16] {};
                    229:                struct {
                    230:                        uint32 D[8];
                    231:                        uint32 A[8];
                    232:                };
                    233:        };
1.1       root      234: 
                    235:        m68030ccr ccr;
                    236:        bool s;                         // SR の S ビット
                    237:        bool m;                         // SR の M ビット
1.1.1.11  root      238:        int  intr_mask;         // SR の割り込みマスク (0-7)
1.1       root      239: 
1.1.1.12  root      240:        // 現在の SP は常に A[7]。A[7] が示しているときは対応する変数の
1.1.1.14! root      241:        // ほうは更新されないため無効 (図中 'x')。
        !           242:        //
        !           243:        //                                              A[7]    usp             isp             msp
        !           244:        //                      ----    ---             ---             ---
        !           245:        // ユーザ                            USP             x               ISP             MSP
        !           246:        // スーパーバイザ(I)     ISP             USP             x               MSP
        !           247:        // スーパーバイザ(M)     MSP             USP             ISP             x
1.1       root      248:        uint32 usp;
                    249:        uint32 isp;
                    250:        uint32 msp;
                    251: 
                    252:        uint32 vbr;
1.1.1.13  root      253:        busaddr sfc;            // (R/W も含む)
                    254:        busaddr dfc;            // (R/W も含む)
1.1       root      255: 
                    256:        uint32 cacr;
                    257:        uint32 caar;
                    258: 
                    259:        union64 srp;
                    260:        union64 crp;
                    261:        uint32 tt[2];
                    262:        uint32 tc;
                    263:        uint16 mmusr;
                    264: 
                    265:        struct fpframe fpframe;
                    266: 
1.1.1.12  root      267:        // SR レジスタ全体を返す
                    268:        uint16 GetSR() const {
                    269:                return (s ? M68K::SR_S : 0)
                    270:                     | (m ? M68K::SR_M : 0)
                    271:                     | (intr_mask << 8)
                    272:                     | ccr.Get();
1.1       root      273:        }
1.1.1.13  root      274:        // SFC, DFC レジスタの値を返す
                    275:        uint32 GetSFC() const { return sfc.GetFC(); }
                    276:        uint32 GetDFC() const { return dfc.GetFC(); }
1.1       root      277: };
                    278: 
                    279: // バス状態
1.1.1.12  root      280: struct m68kbus
                    281: {
1.1.1.13  root      282:        // 論理アドレス。(R/W, FC2-0, Addr すべて使用)
                    283:        busaddr laddr;
                    284: 
                    285:        // 対応する物理アドレス (FC2, Addr のみ使用)
                    286:        busaddr paddr;
                    287: 
                    288:        // アクセスサイズ (SSW_SIZE_*)
                    289:        uint32 size;
1.1       root      290: 
                    291:        // データバス。
                    292:        // 今の所書き込みだけで使う。読み込みデータは戻り値のみ。
                    293:        uint32 data;
                    294: 
1.1.1.13  root      295:        // キャッシュ禁止。/CIIN
                    296:        bool ci;
                    297: 
                    298:        // Supervisor アクセスなら true を返す
                    299:        bool IsSuper() const { return laddr.IsSuper(); }
1.1       root      300: 
                    301:        // バスが Write なら true を返す
1.1.1.13  root      302:        bool IsWrite() const { return laddr.IsWrite(); }
1.1       root      303: 
1.1.1.13  root      304:        // FC を取得する。(これは MMU ルーチンから呼ばれる)
                    305:        uint GetFC() const { return laddr.GetFC(); }
1.1       root      306: 
1.1.1.13  root      307:        // SSW を取得する。
                    308:        uint32 GetSSW() const { return laddr.GetSSW() | size; }
1.1.1.11  root      309: 
1.1.1.13  root      310:        // アクセス方向(R/W)を設定する。
1.1.1.14! root      311:        void SetWrite(bool write_) { laddr.ChangeWrite(write_); }
1.1       root      312: };
                    313: 
1.1.1.12  root      314: // 仮
                    315: #define RegFP(n)       (reg.fpframe.fpf_regs[n])
                    316: #define RegFPCR                (reg.fpframe.fpf_fpcr)
                    317: #define RegFPSR                (reg.fpframe.fpf_fpsr)
                    318: #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.