--- nono/vm/sysclk.cpp 2026/04/29 17:05:32 1.1.1.16 +++ nono/vm/sysclk.cpp 2026/04/29 17:05:59 1.1.1.20 @@ -15,9 +15,9 @@ #include "sysclk.h" #include "config.h" +#include "event.h" #include "interrupt.h" #include "monitor.h" -#include "rtc.h" #include "scheduler.h" #include "syncer.h" @@ -26,8 +26,8 @@ SysClkDevice::SysClkDevice() : inherited(OBJ_SYSCLK) { monitor = gMonitorManager->Regist(ID_MONITOR_SYSCLK, this); - monitor->func = ToMonitorCallback(&SysClkDevice::MonitorUpdate); - monitor->SetSize(31, 3); + monitor->SetCallback(&SysClkDevice::MonitorScreen); + monitor->SetSize(32, 4); } // デストラクタ @@ -39,25 +39,22 @@ SysClkDevice::~SysClkDevice() bool SysClkDevice::Init() { - if (inherited::Init() == false) { - return false; - } - interrupt = GetInterruptDevice(); // クロックは機種ごとに異なる const ConfigItem& item = gConfig->Find("!sysclk-freq"); freq = item.AsInt(); period = 1_sec / freq; - event.time = period; // クロックの同期方法 - sync_rt = GetRTCDevice()->GetSyncRealtime(); + syncer = GetSyncer(); + sync_rt = syncer->GetSyncRealtime(); - event.func = ToEventCallback(&SysClkDevice::Callback); - event.code = 0; - event.SetName("System Clock"); - scheduler->RegistEvent(event); + auto evman = GetEventManager(); + event = evman->Regist(this, + ToEventCallback(&SysClkDevice::Callback), + "System Clock"); + event->time = period; return true; } @@ -115,7 +112,7 @@ SysClkDevice::PokePort(uint32 offset, ui } void -SysClkDevice::MonitorUpdate(Monitor *, TextScreen& screen) +SysClkDevice::MonitorScreen(Monitor *, TextScreen& screen) { int y; @@ -124,8 +121,25 @@ SysClkDevice::MonitorUpdate(Monitor *, T int width = stime < 86400_sec ? 20 : 25; screen.Print(0, y++, "Freq: %u Hz", freq); - screen.Print(0, y++, "Sync: %s", sync_rt ? "Real Time" : "Virtual Time"); - screen.Print(0, y++, "Time: %*s", width, TimeToStr(stime).c_str()); + if (sync_rt) { + screen.Puts(0, y++, "Sync: Real Time"); + screen.Print(0, y++, "Time: %*s", width, TimeToStr(stime).c_str()); + + // TimeToStr は負は想定していないし、符号は数値の直前に足したい。 + screen.Puts(0, y, "Diff:"); + bool neg = false; + if (delta < 0) { + delta = -delta; + neg = true; + } + std::string s = TimeToStr(delta); + int offset = width - s.size(); + screen.Print(6 + offset, y++, "%c%s", (neg ? '-' : '+'), s.c_str()); + } else { + screen.Puts(0, y++, "Sync: Virtual Time"); + screen.Puts(0, y++, TA::Disable, "Time:"); + screen.Puts(0, y++, TA::Disable, "Diff:"); + } } // 割り込み状態を取得(?) @@ -142,18 +156,22 @@ SysClkDevice::GetInt() const // イベントハンドラ void -SysClkDevice::Callback(Event& ev) +SysClkDevice::Callback(Event *ev) { putlog(3, "Interrupt occured"); - // システムクロックとしての現在時刻。 - // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。 - stime += period; - sysint = true; ChangeInterrupt(); if (sync_rt) { + // システムクロックとしての現在時刻。 + // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。 + stime += period; + + // ホスト時間とここで作った実時間との差。 + uint64 now = syncer->GetRealTime(); + delta = (int64)(now - stime); + scheduler->StartRealtimeEvent(ev, stime, period); } else { scheduler->StartEvent(ev);