--- nono/vm/mpu.h 2026/04/29 17:04:28 1.1.1.1 +++ nono/vm/mpu.h 2026/04/29 17:05:16 1.1.1.13 @@ -1,90 +1,91 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// メイン MPU (680x0/88xx0) 共通部 // #pragma once #include "device.h" -#include "m68030.h" +#include "event.h" +#include "message.h" + +class Debugger; +class MainbusDevice; +class Syncer; class MPUDevice : public Device { - typedef Device inherited; + using inherited = Device; public: - MPUDevice(uint32); - virtual ~MPUDevice(); - - virtual bool Init(); - virtual void ResetHard(); - - virtual bool MonitorUpdate(); - - // MPU を request サイクル分実行する - uint32 Run(uint64 request); + MPUDevice(); + virtual ~MPUDevice() override; - // 現在の PPC を取得 - uint32 GetPPC() const { return RegPPC; } + bool Init() override; + void PowerOff() override; - // 割り込み発生を MPU に通知 (オートベクタ) - void Interrupt(int level); + // 現在実行中の命令の PC を取得 + virtual uint32 GetPPC() const = 0; - // 割り込み発生を MPU に通知 (ベクタ) - void Interrupt(int level, int vector); + // 現在の VBR を取得 + virtual uint32 GetVBR() const = 0; - // MPU の処理をこの命令で中断させる。 - // スケジューラのイベントリストに追加が発生した時に VM 側から - // MPU へ処理の中断を指示する。 - void Release() { cpu->atomic_reqflag |= CPU_REQ_RELEASE; } + // 現在アクセス中の論理アドレス、物理アドレスを取得。 + // Laddr == Paddr が MMU オフなのか PA=VA で運用中なのかの区別は + // ここでは付かない。 + virtual uint32 GetLaddr() const = 0; + virtual uint32 GetPaddr() const = 0; - // 基準サイクル数を取得 - uint64 total_cycle() const { return cpu->total_cycle; } + // MPU クロック [kHz] を取得する。 + int GetClockSpeed() const { return clock_khz; } - // A-Line, F-Line 命令エミュレーションのコールバックを指定する。 - // (Human68k エミュレーションで使用) - void SetALineCallback(bool (*callback)(m68kcpu*, void*), void *arg); - void SetFLineCallback(bool (*callback)(m68kcpu*, void*), void *arg); + // MPU クロック [nsec] を取得する。 + uint64 GetClock_nsec() const { return clock_nsec; } - // FPU を持っているか - bool HaveFPU() const { - return cpu->has_fpu; - } + // アクセスウェイトを加算 + virtual void AddCycle(int32 cycle) = 0; - // CPU コアを取得 (主にデバッグ用途) - m68kcpu *GetCPU() const { - return cpu; - } + // 割り込み発生を MPU に通知 + virtual void Interrupt(int level) = 0; - private: - m68kcpu *cpu = NULL; -}; + // MPU からのアクセスをエミュレートする。 + // アドレスは論理アドレス。 + // 空間は現在のデータ空間。 + // アクセスエラーは (int64)-1 を返す。 + virtual uint64 Read8(uint32 addr) = 0; + virtual uint64 Read16(uint32 addr) = 0; + virtual uint64 Read32(uint32 addr) = 0; + virtual uint64 Write8(uint32 addr, uint32 data) = 0; + virtual uint64 Write16(uint32 addr, uint32 data) = 0; + virtual uint64 Write32(uint32 addr, uint32 data) = 0; -// ATC モニタ -class MPUATC : public Object -{ - public: - MPUATC(m68kcpu *cpu); - virtual ~MPUATC() { } + protected: + void TraceMessage(MessageID, uint32); + virtual void SetTrace(bool trace_on) = 0; - virtual bool MonitorUpdate(); + int clock_khz {}; // MPU クロック [kHz] + uint64 clock_nsec {}; // MPU クロック [nsec] - private: - m68kcpu *cpu = NULL; -}; + bool resetting {}; // リセット処理中フラグ -// ブランチ履歴モニタ -class MPUBrHist : public Object -{ - public: - MPUBrHist(m68kcpu *cpu); - virtual ~MPUBrHist() { } + Debugger *debugger {}; + MainbusDevice *mainbus {}; + Syncer *syncer {}; - virtual bool MonitorUpdate(); + // 1命令実行イベント + Event exec_event { this }; - private: - m68kcpu *cpu = NULL; + // Round Mode (モニタ表示用) + static const char * const rmstr[4]; }; +// XXX 互換性のためまだしばらく必要 extern MPUDevice *gMPU; -extern MPUATC *gMPUATC; -extern MPUBrHist *gMPUBrHist; + +static inline MPUDevice *GetMPUDevice() { + return Object::GetObject(OBJ_MPU); +}