Annotation of nono/m88xx0/m88100.h, revision 1.1.1.11

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: 
                      7: #pragma once
                      8: 
                      9: #include "header.h"
1.1.1.2   root       10: #include "branchhistory.h"
1.1       root       11: #include "bus.h"
1.1.1.2   root       12: #include "m88200.h"
1.1       root       13: #include <atomic>
                     14: 
                     15: // 外部リクエストフラグ
                     16: // XXX m680x0 側にもよく似たものがあってどうしたもんか
1.1.1.2   root       17: #define CPU_REQ_STOP           (0x00000001)    // ストップ状態
1.1       root       18: #define CPU_REQ_TRACE          (0x00000004)    // デバッガ有効
                     19: #define CPU_REQ_PROMPT         (0x00000008)    // デバッガプロンプト
                     20: #define CPU_REQ_RELEASE                (0x00000010)    // 命令後に CPU 実行中断
                     21: #define CPU_REQ_INTR           (0x00000020)    // 命令後に割り込みチェック
1.1.1.5   root       22: #define CPU_REQ_RESET          (0x00000040)    // リセット例外
1.1       root       23: 
                     24: // m88100 レジスタイメージを保持する構造体。
                     25: // この構造体はコピーや比較をするので、ポインタとかは置かないこと。
                     26: struct m88100reg
                     27: {
                     28:        // PID(cr0)
                     29:        static const uint32 PID_REV_MASK        = 0x0000ff00; // 0 = MC88100
                     30:        static const uint32 PID_VER_MASK        = 0x000000fe;
                     31:        static const uint32 PID_MASTER          = 0x00000001;
                     32:        // PSR(cr1)
                     33:        static const uint32 PSR_SUPER           = 0x80000000;
                     34:        static const uint32 PSR_BO_LE           = 0x40000000; // ByteOrder(Little)
                     35:        static const uint32 PSR_SER                     = 0x20000000;
                     36:        static const uint32 PSR_C                       = 0x10000000; // Carry
                     37:        static const uint32 PSR_SFD1            = 0x00000008; // SFU1 Disable
                     38:        static const uint32 PSR_MXM                     = 0x00000004; // MisalignedAccessEnable
                     39:        static const uint32 PSR_IND                     = 0x00000002; // Interrupt Disable
                     40:        static const uint32 PSR_SFRZ            = 0x00000001; // Shadow Freeze
                     41: 
                     42:        // 例外処理で使用される S*IP
                     43:        static const uint32 SIP_MASK            = 0xfffffffcU;
                     44:        static const uint32 SIP_V                       = 0x00000002;
                     45:        static const uint32 SIP_E                       = 0x00000001;
                     46: 
                     47:        // DMTn、データ例外
                     48:        static const uint32 DM_BO                       = 0x00008000;
                     49:        static const uint32 DM_DAS                      = 0x00004000;
                     50:        static const uint32 DM_DOUB1            = 0x00002000;
                     51:        static const uint32 DM_LOCK                     = 0x00001000;
                     52:        static const uint32 DM_DREG_MASK        = 0x00000f80;
                     53:        static const uint32 DM_SIGNED           = 0x00000040;
                     54:        static const uint32 DM_EN3                      = 0x00000020;
                     55:        static const uint32 DM_EN2                      = 0x00000010;
                     56:        static const uint32 DM_EN1                      = 0x00000008;
                     57:        static const uint32 DM_EN0                      = 0x00000004;
                     58:        static const uint32 DM_EN_MASK          = (DM_EN0 | DM_EN1 | DM_EN2 | DM_EN3);
                     59:        static const uint32 DM_WRITE            = 0x00000002;
                     60:        static const uint32 DM_VALID            = 0x00000001;
                     61:        // 内部識別フラグ
                     62:        static const uint32 DM_SIZE_B           = (1U << 16) | DM_EN3;
                     63:        static const uint32 DM_SIZE_H           = (1U << 17) | DM_EN3 | DM_EN2;
                     64:        static const uint32 DM_SIZE_W           = (1U << 18) | DM_EN_MASK;
                     65:        static const uint32 DM_USR                      = (1U << 20);
                     66:        static const uint32 DM_BU                       = DM_SIZE_B;
                     67:        static const uint32 DM_B                        = DM_SIZE_B | DM_SIGNED;
                     68:        static const uint32 DM_HU                       = DM_SIZE_H;
                     69:        static const uint32 DM_H                        = DM_SIZE_H | DM_SIGNED;
                     70:        static const uint32 DM_W                        = DM_SIZE_W;
                     71:        static const uint32 DM_D1                       = DM_SIZE_W | DM_DOUB1;
                     72:        static const uint32 DM_D2                       = DM_SIZE_W;
                     73: 
1.1.1.11! root       74:        // FPECR(fcr0)
        !            75:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !            76:        // +---------------+---------------+---------------+-+-+-+-+-+-+-+-+
        !            77:        // |                                               |I|U|P|O|D|U|O|I|
        !            78:        // |                       0                       |O|N|V|P|Z|F|V|N|
        !            79:        // +---------------+---------------+---------------+-+-+-+-+-+-+-+-+
        !            80:        static const uint32 FPECR_MASK  = 0x000000ff;   // 有効ビットマスク
        !            81:        static const uint32 FPECR_FIOV  = 0x00000080;   // FP Integer Overflow
        !            82:        static const uint32 FPECR_FUNIMP= 0x00000040;   // FP Unimplemented
        !            83:        static const uint32 FPECR_FPRV  = 0x00000020;   // FP Privilege Violation
        !            84:        static const uint32 FPECR_FROP  = 0x00000010;   // FP Reserved Operand
        !            85:        static const uint32 FPECR_FDVZ  = 0x00000008;   // FP Divice-by-Zero
        !            86:        static const uint32 FPECR_FUNF  = 0x00000004;   // FP Underflow
        !            87:        static const uint32 FPECR_FOVF  = 0x00000002;   // FP Overflow
        !            88:        static const uint32 FPECR_FINX  = 0x00000001;   // FP Inexact
        !            89: 
        !            90:        // FPHS1(fcr1)
        !            91:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !            92:        // +-+---------------------+---------------------------------------+
        !            93:        // |S|      Exponent       |     High order 20 bits of Mantissa    |
        !            94:        // +-+---------------------+---------------------------------------+
        !            95: 
        !            96:        // FPLS1(fcr2)
        !            97:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !            98:        // +---------------------------------------------------------------+
        !            99:        // |        Low order bits of Mantissa or Integer Operand          |
        !           100:        // +---------------------------------------------------------------+
        !           101: 
        !           102:        // FPHS2(fcr3)
        !           103:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           104:        // +-+---------------------+---------------------------------------+
        !           105:        // |S|      Exponent       |     High order 20 bits of Mantissa    |
        !           106:        // +-+---------------------+---------------------------------------+
        !           107: 
        !           108:        // FPLS2(fcr4)
        !           109:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           110:        // +---------------------------------------------------------------+
        !           111:        // |        Low order bits of Mantissa or Integer Operand          |
        !           112:        // +---------------------------------------------------------------+
        !           113: 
        !           114:        // FPPT(fcr5)
        !           115:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           116:        // +---------------+---------------+---------+---+---+---+---------+
        !           117:        // |               0               |  OPCODE |T1 |T2 |TD | DestReg |
        !           118:        // +---------------+---------------+---------+---+---+---+---------+
        !           119:        static const uint32 FPPT_MASK   = 0x0000ffff;   // 有効ビットマスク
        !           120:        static const uint32 FPPT_OPCODE = 0x0000f800;   // Opcode
        !           121:        static const uint32 FPPT_T1             = 0x00000600;   // Source1 Operand Size
        !           122:        static const uint32 FPPT_T2             = 0x00000180;   // Source2 Operand Size
        !           123:        static const uint32 FPPT_TD             = 0x00000060;   // Destination Size
        !           124:        static const uint32 FPPT_DEST   = 0x0000001f;   // Destination Register No.
        !           125: 
        !           126:        // FPRH(fcr6)
        !           127:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           128:        // +-----+-+-+-+-+-+-----+---------+-------------+-----------------+
        !           129:        // |S|RM |G|R|S|A|   0   |       High Order Bits of Mantissa       |
        !           130:        // +-----+-+-+-+-+-+-----+---------+-------------+-----------------+
        !           131:        static const uint32 FPRH_MASK   = 0xfe1fffff;   // 有効ビットマスク
        !           132:        static const uint32 FPRH_SIGN   = 0x80000000;   // Result Sign
        !           133:        static const uint32 FPRH_RNDMODE= 0x60000000;   // Rounding Mode for Res.
        !           134:        static const uint32 FPRH_GUARD  = 0x10000000;   // Guard  Bit for Result
        !           135:        static const uint32 FPRH_ROUND  = 0x08000000;   // Round  Bit for Result
        !           136:        static const uint32 FPRH_STICKY = 0x04000000;   // Sticky Bit for Result
        !           137:        static const uint32 FPRH_ADDONE = 0x02000000;   // Add One
        !           138:        static const uint32 FPRH_MANT   = 0x001fffff;   // Mantissa(High)
        !           139:        static const uint32 FPRH_1              = 0x00100000;   // 隠し実数部の 1
        !           140: 
        !           141:        // FPRL(fcr7)
        !           142:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           143:        // +---------------------------------------------------------------+
        !           144:        // |                 Low Order Bits of Mantissa                    |
        !           145:        // +---------------------------------------------------------------+
        !           146: 
        !           147:        // FPIT(fcr8)
        !           148:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           149:        // +-----------------------+-------+---------+-+-+-+-+-+-+---------+
        !           150:        // |                       |       |         |D|E|E|E|E|E|         |
        !           151:        // |  RESEXP (12bits)      |   0   |  OPCODE |S|V|Z|U|O|N| DestReg |
        !           152:        // +-----------------------+-------+---------+-+-+-+-+-+-+---------+
        !           153:        static const uint32 FPIT_MASK   = 0xfff0ffff;   // 有効ビットマスク
        !           154:        static const uint32 FPIT_RESEXP = 0xfff00000;   // Result Exponent
        !           155:        static const uint32 FPIT_OPCODE = 0x0000f800;   // Opcode
        !           156:        static const uint32 FPIT_DESTSIZ= 0x00000400;   // Destination Size
        !           157:        static const uint32 FPIT_EFINV  = 0x00000200;   // Enable Invalid Op.
        !           158:        static const uint32 FPIT_EFDVZ  = 0x00000100;   // Enable Divide-by-Zero
        !           159:        static const uint32 FPIT_EFUNF  = 0x00000080;   // Enable Underflow
        !           160:        static const uint32 FPIT_EFOVF  = 0x00000040;   // Enable Overflow
        !           161:        static const uint32 FPIT_EFINX  = 0x00000020;   // Enable Inexact
        !           162:        static const uint32 FPIT_DEST   = 0x0000001f;   // Destination Register No.
        !           163: 
        !           164:        // FPSR(fcr62)
        !           165:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           166:        // +---------------+---------------+---------------+-----+-+-+-+-+-+
        !           167:        // |                                                     |A|A|A|A|A|
        !           168:        // |                        0                            |V|D|U|O|I|
        !           169:        // +---------------+---------------+---------------+-----+-+-+-+-+-+
        !           170:        static const uint32 FPSR_MASK   = 0x0000001f;   // 有効ビットマスク
        !           171:        static const uint32 FPSR_AFINV  = 0x00000010;   // Acc. Invalid Op. Flag
        !           172:        static const uint32 FPSR_AFDVZ  = 0x00000008;   // Acc. Divide-by-Zero Flag
        !           173:        static const uint32 FPSR_AFUNF  = 0x00000004;   // Acc. Underflow Flag
        !           174:        static const uint32 FPSR_AFOVF  = 0x00000002;   // Acc. Overflow Flag
        !           175:        static const uint32 FPSR_AFINX  = 0x00000001;   // Acc. Inexact Flag
        !           176: 
        !           177:        // FPCR(fcr63)
        !           178:        //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        !           179:        // +---------------+---------------+---+-----------+-----+-+-+-+-+-+
        !           180:        // |                               |   |                 |E|E|E|E|E|
        !           181:        // |               0               |RM |                 |V|D|U|O|I|
        !           182:        // +---------------+---------------+---+-----------+-----+-+-+-+-+-+
        !           183:        static const uint32 FPCR_MASK   = 0x0000c01f;   // 有効ビットマスク
        !           184:        static const uint32 FPCR_RM             = 0x0000c000;   // Rounding Mask
        !           185:        static const uint32 FPCR_EFINV  = 0x00000010;   // Enable Invalid Operation
        !           186:        static const uint32 FPCR_EFDVZ  = 0x00000008;   // Enable Divide-by-Zero
        !           187:        static const uint32 FPCR_EFUNF  = 0x00000004;   // Enable Underflow
        !           188:        static const uint32 FPCR_EFOVF  = 0x00000002;   // Enable Overflow
        !           189:        static const uint32 FPCR_EFINX  = 0x00000001;   // Enable Inexact
        !           190: 
1.1       root      191:        // 頻繁にアクセスしそうな変数はオフセットの若いほうに持ってきておく。
                    192: 
                    193:        // 実行中の命令
                    194:        uint64 opX = 0;
                    195:        // プリフェッチ命令
                    196:        uint64 opF = 0;
                    197: 
                    198:        uint32 xip = 0;
                    199:        uint32 nip = 0;
                    200:        uint32 fip = 0;
                    201: 
                    202:        uint32 r[32] {};
                    203:        union {
                    204:                uint32 cr[21] {};
                    205:                struct {
                    206:                        uint32 pid;             // cr0
                    207:                        uint32 psr;             // cr1
                    208:                        uint32 epsr;    // cr2
                    209:                        uint32 ssbr;    // cr3
                    210:                        uint32 sxip;    // cr4
                    211:                        uint32 snip;    // cr5
                    212:                        uint32 sfip;    // cr6
                    213:                        uint32 vbr;             // cr7
                    214:                        uint32 dmt0;    // cr8
                    215:                        uint32 dmd0;    // cr9
                    216:                        uint32 dma0;    // cr10
                    217:                        uint32 dmt1;    // cr11
                    218:                        uint32 dmd1;    // cr12
                    219:                        uint32 dma1;    // cr13
                    220:                        uint32 dmt2;    // cr14
                    221:                        uint32 dmd2;    // cr15
                    222:                        uint32 dma2;    // cr16
                    223:                        uint32 sr[4];   // cr17,18,19,20
                    224:                };
                    225:        };
                    226:        union {
                    227:                uint32 fcr[11] {};
                    228:                struct {
                    229:                        uint32 fpecr;   // fcr0
                    230:                        uint32 fphs1;   // fcr1
                    231:                        uint32 fpls1;   // fcr2
                    232:                        uint32 fphs2;   // fcr3
                    233:                        uint32 fpls2;   // fcr4
                    234:                        uint32 fppt;    // fcr5
                    235:                        uint32 fprh;    // fcr6
                    236:                        uint32 fprl;    // fcr7
                    237:                        uint32 fpit;    // fcr8
                    238:                        uint32 fpsr;    // fcr62 [9]
                    239:                        uint32 fpcr;    // fcr63 [10]
                    240:                };
                    241:        };
                    242: 
                    243:        // 直近のデータアクセスアドレス
                    244:        uint32 lastaddr;
                    245: 
                    246:        // スーパーバイザ/ユーザモードなら true
                    247:        bool IsSuper()  const { return (psr & PSR_SUPER) != 0; }
                    248:        bool IsUser()   const { return (psr & PSR_SUPER) == 0; }
                    249: 
1.1.1.5   root      250:        // 割り込みが許可なら true
                    251:        bool IsIntrEnable() const { return (psr & PSR_IND) == 0; }
                    252: 
1.1.1.4   root      253:        // SFU1(FPU)が有効なら true
                    254:        bool IsFPUEnable() const        { return (psr & PSR_SFD1) == 0; }
                    255: 
1.1       root      256:        // MXM (Misaligned Access Enable) なら true
                    257:        bool IsMXM()    const { return (psr & PSR_MXM) != 0; }
                    258: 
                    259:        // キャリーフラグが立っていれば 1 を返す
                    260:        uint32 GetCY() const { return (psr >> 28) & 1; }
1.1.1.4   root      261: 
                    262:        // キャリーフラグをセットする。
                    263:        // cy のうち最下位ビットのみ参照する (呼び出し側はマスクせず渡してよい)
1.1       root      264:        void SetCY(uint cy) {
                    265:                psr &= ~PSR_C;
                    266:                psr |= ((cy & 1) << 28);
                    267:        }
                    268: 
1.1.1.11! root      269:        static const uint32 fcr_mask[11];
1.1       root      270:        static const char * const sipname[3];
1.1.1.2   root      271:        static const char * const dmt_en_str[16];
1.1       root      272: };
                    273: 
                    274: class m88kcpu : public m88100reg
                    275: {
1.1.1.4   root      276:        static const uint64 DELAYSLOT = 1ULL << 62;
                    277: 
                    278:        enum ExceptionKind
                    279:        {
                    280:                NORMAL,
                    281:                DATA,
                    282:                ERROR,
                    283:                INTR,
                    284:                TRAP,
                    285:        };
                    286: 
1.1       root      287:  public:
1.1.1.8   root      288:        m88kcpu();
1.1       root      289:        virtual ~m88kcpu();
                    290: 
1.1.1.8   root      291:        void PowerOn();
                    292:        void RequestReset();
                    293: 
1.1.1.5   root      294:        uint32 Run(uint32 delta);
1.1       root      295:        void Release();
1.1.1.5   root      296: 
                    297:        // 仮想時刻を返す
1.1.1.6   root      298:        uint64 GetVTime() const { return total_vtime + Cycle2Vtime(used_cycle); }
1.1       root      299: 
1.1.1.5   root      300:        // 割り込み信号線が変化したことの通知を受ける。
                    301:        // level は 0 か 1。
                    302:        void Interrupt(int level);
1.1       root      303: 
1.1.1.2   root      304:        // PID.VERSION を設定する (初期化時に呼ぶ)
                    305:        void SetVersion(uint32 version);
                    306: 
1.1.1.4   root      307:        // クラス外部からの xip 取得
                    308:        uint32 GetXIP() const   { return xip; }
1.1       root      309: 
                    310:        // op が>=0ならバスエラーは起きていない
                    311:        //  そのときに DELAYSLOT bit が 0 ならば通常
                    312:        //  bit32 が 1 ならば遅延スロット命令
                    313:        // op が負数ならバスエラーが起きた
                    314:        //  そのときに DELAYSLOT bit が 1 ならば通常バスエラー
                    315:        //  bit32 が 0 ならば遅延スロットでのバスエラー
                    316:        // バスエラーかどうかのチェックのほうが回数が多いため、
                    317:        // バスエラー優先にしたい。
                    318: 
1.1.1.4   root      319:        static bool OpIsBusErr(uint64 op) {
1.1       root      320:                return (int64)op < 0;
                    321:        }
1.1.1.4   root      322: 
                    323:        // op が DelaySlot 実行なら true を返す。デバッガで表示用に使う。
                    324:        static bool OpIsDelay(uint64 op) {
1.1       root      325:                return (OpIsBusErr(op) ? ~op : op) & DELAYSLOT;
                    326:        }
                    327: 
1.1.1.4   root      328:        // サイクルを加算 (m88200 から使う)
1.1.1.5   root      329:        // 今は単純に加算しているだけでオーバーラップなどは考慮してない
                    330:        void AddCycle(int32 wait) { used_cycle += wait; }
                    331: 
                    332:        // MPU クロックを設定
1.1.1.7   root      333:        void SetClockSpeed(uint32 clock_khz_);
1.1.1.4   root      334: 
                    335:        std::atomic<uint32> atomic_reqflag {}; // リクエストフラグ
                    336: 
                    337:        // [0] 命令バス
                    338:        // [1] データバス
                    339:        m88200 cmmu[2] {};
                    340: 
                    341:        // ブランチ履歴 (例外履歴を含む)
1.1.1.9   root      342:        BranchHistory_m88xx0 brhist { BranchHistory::BrHist };
1.1.1.4   root      343:        // 例外履歴のみ
1.1.1.9   root      344:        BranchHistory_m88xx0 exhist { BranchHistory::ExHistOnly };
1.1.1.4   root      345: 
1.1.1.5   root      346:        // 32bit 命令コードからディスパッチ用の 12bit に変換。
                    347:        static uint32 op32_to_12(uint32 op) {
                    348:                return ((op >> 20) & 0x0fc0) | ((op >> 10) & 0x003f);
                    349:        }
                    350: 
1.1.1.4   root      351:        // 例外名を返す
                    352:        static const char *GetExceptionName(int vector);
                    353: 
1.1.1.9   root      354:        // 疑似 STOP 状態に入る機能を有効にする場合 true
                    355:        bool pseudo_stop_enable {};
                    356: 
1.1.1.10  root      357:        // DOS call エミュレーションコールバックを設定する
                    358:        void SetFLineCallback(bool (*callback)(m88kcpu *, void *), void *arg);
                    359: 
1.1.1.4   root      360:  private:
1.1.1.5   root      361:        void Reset();
                    362: 
1.1.1.4   root      363:        uint64 fetch() {
                    364:                nip = fip;
                    365:                opF = cmmu[0].load_32(fip);
                    366:                fip += 4;
                    367:                return opF;
                    368:        }
                    369: 
                    370:        // PSR を newpsr に変更する。
1.1.1.2   root      371:        // CY ビットは特別にこの関数を経由しないで変更してよいことにする。
                    372:        void SetPSR(uint32 newpsr)
                    373:        {
                    374:                psr = newpsr;
1.1.1.4   root      375:                SetPSR();
                    376:        }
                    377:        // 更新された psr に基づいて、PSR 変更によって必要な処理をする。
                    378:        // CY ビットを変更した場合は呼ばなくてよいことにする。
                    379:        void SetPSR()
                    380:        {
1.1.1.2   root      381:                // CMMU に S/U 信号を出す
                    382:                cmmu[0].SetSuper(IsSuper());
                    383:                cmmu[1].SetSuper(IsSuper());
1.1.1.5   root      384:                // 割り込み許可なら割り込みチェック
                    385:                if (IsIntrEnable()) {
                    386:                        atomic_reqflag |= CPU_REQ_INTR;
                    387:                }
1.1.1.2   root      388:        }
                    389: 
1.1.1.11! root      390:        // FPxS1, FPxS2 レジスタを設定
        !           391:        void SetFPxS(uint32& h, uint32& l, double src, uint32 t);
        !           392:        void SetFPS1(double src, uint32 t1) { SetFPxS(fphs1, fpls1, src, t1); }
        !           393:        void SetFPS2(double src, uint32 t2) { SetFPxS(fphs2, fpls2, src, t2); }
        !           394:        void SetFPS1(uint32 src) { fpls1 = src; }
        !           395:        void SetFPS2(uint32 src) { fpls2 = src; }
        !           396:        // FP Result を FPIT, FPRH, FPRL レジスタに設定
        !           397:        void SetFPRx(double src);
        !           398: 
1.1       root      399:        void Exception(int vec);
                    400:        void ExceptionCore(int vec, ExceptionKind cause);
1.1.1.5   root      401:        uint32 Calcdmt(uint32 flag);
                    402:        void ReadDataException32(uint32 addr, uint32 flag);
                    403:        void ReadDataException64(uint32 addr, uint32 flag);
                    404:        void WriteDataException32(uint32 addr, uint32 flag);
                    405:        void WriteDataException64(uint32 addr, uint32 flag);
                    406:        void XmemDataException(uint32 addr, uint32 flag);
1.1.1.11! root      407:        void FPPreciseException(uint32 cause, double s2);
        !           408:        void FPPreciseException(uint32 cause, double s1, double s2);
        !           409:        void FPPreciseException(uint32 cause);
        !           410:        void FPImpreciseException(uint32 cause);
1.1.1.2   root      411: 
1.1       root      412:        // ブランチ処理用
1.1.1.4   root      413:        void EnterBranch(uint32 toaddr);
1.1       root      414:        void ExitBranch();
                    415:        void ExitDelayBranch();
1.1.1.2   root      416:        uint32 nop_counter {};  // STOP 検出用の nop 命令カウンタ
                    417: 
1.1       root      418:        // ロードストア命令用の下処理
1.1.1.2   root      419:        bool ldst_usr(uint32& usr);
1.1       root      420:        uint32 ldst_scale(uint32 size);
                    421:        bool ldst_align(uint32 size, uint32& addr);
1.1.1.11! root      422:        // 浮動小数点数命令用の処理
        !           423:        void ops_int(int mode);
1.1       root      424: 
                    425: #define OP_PROTO(name) void __CONCAT(op_,name)()
                    426: #include "m88100ops.h"
1.1.1.2   root      427: OP_PROTO(illegal);
1.1       root      428: #undef OP_PROTO
                    429: 
                    430:        void op_unimpl() {
                    431:                printf("unimplemented op XIP=%08x opX=%08x\n", xip, (uint32)opX);
                    432:        }
1.1.1.4   root      433:        void fpu_unimpl();
                    434: 
1.1.1.5   root      435:        // 仮想時刻 [nsec]
                    436:        uint64 total_vtime {};
                    437: 
                    438:        // サイクル数を仮想時間 [nsec] に変換
                    439:        uint64 Cycle2Vtime(int32 cycle) const {
1.1.1.7   root      440:                return (int64)cycle * c2v;
1.1.1.4   root      441:        }
                    442: 
1.1.1.5   root      443:        // 仮想時間 [nsec] をサイクル数に変換
                    444:        uint32 Vtime2Cycle(uint32 vtime) const {
1.1.1.7   root      445:                return ((uint64)vtime * v2c_factor) >> v2c_shift;
1.1.1.5   root      446:        }
                    447: 
                    448:        // 今のところサイクルを正確に実装するのは無理なので
                    449:        // 適当に全部積み上げてある。
                    450:        uint32 used_cycle {};           // 現在のターンでこれまでに消費したサイクル数
                    451:        uint32 goal_cycle {};           // 現在のターンで消費すべきサイクル数
                    452:        uint32 clock_khz {};            // MPU クロック [kHz]
1.1.1.7   root      453:        uint32 c2v {};                          // サイクル数を nsec に変換する際の係数
                    454:        uint64 v2c_factor {};           // nsec をサイクル数に変換する際の乗算係数
                    455:        uint32 v2c_shift {};            // nsec をサイクル数に変換する際のシフト係数
1.1.1.5   root      456: 
                    457:        // ペンディング中の割り込みレベル
                    458:        int intr_pending {};
                    459: 
1.1.1.11! root      460:        // float,double と整数値の相互変換
        !           461:        static float u2f(uint32 u) {
        !           462:                float v;
        !           463:                memcpy(&v, &u, sizeof(v));
        !           464:                return v;
        !           465:        }
        !           466:        static double u2d(uint64 u) {
        !           467:                double v;
        !           468:                memcpy(&v, &u, sizeof(v));
        !           469:                return v;
        !           470:        }
        !           471:        static uint32 f2u(float v) {
        !           472:                uint32 u;
        !           473:                memcpy(&u, &v, sizeof(u));
        !           474:                return u;
        !           475:        }
        !           476:        static uint64 d2u(double v) {
        !           477:                uint64 u;
        !           478:                memcpy(&u, &v, sizeof(u));
        !           479:                return u;
        !           480:        }
        !           481: 
1.1.1.10  root      482:        // DOS call エミュレーション
                    483:        bool (*fline_callback)(m88kcpu *, void *) = NULL;
                    484:        void *fline_arg {};
                    485: 
1.1.1.3   root      486:        // 例外名
                    487:        static const char * const exception_names[];
1.1       root      488: };

unix.superglobalmegacorp.com

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