--- nono/vm/mpu88xx0.h 2026/04/29 17:05:18 1.1.1.12 +++ nono/vm/mpu88xx0.h 2026/04/29 17:06:01 1.1.1.18 @@ -12,44 +12,24 @@ #include "mpu.h" #include "branchhistory.h" -#include "event.h" #include "m88100.h" #include "m88200.h" #include -class MPU88xx0Device : public MPUDevice, private M88100 +class MPU88xx0Device : public MainMPUDevice, private M88100 { - using inherited = MPUDevice; - - static const uint32 CPU_STATE_NORMAL = 0; - static const uint32 CPU_STATE_STOP = 1; // 疑似 STOP 状態 - - enum ExceptionKind { - NORMAL, - DATA, - ERROR, - INTR, - TRAP, - }; + using inherited = MainMPUDevice; + friend class Luna88kPROMEmuDevice; public: MPU88xx0Device(); - virtual ~MPU88xx0Device() override; + ~MPU88xx0Device() override; bool Init() override; void ResetHard(bool poweron) override; - // MPU からのアクセスをエミュレートする。 - // アドレスは論理アドレス。 - // 空間は現在のデータ空間。 - // ミスアラインドアクセスも可能。 - // アクセスエラーは -1 を返す。 - uint64 Read8(uint32 addr) override; - uint64 Read16(uint32 addr) override; - uint64 Read32(uint32 addr) override; - uint64 Write8(uint32 addr, uint32 data) override; - uint64 Write16(uint32 addr, uint32 data) override; - uint64 Write32(uint32 addr, uint32 data) override; + // キャッシュ禁止通知 (LUNA-88K では使っていない?) + void SetCI() override { } // 現在実行中の命令の PC を取得 uint32 GetPPC() const override { return reg.xip; } @@ -57,6 +37,9 @@ class MPU88xx0Device : public MPUDevice, // 現在の VBR を取得 uint32 GetVBR() const override { return reg.vbr; } + // MPU 名を取得 + const char *GetMPUName() const override { return "MC88100"; } + // スーパーバイザ/ユーザモードなら true bool IsSuper() const { return (reg.psr & PSR_SUPER) != 0; } bool IsUser() const { return (reg.psr & PSR_SUPER) == 0; } @@ -64,20 +47,18 @@ class MPU88xx0Device : public MPUDevice, // 割り込みが許可なら true bool IsIntrEnable() const { return (reg.psr & PSR_IND) == 0; } - // CPU の実行状態 (uint32) を返す。 - uint32 GetState() const { return cpu_state; } - - // 現在アクセス中の論理アドレス、物理アドレスを取得。 - uint32 GetLaddr() const override; - uint32 GetPaddr() const override; - - // アクセスウェイトを加算 - void AddCycle(int32 cycle) override { + // アクセスウェイト [clock] を加算。m88200 が呼ぶ。 + void AddCycle(int32 cycle) { // XXX 本来は今アクセスしてきている(= バスマスターの) CMMU に // 対して加算するべき?かもだが、まだその辺の概念がない。 used_cycle += cycle; } + // アクセスウェイト [nsec] を加算。m88200 が呼ぶ。 + void AddWait(uint64 nsec) { + buswait += nsec; + } + // 割り込み発生を MPU に通知 void Interrupt(int level) override; @@ -98,18 +79,18 @@ class MPU88xx0Device : public MPUDevice, private: // リセット例外コールバック - void ResetCallback(Event& ev); + void ResetCallback(Event *); // 命令実行系コールバック - void ExecNormal(Event& ev); - void ExecTrace(Event& ev); + void ExecNormal(Event *); + void ExecTrace(Event *); // トレース設定。デバッガから呼び出される。 - void SetTrace(bool trace_on) override; + void SetTrace(bool enable) override; uint64 fetch() { reg.nip = reg.fip; - reg.opF = cmmu[0]->load_32(reg.fip); + reg.opF = cmmu[0]->load_4(reg.fip); reg.fip += 4; return reg.opF; } @@ -124,11 +105,7 @@ class MPU88xx0Device : public MPUDevice, } // 更新された psr に基づいて、PSR 変更によって必要な処理をする。 // CY ビットを変更した場合は呼ばなくてよいことにする。 - void SetPSR() { - // CMMU に S/U 信号を出す - cmmu[0]->SetSuper(IsSuper()); - cmmu[1]->SetSuper(IsSuper()); - } + void SetPSR(); // キャリーフラグが立っていれば 1 を返す uint32 GetCY() const { return (reg.psr >> 28) & 1; } @@ -147,7 +124,7 @@ class MPU88xx0Device : public MPUDevice, bool IsMXM() const { return (reg.psr & PSR_MXM) != 0; } // FPxS1, FPxS2 レジスタを設定 - static void SetFPxS(uint32& h, uint32& l, double src, uint32 t); + static void SetFPxS(uint32 *h, uint32 *l, double src, uint32 t); void SetFPS1(double src, uint32 t1); void SetFPS2(double src, uint32 t2); void SetFPS1(uint32 src); @@ -155,9 +132,12 @@ class MPU88xx0Device : public MPUDevice, // FP Result を FPIT, FPRH, FPRL レジスタに設定 void SetFPRx(double src); - void Exception(int vec); - void ExceptionCore(int vec, ExceptionKind cause); - uint32 Calcdmt(uint32 flag); + void ExceptionCore(uint32 primask); + void Exception(uint32 pri); + void OuterException(uint32 pri); + void InternalException(uint32 vec); + void TrapException(uint32 vec); + uint32 MakeDMT(uint32 flag); void ReadDataException32(uint32 addr, uint32 flag); void ReadDataException64(uint32 addr, uint32 flag); void WriteDataException32(uint32 addr, uint32 flag); @@ -173,9 +153,8 @@ class MPU88xx0Device : public MPUDevice, uint32 nop_counter {}; // STOP 検出用の nop 命令カウンタ // ロードストア命令用の下処理 - bool ldst_usr(uint32& usr); uint32 ldst_scale(uint32 size); - bool ldst_align(uint32 size, uint32& addr); + // 浮動小数点数命令用の処理 void ops_int(int mode); @@ -184,8 +163,6 @@ class MPU88xx0Device : public MPUDevice, OP_PROTO(illegal); #undef OP_PROTO - void fpu_unimpl(); - // float,double と整数値の相互変換 static float u2f(uint32 u) { float v; @@ -223,12 +200,17 @@ OP_PROTO(illegal); // 電源オンからの累積消費サイクル uint64 used_cycle {}; - // ペンディング中の割り込みレベル - int intr_pending {}; + // 今回のバスウェイト [nsec] + uint64 buswait {}; + + // 割り込み信号線の状態。 + bool intr_asserted {}; + + // ペンディング中の例外優先度。EXCPRI_* + uint32 excep_pending {}; - // CPU の状態 - void ChangeState(uint32 new_state); - uint32 cpu_state {}; + // 内部例外/トラップ例外のベクタ番号。EXCVEC_* + uint32 excep_vector {}; // 疑似 STOP 状態に入る機能を有効にする場合 true bool pseudo_stop_enable {}; @@ -238,13 +220,14 @@ OP_PROTO(illegal); void *fline_arg {}; // レジスタモニター - DECLARE_MONITOR_CALLBACK(MonitorUpdate); - Monitor monitor { this }; + DECLARE_MONITOR_SCREEN(MonitorScreen); + Monitor *monitor {}; // イベントコールバック EventCallback_t exec_normal {}; }; -static inline MPU88xx0Device *GetMPU88xx0Device() { - return Object::GetObject(OBJ_MPU); +// これを呼びたい人は mpu を持ってるはず。 +inline MPU88xx0Device *GetMPU88xx0Device(Device *mpu_) { + return dynamic_cast(mpu_); }