--- nono/m88xx0/m88100.h 2026/04/29 17:05:05 1.1.1.11 +++ nono/m88xx0/m88100.h 2026/04/29 17:05:07 1.1.1.12 @@ -10,16 +10,14 @@ #include "branchhistory.h" #include "bus.h" #include "m88200.h" +#include #include // 外部リクエストフラグ // XXX m680x0 側にもよく似たものがあってどうしたもんか -#define CPU_REQ_STOP (0x00000001) // ストップ状態 -#define CPU_REQ_TRACE (0x00000004) // デバッガ有効 -#define CPU_REQ_PROMPT (0x00000008) // デバッガプロンプト -#define CPU_REQ_RELEASE (0x00000010) // 命令後に CPU 実行中断 #define CPU_REQ_INTR (0x00000020) // 命令後に割り込みチェック -#define CPU_REQ_RESET (0x00000040) // リセット例外 + +class MPU88xx0Device; // m88100 レジスタイメージを保持する構造体。 // この構造体はコピーや比較をするので、ポインタとかは置かないこと。 @@ -285,17 +283,18 @@ class m88kcpu : public m88100reg }; public: - m88kcpu(); + static const uint32 CPU_STATE_NORMAL = 0; + static const uint32 CPU_STATE_STOP = 1; // 疑似 STOP 状態 + + public: + m88kcpu(MPU88xx0Device *dev_); virtual ~m88kcpu(); void PowerOn(); - void RequestReset(); + uint64 Reset(); - uint32 Run(uint32 delta); - void Release(); - - // 仮想時刻を返す - uint64 GetVTime() const { return total_vtime + Cycle2Vtime(used_cycle); } + int Exec(); + int ExecPseudoStop(); // 割り込み信号線が変化したことの通知を受ける。 // level は 0 か 1。 @@ -307,6 +306,9 @@ class m88kcpu : public m88100reg // クラス外部からの xip 取得 uint32 GetXIP() const { return xip; } + // クラス外部からの vbr 取得 + uint32 GetVBR() const { return vbr; } + // op が>=0ならバスエラーは起きていない // そのときに DELAYSLOT bit が 0 ならば通常 // bit32 が 1 ならば遅延スロット命令 @@ -329,14 +331,14 @@ class m88kcpu : public m88100reg // 今は単純に加算しているだけでオーバーラップなどは考慮してない void AddCycle(int32 wait) { used_cycle += wait; } - // MPU クロックを設定 - void SetClockSpeed(uint32 clock_khz_); - std::atomic atomic_reqflag {}; // リクエストフラグ + // CPU の状態 + uint32 cpu_state {}; + // [0] 命令バス // [1] データバス - m88200 cmmu[2] {}; + std::array cmmu {}; // ブランチ履歴 (例外履歴を含む) BranchHistory_m88xx0 brhist { BranchHistory::BrHist }; @@ -348,9 +350,6 @@ class m88kcpu : public m88100reg return ((op >> 20) & 0x0fc0) | ((op >> 10) & 0x003f); } - // 例外名を返す - static const char *GetExceptionName(int vector); - // 疑似 STOP 状態に入る機能を有効にする場合 true bool pseudo_stop_enable {}; @@ -358,8 +357,6 @@ class m88kcpu : public m88100reg void SetFLineCallback(bool (*callback)(m88kcpu *, void *), void *arg); private: - void Reset(); - uint64 fetch() { nip = fip; opF = cmmu[0].load_32(fip); @@ -381,10 +378,6 @@ class m88kcpu : public m88100reg // CMMU に S/U 信号を出す cmmu[0].SetSuper(IsSuper()); cmmu[1].SetSuper(IsSuper()); - // 割り込み許可なら割り込みチェック - if (IsIntrEnable()) { - atomic_reqflag |= CPU_REQ_INTR; - } } // FPxS1, FPxS2 レジスタを設定 @@ -432,27 +425,11 @@ OP_PROTO(illegal); } void fpu_unimpl(); - // 仮想時刻 [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; - } - // 今のところサイクルを正確に実装するのは無理なので // 適当に全部積み上げてある。 - uint32 used_cycle {}; // 現在のターンでこれまでに消費したサイクル数 - uint32 goal_cycle {}; // 現在のターンで消費すべきサイクル数 - uint32 clock_khz {}; // MPU クロック [kHz] - uint32 c2v {}; // サイクル数を nsec に変換する際の係数 - uint64 v2c_factor {}; // nsec をサイクル数に変換する際の乗算係数 - uint32 v2c_shift {}; // nsec をサイクル数に変換する際のシフト係数 + + // 電源オンからの累積消費サイクル + uint64 used_cycle {}; // ペンディング中の割り込みレベル int intr_pending {}; @@ -479,10 +456,13 @@ OP_PROTO(illegal); return u; } + void ChangeState(uint32 new_state); + + int instruction_in_stop {}; + + MPU88xx0Device *dev {}; + // DOS call エミュレーション bool (*fline_callback)(m88kcpu *, void *) = NULL; void *fline_arg {}; - - // 例外名 - static const char * const exception_names[]; };