--- nono/vm/newsctlr.cpp 2026/04/29 17:05:38 1.1.1.5 +++ nono/vm/newsctlr.cpp 2026/04/29 17:06:00 1.1.1.8 @@ -42,8 +42,10 @@ #include "newsctlr.h" #include "dipsw.h" #include "ethernet.h" +#include "event.h" #include "interrupt.h" #include "scheduler.h" +#include "syncer.h" #include "textscreen.h" // コンストラクタ @@ -65,6 +67,9 @@ NewsCtlrDevice::Init() { dipsw = GetDipswDevice(); + // クロックの同期方法。 + sync_rt = GetSyncer()->GetSyncRealtime(); + // ステータス読み出しのためにキャストしたのを持っておく interrupt = dynamic_cast(GetInterruptDevice()); assert(interrupt); @@ -78,10 +83,11 @@ NewsCtlrDevice::Init() putmsg(1, "macaddr=%s", macaddr.ToString(':').c_str()); memcpy(&oidrom[8], &macaddr, sizeof(macaddr)); - timer_event.func = ToEventCallback(&NewsCtlrDevice::TimerCallback); - timer_event.time = 10_msec; - timer_event.SetName("SystemTimer"); - scheduler->RegistEvent(timer_event); + auto evman = GetEventManager(); + timer_event = evman->Regist(this, + ToEventCallback(&NewsCtlrDevice::TimerCallback), + "SystemTimer"); + timer_event->time = TIMER_PERIOD; return true; } @@ -99,6 +105,9 @@ NewsCtlrDevice::ResetHard(bool poweron) // たぶん電源オンで即起動? 知らんけど。 if (poweron) { + if (sync_rt) { + stime = GetSyncer()->GetRealTime(); + } scheduler->StartEvent(timer_event); } } @@ -207,7 +216,7 @@ NewsCtlrDevice::Peek1(uint32 addr) // NewsIO の下請けとして呼ばれる。 void -NewsCtlrDevice::MonitorUpdateNewsCtlr(TextScreen& screen, int y) +NewsCtlrDevice::MonitorScreenNewsCtlr(TextScreen& screen, int y) { // テーブル方式ではないので、Read/Write と手動で揃える…。 @@ -312,13 +321,18 @@ NewsCtlrDevice::WriteTimer(uint32 data) // システムタイマーイベント void -NewsCtlrDevice::TimerCallback(Event& ev) +NewsCtlrDevice::TimerCallback(Event *ev) { timer_intr = true; ChangeInterrupt(); - // XXX clock-sync はまた後ほど - scheduler->RestartEvent(ev); + // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。 + if (sync_rt) { + stime += TIMER_PERIOD; + scheduler->StartRealtimeEvent(ev, stime, TIMER_PERIOD); + } else { + scheduler->RestartEvent(ev); + } } // 割り込み信号線の状態を変える