--- nono/vm/goldfish_timer.cpp 2026/04/29 17:05:38 1.1.1.4 +++ nono/vm/goldfish_timer.cpp 2026/04/29 17:06:00 1.1.1.7 @@ -48,10 +48,11 @@ // 読み込み時は割り込み許可なら $1、禁止なら $0。 #include "goldfish_timer.h" +#include "event.h" #include "goldfish_pic.h" #include "goldfish_rtc.h" +#include "mainbus.h" #include "monitor.h" -#include "mpu.h" #include "scheduler.h" #include "syncer.h" @@ -65,7 +66,7 @@ GFTimerDevice::GFTimerDevice() { // モニタは GFRTC + GFTimer で共有。 monitor = gMonitorManager->Regist(ID_MONITOR_RTC, this); - monitor->func = ToMonitorCallback(&GFTimerDevice::MonitorUpdate); + monitor->SetCallback(&GFTimerDevice::MonitorScreen); monitor->SetSize(38, 7); } @@ -86,17 +87,18 @@ GFTimerDevice::Init() gfrtc = dynamic_cast(GetRTCDevice()); syncer = GetSyncer(); + auto evman = GetEventManager(); + event = evman->Regist(this, NULL, "Goldfish Timer"); + // クロックの同期方法 - sync_rt = GetRTCDevice()->GetSyncRealtime(); + sync_rt = syncer->GetSyncRealtime(); // それによってイベントを分けてある。(time はどちらも都度セットする) if (sync_rt) { - event.func = ToEventCallback(&GFTimerDevice::CallbackRT); + event->SetCallback(&GFTimerDevice::CallbackRT); } else { - event.func = ToEventCallback(&GFTimerDevice::CallbackVT); + event->SetCallback(&GFTimerDevice::CallbackVT); } - event.SetName("Goldfish Timer"); - scheduler->RegistEvent(event); return true; } @@ -106,8 +108,8 @@ void GFTimerDevice::ResetHard(bool poweron) { scheduler->StopEvent(event); - elapsed = 0; - alarm = 0; + elapsed.q = 0; + alarm.q = 0; mtime = 0; mtime_epoch = 0; @@ -123,20 +125,19 @@ GFTimerDevice::ReadPort(uint32 offset) switch (offset) { case GFRTC::TIME_LOW: - elapsed = Now(); - data = (uint32)elapsed; + elapsed.q = Now(); + data = elapsed.l; if (__predict_false(loglevel >= 2)) { if (loglevel >= 3) { putlogn("TIME_LOW -> $%08x", data.Data()); } else { - putlogn("TIME -> $%08x'%08x", - (uint32)(elapsed >> 32), data.Data()); + putlogn("TIME -> $%08x'%08x", elapsed.h, data.Data()); } } break; case GFRTC::TIME_HIGH: - data = (uint32)(elapsed >> 32); + data = elapsed.h; putlog(3, "TIME_HIGH -> $%08x", data.Data()); break; @@ -146,12 +147,12 @@ GFTimerDevice::ReadPort(uint32 offset) break; case GFRTC::ALARM_STATUS: - data = event.IsRunning() ? 1 : 0; + data = event->IsRunning() ? 1 : 0; putlog(2, "ALARM_STATUS -> $%08x", data.Data()); break; default: - putlog(1, "Read unknown $%08x", mpu->GetPaddr()); + putlog(1, "Read unknown $%08x", GetMainbusDevice()->GetPaddr()); data.SetBusErr(); break; } @@ -167,14 +168,14 @@ GFTimerDevice::WritePort(uint32 offset, switch (offset) { case GFRTC::ALARM_LOW: - alarm = alarm_high | data; + alarm.h = alarm_high; + alarm.l = data; alarm_high = 0; if (__predict_false(loglevel >= 2)) { if (loglevel >= 3) { putlogn("ALARM_LOW <- $%08x", data); } else { - putlogn("ALARM <- $%08x'%08x", - (uint32)(alarm >> 32), (uint32)alarm); + putlogn("ALARM <- $%08x'%08x", alarm.h, alarm.l); } } StartAlarm(); @@ -182,7 +183,7 @@ GFTimerDevice::WritePort(uint32 offset, case GFRTC::ALARM_HIGH: putlog(3, "ALARM_HIGH <- $%08x", data); - alarm_high = (uint64)data << 32; + alarm_high = data; break; case GFRTC::INTR_STATUS: @@ -199,7 +200,7 @@ GFTimerDevice::WritePort(uint32 offset, case GFRTC::ALARM_CLEAR: putlog(1, "Clear alarm"); - alarm = 0; + alarm.q = 0; break; case GFRTC::INTR_CLEAR: @@ -209,7 +210,8 @@ GFTimerDevice::WritePort(uint32 offset, break; default: - putlog(1, "Write unknown $%08x <- $%08x", mpu->GetPaddr(), data); + putlog(1, "Write unknown $%08x <- $%08x", + GetMainbusDevice()->GetPaddr(), data); r = BusData::BusErr; break; } @@ -229,14 +231,14 @@ GFTimerDevice::PeekPort(uint32 offset) case GFRTC::INTR_STATUS: return intr_assert ? 1 : 0; case GFRTC::ALARM_STATUS: - return event.IsRunning() ? 1 : 0; + return event->IsRunning() ? 1 : 0; default: return BusData::BusErr; } } void -GFTimerDevice::MonitorUpdate(Monitor *, TextScreen& screen) +GFTimerDevice::MonitorScreen(Monitor *, TextScreen& screen) { int y = 0; @@ -246,10 +248,10 @@ GFTimerDevice::MonitorUpdate(Monitor *, screen.Puts(0, y++, ""); screen.Print(0, y++, "Time: %26s", TimeToStr(now).c_str()); - screen.Print(0, y++, "Alarm: %26s", TimeToStr(alarm).c_str()); + screen.Print(0, y++, "Alarm: %26s", TimeToStr(alarm.q).c_str()); y++; - gfrtc->MonitorUpdateRTC(screen, y); + gfrtc->MonitorScreenRTC(screen, y); } // 現在時刻を返す @@ -281,29 +283,29 @@ GFTimerDevice::StartAlarm() // 仮想時間モードなら ALARM 時刻に発火するイベントをセットするだけ。 // 実時間モードならひとまず仮に本来の仮想時刻にイベントは起こすが、 // 割り込みを上げるかどうかは向こうで調整する。 - // event.code は VT モードの時には不要だが気にせず立てる。 + // event->code は VT モードの時には不要だが気にせず立てる。 // 指定されたアラームがすでに過去の時刻なら QEMU は即発火するようだ。 - if (__predict_true(alarm > now)) { - event.time = alarm - now; + if (__predict_true(alarm.q > now)) { + event->time = alarm.q - now; } else { if (__predict_false(loglevel >= 1)) { - uint64 delta = now - alarm; + uint64 delta = now - alarm.q; putlogn("ALARM: past alarm -%s", TimeToStr(delta).c_str()); } - event.time = 0; + event->time = 0; } - event.code = 1; + event->code = 1; scheduler->RestartEvent(event); } // 実時間モードでのコールバック。 void -GFTimerDevice::CallbackRT(Event& ev) +GFTimerDevice::CallbackRT(Event *ev) { // アラーム開始後最初の1回だけ自分の時間軸をアラーム分だけ進める。 - if (event.code) { - mtime += ev.time; - event.code = 0; + if (event->code) { + mtime += event->time; + event->code = 0; } uint64 mnow = syncer->GetRealTime() - mtime_epoch; @@ -320,7 +322,7 @@ GFTimerDevice::CallbackRT(Event& ev) // 仮想時間モードでのコールバック。 void -GFTimerDevice::CallbackVT(Event& ev) +GFTimerDevice::CallbackVT(Event *ev) { // 仮想時間モードなら、イベントが起きたここがゴール。 // アラームは単発イベントなのでリスタート不要。