--- nono/vm/mpu88xx0.cpp 2026/04/29 17:04:39 1.1.1.3 +++ nono/vm/mpu88xx0.cpp 2026/04/29 17:04:50 1.1.1.6 @@ -13,14 +13,14 @@ std::unique_ptr gMPU88200ATC[2]; // コンストラクタ -MPU88xx0Device::MPU88xx0Device(uint32 addr) +MPU88xx0Device::MPU88xx0Device(uint32 reset_vector) { monitor_size = nnSize(79, 18); - // リセットベクタアドレスは Reset() で指定するので保持しておく - reset_vector = addr; + cpu.reset(new m88kcpu(reset_vector)); - cpu.reset(new m88kcpu()); + // リセット例外イベントコールバック設定 + event.func = (DeviceCallback_t)&MPU88xx0Device::Callback; // LUNA88K では CMMU の ID は次のように割り振ってあるようだ。 // OpenBSD の sys/arch/luna68k/include/board.h より。 @@ -48,25 +48,59 @@ MPU88xx0Device::~MPU88xx0Device() { } -// リセット -// (MPU が動くのはこの後 Scheduler::Run() を発行した後) +bool +MPU88xx0Device::Init() +{ + // 親クラス + if (inherited::Init() == false) { + return false; + } + // MPU クロックは親 Init() で読み込んで、ここで cpu にセットする + cpu->SetClockSpeed(clock_khz); + + return true; +} + +// リセット例外イベントコールバック void -MPU88xx0Device::ResetHard() +MPU88xx0Device::Callback(Event& ev) +{ + cpu->RequestReset(); +} + +// アクセス中の論理アドレスを取得 +uint32 +MPU88xx0Device::GetLaddr() const +{ + m88200 *cmmu = m88200::GetBusMaster(); + assert(cmmu); + return cmmu->GetLaddr(); +} + +// アクセス中の物理アドレスを取得 +uint32 +MPU88xx0Device::GetPaddr() const { - cpu->Reset(reset_vector); + m88200 *cmmu = m88200::GetBusMaster(); + assert(cmmu); + return cmmu->GetPaddr(); +} + +// アクセスウェイトを加算 +void +MPU88xx0Device::AddCycle(int32 cycle) +{ + // 今アクセスしてきている(= バスマスターの) CMMU に対して加算する + m88200 *cmmu = m88200::GetBusMaster(); + assert(cmmu); + cmmu->AddCycle(cycle); } // Interrupt void -MPU88xx0Device::Interrupt(Object *src, int level) +MPU88xx0Device::Interrupt(int level) { - // XXX: なぜか 1 レベルずれている? - level++; - if (gSysCtlr->GetIntMask(0) & (1 << level)) { - putlog(1, "Interrupt from %s", src->devname.c_str()); - gSysCtlr->TellIntLevel(0, 1 << level); - cpu->Interrupt(); - } + cpu->Interrupt(level); } // モニター更新 @@ -145,15 +179,14 @@ MPU88xx0Device::MonitorUpdate(TextScreen // 制御レジスタ(右中) x = 55; y = 9; - monitor.Print(x, y++, "ssbr(cr3):%08x", reg.ssbr); - monitor.Print(x, y++, "vbr (cr7):%08x", reg.vbr); for (int i = 0; i < 4; i++) { int rn = 17 + i; - monitor.Print(x, y + i, "sr%d(cr%d):%08x", i, rn, reg.cr[rn]); + monitor.Print(x, y++, "sr%d(cr%d):%08x", i, rn, reg.cr[rn]); } + monitor.Print(x, y++, "ssbr(cr3):%08x", reg.ssbr); + monitor.Print(x, y++, "vbr (cr7):%08x", reg.vbr); // MMU レジスタ(下段) - x = 0; y = 15; for (int i = 0; i <= 2; i++) { int dt = 8 + i * 3;