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

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.12! root        9: #include "header.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;
        !            72: 
        !            73:        // FP
        !            74:        static const uint32 FPCR_MASK           = 0x0000fff0;
        !            75:        static const uint32 FPSR_MASK           = 0x0ffffff8;
        !            76: 
        !            77:        // 例外
        !            78:        // (型は core.cpp の try-catch と揃えること)
        !            79:        static const int EXCEP_RESET                    = 0;
        !            80:        static const int EXCEP_BUSERR                   = 2;
        !            81:        static const int EXCEP_ADDRERR                  = 3;
        !            82:        static const int EXCEP_ILLEGAL                  = 4;
        !            83:        static const int EXCEP_ZERODIV                  = 5;
        !            84:        static const int EXCEP_CHK                              = 6;
        !            85:        static const int EXCEP_TRAPV                    = 7;
        !            86:        static const int EXCEP_PRIV                             = 8;
        !            87:        static const int EXCEP_TRACE                    = 9;
        !            88:        static const int EXCEP_ALINE                    = 10;
        !            89:        static const int EXCEP_FLINE                    = 11;
        !            90:        static const int EXCEP_COPRO                    = 13;
        !            91:        static const int EXCEP_FORMAT                   = 14;
        !            92:        static const int EXCEP_UNINIT_INTR              = 16;
        !            93:        static const int EXCEP_SPURIOUS                 = 24;
        !            94:        static const int EXCEP_LEVEL_BASE               = 24;   // オートベクタ演算用
        !            95:        static const int EXCEP_LEVEL1                   = 25;
        !            96:        static const int EXCEP_LEVEL7                   = 31;
        !            97:        static const int EXCEP_TRAP0                    = 32;
        !            98:        static const int EXCEP_TRAP15                   = 47;
        !            99:        static const int EXCEP_FPCP_BRANCH              = 48;
        !           100:        static const int EXCEP_FPCP_INEXACT             = 49;
        !           101:        static const int EXCEP_FPCP_ZERODIV             = 50;
        !           102:        static const int EXCEP_FPCP_UNFL                = 51;
        !           103:        static const int EXCEP_FPCP_OPERR               = 52;
        !           104:        static const int EXCEP_FPCP_OVFL                = 53;
        !           105:        static const int EXCEP_FPCP_SNAN                = 54;
        !           106:        static const int EXCEP_MMU_CONFIG               = 56;
        !           107: };
        !           108: 
        !           109: struct m68030ccr
        !           110: {
        !           111:  protected:
        !           112:        // X フラグは、X の X_BIT が立っていれば 1
        !           113:        // N フラグは、N の N_BIT が立っていれば 1
        !           114:        // Z フラグは、Z == 0 なら 1
        !           115:        // V フラグは、V の V_BIT が立っていれば 1
        !           116:        // C フラグは、C の C_BIT が立っていれば 1
        !           117:        static const uint32 X_BIT = 0x00000001;
        !           118:        static const uint32 N_BIT = 0x80000000;
        !           119:        static const uint32 V_BIT = 0x80000000;
        !           120:        static const uint32 C_BIT = 0x00000001;
        !           121: 
        !           122:        uint32 X;
        !           123:        uint32 V;
        !           124:        uint32 N;
        !           125:        union {
        !           126:                uint64 CZ;
        !           127:                struct {
        !           128: #if BYTE_ORDER == LITTLE_ENDIAN
        !           129:                        uint32 Z;
        !           130:                        uint32 C;
        !           131: #else
        !           132:                        uint32 C;
        !           133:                        uint32 Z;
        !           134: #endif
        !           135:                } __packed;
        !           136:        };
1.1       root      137: 
1.1.1.12! root      138:  public:
        !           139:        // value をフラグにセットする
        !           140:        void SetX(bool value) { X = (value) ? X_BIT : 0; }
        !           141:        void SetN(bool value) { N = (value) ? N_BIT : 0; }
        !           142:        void SetZ(bool value) { Z = (value) ? 0 : 1; }
        !           143:        void SetV(bool value) { V = (value) ? V_BIT : 0; }
        !           144:        void SetC(bool value) { C = (value) ? C_BIT : 0; }
        !           145: 
        !           146:        // フラグが立っていれば真を返す
        !           147:        bool IsX() const { return ((X & X_BIT) != 0); }
        !           148:        bool IsN() const { return ((N & N_BIT) != 0); }
        !           149:        bool IsZ() const { return (Z == 0); }
        !           150:        bool IsV() const { return ((V & V_BIT) != 0); }
        !           151:        bool IsC() const { return ((C & C_BIT) != 0); }
        !           152: 
        !           153:        // CCR レジスタの内容を作って返す
        !           154:        uint8 Get() const {
        !           155:                return (IsX() ? M68K::CCR_X : 0)
        !           156:                     | (IsN() ? M68K::CCR_N : 0)
        !           157:                     | (IsZ() ? M68K::CCR_Z : 0)
        !           158:                     | (IsV() ? M68K::CCR_V : 0)
        !           159:                     | (IsC() ? M68K::CCR_C : 0);
        !           160:        }
1.1.1.10  root      161: 
1.1.1.12! root      162:        // CCR レジスタに val をセットする
        !           163:        void Set(uint8 val) {
        !           164:                SetX((val) & M68K::CCR_X);
        !           165:                SetN((val) & M68K::CCR_N);
        !           166:                SetZ((val) & M68K::CCR_Z);
        !           167:                SetV((val) & M68K::CCR_V);
        !           168:                SetC((val) & M68K::CCR_C);
        !           169:        }
1.1       root      170: 
1.1.1.12! root      171:        bool CondT()  const { return true; }
        !           172:        bool CondF()  const { return false; }
        !           173:        bool CondHI() const { return !IsC() && !IsZ(); }
        !           174:        bool CondLS() const { return IsC() || IsZ(); }
        !           175:        bool CondCC() const { return !IsC(); }
        !           176:        bool CondCS() const { return IsC(); }
        !           177:        bool CondNE() const { return !IsZ(); }
        !           178:        bool CondEQ() const { return IsZ(); }
        !           179:        bool CondVC() const { return !IsV(); }
        !           180:        bool CondVS() const { return IsV(); }
        !           181:        bool CondPL() const { return !IsN(); }
        !           182:        bool CondMI() const { return IsN(); }
        !           183:        bool CondGE() const { return (IsN() && IsV()) || (!IsN() && !IsV()); }
        !           184:        bool CondLT() const { return (IsN() && !IsV()) || (!IsN() && IsV()); }
        !           185:        bool CondGT() const {
        !           186:                return (IsN() && IsV() && !IsZ()) || (!IsN() && !IsV() && !IsZ());
        !           187:        }
        !           188:        bool CondLE() const {
        !           189:                return IsZ() || (IsN() && !IsV()) || (!IsN() && IsV());
        !           190:        }
        !           191: 
        !           192:        // cond で示される条件が成立すれば true を返す。
        !           193:        inline bool Cond(int cond) const {
        !           194:                switch (cond) {
        !           195:                 case 0:        // T
        !           196:                        return CondT();
        !           197:                 case 1:        // F
        !           198:                        return CondF();
        !           199:                 case 2:
        !           200:                        return CondHI();
        !           201:                 case 3:
        !           202:                        return CondLS();
        !           203:                 case 4:
        !           204:                        return CondCC();
        !           205:                 case 5:
        !           206:                        return CondCS();
        !           207:                 case 6:
        !           208:                        return CondNE();
        !           209:                 case 7:
        !           210:                        return CondEQ();
        !           211:                 case 8:
        !           212:                        return CondVC();
        !           213:                 case 9:
        !           214:                        return CondVS();
        !           215:                 case 10:
        !           216:                        return CondPL();
        !           217:                 case 11:
        !           218:                        return CondMI();
        !           219:                 case 12:
        !           220:                        return CondGE();
        !           221:                 case 13:
        !           222:                        return CondLT();
        !           223:                 case 14:
        !           224:                        return CondGT();
        !           225:                 case 15:
        !           226:                        return CondLE();
        !           227:                }
        !           228:                __unreachable();
        !           229:        }
        !           230: };
1.1       root      231: 
                    232: // レジスタイメージを保持する構造体。
                    233: // この構造体はコピーとか比較をするのでポインタとかは置かないこと。
1.1.1.12! root      234: struct m68kreg
        !           235: {
1.1       root      236:        uint32 pc;
1.1.1.12! root      237:        union {
        !           238:                uint32 R[16] {};
        !           239:                struct {
        !           240:                        uint32 D[8];
        !           241:                        uint32 A[8];
        !           242:                };
        !           243:        };
1.1       root      244: 
                    245:        m68030ccr ccr;
                    246:        bool s;                         // SR の S ビット
                    247:        bool m;                         // SR の M ビット
1.1.1.11  root      248:        int  intr_mask;         // SR の割り込みマスク (0-7)
1.1       root      249: 
1.1.1.12! root      250:        // 現在の SP は常に A[7]。A[7] が示しているときは対応する変数の
1.1.1.10  root      251:        // ほうは更新されないため無効。
1.1.1.12! root      252:        // ユーザ状態なら A[7] が USP を示し usp は無効、
1.1.1.10  root      253:        // isp, msp は ISP, MSP を示して有効。
1.1.1.12! root      254:        // スーパバイザ状態で SR_M なら A[7] が MSP を示し msp は無効、
1.1.1.10  root      255:        // isp, usp は ISP, USP を示して有効。
1.1.1.12! root      256:        // スーパバイザ状態で !SR_M なら A[7] が ISP を示し isp は無効、
1.1.1.10  root      257:        // msp, usp は MSP, USP を示して有効。
1.1       root      258:        uint32 usp;
                    259:        uint32 isp;
                    260:        uint32 msp;
                    261: 
                    262:        uint32 vbr;
                    263:        uint32 sfc;
                    264:        uint32 dfc;
                    265: 
                    266:        uint32 cacr;
                    267:        uint32 caar;
                    268: 
                    269:        union64 srp;
                    270:        union64 crp;
                    271:        uint32 tt[2];
                    272:        uint32 tc;
                    273:        uint16 mmusr;
                    274: 
                    275:        struct fpframe fpframe;
                    276: 
1.1.1.12! root      277:        // SR レジスタ全体を返す
        !           278:        uint16 GetSR() const {
        !           279:                return (s ? M68K::SR_S : 0)
        !           280:                     | (m ? M68K::SR_M : 0)
        !           281:                     | (intr_mask << 8)
        !           282:                     | ccr.Get();
1.1       root      283:        }
                    284: };
                    285: 
                    286: // バス状態
1.1.1.12! root      287: struct m68kbus
        !           288: {
1.1       root      289:        // 論理アドレスと SSW。
                    290:        // SSW はアクセス前に SSW_BUS_{R,W} と FC[012] をセットすること。
                    291:        DEF_UNION64(, ssw_laddr, ssw, laddr);
                    292: 
                    293:        uint32 paddr;                   // 対応する物理アドレス
                    294:        // データバス。
                    295:        // 今の所書き込みだけで使う。読み込みデータは戻り値のみ。
                    296:        uint32 data;
                    297: 
                    298:        // SSW のうち現在の FC2 だけ別途覚えておく。
                    299:        // FC2 が変化するのは SR:S による特権モードが変わった時だけなので。
                    300:        uint16 fc2;
                    301: 
                    302:        // バスが Write なら true を返す
1.1.1.12! root      303:        bool IsWrite() const { return (ssw & M68K::SSW_BUS_R) == 0; }
1.1       root      304: 
                    305:        // このへんどうするか
                    306: 
                    307:        // FC2 をキャッシュしておく。
                    308:        void SetFC2(bool newfc2) {
                    309:                fc2 = newfc2 ? 4 : 0;
                    310:        }
                    311:        // FC を取得する。
                    312:        // これは MMU ルーチンから呼ばれる。そのためこの時点ではすでに
                    313:        // FC0/1 と FC2 は ssw に合成済みなので、これでよい。
1.1.1.12! root      314:        uint GetFC() const { return ssw & M68K::SSW_FC_MASK; }
1.1.1.11  root      315: 
1.1.1.12! root      316:        // バスエラー時に SSW をセットする。
        !           317:        void SET_SSW(bool use_mmu, uint size);
1.1       root      318: };
                    319: 
1.1.1.12! root      320: // 仮
        !           321: #define RegFP(n)       (reg.fpframe.fpf_regs[n])
        !           322: #define RegFPCR                (reg.fpframe.fpf_fpcr)
        !           323: #define RegFPSR                (reg.fpframe.fpf_fpsr)
        !           324: #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.