--- nono/vm/mpu680x0.cpp 2026/04/29 17:05:41 1.1.1.20 +++ 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" @@ -70,8 +71,6 @@ MPU680x0Device::MPU680x0Device() // 例外カウンタ excep_counter.resize(256); - - SetTrace(false); } // デストラクタ @@ -160,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; @@ -214,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; @@ -237,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 { // リセット例外でダブルバスフォールトならここで停止。 @@ -251,7 +251,7 @@ MPU680x0Device::ResetCallback(Event& ev) // ここでは割り込みをチェックし、必要なら割り込み処理を起動、 // そうでなければ通常の命令実行を行う。 void -MPU680x0Device::ExecFull(Event& ev) +MPU680x0Device::ExecFull(Event *ev) { if (cpu_state == CPU_STATE_HALT) { // HALT なら停止。 @@ -272,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); @@ -289,7 +289,7 @@ MPU680x0Device::ExecFull(Event& ev) // トレース実行 void -MPU680x0Device::ExecTrace(Event& ev) +MPU680x0Device::ExecTrace(Event *ev) { debugger->ExecMain(); ExecFull(ev); @@ -306,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); } } @@ -321,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); } } @@ -339,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 クロック期間安定していること云々は省略 @@ -368,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); } } @@ -378,7 +378,7 @@ MPU680x0Device::InterruptCallback(Event& void MPU680x0Device::MakeNextFull() { - exec_event.func = exec_full; + exec_event->func = exec_full; } // A-Line 命令エミュレーションのコールバックを指定。 @@ -417,7 +417,7 @@ MPU680x0Device::Halt() MakeNextFull(); // UI に通知 (メッセージボックス表示とか) - UIMessage::Post(UIMessage::HALT); + gMainApp.GetUIMessage()->Post(UIMessage::HALT); } // モニター更新の下請け (レジスタ共通部分) @@ -787,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; @@ -847,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)) { @@ -925,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++) {