--- nono/vm/mpu64180.cpp 2026/04/29 17:05:33 1.1.1.5 +++ nono/vm/mpu64180.cpp 2026/04/29 17:05:50 1.1.1.7 @@ -11,7 +11,9 @@ #include "mpu64180.h" #include "config.h" #include "debugger.h" +#include "event.h" #include "hd647180.h" +#include "hd647180asci.h" #include "pio.h" #include "scheduler.h" #include "ssg.h" @@ -72,6 +74,20 @@ MPU64180Device::putlogn(const char *fmt, WriteLog(buf); } +bool +MPU64180Device::Create() +{ + try { + asci.reset(new HD647180ASCIDevice()); + } catch (...) { } + if ((bool)asci == false) { + warnx("Failed to initialize HD647180ASCIDevice at %s", __method__); + return false; + } + + return true; +} + // 初期化 bool MPU64180Device::Init() @@ -112,12 +128,13 @@ MPU64180Device::Init() // 命令実行イベント。func, time は都度設定する。 // 登録は親クラスで行ってある。 - exec_event.SetName("XP(HD647180) Execute"); + exec_event->SetName("XP(HD647180) Execute"); // タイマーイベント。time は都度設定する。 - timer_event.func = ToEventCallback(&MPU64180Device::TimerCallback); - timer_event.SetName("XP(HD647180) Timer"); - scheduler->RegistEvent(timer_event); + auto evman = GetEventManager(); + timer_event = evman->Regist(this, + ToEventCallback(&MPU64180Device::TimerCallback), + "XP(HD647180) Timer"); return true; } @@ -180,7 +197,7 @@ MPU64180Device::Reset() opmode = OpMode::Reset; // 命令実行サイクルを停止 - exec_event.SetName("XP(HD647180) Reset"); + exec_event->SetName("XP(HD647180) Reset"); scheduler->StopEvent(exec_event); // 汎用レジスタの値は不定。目印として $cc で埋めておく。 @@ -238,12 +255,12 @@ MPU64180Device::EnterNormal() opmode = OpMode::Normal; SetExec(ToEventCallback(&MPU64180Device::ExecNormal)); - exec_event.SetName("XP(HD647180) Execute"); + exec_event->SetName("XP(HD647180) Execute"); SetTrace(debugger->IsTrace()); // 3 クロック後から通常サイクル開始? (HD647180.pdf, p23) - exec_event.time = 3 * clock_nsec; + exec_event->time = 3 * clock_nsec; scheduler->RestartEvent(exec_event); } @@ -254,8 +271,8 @@ MPU64180Device::EnterSleep() // ExecNormal() 内で StartEvent() をしないに分岐するのは無駄が多いので、 // ここでは一旦コールバックだけ差し替えて、イベントを停止する。 SetExec(ToEventCallback(&MPU64180Device::ExecSleep)); - exec_event.SetName("XP(HD647180) Sleep"); - exec_event.time = 0; + exec_event->SetName("XP(HD647180) Sleep"); + exec_event->time = 0; // 内蔵デバイスのイベントも停止する。 scheduler->StopEvent(timer_event); @@ -267,21 +284,21 @@ MPU64180Device::EnterWakeup() { // 復帰処理のため一旦 Wakeup へ。 SetExec(ToEventCallback(&MPU64180Device::ExecWakeup)); - exec_event.time = 3 * clock_nsec; + exec_event->time = 3 * clock_nsec; scheduler->StartEvent(exec_event); } // スリープに入る時のイベント void -MPU64180Device::ExecSleep(Event& ev) +MPU64180Device::ExecSleep(Event *ev) { // 実行イベントを停止する。(StartEvent() を呼ばない) } // スリープから復帰するイベント void -MPU64180Device::ExecWakeup(Event& ev) +MPU64180Device::ExecWakeup(Event *ev) { // EI なら、割り込み処理から再開。 // DI なら、次の命令から再開。 @@ -307,7 +324,7 @@ MPU64180Device::TraceMessage(MessageID m // トレース実行 void -MPU64180Device::ExecTrace(Event& ev) +MPU64180Device::ExecTrace(Event *ev) { debugger->ExecXP(); (this->*exec_func)(ev); @@ -319,8 +336,8 @@ MPU64180Device::SetExec(EventCallback_t { exec_func = new_exec; - if (exec_event.func != ToEventCallback(&MPU64180Device::ExecTrace)) { - exec_event.func = exec_func; + if (exec_event->func != ToEventCallback(&MPU64180Device::ExecTrace)) { + exec_event->func = exec_func; } } @@ -335,7 +352,7 @@ MPU64180Device::SetTrace(bool enable) } else { func = exec_func; } - exec_event.func = func; + exec_event->func = func; } // IX/IY 分を考慮したサイクル数 @@ -571,7 +588,7 @@ MPU64180Device::MonitorUpdateIO(Monitor screen.Puts(16 + 5 * i, y, TA::OnOff(val & (1U << (7 - i))), rcr_str[i]); } - screen.Print(46, y, "RefCyc=%u", (1 << (val & 3)) * 10); + screen.Print(46, y, "RefCyc=%u", (1U << (val & 3)) * 10); y++; y++;