--- nono/m88xx0/m88100.h 2026/04/29 17:04:40 1.1.1.4 +++ nono/m88xx0/m88100.h 2026/04/29 17:04:54 1.1.1.9 @@ -19,6 +19,7 @@ #define CPU_REQ_PROMPT (0x00000008) // デバッガプロンプト #define CPU_REQ_RELEASE (0x00000010) // 命令後に CPU 実行中断 #define CPU_REQ_INTR (0x00000020) // 命令後に割り込みチェック +#define CPU_REQ_RESET (0x00000040) // リセット例外 // m88100 レジスタイメージを保持する構造体。 // この構造体はコピーや比較をするので、ポインタとかは置かないこと。 @@ -129,6 +130,9 @@ struct m88100reg bool IsSuper() const { return (psr & PSR_SUPER) != 0; } bool IsUser() const { return (psr & PSR_SUPER) == 0; } + // 割り込みが許可なら true + bool IsIntrEnable() const { return (psr & PSR_IND) == 0; } + // SFU1(FPU)が有効なら true bool IsFPUEnable() const { return (psr & PSR_SFD1) == 0; } @@ -166,11 +170,18 @@ class m88kcpu : public m88100reg m88kcpu(); virtual ~m88kcpu(); - void Reset(uint32 reset_vector); - uint32 Run(uint64 request); + void PowerOn(); + void RequestReset(); + + uint32 Run(uint32 delta); void Release(); - void Interrupt(); + // 仮想時刻を返す + uint64 GetVTime() const { return total_vtime + Cycle2Vtime(used_cycle); } + + // 割り込み信号線が変化したことの通知を受ける。 + // level は 0 か 1。 + void Interrupt(int level); // PID.VERSION を設定する (初期化時に呼ぶ) void SetVersion(uint32 version); @@ -196,12 +207,12 @@ class m88kcpu : public m88100reg return (OpIsBusErr(op) ? ~op : op) & DELAYSLOT; } - // 積算実行サイクル数を取得 - uint64 GetTotalCycle() const { return total_cycle; } - // サイクルを加算 (m88200 から使う) - // 今は単純に加算しているだけで正確ではない - void AddCycle(uint64 cycle) { total_cycle += cycle; } + // 今は単純に加算しているだけでオーバーラップなどは考慮してない + void AddCycle(int32 wait) { used_cycle += wait; } + + // MPU クロックを設定 + void SetClockSpeed(uint32 clock_khz_); std::atomic atomic_reqflag {}; // リクエストフラグ @@ -210,14 +221,24 @@ class m88kcpu : public m88100reg m88200 cmmu[2] {}; // ブランチ履歴 (例外履歴を含む) - BranchHistory_m88xx0 brhist {}; + BranchHistory_m88xx0 brhist { BranchHistory::BrHist }; // 例外履歴のみ - BranchHistory_m88xx0 exhist {}; + BranchHistory_m88xx0 exhist { BranchHistory::ExHistOnly }; + + // 32bit 命令コードからディスパッチ用の 12bit に変換。 + static uint32 op32_to_12(uint32 op) { + return ((op >> 20) & 0x0fc0) | ((op >> 10) & 0x003f); + } // 例外名を返す static const char *GetExceptionName(int vector); + // 疑似 STOP 状態に入る機能を有効にする場合 true + bool pseudo_stop_enable {}; + private: + void Reset(); + uint64 fetch() { nip = fip; opF = cmmu[0].load_32(fip); @@ -239,13 +260,21 @@ class m88kcpu : public m88100reg // CMMU に S/U 信号を出す cmmu[0].SetSuper(IsSuper()); cmmu[1].SetSuper(IsSuper()); + // 割り込み許可なら割り込みチェック + if (IsIntrEnable()) { + atomic_reqflag |= CPU_REQ_INTR; + } } void Exception(int vec); void ExceptionCore(int vec, ExceptionKind cause); - void ReadDataException(uint32 addr, uint32 flag); - void WriteDataException(uint32 addr, uint32 data, uint32 flag); - void XmemDataException(uint32 addr, uint32 data, uint32 flag); + uint32 Calcdmt(uint32 flag); + void ReadDataException32(uint32 addr, uint32 flag); + void ReadDataException64(uint32 addr, uint32 flag); + void WriteDataException32(uint32 addr, uint32 flag); + void WriteDataException64(uint32 addr, uint32 flag); + void XmemDataException(uint32 addr, uint32 flag); + void FPException(int fpex); // ブランチ処理用 void EnterBranch(uint32 toaddr); @@ -268,14 +297,30 @@ OP_PROTO(illegal); } void fpu_unimpl(); - // 32bit 命令コードからディスパッチ用の 12bit に変換。 - static uint32 op32_to_12(uint32 op) { - return ((op >> 20) & 0x0fc0) | ((op >> 10) & 0x003f); + // 仮想時刻 [nsec] + uint64 total_vtime {}; + + // サイクル数を仮想時間 [nsec] に変換 + uint64 Cycle2Vtime(int32 cycle) const { + return (int64)cycle * c2v; + } + + // 仮想時間 [nsec] をサイクル数に変換 + uint32 Vtime2Cycle(uint32 vtime) const { + return ((uint64)vtime * v2c_factor) >> v2c_shift; } - // 積算実行サイクル数 - // 今のところ正確に実装するのは無理なので、適当に全部積み上げてある。 - uint64 total_cycle {}; + // 今のところサイクルを正確に実装するのは無理なので + // 適当に全部積み上げてある。 + uint32 used_cycle {}; // 現在のターンでこれまでに消費したサイクル数 + uint32 goal_cycle {}; // 現在のターンで消費すべきサイクル数 + uint32 clock_khz {}; // MPU クロック [kHz] + uint32 c2v {}; // サイクル数を nsec に変換する際の係数 + uint64 v2c_factor {}; // nsec をサイクル数に変換する際の乗算係数 + uint32 v2c_shift {}; // nsec をサイクル数に変換する際のシフト係数 + + // ペンディング中の割り込みレベル + int intr_pending {}; // 例外名 static const char * const exception_names[];