--- nono/vm/syncer.cpp 2026/04/29 17:05:33 1.1.1.4 +++ nono/vm/syncer.cpp 2026/04/29 17:05:42 1.1.1.6 @@ -43,19 +43,28 @@ Syncer::~Syncer() bool Syncer::Init() { - if (inherited::Init() == false) { - return false; - } - mpu680x0 = dynamic_cast(mpu); - mode = SCHED_POWEROFF; + mode = SYNCMODE_POWEROFF; overslept = 0; + dmac_idle = 1; // 高速モード指定 bool fast_mode = gConfig->Find("fast-mode").AsInt(); RequestFullSpeed(fast_mode); + // クロックの同期方法 + const ConfigItem& sync_item = gConfig->Find("clock-sync"); + auto clock_sync = sync_item.AsString(); + if (clock_sync == "real") { + sync_realtime = true; + } else if (clock_sync == "virtual") { + sync_realtime = false; + } else { + sync_item.Err(); + return false; + } + scheduler->ConnectMessage(MessageID::SCHEDULER_SYNCMODE, this, ToMessageCallback(&Syncer::ChangeModeMessage)); @@ -110,7 +119,23 @@ Syncer::RequestCPUMode(uint32 cpumode) { uint32 newmode; - newmode = (mode & ~SCHED_CPU_MASK) | cpumode; + halt = cpumode & SYNCMODE_CPU_HALT; + cpu_idle = cpumode & SYNCMODE_CPU_STOP; + + newmode = (mode & ~SYNCMODE_CPU_MASK) | halt | (cpu_idle & dmac_idle); + + ChangeMode(newmode); +} + +// DMAC のアクティブ状態を指示する。 +void +Syncer::RequestDMACActive(bool active) +{ + uint32 newmode; + + dmac_idle = active ? 0 : SYNCMODE_IDLE; + + newmode = (mode & ~SYNCMODE_IDLE) | (cpu_idle & dmac_idle); ChangeMode(newmode); } @@ -132,9 +157,9 @@ Syncer::RequestBootPageMode(bool isrom) uint32 newmode; if (isrom) { - newmode = mode | SCHED_BOOT; + newmode = mode | SYNCMODE_BOOT; } else { - newmode = mode & ~SCHED_BOOT; + newmode = mode & ~SYNCMODE_BOOT; } ChangeMode(newmode); @@ -147,9 +172,9 @@ Syncer::RequestKeyPressed(bool pressed) uint32 newmode; if (pressed) { - newmode = mode | SCHED_KEY; + newmode = mode | SYNCMODE_KEY; } else { - newmode = mode & ~SCHED_KEY; + newmode = mode & ~SYNCMODE_KEY; } ChangeMode(newmode); @@ -162,9 +187,9 @@ Syncer::RequestPowerOffMode(bool powerof uint32 newmode; if (poweroff) { - newmode = mode | SCHED_POWEROFF; + newmode = mode | SYNCMODE_POWEROFF; } else { - newmode = mode & ~SCHED_POWEROFF; + newmode = mode & ~SYNCMODE_POWEROFF; } ChangeMode(newmode); @@ -178,16 +203,16 @@ Syncer::ChangeModeMessage(MessageID msgi if (msgid == MessageID::SCHEDULER_SYNCMODE) { if (arg) { - newmode = mode & ~SCHED_SYNC; + newmode = mode & ~SYNCMODE_SYNC; } else { - newmode = mode | SCHED_SYNC; + newmode = mode | SYNCMODE_SYNC; } ChangeMode(newmode); } } -// メンバ変数 mode_request に従ってスケジューラの動作状態を変更。 +// newmode に従ってスケジューラの動作状態を変更。 // 自スレッドから呼ぶこと。 void Syncer::ChangeMode(uint32 newmode) @@ -368,52 +393,56 @@ Syncer::PutlogRealtime() // モニタ更新の下請け (Scheduler から呼ばれる) int -Syncer::MonitorUpdateSub(TextScreen& screen, uint64 vtime) +Syncer::MonitorUpdateSub(TextScreen& screen, uint64 tmp_vtime) { int y = 0; - screen.Print(0, y, "Mode: 0x%04x (", mode); - switch (mode & SCHED_CPU_MASK) { - case SCHED_CPU_NORMAL: + // 一応ローカルコピー。 + uint32 tmp_mode = mode; + uint64 tmp_rtime = rtime; + uint64 sync_rt_delta = tmp_rtime - rtime_epoch; + uint64 sync_vt_delta = tmp_vtime - vtime_epoch; + + screen.Print(0, y, "Mode: 0x%04x (", tmp_mode); + switch (tmp_mode & SYNCMODE_CPU_MASK) { + case SYNCMODE_CPU_NORMAL: screen.Puts(14, y, TA::Off, "Run"); break; - case SCHED_CPU_STOP: + case SYNCMODE_CPU_STOP: screen.Puts(14, y, TA::On, "STOP"); break; - case SCHED_CPU_HALT: + case SYNCMODE_CPU_HALT: screen.Puts(14, y, TA::On, "HALT"); break; } - if ((mode & SCHED_SYNC)) { + if ((tmp_mode & SYNCMODE_SYNC)) { screen.Puts(19, y, TA::On, "Sync"); } else { screen.Puts(19, y, TA::Off, "Full"); } - screen.Puts(24, y, TA::OnOff((mode & SCHED_BOOT)), "Boot"); - screen.Puts(29, y, TA::OnOff((mode & SCHED_KEY)), "Key"); - screen.Puts(34, y, TA::OnOff((mode & SCHED_POWEROFF)), "POff"); + screen.Puts(24, y, TA::OnOff((tmp_mode & SYNCMODE_BOOT)), "Boot"); + screen.Puts(29, y, TA::OnOff((tmp_mode & SYNCMODE_KEY)), "Key"); + screen.Puts(34, y, TA::OnOff((tmp_mode & SYNCMODE_POWEROFF)), "POff"); screen.Puts(38, y, ")"); y++; - uint64 rt = rtime; - uint64 vt = vtime; - auto s_rt = TimeToStr(rt); - auto s_vt = TimeToStr(vt); - std::string s_sync_rt {}; - std::string s_sync_vt {}; - if (mode != 0) { - uint64 sync_rt = rtime - rtime_epoch; - uint64 sync_vt = vtime - vtime_epoch; - s_sync_rt = TimeToStr(sync_rt); - s_sync_vt = TimeToStr(sync_vt); - } // 日まで表示しようとするときは桁位置を動かす - int width = std::max(rt, vt) < 86400_sec ? 20 : 25; + int width = std::max(tmp_rtime, tmp_vtime) < 86400_sec ? 20 : 25; - screen.Print(0, y++, "Total Real Time: %*s", width, s_rt.c_str()); - screen.Print(4, y++, "Virtual Time: %*s", width, s_vt.c_str()); - screen.Print(0, y++, "Sync Real Time: %*s", width, s_sync_rt.c_str()); - screen.Print(4, y++, "Virtual Time: %*s", width, s_sync_vt.c_str()); + std::string trt = TimeToStr(tmp_rtime); + std::string tvt = TimeToStr(tmp_vtime); + // 012345678901234567 + screen.Print(0, y++, "Total Real Time: %*s", width, trt.c_str()); + screen.Print(4, y++, "Virtual Time: %*s", width, tvt.c_str()); + screen.Puts(0, y + 0, "Sync Real Time:"); + screen.Puts(4, y + 1, "Virtual Time:"); + if (tmp_mode != 0) { + std::string srt = TimeToStr(sync_rt_delta); + std::string svt = TimeToStr(sync_vt_delta); + screen.Print(18, y + 0, "%*s", width, srt.c_str()); + screen.Print(18, y + 1, "%*s", width, svt.c_str()); + } + y += 2; screen.Puts(0, y, "Rating MPU Speed :"); uint clock_khz = mpu->GetClockSpeed();