--- nono/vm/sysclk.cpp 2026/04/29 17:05:17 1.1.1.12 +++ nono/vm/sysclk.cpp 2026/04/29 17:05:42 1.1.1.18 @@ -16,7 +16,7 @@ #include "sysclk.h" #include "config.h" #include "interrupt.h" -#include "rtc.h" +#include "monitor.h" #include "scheduler.h" #include "syncer.h" @@ -24,15 +24,9 @@ SysClkDevice::SysClkDevice() : inherited(OBJ_SYSCLK) { - AddAlias("SysClk"); - - monitor.func = ToMonitorCallback(&SysClkDevice::MonitorUpdate); - monitor.SetSize(31, 2); - monitor.Regist(ID_MONITOR_SYSCLK); - - event.func = ToEventCallback(&SysClkDevice::Callback); - event.code = 0; - event.Regist("System Clock"); + monitor = gMonitorManager->Regist(ID_MONITOR_SYSCLK, this); + monitor->func = ToMonitorCallback(&SysClkDevice::MonitorUpdate); + monitor->SetSize(31, 3); } // デストラクタ @@ -44,19 +38,22 @@ SysClkDevice::~SysClkDevice() bool SysClkDevice::Init() { - if (inherited::Init() == false) { - return false; - } - interrupt = GetInterruptDevice(); // クロックは機種ごとに異なる - const ConfigItem& item = gConfig->Find("!sysclk-period"); - period = item.AsInt(); + const ConfigItem& item = gConfig->Find("!sysclk-freq"); + freq = item.AsInt(); + period = 1_sec / freq; event.time = period; // クロックの同期方法 - sync_rt = GetRTCDevice()->GetSyncRealtime(); + auto syncer = GetSyncer(); + sync_rt = syncer->GetSyncRealtime(); + + event.func = ToEventCallback(&SysClkDevice::Callback); + event.code = 0; + event.SetName("System Clock"); + scheduler->RegistEvent(event); return true; } @@ -72,34 +69,47 @@ SysClkDevice::ResetHard(bool poweron) } // 電源オンですぐ起動 - sysint = false; scheduler->RestartEvent(event); } + + // さすがに割り込みネゲートくらいするよな? + sysint = false; + ChangeInterrupt(); } -uint64 -SysClkDevice::Read(uint32 offset) +busdata +SysClkDevice::ReadPort(uint32 offset) { // 1 ポートしかない - return GetInt(); + busdata data = GetInt(); + data |= BusData::Size1; + return data; } -uint64 -SysClkDevice::Write(uint32 offset, uint32 data) +busdata +SysClkDevice::WritePort(uint32 offset, uint32 data) { // 何か書き込まれたら、フラグをクリア putlog(3, "Clear system clock interrupt"); sysint = false; - interrupt->NegateINT(this); - return 0; + ChangeInterrupt(); + + busdata r = BusData::Size1; + return r; } -uint64 -SysClkDevice::Peek(uint32 offset) +busdata +SysClkDevice::PeekPort(uint32 offset) { return GetInt(); } +bool +SysClkDevice::PokePort(uint32 offset, uint32 data) +{ + return false; +} + void SysClkDevice::MonitorUpdate(Monitor *, TextScreen& screen) { @@ -109,6 +119,7 @@ SysClkDevice::MonitorUpdate(Monitor *, T y = 0; 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()); } @@ -131,16 +142,23 @@ SysClkDevice::Callback(Event& ev) { putlog(3, "Interrupt occured"); - // システムクロックとしての現在時刻。 - // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。 - stime += period; - sysint = true; - interrupt->AssertINT(this); + ChangeInterrupt(); if (sync_rt) { + // システムクロックとしての現在時刻。 + // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。 + stime += period; + scheduler->StartRealtimeEvent(ev, stime, period); } else { scheduler->StartEvent(ev); } } + +// 割り込み信号線の状態を変える。 +void +SysClkDevice::ChangeInterrupt() +{ + interrupt->ChangeINT(this, sysint); +}