Annotation of nono/vm/mpu680x0.h, revision 1.1.1.15

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.10  root        7: //
                      8: // MPU (MC68030)
                      9: //
1.1       root       10: 
                     11: #pragma once
                     12: 
                     13: #include "mpu.h"
1.1.1.11  root       14: #include "branchhistory.h"
1.1.1.13  root       15: #include "bus.h"
1.1.1.11  root       16: #include "event.h"
1.1.1.15! root       17: #include "m680x0.h"
1.1.1.11  root       18: #include "m68030mmu.h"
1.1.1.15! root       19: #include <array>
1.1.1.11  root       20: 
                     21: class InterruptDevice;
1.1.1.13  root       22: class m68030Cache;
1.1.1.14  root       23: struct m68030CacheLine;
1.1.1.15! root       24: enum class m68030MPUType;
        !            25: class m68040TT;
        !            26: class m68040TC;
        !            27: class m68040ATC;
        !            28: class m68040ATCEntry;
1.1       root       29: 
1.1.1.14  root       30: class MPU680x0Device : public MainMPUDevice
1.1       root       31: {
1.1.1.14  root       32:        using inherited = MainMPUDevice;
1.1.1.11  root       33:        friend class m68030MMU;
                     34: 
                     35:        // CPU の実行状態
                     36:        static const uint32 CPU_STATE_NORMAL    = 0;
                     37:        static const uint32 CPU_STATE_STOP              = 1;
                     38:        static const uint32 CPU_STATE_HALT              = 2;
                     39: 
1.1       root       40:  public:
1.1.1.7   root       41:        MPU680x0Device();
1.1.1.13  root       42:        ~MPU680x0Device() override;
1.1       root       43: 
1.1.1.2   root       44:        bool Init() override;
1.1.1.10  root       45:        void ResetHard(bool poweron) override;
1.1       root       46: 
                     47:        // 現在の PPC を取得
1.1.1.11  root       48:        uint32 GetPPC() const override { return ppc; }
1.1       root       49: 
1.1.1.10  root       50:        // 現在の VBR を取得
1.1.1.11  root       51:        uint32 GetVBR() const override { return reg.vbr; }
                     52: 
1.1.1.15! root       53:        // MPU 種別を取得
        !            54:        m680x0MPUType GetMPUType() const { return mpu_type; }
        !            55: 
        !            56:        // FPU
        !            57:        m680x0FPUType GetFPUType() const { return fpu_type; }
        !            58:        bool HasFPU() const     { return fpu_type.Is4060FPU() || fpu_type.Is6888x(); }
        !            59: 
1.1.1.13  root       60:        // MPU 名を取得
1.1.1.15! root       61:        const char *GetMPUName() const override { return mpu_name; }
1.1.1.13  root       62: 
1.1.1.11  root       63:        bool IsSuper() const    { return reg.s; }
                     64:        bool IsMaster() const   { return reg.m; }
                     65: 
                     66:        // CPU の実行状態 (uint32) を返す。
                     67:        uint32 GetState() const { return cpu_state; }
1.1.1.10  root       68: 
1.1       root       69:        // 現在アクセス中の論理アドレス、物理アドレスを取得。
1.1.1.13  root       70:        uint32 GetLaddr() const override { return bus.laddr.Addr(); }
                     71:        uint32 GetPaddr() const override { return bus.paddr.Addr(); }
1.1       root       72: 
1.1.1.5   root       73:        // 割り込みレベルが変わったことを MPU に通知
                     74:        void Interrupt(int level) override;
1.1       root       75: 
                     76:        // A-Line, F-Line 命令エミュレーションのコールバックを指定する。
                     77:        // (Human68k エミュレーションで使用)
1.1.1.11  root       78:        void SetALineCallback(bool (*callback)(MPU680x0Device*, void*), void *arg);
                     79:        void SetFLineCallback(bool (*callback)(MPU680x0Device*, void*), void *arg);
1.1       root       80: 
1.1.1.14  root       81:        // バーストアクセスをサポートするか
                     82:        void EnableBurstAccess(bool enable) { has_burst_access = enable; }
                     83: 
1.1.1.13  root       84:        void SetCI() override {
                     85:                bus.ci = true;
                     86:        }
1.1.1.9   root       87: 
1.1.1.11  root       88:        // ホールト
1.1.1.10  root       89:        void Halt();
                     90: 
1.1.1.11  root       91:        // 基本アクセス。内部から使用する。
                     92:        // アドレスは論理アドレスで、空間は現在の命令/データ空間。
                     93:        // バスエラーなら C++ の例外をスローする。
1.1.1.15! root       94:        virtual uint32 fetch_2() = 0;
        !            95:        virtual uint32 fetch_4() = 0;
1.1.1.14  root       96:        uint32 read_n(uint32 laddr, uint size) {
                     97:                busaddr addr =
                     98:                        busaddr(laddr) | fc_data | BusAddr::R | busaddr::Size(size);
                     99:                return read_data(addr);
                    100:        }
                    101:        void write_n(uint32 laddr, uint size, uint32 data) {
                    102:                busaddr addr =
                    103:                        busaddr(laddr) | fc_data | BusAddr::W | busaddr::Size(size);
                    104:                write_data(addr, data);
                    105:        }
                    106:        uint32 read_1(uint32 laddr) { return read_n(laddr, 1); }
                    107:        uint32 read_2(uint32 laddr) { return read_n(laddr, 2); }
                    108:        uint32 read_4(uint32 laddr) { return read_n(laddr, 4); }
                    109:        void write_1(uint32 laddr, uint32 data) { write_n(laddr, 1, data); }
                    110:        void write_2(uint32 laddr, uint32 data) { write_n(laddr, 2, data); }
                    111:        void write_4(uint32 laddr, uint32 data) { write_n(laddr, 4, data); }
1.1.1.11  root      112: 
                    113:        // MMU アクセス
1.1.1.15! root      114:        virtual busaddr TranslatePeek(busaddr laddr) = 0;
1.1.1.14  root      115:        // 統計
1.1.1.15! root      116:        virtual void CalcStat() = 0;
1.1.1.11  root      117: 
                    118:        // レジスタ
                    119:        uint16 GetIR() const    { return ir; }
                    120:        uint16 GetIR2() const   { return ir2; }
                    121:        // SR を変更する (Human68k から使う)
                    122:        void SetSR(uint16);
                    123:        uint16 GetSR() const    { return reg.GetSR(); }
                    124: 
1.1.1.15! root      125:  protected:
1.1.1.10  root      126:        // リセット例外コールバック
                    127:        void ResetCallback(Event& ev);
                    128: 
                    129:        // 命令実行系コールバック
                    130:        void ExecShort(Event& ev);
                    131:        void ExecFull(Event& ev);
                    132:        void ExecTrace(Event& ev);
1.1.1.5   root      133: 
1.1.1.10  root      134:        // トレース設定。デバッガから呼び出される。
                    135:        void SetTrace(bool trace_on) override;
1.1.1.9   root      136: 
1.1.1.10  root      137:        // 割り込みイベントコールバック
                    138:        void InterruptCallback(Event& ev);
                    139: 
1.1.1.11  root      140:        // 動作モード変更
                    141:        void ChangeState(uint32 new_state);
1.1.1.8   root      142: 
1.1.1.11  root      143:        // 次の実行サイクルを Full にする。
                    144:        void MakeNextFull();
1.1.1.8   root      145: 
1.1.1.11  root      146:        inline void CYCLE(int cc) {
                    147:                used_cycle += cc;
                    148:        }
                    149:        inline void CYCLE2(int cc, int ncc) {
                    150:                used_cycle += cc;
                    151:                cycle_nocache += ncc - cc;
                    152:        }
                    153: 
                    154:        // PC を addr に変更する。
                    155:        // ベクタへのジャンプはここではなく JumpVector()。
                    156:        inline void Jump(uint32 addr) {
                    157:                // 先にブランチ履歴に記録
1.1.1.12  root      158:                brhist.AddEntry(ppc | (IsSuper() ? 1 : 0), addr, ir);
1.1.1.11  root      159: 
                    160:                if (__predict_false((addr & 1) != 0)) {
1.1.1.12  root      161:                        ExceptionBuserr(M68K::EXCEP_ADDRERR);
1.1.1.11  root      162:                        return;
                    163:                }
                    164:                reg.pc = addr;
                    165:        }
                    166: 
                    167:        // -(An) 実行前にレジスタを保存する。
                    168:        // バスエラーからの復帰用。
                    169:        inline void save_reg_pd(int n) {
                    170:                // 該当ビットのフラグを立てる
                    171:                flag_pd |= (1 << n);
                    172: 
                    173:                // 保存
                    174:                save_pd[n] = reg.A[n];
                    175:        }
                    176: 
                    177:        // (An)+ 実行前にレジスタを保存する。
                    178:        // バスエラーからの復帰用。
                    179:        inline void save_reg_pi(int n) {
                    180:                // 該当ビットのフラグを立てる
                    181:                flag_pi |= (1 << n);
                    182: 
                    183:                // 保存
                    184:                save_pi[n] = reg.A[n];
                    185:        }
                    186: 
1.1.1.14  root      187:        // -(An) 実行前にレジスタを(まだ保存してなければ)保存する。
                    188:        // 1命令で同じレジスタを2回 -(An) する可能性がある命令用。
                    189:        inline void save_reg_pd_if(int n) {
                    190:                if ((flag_pd & (1 << n)) == 0) {
                    191:                        save_reg_pd(n);
                    192:                }
                    193:        }
                    194:        // (An)+ 実行前にレジスタを(まだ保存してなければ)保存する。
                    195:        // 1命令で同じレジスタを2回 (An)+ する可能性がある命令用。
                    196:        inline void save_reg_pi_if(int n) {
                    197:                if ((flag_pi & (1 << n)) == 0) {
                    198:                        save_reg_pi(n);
                    199:                }
                    200:        }
                    201: 
1.1.1.11  root      202:        void restore_reg_pi();
                    203:        void restore_reg_pd();
1.1.1.14  root      204:        void JumpVector(uint vector, bool from_buserr);
1.1.1.11  root      205: 
                    206:  protected:
1.1.1.15! root      207: #include "m680x0ea.h"
1.1.1.11  root      208: 
1.1.1.15! root      209:  protected:
1.1.1.11  root      210:        // 基本アクセスルーチンを使った便利サブルーチン
1.1.1.14  root      211:        inline void push_2(uint32 data) {
1.1.1.11  root      212:                reg.A[7] -= 2;
1.1.1.14  root      213:                write_2(reg.A[7], data);
1.1.1.11  root      214:        }
1.1.1.14  root      215:        inline void push_4(uint32 data) {
1.1.1.11  root      216:                reg.A[7] -= 4;
1.1.1.14  root      217:                write_4(reg.A[7], data);
1.1.1.11  root      218:        }
1.1.1.14  root      219:        inline uint32 pop_2() {
                    220:                uint32 data = read_2(reg.A[7]);
1.1.1.11  root      221:                reg.A[7] += 2;
                    222:                return data;
                    223:        }
1.1.1.14  root      224:        inline uint32 pop_4() {
                    225:                uint32 data = read_4(reg.A[7]);
1.1.1.11  root      226:                reg.A[7] += 4;
                    227:                return data;
                    228:        }
                    229: 
1.1.1.13  root      230:        // バスアクセス
1.1.1.15! root      231:        virtual uint32 read_data(busaddr addr) = 0;
        !           232:        virtual void write_data(busaddr addr, uint32 data) = 0;
1.1.1.14  root      233: 
1.1.1.15! root      234:        // 物理バスアクセス
1.1.1.14  root      235:        busdata read_phys();
                    236:        busdata write_phys(uint32 data);
                    237:        bool read_phys_burst(uint32 *dst);
1.1.1.15! root      238:        busdata read_phys_4(uint32 addr);
        !           239:        busdata write_phys_4(uint32 addr, uint32 data);
1.1.1.13  root      240: 
1.1.1.11  root      241: #define OP_PROTO(name) void __CONCAT(op_,name)()
1.1.1.15! root      242: #include "m680x0ops.h"
1.1.1.11  root      243: #undef OP_PROTO
                    244: 
1.1.1.14  root      245:        void ops_divu_32_32(uint r, uint q);
                    246:        void ops_divu_64_32(uint r, uint q);
                    247:        void ops_divs_32_32(uint r, uint q);
                    248:        void ops_divs_64_32(uint r, uint q);
1.1.1.15! root      249:        void ops_link(int32 imm);
1.1.1.11  root      250:        void ops_movec_rc_rn();
                    251:        void ops_movec_rn_rc();
1.1.1.15! root      252:        virtual bool ops_movec_rc_rn_cpu(uint c, uint n) = 0;
        !           253:        virtual bool ops_movec_rn_rc_cpu(uint c, uint n) = 0;
1.1.1.11  root      254:        void ops_movep();
                    255:        // もともとソース内のテンプレートだった
                    256:        void ops_movem_list_ea(int bytesize);
                    257:        void ops_movem_ea_list(int bytesize);
                    258:        void ops_trapcc(uint cond);
                    259:        inline void ops_bra();
1.1.1.15! root      260:        busaddr translate_fc40(busaddr);
1.1.1.11  root      261: 
                    262:        void ops_rte();
                    263:        void ops_stop();
                    264:        void ops_reset();
1.1.1.15! root      265:        virtual void ops_mmu30() = 0;
        !           266:        virtual void ops_mmu40_pflush() = 0;
1.1.1.11  root      267: 
1.1.1.15! root      268:        void ResetFPU(bool hard);
        !           269:        void fpu_init();
        !           270:        uint32 cea_fpu(int bytes);
        !           271:        void read_8(uint32 addr, uint32 *data);
        !           272:        void read_12(uint32 addr, uint32 *data);
        !           273:        void write_8(uint32 addr, const uint32 *data);
        !           274:        void write_12(uint32 addr, const uint32 *data);
        !           275:        bool readSRC(int size_id, uint32 *data);
        !           276: 
        !           277:        void fpu_op_illg();
        !           278:        void fpu_op_illg2();
        !           279: 
        !           280:        void fpu_op_fgen_reg();
        !           281:        void fpu_op_fgen_mem();
        !           282:        void fgen(const uint32 *srcdata, uint srcsize_id);
        !           283:        void fgen881pre(uint dstnum, const uint32 *srcdata, uint srcsize_id);
        !           284:        bool fgen040pre(uint opmode, uint dst, const uint32 *src, uint srcsize);
        !           285:        void fpu_op_fmovecr();
        !           286:        void fpu_op_fmove_to_mem();
        !           287:        void fpu_op_fmove_b_mem();
        !           288:        void fpu_op_fmove_w_mem();
        !           289:        void fpu_op_fmove_l_mem();
        !           290:        void fpu_op_fmove_s_mem();
        !           291:        void fpu_op_fmove_d_mem();
        !           292:        void fpu_op_fmove_x_mem();
        !           293:        void fpu_op_fmove_p_mem();
        !           294:        void fpu_op_fmove_ea2ctl();
        !           295:        void fpu_op_fmovem_ea2ctl();
        !           296:        void fpu_op_fmove_ctl2ea();
        !           297:        void fpu_op_fmovem_ctl2ea();
        !           298:        void fpu_op_fmovem_ea2reg();
        !           299:        void fpu_op_fmovem_reg2ea();
        !           300:        void fpu_op_fscc();
        !           301:        void fpu_op_fdbcc();
        !           302:        void fpu_op_ftrapcc_w();
        !           303:        void fpu_op_ftrapcc_l();
        !           304:        void fpu_op_ftrapcc();
        !           305:        void fpu_op_fbcc_w();
        !           306:        void fpu_op_fbcc_l();
        !           307:        void fpu_op_fsave();
        !           308:        void fpu_op_frestore();
        !           309:        void fpu_op_fsave_frame_noimpl(std::array<uint32, 13>&);
        !           310: 
        !           311:        static struct fpframe initial_fpframe;
        !           312:        static const uint32 fsave_frame_null[1];
        !           313:        static const uint32 fsave_frame_idle_68881[7];
        !           314:        static const uint32 fsave_frame_idle_68040[1];
1.1.1.11  root      315: 
1.1.1.13  root      316:        // キャッシュ
1.1.1.15! root      317:        virtual void SetCACR(uint32) = 0;
1.1.1.11  root      318: 
1.1.1.15! root      319:        virtual bool TranslateRead() = 0;
        !           320:        virtual bool TranslateWrite() = 0;
1.1.1.11  root      321: 
                    322:        // 例外
1.1.1.15! root      323:        void GenerateExframe0(uint vector, uint16 sr, uint32 pc);
        !           324:        void GenerateExframe2(uint vector, uint16 sr, uint32 pc, uint32 addr);
        !           325:        void GenerateExframe7(uint vector, uint16 sr);
1.1.1.14  root      326:        void GenerateExframeB(uint vector, uint16 sr);
1.1.1.11  root      327:        int  ExceptionReset();
1.1.1.14  root      328:        void ExceptionBuserr(uint vector);
1.1.1.13  root      329:        uint64 ExceptionInterrupt();
1.1.1.12  root      330:        void ExceptionTrap15();
1.1.1.15! root      331:        void ExceptionFP(uint vector);
1.1.1.14  root      332:        void Exception(uint vector);
1.1.1.15! root      333:        void ExceptionGeneric(uint ext_vector, uint32 inst);
        !           334: 
        !           335:        // リセット例外の CPU 固有部分。
        !           336:        virtual void ResetCache() = 0;
        !           337:        virtual void ResetMMU() = 0;
1.1.1.11  root      338: 
                    339:        // 二重バスフォールト
                    340:        void DoubleBusFault(const char *where);
                    341: 
                    342:  public:
                    343:        // レジスタ
                    344:        m68kreg reg {};
                    345:        bool mmu_enable {};             // MMU が有効なら true
                    346: 
                    347:        // バス
                    348:        m68kbus bus {};
1.1.1.13  root      349:        // 現在の特権状態でのプログラム空間とデータ空間アクセス用。
                    350:        busaddr fc_inst {};             // こっちは R 含む
                    351:        busaddr fc_data {};             // こっちは R/W 含まない
1.1.1.11  root      352: 
1.1.1.15! root      353:  protected:
1.1.1.11  root      354:        uint16 ir {};
                    355:        uint16 ir2 {};
                    356:        // 現在実行中の命令の先頭アドレス
                    357:        uint32 ppc {};
                    358: 
                    359:        // レジスタ(状態保存用)
                    360:        uint32 save_pd[8] {};   // -(An) を保存
                    361:        uint32 save_pi[8] {};   // (An)+ を保存
                    362:        uint8  flag_pd {};              // -(An) のどのレジスタを保存したか
                    363:        uint8  flag_pi {};              // (An)+ のどのレジスタを保存したか
                    364: 
                    365:        // FPU
1.1.1.15! root      366:        enum {
        !           367:                FPU_STATE_NULL,         // 内部状態なし
        !           368:                FPU_STATE_IDLE,         // FRESTORE 以降に FPU 命令を実行した
        !           369:                FPU_STATE_BUSY,         // ビジー状態 (実装していない)
        !           370:                FPU_STATE_NOIMPL,       // 浮動小数点未実装命令
        !           371:        } fpu_state {};
1.1.1.11  root      372:        struct fpemu fe {};
                    373: 
1.1.1.15! root      374:        // 68040 FPU 用の内部状態
        !           375:        struct FPU40 {
        !           376:                uint32 reg1b;           // CMDREG1B
        !           377:                uint32 ea;                      // 計算した EA
        !           378:                enum {
        !           379:                        // NONE は未決定だが Unnormal/Denormal ではないいずれかなので
        !           380:                        // UNNORMAL より小さい値にしておく。(大小比較する)
        !           381:                        TAG_NONE                = -1,
        !           382:                        TAG_NORMAL              = 0,
        !           383:                        TAG_ZERO                = 1,
        !           384:                        TAG_INF                 = 2,
        !           385:                        TAG_NAN                 = 3,
        !           386:                        TAG_UNNORMAL    = 4,    // .X denormal or unnormal
        !           387:                        TAG_DENORMAL    = 5,    // .S/.D denormal
        !           388: 
        !           389:                        // 内部表現 (下位3ビットは維持したまま上位で詳細を区別する)
        !           390:                        TAG_DENORMAL_S  = (0x10 | TAG_DENORMAL),
        !           391:                        TAG_DENORMAL_D  = (0x20 | TAG_DENORMAL),
        !           392:                        TAG_DENORMAL_X  = (0x30 | TAG_UNNORMAL),
        !           393:                        TAG_UNNORMAL_X  = (0x40 | TAG_UNNORMAL),
        !           394:                        // PACKED のときタグは undefined となっている。仕方ないので 7。
        !           395:                        TAG_PACKED              = 0x07 ,
        !           396:                };
        !           397:                int32 stag;
        !           398:                int32 dtag;
        !           399:                uint32 etemp[3];
        !           400:                uint32 fptemp[3];
        !           401:                enum {
        !           402:                        E1 = 0x04000000,
        !           403:                        E3 = 0x02000000,
        !           404:                };
        !           405:                uint32 eflag;
        !           406:                bool post;                      // T bit, post-op exception
        !           407: 
        !           408:                // 表示用のフラグ。例外発生から FSAVE の間までが有効。
        !           409:                bool enable;
        !           410:        } fpu40 {};
        !           411: 
1.1.1.11  root      412:        // CPU の実行状態
                    413:        uint32 cpu_state {};
1.1.1.7   root      414: 
1.1.1.10  root      415:        // 割り込みペンディング
                    416:        bool intr_pending {};
                    417: 
1.1.1.11  root      418:        // 現在の外部割り込みレベル
                    419:        int intr_level {};
                    420: 
                    421:        // 電源オンからの累積消費サイクル
                    422:        uint64 used_cycle {};
                    423: 
1.1.1.13  root      424:        // 今回のバスウェイト [nsec]
                    425:        uint64 buswait {};
                    426: 
1.1.1.14  root      427:        // 外部バスがバースト転送に対応していれば true
                    428:        bool has_burst_access {};
                    429: 
1.1.1.15! root      430:        // 命令キャッシュ有効 (icache->enable のコピー)
        !           431:        bool icache_enable {};
1.1.1.11  root      432:        int32 cycle_nocache {};         // ノーキャッシュケースの時の追加分
                    433: 
1.1.1.15! root      434:        // MPU/FPU 種別
        !           435:        m680x0MPUType mpu_type {};
        !           436:        m680x0FPUType fpu_type {};
        !           437:        const char *mpu_name {};
        !           438: 
1.1.1.11  root      439:        // A-Line, F-Line 命令エミュレーションのコールバックとユーザ引数。
                    440:        // ユーザ引数には関与しないので呼び出し側が自由に指定してよい。
                    441:        // コールバック側で処理完了したら true を返す。
                    442:        // デフォルトの処理(すなわちm68k例外)にする場合は false を返す。
                    443:        bool (*aline_callback)(MPU680x0Device *, void *) {};
                    444:        void *aline_arg {};
                    445:        bool (*fline_callback)(MPU680x0Device *, void *) {};
                    446:        void *fline_arg {};
                    447: 
                    448:        // ブランチ履歴 (例外履歴を含む)
                    449:        BranchHistory_m680x0 brhist { OBJ_MPU_BRHIST };
                    450:        // 例外履歴のみ
                    451:        BranchHistory_m680x0 exhist { OBJ_MPU_EXHIST };
                    452: 
                    453:        // 割り込みイベント
                    454:        Event intr_event { this };
                    455: 
1.1.1.10  root      456:        // トレースでコールバックを差し替えることができるように
                    457:        // イベントコールバックを変数に入れてある
                    458:        EventCallback_t exec_short {};
                    459:        EventCallback_t exec_full {};
1.1.1.4   root      460: 
1.1.1.15! root      461:        // モニター
        !           462:        void MonitorUpdateRegCommon(TextScreen&, m68kreg&, uint32, uint32);
        !           463:        int  MonitorUpdateFPU(TextScreen&, int y, m68kreg&);
        !           464:        Monitor *reg_monitor {};
        !           465:        Monitor *atc_monitor {};
        !           466:        Monitor *cache_monitor {};
1.1.1.11  root      467: 
1.1.1.15! root      468:        InterruptDevice *interruptdev {};
        !           469:        VectorTable *vectortable {};
        !           470: };
        !           471: 
        !           472: class MPU68030Device : public MPU680x0Device
        !           473: {
        !           474:        using inherited = MPU680x0Device;
        !           475: 
        !           476:  public:
        !           477:        MPU68030Device();
        !           478:        ~MPU68030Device() override;
        !           479: 
        !           480:        void SetLogLevel(int loglevel_) override;
1.1.1.11  root      481: 
1.1.1.15! root      482:        uint64 GetSRP()  const { return reg.srp.q; }
        !           483:        uint32 GetSRPh() const { return reg.srp.h; }
        !           484:        uint32 GetSRPl() const { return reg.srp.l; }
        !           485:        uint64 GetCRP()  const { return reg.crp.q; }
        !           486:        uint32 GetCRPh() const { return reg.crp.h; }
        !           487:        uint32 GetCRPl() const { return reg.crp.l; }
        !           488:        uint64 GetTT(int idx) const { return reg.tt[idx]; }
        !           489:        uint32 GetTC() const { return reg.tc; }
        !           490:        uint16 GetMMUSR() const { return reg.mmusr; }
        !           491: 
        !           492:        busaddr TranslatePeek(busaddr laddr) override;
        !           493:        void CalcStat() override;
        !           494: 
        !           495:  private:
        !           496:        // リセット
        !           497:        void ResetCache() override;
        !           498:        void ResetMMU() override;
        !           499: 
        !           500:        // 命令
        !           501:        bool ops_movec_rc_rn_cpu(uint c, uint n) override;
        !           502:        bool ops_movec_rn_rc_cpu(uint c, uint n) override;
        !           503:        void ops_mmu30() override;
        !           504:        void ops_mmu40_pflush() override;
        !           505:        uint32 get_fc();
        !           506:        void mmu_op_illg2();
        !           507:        void mmu_op_pflush();
        !           508:        void mmu_op_pflush_ea();
        !           509:        void mmu_op_pload();
        !           510:        void mmu_op_ptest();
        !           511: 
        !           512:        // バスアクセス
        !           513:        uint32 fetch_2() override;
        !           514:        uint32 fetch_4() override;
        !           515:        uint32 read_data(busaddr addr) override;
        !           516:        busdata read_nocache(busaddr addr);
        !           517:        void write_data(busaddr addr, uint32 data) override;
        !           518: 
        !           519:        busdata read_cache(m68030Cache *cache, busaddr addr);
        !           520:        busdata read_line(m68030CacheLine *, uint32 tag, uint32 opermask);
        !           521:        busdata read_single(busdata bd, uint32 readmask, uint32 opermask);
        !           522:        busdata write_bus(busaddr addr, uint32 data);
        !           523: 
        !           524:        // キャッシュ
        !           525:        void SetCACR(uint32) override;
        !           526: 
        !           527:        // MMU
        !           528:        bool TranslateRead() override;
        !           529:        bool TranslateWrite() override;
        !           530:        bool CheckTT();
        !           531: 
        !           532:        bool SetSRP(uint32, uint32);
        !           533:        bool SetCRP(uint32, uint32);
        !           534:        void SetTT(int idx, uint32);
        !           535:        bool SetTC(uint32);
        !           536:        void SetMMUSR(uint16);
        !           537:        // MMU 有効状態を更新。(TC と TT の変更で呼ばれる)
        !           538:        void mmu_enable_changed();
        !           539: 
        !           540:  public:
        !           541:        // MMU work
        !           542:        m68030TT mmu_tt[2] /*{}*/;
        !           543:        m68030TC mmu_tc /*{}*/;
        !           544:        m68030ATC atc {this};
        !           545: 
        !           546:  private:
        !           547:        DECLARE_MONITOR_CALLBACK(MonitorUpdateReg);
        !           548:        DECLARE_MONITOR_CALLBACK(MonitorUpdateATC);
1.1.1.13  root      549:        DECLARE_MONITOR_CALLBACK(MonitorUpdateCache);
1.1.1.15! root      550:        int MonitorUpdateMMU(TextScreen&, int, m68kreg&);
1.1.1.14  root      551:        int MonitorUpdateCache1(TextScreen&, int y, m68030Cache *,
                    552:                char (*)(const m68030CacheLine&));
1.1.1.13  root      553: 
1.1.1.15! root      554:        // キャッシュ
        !           555:        std::unique_ptr<m68030Cache> icache /*{}*/;
        !           556:        std::unique_ptr<m68030Cache> dcache /*{}*/;
        !           557: };
        !           558: 
        !           559: class MPU68040Device : public MPU680x0Device
        !           560: {
        !           561:        using inherited = MPU680x0Device;
        !           562: 
        !           563:  public:
        !           564:        MPU68040Device();
        !           565:        ~MPU68040Device() override;
        !           566: 
        !           567:        uint32 GetITT(int n) const      { return reg.itt[n]; }
        !           568:        uint32 GetDTT(int n) const      { return reg.dtt[n]; }
        !           569:        uint32 GetSRP()         const   { return reg.srp40; }
        !           570:        uint32 GetURP()         const   { return reg.urp40; }
        !           571:        uint32 GetTC()          const   { return reg.tc40; }
        !           572:        uint32 GetMMUSR()       const   { return reg.mmusr40; }
        !           573: 
        !           574:        busaddr TranslatePeek(busaddr laddr) override;
        !           575:        void CalcStat() override;
        !           576: 
        !           577:  private:
        !           578:        // リセット
        !           579:        void ResetCache() override;
        !           580:        void ResetMMU() override;
        !           581: 
        !           582:        // 命令
        !           583:        bool ops_movec_rc_rn_cpu(uint c, uint n) override;
        !           584:        bool ops_movec_rn_rc_cpu(uint c, uint n) override;
        !           585:        void ops_mmu30() override;
        !           586:        void ops_mmu40_pflush() override;
        !           587: 
        !           588:        // バスアクセス
        !           589:        uint32 fetch_2() override;
        !           590:        uint32 fetch_4() override;
        !           591:        uint32 read_data(busaddr addr) override;
        !           592:        busdata read_nocache(busaddr addr);
        !           593:        void write_data(busaddr addr, uint32 data) override;
        !           594: 
        !           595:        // キャッシュ
        !           596:        void SetCACR(uint32) override;
        !           597: 
        !           598:        // MMU
        !           599:        bool TranslateRead() override;
        !           600:        bool TranslateWrite() override;
        !           601:        m68040TT *CheckTT(std::array<std::unique_ptr<m68040TT>, 2>&) const;
        !           602:        bool LookupATC(m68040ATC&);
        !           603:        bool Search(m68040ATCEntry *);
        !           604:        uint32 PeekDesc(uint32 base, uint32 idx);
        !           605: 
        !           606:        void SetTT(m68040TT *, uint32);
        !           607:        void SetSRP(uint32);
        !           608:        void SetURP(uint32);
        !           609:        void SetTC(uint32);
        !           610:        // MMU 有効状態を更新。(TC と *TTn の変更で呼ばれる)
        !           611:        void mmu_enable_changed();
        !           612: 
        !           613:        DECLARE_MONITOR_CALLBACK(MonitorUpdateReg);
        !           614:        DECLARE_MONITOR_CALLBACK(MonitorUpdateATC);
        !           615:        int MonitorUpdateMMU(TextScreen&, int, m68kreg&);
        !           616:        void MonitorUpdateTT(TextScreen&, int x, int y, const char *, uint32);
        !           617:        void MonitorUpdateATC1(TextScreen&, int, const m68040ATC *);
        !           618: 
        !           619:        // FPU
        !           620:        void MonitorUpdateFPU40(TextScreen&, int y, const FPU40&);
        !           621:        static std::string GetReg1BName(uint32 opclass, uint32 sz, uint32 cmd);
        !           622:        static std::string GetFPUTagName(int32);
        !           623: 
        !           624:        std::array<std::unique_ptr<m68040TT>, 2> mmu_itt /*{}*/;
        !           625:        std::array<std::unique_ptr<m68040TT>, 2> mmu_dtt /*{}*/;
        !           626:        std::unique_ptr<m68040TC> mmu_tc /*{}*/;
        !           627: 
        !           628:        std::unique_ptr<m68040ATC> atc_inst /*{}*/;
        !           629:        std::unique_ptr<m68040ATC> atc_data /*{}*/;
1.1       root      630: };
                    631: 
1.1.1.15! root      632: // ブートストラップ
        !           633: extern MPU680x0Device *NewMPU680x0Device();
        !           634: 
1.1.1.13  root      635: // これを呼びたい人は mpu を持ってるはず。
                    636: static inline MPU680x0Device *GetMPU680x0Device(Device *mpu_) {
                    637:        return dynamic_cast<MPU680x0Device*>(mpu_);
1.1.1.11  root      638: }

unix.superglobalmegacorp.com

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