--- nono/vm/syncer.cpp 2026/04/29 17:05:17 1.1 +++ nono/vm/syncer.cpp 2026/04/29 17:05:33 1.1.1.4 @@ -10,9 +10,8 @@ #include "syncer.h" #include "config.h" -#include "mainapp.h" -#include "mainbus.h" -#include "mainram.h" +#include "monitor.h" +#include "mpu680x0.h" #include "scheduler.h" //#define DEBUG @@ -33,10 +32,6 @@ Syncer::Syncer() for (int i = 0; i < perfq.Capacity(); i++) { perfq.Enqueue(1000); } - - sync_event.func = ToEventCallback(&Syncer::SyncCallback); - sync_event.time = 50_msec; - sync_event.Regist("Sync"); } // デストラクタ @@ -52,8 +47,7 @@ Syncer::Init() return false; } - mainbus = GetMainbusDevice(); - mainram = GetMainRAMDevice(); + mpu680x0 = dynamic_cast(mpu); mode = SCHED_POWEROFF; overslept = 0; @@ -63,7 +57,12 @@ Syncer::Init() RequestFullSpeed(fast_mode); scheduler->ConnectMessage(MessageID::SCHEDULER_SYNCMODE, this, - ToMessageCallback(&Syncer::ChangeModeCallback)); + ToMessageCallback(&Syncer::ChangeModeMessage)); + + sync_event.func = ToEventCallback(&Syncer::SyncCallback); + sync_event.time = 50_msec; + sync_event.SetName("Sync"); + scheduler->RegistEvent(sync_event); return true; } @@ -126,7 +125,7 @@ Syncer::RequestFullSpeed(bool enable) } // ブートページモードの変更を指示する。 -// (VM::SwitchBootPage から呼ぶので個別には呼ばないこと) +// (MainbusBaseDevice::SwitchBootPage から呼ぶので個別には呼ばないこと) void Syncer::RequestBootPageMode(bool isrom) { @@ -173,7 +172,7 @@ Syncer::RequestPowerOffMode(bool powerof // 動作状態変更のメッセージコールバック void -Syncer::ChangeModeCallback(MessageID msgid, uint32 arg) +Syncer::ChangeModeMessage(MessageID msgid, uint32 arg) { uint32 newmode; @@ -205,17 +204,10 @@ Syncer::ChangeMode(uint32 newmode) if (newmode == 0) { // 高速モードに putlog(2, "Fast mode"); - - // 高速モードでは RAM は直接アクセス - mainbus->direct_ram_size = mainram->GetSize(); - } else { // 同期モードに putlog(2, "Sync mode"); - // 同期モードでは RAM アクセスはデバイス経由 - mainbus->direct_ram_size = 0; - // 同期用の基準点を設置。 // ゲストが STOP 命令による定常状態にいる時は // 割り込みなど短期間だけ高速モードになるのを繰り返す。 @@ -326,9 +318,9 @@ Syncer::CalcPerf() // 百分率で小数以下1桁分までとなるよう整数で計算する perfq.EnqueueForce((uint32)(vperf * 1000 / rperf)); // 移動平均を求める (perfq は常に要素数分埋めてある) - int ma = 0; - int qlen = perfq.Length(); - __assume(qlen > 0); + uint ma = 0; + uint qlen = perfq.Length(); + __assume(qlen != 0); for (int i = 0; i < qlen; i++) { auto v = perfq.Peek(i); ma += v; @@ -342,6 +334,11 @@ Syncer::CalcPerf() last_sync_count = sync_count; sync_count = 0; + // 関係ないけど、ついでにここで MPU 内の各種移動平均をとる。 + if (mpu680x0) { + mpu680x0->CalcStat(); + } + last_perf_rtime = rtime; last_perf_vtime = vtime; next_perf_rtime = rtime + PERF_INTERVAL; @@ -354,9 +351,9 @@ Syncer::PutlogRealtime() uint64 vtime = scheduler->GetVirtTime(); // 電源オン時からここまでの時間を表示するだけでリセット等はしない。 - putlog(0, "Elapsed time since power-on: %d.%03d sec, %6.2f%%", - (int)(rtime / (1000 * 1000 * 1000)), - (int)((rtime / (1000 * 1000)) % 1000), + putlog(0, "Elapsed since power-on: %u.%03u sec, %6.2f%%", + (uint)(rtime / (1000 * 1000 * 1000)), + (uint)((rtime / (1000 * 1000)) % 1000), (double)vtime / rtime * 100); #if 0 @@ -418,7 +415,18 @@ Syncer::MonitorUpdateSub(TextScreen& scr 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()); - screen.Print(0, y++, "Performance : %4d%%", perf_counter); + screen.Puts(0, y, "Rating MPU Speed :"); + uint clock_khz = mpu->GetClockSpeed(); + if (__predict_true((clock_khz % 1000) == 0)) { + screen.Print(21, y++, "%4u.%1uMHz", + clock_khz / 1000, (clock_khz / 100) % 10); + } else { + screen.Print(21, y++, "%4u.%03uMHz", + clock_khz / 1000, clock_khz % 1000); + } + uint eff_khz = clock_khz * perf_counter / 100; + screen.Print(0, y++, "Effective MPU Speed: %4u.%1uMHz (%4u%%)", + (eff_khz / 1000), (eff_khz / 100) % 10, perf_counter); int x = 52; int y1 = 0;