--- nono/vm/mpu680x0.h 2026/04/29 17:05:20 1.1.1.12 +++ nono/vm/mpu680x0.h 2026/04/29 17:05:24 1.1.1.13 @@ -12,12 +12,14 @@ #include "mpu.h" #include "branchhistory.h" +#include "bus.h" #include "event.h" #include "m68030.h" #include "m68030mmu.h" #include "mainbus.h" class InterruptDevice; +class m68030Cache; class MPU680x0Device : public MPUDevice { @@ -31,8 +33,9 @@ class MPU680x0Device : public MPUDevice public: MPU680x0Device(); - virtual ~MPU680x0Device() override; + ~MPU680x0Device() override; + void SetLogLevel(int loglevel_) override; bool Init() override; void ResetHard(bool poweron) override; @@ -42,6 +45,9 @@ class MPU680x0Device : public MPUDevice // 現在の VBR を取得 uint32 GetVBR() const override { return reg.vbr; } + // MPU 名を取得 + const char *GetMPUName() const override { return "MC68030"; } + bool IsSuper() const { return reg.s; } bool IsMaster() const { return reg.m; } @@ -49,11 +55,8 @@ class MPU680x0Device : public MPUDevice uint32 GetState() const { return cpu_state; } // 現在アクセス中の論理アドレス、物理アドレスを取得。 - uint32 GetLaddr() const override { return bus.laddr; } - uint32 GetPaddr() const override { return bus.paddr; } - - // アクセスウェイトを加算 - void AddCycle(int32 cycle) override { used_cycle += cycle; } + uint32 GetLaddr() const override { return bus.laddr.Addr(); } + uint32 GetPaddr() const override { return bus.paddr.Addr(); } // 割り込みレベルが変わったことを MPU に通知 void Interrupt(int level) override; @@ -66,15 +69,9 @@ class MPU680x0Device : public MPUDevice // FPU を持っているか bool HaveFPU() const { return has_fpu; } - // MPU からのアクセスをエミュレートする。 - // アドレスは論理アドレスで、空間は現在のデータ空間。 - // バスエラーなら (uint64)-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; + void SetCI() override { + bus.ci = true; + } // ホールト void Halt(); @@ -82,7 +79,6 @@ class MPU680x0Device : public MPUDevice // 基本アクセス。内部から使用する。 // アドレスは論理アドレスで、空間は現在の命令/データ空間。 // バスエラーなら C++ の例外をスローする。 - uint32 fetch_8(); uint32 fetch_16(); uint32 fetch_32(); uint32 read_8(uint32 addr); @@ -93,7 +89,7 @@ class MPU680x0Device : public MPUDevice void write_32(uint32 addr, uint32 data); // MMU アクセス - uint64 TranslatePeek(uint32 laddr, uint fc, bool do_search); + busaddr TranslatePeek(busaddr laddr); // レジスタ uint16 GetIR() const { return ir; } @@ -176,28 +172,19 @@ class MPU680x0Device : public MPUDevice void restore_reg_pi(); void restore_reg_pd(); - void JumpVector(int vector); + void JumpVector(int vector, bool from_buserr); protected: #include "m68030ea.h" private: -#include "m68030bus.h" - inline uint32 fetch_16_bus(); - inline uint32 fetch_32_bus(); - inline uint32 read_8_bus(); - inline uint32 read_16_bus(); - inline uint32 read_32_bus(); - inline void write_8_bus(); - inline void write_16_bus(); - inline void write_32_bus(); - // FC 指定 - uint32 read_8_fc(uint32 addr); - uint32 read_16_fc(uint32 addr); - uint32 read_32_fc(uint32 addr); - void write_8_fc(uint32 addr, uint32 data); - void write_16_fc(uint32 addr, uint32 data); - void write_32_fc(uint32 addr, uint32 data); + // FC 指定アクセス + uint32 read_8_fc(busaddr addr); + uint32 read_16_fc(busaddr addr); + uint32 read_32_fc(busaddr addr); + void write_8_fc(busaddr addr, uint32 data); + void write_16_fc(busaddr addr, uint32 data); + void write_32_fc(busaddr addr, uint32 data); // 基本アクセスルーチンを使った便利サブルーチン inline void push_16(uint32 data) { @@ -219,6 +206,16 @@ class MPU680x0Device : public MPUDevice return data; } + // バスアクセス + uint32 fetch_16_bus(uint32 addr); + uint32 fetch_32_bus(uint32 addr); + uint32 read_8_bus(busaddr addr); + uint32 read_16_bus(busaddr addr); + uint32 read_32_bus(busaddr addr); + void write_8_bus(busaddr addr, uint32 data); + void write_16_bus(busaddr addr, uint32 data); + void write_32_bus(busaddr addr, uint32 data); + #define OP_PROTO(name) void __CONCAT(op_,name)() #include "m68030ops.h" #undef OP_PROTO @@ -245,6 +242,20 @@ class MPU680x0Device : public MPUDevice #include "m68030fpu.h" void fpu_op_start(); + // キャッシュ + void SetCACR(uint32); + uint32 fetch_16_cache(uint32 addr); + uint32 fetch_32_cache(uint32 addr); + uint32 fetch_32_cache_aligned(uint32 addr); +#if 0 + uint32 read_8_cache(busaddr addr); + uint32 read_16_cache(busaddr addr); + uint32 read_32_cache(busaddr addr); + void write_8_cache(busaddr addr, uint32 data); + void write_16_cache(busaddr addr, uint32 data); + void write_32_cache(busaddr addr, uint32 data); +#endif + // MMU bool SetSRP(uint32, uint32); bool SetCRP(uint32, uint32); @@ -256,7 +267,7 @@ class MPU680x0Device : public MPUDevice bool TranslateRead(); bool TranslateWrite(); - bool CheckTT() const; + bool CheckTT(); uint32 get_fc(); void mmu_op_illg2(); void mmu_op_pflush(); @@ -272,7 +283,7 @@ class MPU680x0Device : public MPUDevice void GenerateExframeB(int vector, uint16 sr); int ExceptionReset(); void ExceptionBuserr(int); - int ExceptionInterrupt(); + uint64 ExceptionInterrupt(); void ExceptionTrap15(); void Exception(int); void ExceptionGeneric(int vector, uint32 inst); @@ -293,6 +304,9 @@ class MPU680x0Device : public MPUDevice // バス m68kbus bus {}; + // 現在の特権状態でのプログラム空間とデータ空間アクセス用。 + busaddr fc_inst {}; // こっちは R 含む + busaddr fc_data {}; // こっちは R/W 含まない private: uint16 ir {}; @@ -306,6 +320,11 @@ class MPU680x0Device : public MPUDevice uint8 flag_pd {}; // -(An) のどのレジスタを保存したか uint8 flag_pi {}; // (An)+ のどのレジスタを保存したか + // キャッシュ + bool icache_enable {}; + bool icache_freeze {}; + std::unique_ptr icache /*{}*/; + // FPU int has_fpu {}; // 0:FPUなし、1:68881、2:68882(?) bool fpu_dirty {}; @@ -323,6 +342,9 @@ class MPU680x0Device : public MPUDevice // 電源オンからの累積消費サイクル uint64 used_cycle {}; + // 今回のバスウェイト [nsec] + uint64 buswait {}; + int32 cycle_nocache {}; // ノーキャッシュケースの時の追加分 // A-Line, F-Line 命令エミュレーションのコールバックとユーザ引数。 @@ -355,10 +377,15 @@ class MPU680x0Device : public MPUDevice DECLARE_MONITOR_CALLBACK(MonitorUpdateATC); Monitor atc_monitor { this }; + // キャッシュモニター + DECLARE_MONITOR_CALLBACK(MonitorUpdateCache); + Monitor cache_monitor { this }; + InterruptDevice *interruptdev {}; VectorTable *vectortable {}; }; -static inline MPU680x0Device *GetMPU680x0Device() { - return Object::GetObject(OBJ_MPU); +// これを呼びたい人は mpu を持ってるはず。 +static inline MPU680x0Device *GetMPU680x0Device(Device *mpu_) { + return dynamic_cast(mpu_); }