--- nono/vm/mpu.cpp 2026/04/29 17:05:37 1.1.1.15 +++ nono/vm/mpu.cpp 2026/04/29 17:05:59 1.1.1.19 @@ -25,6 +25,7 @@ #include "mpu.h" #include "config.h" #include "debugger.h" +#include "event.h" #include "mainbus.h" #include "scheduler.h" #include "syncer.h" @@ -50,18 +51,33 @@ MPUDevice::Init() { debugger = GetDebugger(); - // パラメータは継承側でセットしている。 - scheduler->RegistEvent(exec_event); + auto evman = GetEventManager(); + exec_event = evman->Regist(this, NULL, "MPU Execute"); return true; } void +MPUDevice::ResetHard(bool poweron) +{ + inherited::ResetHard(poweron); + last_vector = -1; +} + +void MPUDevice::PowerOff() { scheduler->StopEvent(exec_event); } +int32 +MPUDevice::GetAndResetLastVector() +{ + auto vector = last_vector; + last_vector = -1; + return vector; +} + // // メイン MPU (680x0/88xx0) 共通部 @@ -103,17 +119,19 @@ MainMPUDevice::Init() item.Err(); return false; } - clock_nsec = 1000 * 1000 / clock_khz; - if (clock_nsec < 1) { + clock_tsec = 1_msec / clock_khz; + if (clock_tsec < 1) { item.Err("Clock speed too high"); return false; } + // キャッシュを無効にするテスト用。 + force_disable_dcache = gConfig->Find("mpu-force-disable-dcache").AsBool(); + force_disable_icache = gConfig->Find("mpu-force-disable-icache").AsBool(); + scheduler->ConnectMessage(MessageID::MPU_TRACE_MAIN, this, ToMessageCallback(&MainMPUDevice::TraceMessage)); - exec_event.SetName("MPU Execute"); - return true; } @@ -130,6 +148,23 @@ MainMPUDevice::TraceMessage(MessageID ms SetTrace((bool)arg); } +void +MainMPUDevice::ChangeState(uint32 new_state) +{ + // new_mode (CPU_STATE_*) と + // NotifyCPUMode() の引数 Syncer::SYNCMODE_CPU_* は + // 実は同じ値なのでそのまま渡してよいことにする。 + static_assert(CPU_STATE_NORMAL == Syncer::SYNCMODE_CPU_NORMAL, ""); + static_assert(CPU_STATE_STOP == Syncer::SYNCMODE_CPU_STOP, ""); + static_assert(CPU_STATE_HALT == Syncer::SYNCMODE_CPU_HALT, ""); + + if (cpu_state != new_state) { + cpu_state = new_state; + // スケジューラに通知 + syncer->NotifyCPUMode(cpu_state); + } +} + // Round Mode (モニタ表示用) /*static*/ const char * const MainMPUDevice::rmstr[4] = {