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

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