--- nono/vm/newsctlr.cpp 2026/04/29 17:05:29 1.1.1.4 +++ 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" // コンストラクタ @@ -63,18 +65,17 @@ NewsCtlrDevice::~NewsCtlrDevice() bool NewsCtlrDevice::Init() { - if (inherited::Init() == false) { - return false; - } - dipsw = GetDipswDevice(); + // クロックの同期方法。 + sync_rt = GetSyncer()->GetSyncRealtime(); + // ステータス読み出しのためにキャストしたのを持っておく interrupt = dynamic_cast(GetInterruptDevice()); assert(interrupt); // MAC アドレスを ROM にセット。 - macaddr_t macaddr; + MacAddr macaddr; if (EthernetDevice::GetConfigMacAddr(0, &macaddr, false) == false) { // エラーメッセージは表示済み return false; @@ -82,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; } @@ -103,6 +105,9 @@ NewsCtlrDevice::ResetHard(bool poweron) // たぶん電源オンで即起動? 知らんけど。 if (poweron) { + if (sync_rt) { + stime = GetSyncer()->GetRealTime(); + } scheduler->StartEvent(timer_event); } } @@ -211,7 +216,7 @@ NewsCtlrDevice::Peek1(uint32 addr) // NewsIO の下請けとして呼ばれる。 void -NewsCtlrDevice::MonitorUpdateNewsCtlr(TextScreen& screen, int y) +NewsCtlrDevice::MonitorScreenNewsCtlr(TextScreen& screen, int y) { // テーブル方式ではないので、Read/Write と手動で揃える…。 @@ -316,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); + } } // 割り込み信号線の状態を変える