--- nono/vm/mpu680x0.cpp 2026/04/29 17:05:37 1.1.1.19 +++ nono/vm/mpu680x0.cpp 2026/04/29 17:05:49 1.1.1.21 @@ -23,6 +23,7 @@ #include "mpu680x0.h" #include "config.h" #include "debugger.h" +#include "event.h" #include "exttostr.h" #include "interrupt.h" #include "m68030cache.h" @@ -30,7 +31,6 @@ #include "mainapp.h" #include "mainbus.h" #include "scheduler.h" -#include "syncer.h" #include "uimessage.h" #include "vectortable.h" @@ -71,8 +71,6 @@ MPU680x0Device::MPU680x0Device() // 例外カウンタ excep_counter.resize(256); - - SetTrace(false); } // デストラクタ @@ -150,7 +148,6 @@ MPU680x0Device::Init() break; } - debugger = GetDebugger(); interruptdev = GetInterruptDevice(); vectortable = GetVectorTable(); @@ -162,10 +159,11 @@ MPU680x0Device::Init() // その後 /IPEND をアサートするのはその次のアップエッジ。 // 合わせると、IPL0-2 が変化してから /IPEND がアサートされるまでは // 2 ~ 3 クロックかかる。(Figure 8-4) - intr_event.func = ToEventCallback(&MPU680x0Device::InterruptCallback); - intr_event.time = 3 * clock_nsec; - intr_event.SetName(GetName() + " Interrupt"); - scheduler->RegistEvent(intr_event); + auto evman = GetEventManager(); + intr_event = evman->Regist(this, + ToEventCallback(&MPU680x0Device::InterruptCallback), + GetName() + " Interrupt"); + intr_event->time = 3 * clock_nsec; // レジスタモニタの行数。 int height = 9; @@ -216,16 +214,16 @@ MPU680x0Device::ResetHard(bool poweron) // SP, PC をフェッチするという順序にしないといけないため、リセット例外が // 起動するまでに時間がかかるというところを都合よく真似ておく。 - exec_event.func = ToEventCallback(&MPU680x0Device::ResetCallback); - exec_event.time = 520 * clock_nsec; - exec_event.SetName(GetName() + " Reset"); + exec_event->func = ToEventCallback(&MPU680x0Device::ResetCallback); + exec_event->time = 520 * clock_nsec; + exec_event->SetName(GetName() + " Reset"); scheduler->RestartEvent(exec_event); } // リセット例外コールバック。 // MPU リセットから規定時間後に呼ばれる。 void -MPU680x0Device::ResetCallback(Event& ev) +MPU680x0Device::ResetCallback(Event *ev) { resetting = false; intr_pending = false; @@ -239,9 +237,9 @@ MPU680x0Device::ResetCallback(Event& ev) // 以降は通常走行。 if (cpu_state == CPU_STATE_NORMAL) { - exec_event.func = exec_short; - exec_event.time = cycle * clock_nsec; - exec_event.SetName(GetName() + " Execute"); + exec_event->func = exec_short; + exec_event->time = cycle * clock_nsec; + exec_event->SetName(GetName() + " Execute"); scheduler->RestartEvent(exec_event); } else { // リセット例外でダブルバスフォールトならここで停止。 @@ -253,7 +251,7 @@ MPU680x0Device::ResetCallback(Event& ev) // ここでは割り込みをチェックし、必要なら割り込み処理を起動、 // そうでなければ通常の命令実行を行う。 void -MPU680x0Device::ExecFull(Event& ev) +MPU680x0Device::ExecFull(Event *ev) { if (cpu_state == CPU_STATE_HALT) { // HALT なら停止。 @@ -274,12 +272,12 @@ MPU680x0Device::ExecFull(Event& ev) intr_pending = false; // 前の命令実行後となるここで割り込みを起動 - ev.time = ExceptionInterrupt(); + ev->time = ExceptionInterrupt(); scheduler->StartEvent(ev); } else { if (cpu_state == CPU_STATE_NORMAL) { // コールバックを通常処理に戻してから... - exec_event.func = exec_short; + exec_event->func = exec_short; // この場で次の命令を実行。 ExecShort(ev); @@ -291,7 +289,7 @@ MPU680x0Device::ExecFull(Event& ev) // トレース実行 void -MPU680x0Device::ExecTrace(Event& ev) +MPU680x0Device::ExecTrace(Event *ev) { debugger->ExecMain(); ExecFull(ev); @@ -308,11 +306,11 @@ MPU680x0Device::SetTrace(bool enable) exec_short = ToEventCallback(&MPU680x0Device::ExecShort); exec_full = ToEventCallback(&MPU680x0Device::ExecFull); } - exec_event.func = exec_full; + exec_event->func = exec_full; // STOP 命令中にオンにするには、停止しているイベントを起こす。 // STOP 命令中にオフにする場合は、何もしなくていい。 - if (enable && exec_event.IsRunning() == false) { + if (enable && exec_event->IsRunning() == false) { scheduler->StartEvent(exec_event); } } @@ -323,8 +321,8 @@ MPU680x0Device::Interrupt(int level) { assertmsg(0 <= level && level <= 7, "level=%d", level); - intr_event.code = level; - if (intr_event.IsRunning() == false) { + intr_event->code = level; + if (intr_event->IsRunning() == false) { scheduler->StartEvent(intr_event); } } @@ -341,9 +339,9 @@ MPU680x0Device::Interrupt(int level) // 外部割り込みが来たので、レベル比較などをして、必要なら次の命令境界で // 割り込みチェックを行うようにするところ。 void -MPU680x0Device::InterruptCallback(Event& ev) +MPU680x0Device::InterruptCallback(Event *ev) { - uint level = ev.code; + uint level = ev->code; uint mask = reg.intr_mask; // 信号線が 2 クロック期間安定していること云々は省略 @@ -370,7 +368,7 @@ MPU680x0Device::InterruptCallback(Event& // STOP 状態だったらここでイベントを開始する if (cpu_state == CPU_STATE_STOP) { // STOP から抜ける時間? - exec_event.time = 1 * clock_nsec; + exec_event->time = 1 * clock_nsec; scheduler->StartEvent(exec_event); } } @@ -380,24 +378,7 @@ MPU680x0Device::InterruptCallback(Event& void MPU680x0Device::MakeNextFull() { - exec_event.func = exec_full; -} - -void -MPU680x0Device::ChangeState(uint32 new_state) -{ - // new_mode (CPU_STATE_*) と - // RequestCPUMode() の引数 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->RequestCPUMode(cpu_state); - } + exec_event->func = exec_full; } // A-Line 命令エミュレーションのコールバックを指定。 @@ -436,7 +417,7 @@ MPU680x0Device::Halt() MakeNextFull(); // UI に通知 (メッセージボックス表示とか) - UIMessage::Post(UIMessage::HALT); + gMainApp.GetUIMessage()->Post(UIMessage::HALT); } // モニター更新の下請け (レジスタ共通部分) @@ -806,7 +787,7 @@ MPU68030Device::MonitorUpdateATC(Monitor bool tt_once_hit; { - std::unique_lock lock(table->atchist_mtx); + std::lock_guard lock(table->atchist_mtx); for (int i = 0; i < table->atchist.Length(); i++) { const auto& s = table->atchist.Peek(i); total += s.total; @@ -866,7 +847,7 @@ MPU68030Device::CalcStat() // こっちはロックする { - std::unique_lock lock(table->atchist_mtx); + std::lock_guard lock(table->atchist_mtx); table->atchist.EnqueueForce(s); if (__predict_false(s.tthit != 0)) { @@ -944,7 +925,7 @@ MPU68030Device::MonitorUpdateCache1(Text // 統計。 float hit = 0.0; { - std::unique_lock lock(cache->hist_mtx); + std::lock_guard lock(cache->hist_mtx); int len = cache->hist.Length(); if (len != 0) { for (int i = 0; i < cache->hist.Length(); i++) { @@ -974,6 +955,8 @@ MPU68040Device::MPU68040Device() mpu_name = "MC68040"; SetName("MPU(68040)"); + cycle_table = cycle_table_040; + mmu_itt[0].reset(new m68040TT("ITT0", ®.itt[0])); mmu_itt[1].reset(new m68040TT("ITT1", ®.itt[1])); mmu_dtt[0].reset(new m68040TT("DTT0", ®.dtt[0])); @@ -989,7 +972,7 @@ MPU68040Device::MPU68040Device() // ATC モニター (Inst/Data) atc_monitor = gMonitorManager->Regist(ID_MONITOR_MPUATC, this); atc_monitor->func = ToMonitorCallback(&MPU68040Device::MonitorUpdateATC); - atc_monitor->SetSize(121, 34); + atc_monitor->SetSize(125, 34); } // デストラクタ