Annotation of nono/vm/mpu88xx0.h, revision 1.1.1.18

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.11  root        7: //
                      8: // MPU (M88xx0)
                      9: //
1.1       root       10: 
                     11: #pragma once
                     12: 
                     13: #include "mpu.h"
1.1.1.12  root       14: #include "branchhistory.h"
1.1       root       15: #include "m88100.h"
1.1.1.12  root       16: #include "m88200.h"
                     17: #include <array>
1.1       root       18: 
1.1.1.14  root       19: class MPU88xx0Device : public MainMPUDevice, private M88100
1.1       root       20: {
1.1.1.14  root       21:        using inherited = MainMPUDevice;
1.1.1.13  root       22:        friend class Luna88kPROMEmuDevice;
1.1.1.12  root       23: 
1.1       root       24:  public:
1.1.1.8   root       25:        MPU88xx0Device();
1.1.1.13  root       26:        ~MPU88xx0Device() override;
1.1.1.5   root       27: 
                     28:        bool Init() override;
1.1.1.11  root       29:        void ResetHard(bool poweron) override;
1.1       root       30: 
1.1.1.13  root       31:        // キャッシュ禁止通知 (LUNA-88K では使っていない?)
                     32:        void SetCI() override { }
1.1.1.12  root       33: 
1.1       root       34:        // 現在実行中の命令の PC を取得
1.1.1.12  root       35:        uint32 GetPPC() const override { return reg.xip; }
1.1       root       36: 
1.1.1.11  root       37:        // 現在の VBR を取得
1.1.1.12  root       38:        uint32 GetVBR() const override { return reg.vbr; }
                     39: 
1.1.1.13  root       40:        // MPU 名を取得
                     41:        const char *GetMPUName() const override { return "MC88100"; }
                     42: 
1.1.1.12  root       43:        // スーパーバイザ/ユーザモードなら true
                     44:        bool IsSuper() const            { return (reg.psr & PSR_SUPER) != 0; }
                     45:        bool IsUser() const                     { return (reg.psr & PSR_SUPER) == 0; }
                     46: 
                     47:        // 割り込みが許可なら true
                     48:        bool IsIntrEnable() const       { return (reg.psr & PSR_IND) == 0; }
                     49: 
1.1.1.13  root       50:        // アクセスウェイト [clock] を加算。m88200 が呼ぶ。
                     51:        void AddCycle(int32 cycle) {
1.1.1.12  root       52:                // XXX 本来は今アクセスしてきている(= バスマスターの) CMMU に
                     53:                // 対して加算するべき?かもだが、まだその辺の概念がない。
                     54:                used_cycle += cycle;
                     55:        }
1.1.1.4   root       56: 
1.1.1.13  root       57:        // アクセスウェイト [nsec] を加算。m88200 が呼ぶ。
1.1.1.18! root       58:        void AddWait(uint64 nsec) {
1.1.1.13  root       59:                buswait += nsec;
                     60:        }
                     61: 
1.1       root       62:        // 割り込み発生を MPU に通知
1.1.1.5   root       63:        void Interrupt(int level) override;
1.1       root       64: 
1.1.1.10  root       65:        // DOS call エミュレーションのコールバックを指定する
1.1.1.12  root       66:        void SetFLineCallback(bool (*callback)(MPU88xx0Device *, void *),
                     67:                void *arg);
1.1.1.10  root       68: 
1.1.1.12  root       69:        // op が負数ならバスエラーが起きた
                     70:        static bool OpIsBusErr(uint64 op) {
                     71:                return (int64)op < 0;
                     72:        }
                     73: 
                     74:        m88100reg reg {};
                     75: 
                     76:        // 直近のデータアクセスアドレス。
                     77:        // XXX メモリブレークポイント用だがもう少しなんとかしたい
                     78:        uint64 lastaddr {};
1.1.1.11  root       79: 
1.1       root       80:  private:
1.1.1.11  root       81:        // リセット例外コールバック
1.1.1.17  root       82:        void ResetCallback(Event *);
1.1.1.11  root       83: 
                     84:        // 命令実行系コールバック
1.1.1.17  root       85:        void ExecNormal(Event *);
                     86:        void ExecTrace(Event *);
1.1.1.11  root       87: 
                     88:        // トレース設定。デバッガから呼び出される。
1.1.1.16  root       89:        void SetTrace(bool enable) override;
1.1.1.11  root       90: 
1.1.1.12  root       91:        uint64 fetch() {
                     92:                reg.nip = reg.fip;
1.1.1.14  root       93:                reg.opF = cmmu[0]->load_4(reg.fip);
1.1.1.12  root       94:                reg.fip += 4;
                     95:                return reg.opF;
                     96:        }
                     97: 
                     98:        void Prefetch();
                     99: 
                    100:        // PSR を newpsr に変更する。
                    101:        // CY ビットは特別にこの関数を経由しないで変更してよいことにする。
                    102:        void SetPSR(uint32 newpsr) {
                    103:                reg.psr = newpsr;
                    104:                SetPSR();
                    105:        }
                    106:        // 更新された psr に基づいて、PSR 変更によって必要な処理をする。
                    107:        // CY ビットを変更した場合は呼ばなくてよいことにする。
1.1.1.17  root      108:        void SetPSR();
1.1.1.12  root      109: 
                    110:        // キャリーフラグが立っていれば 1 を返す
                    111:        uint32 GetCY() const    { return (reg.psr >> 28) & 1; }
                    112: 
                    113:        // キャリーフラグをセットする。
                    114:        // cy のうち最下位ビットのみ参照する (呼び出し側はマスクせず渡してよい)
                    115:        void SetCY(uint cy) {
                    116:                reg.psr &= ~PSR_C;
                    117:                reg.psr |= ((cy & 1) << 28);
                    118:        }
                    119: 
                    120:        // SFU1(FPU)が有効なら true
                    121:        bool IsFPUEnable() const        { return (reg.psr & PSR_SFD1) == 0; }
                    122: 
                    123:        // MXM (Misaligned Access Enable) なら true
                    124:        bool IsMXM() const                      { return (reg.psr & PSR_MXM) != 0; }
                    125: 
                    126:        // FPxS1, FPxS2 レジスタを設定
1.1.1.14  root      127:        static void SetFPxS(uint32 *h, uint32 *l, double src, uint32 t);
1.1.1.12  root      128:        void SetFPS1(double src, uint32 t1);
                    129:        void SetFPS2(double src, uint32 t2);
                    130:        void SetFPS1(uint32 src);
                    131:        void SetFPS2(uint32 src);
                    132:        // FP Result を FPIT, FPRH, FPRL レジスタに設定
                    133:        void SetFPRx(double src);
                    134: 
1.1.1.17  root      135:        void ExceptionCore(uint32 primask);
                    136:        void Exception(uint32 pri);
                    137:        void OuterException(uint32 pri);
                    138:        void InternalException(uint32 vec);
                    139:        void TrapException(uint32 vec);
                    140:        uint32 MakeDMT(uint32 flag);
1.1.1.12  root      141:        void ReadDataException32(uint32 addr, uint32 flag);
                    142:        void ReadDataException64(uint32 addr, uint32 flag);
                    143:        void WriteDataException32(uint32 addr, uint32 flag);
                    144:        void WriteDataException64(uint32 addr, uint32 flag);
                    145:        void XmemDataException(uint32 addr, uint32 flag);
                    146:        void FPPreciseException(uint32 cause, double s2);
                    147:        void FPPreciseException(uint32 cause, double s1, double s2);
                    148:        void FPPreciseException(uint32 cause);
                    149:        void FPImpreciseException(uint32 cause);
                    150: 
                    151:        // ブランチ処理用
                    152:        void DoBranch(uint32 toaddr, bool next_exec);
                    153:        uint32 nop_counter {};  // STOP 検出用の nop 命令カウンタ
                    154: 
                    155:        // ロードストア命令用の下処理
                    156:        uint32 ldst_scale(uint32 size);
1.1.1.14  root      157: 
1.1.1.12  root      158:        // 浮動小数点数命令用の処理
                    159:        void ops_int(int mode);
                    160: 
                    161: #define OP_PROTO(name) void __CONCAT(op_,name)()
                    162: #include "m88100ops.h"
                    163: OP_PROTO(illegal);
                    164: #undef OP_PROTO
                    165: 
                    166:        // float,double と整数値の相互変換
                    167:        static float u2f(uint32 u) {
                    168:                float v;
                    169:                memcpy(&v, &u, sizeof(v));
                    170:                return v;
                    171:        }
                    172:        static double u2d(uint64 u) {
                    173:                double v;
                    174:                memcpy(&v, &u, sizeof(v));
                    175:                return v;
                    176:        }
                    177:        static uint32 f2u(float v) {
                    178:                uint32 u;
                    179:                memcpy(&u, &v, sizeof(u));
                    180:                return u;
                    181:        }
                    182:        static uint64 d2u(double v) {
                    183:                uint64 u;
                    184:                memcpy(&u, &v, sizeof(u));
                    185:                return u;
                    186:        }
                    187: 
                    188:        // [0] 命令バス
                    189:        // [1] データバス
                    190:        std::array<std::unique_ptr<m88200>, 2> cmmu {};
                    191: 
                    192:        // ブランチ履歴 (例外履歴を含む)
                    193:        BranchHistory_m88xx0 brhist { OBJ_MPU_BRHIST };
                    194:        // 例外履歴のみ
                    195:        BranchHistory_m88xx0 exhist { OBJ_MPU_EXHIST };
                    196: 
                    197:        // 今のところサイクルを正確に実装するのは無理なので
                    198:        // 適当に全部積み上げてある。
                    199: 
                    200:        // 電源オンからの累積消費サイクル
                    201:        uint64 used_cycle {};
                    202: 
1.1.1.13  root      203:        // 今回のバスウェイト [nsec]
                    204:        uint64 buswait {};
                    205: 
1.1.1.17  root      206:        // 割り込み信号線の状態。
                    207:        bool intr_asserted {};
                    208: 
                    209:        // ペンディング中の例外優先度。EXCPRI_*
                    210:        uint32 excep_pending {};
                    211: 
                    212:        // 内部例外/トラップ例外のベクタ番号。EXCVEC_*
                    213:        uint32 excep_vector {};
1.1.1.12  root      214: 
                    215:        // 疑似 STOP 状態に入る機能を有効にする場合 true
                    216:        bool pseudo_stop_enable {};
                    217: 
                    218:        // DOS call エミュレーション
                    219:        bool (*fline_callback)(MPU88xx0Device *, void *) = NULL;
                    220:        void *fline_arg {};
                    221: 
1.1.1.9   root      222:        // レジスタモニター
1.1.1.18! root      223:        DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1.1.15  root      224:        Monitor *monitor {};
1.1.1.2   root      225: 
1.1.1.11  root      226:        // イベントコールバック
                    227:        EventCallback_t exec_normal {};
1.1.1.2   root      228: };
                    229: 
1.1.1.13  root      230: // これを呼びたい人は mpu を持ってるはず。
1.1.1.18! root      231: inline MPU88xx0Device *GetMPU88xx0Device(Device *mpu_) {
1.1.1.13  root      232:        return dynamic_cast<MPU88xx0Device*>(mpu_);
1.1.1.12  root      233: }

unix.superglobalmegacorp.com

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