--- nono/vm/syncer.h 2026/04/29 17:05:17 1.1.1.1 +++ nono/vm/syncer.h 2026/04/29 17:05:38 1.1.1.5 @@ -13,11 +13,9 @@ #include "event.h" #include "fixedqueue.h" #include "message.h" -#include "monitor.h" #include "stopwatch.h" -class MainbusDevice; -class MainRAMDevice; +class MPU680x0Device; class Syncer : public Device { @@ -29,31 +27,34 @@ class Syncer : public Device // ビットがすべて %0 なら高速モード、どれかでも %1 なら通常モードになる。 // // | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 | - // mode | |POFF|KEY |BOOT|SYNC| CPUSTAT | - // | | | | +---+---- CPU の状態 + // mode | |POFF|KEY |BOOT|SYNC|HALT|IDLE| + // | | | | | +---- CPU & DMAC アイドル + // | | | | +--------- CPU HALT // | | | +-------------- 高速モード抑制 // | | +------------------- ブートページ実行中 // | +------------------------ キー入力中 // +----------------------------- 電源オフ // - // bit1,0 (CPUSTAT) は CPU の状態を示す。%00 の時だけ高速走行が可能。 - // これは RequestCPUMode() の引数で指定する。 - // b1 b0 - // 0 0 通常状態 - // 0 1 STOP 状態 (m88k なら擬似 STOP 状態) - // 1 0 HALT 状態 (ダブルバスフォールト) - // 1 1 HALT 状態だがこちらのビットパターンは使わない - - static const uint32 SCHED_CPU_STOP = 0x0001; // CPU が STOP 状態 - static const uint32 SCHED_CPU_HALT = 0x0002; // CPU が HALT 状態 - static const uint32 SCHED_SYNC = 0x0004; // 高速モード抑制指示(UI) - static const uint32 SCHED_BOOT = 0x0008; // ブートページ実行中 - static const uint32 SCHED_KEY = 0x0010; // キー入力中 - static const uint32 SCHED_POWEROFF = 0x0020; // 電源オフ + // bit1,0 は CPU から来るが、このうち bit0 だけ DMAC からのアイドル + // ビットとの積(AND) になっているので、mode 中の bit0 は CPU も DMAC も + // ともにアイドルの時だけ 1 になる。 + // + // CPU HALT (bit1) ----------------------> HALT (bit1) + // CPU STOP (bit0) -----------------|& + // |&---> IDLE (bit0) + // DMAC Active ---|>--- DMAC Idle ---|& + + static const uint32 SYNCMODE_IDLE = 0x0001; // CPU & DMAC アイドル + static const uint32 SYNCMODE_CPU_HALT = 0x0002; // CPU が HALT 状態 + static const uint32 SYNCMODE_SYNC = 0x0004; // 等速モード指示(UI) + static const uint32 SYNCMODE_BOOT = 0x0008; // ブートページ実行中 + static const uint32 SYNCMODE_KEY = 0x0010; // キー入力中 + static const uint32 SYNCMODE_POWEROFF = 0x0020; // 電源オフ // 便宜上用意しておく - static const uint32 SCHED_CPU_NORMAL= 0x0000; // CPU が通常状態 - static const uint32 SCHED_CPU_MASK = (SCHED_CPU_STOP | SCHED_CPU_HALT); + static const uint32 SYNCMODE_CPU_NORMAL = 0x0000; // CPU が通常状態 + static const uint32 SYNCMODE_CPU_STOP = 0x0001; // CPU が STOP 状態 + static const uint32 SYNCMODE_CPU_MASK = 0x0003; // (HALT|STOP) public: Syncer(); @@ -74,9 +75,12 @@ class Syncer : public Device // CPU 状態変更を指示する。 void RequestCPUMode(uint32 mode_); + // DMAC のアクティブ状態を指示する。 + void RequestDMACActive(bool active); + // 高速モード(UIによる指示)なら true を返す。 // ここでいう高速モードは STOP 状態中でも高速モード。 - bool GetFullSpeed() const { return ((mode & SCHED_SYNC) == 0); } + bool GetFullSpeed() const { return ((mode & SYNCMODE_SYNC) == 0); } // 高速モードを指示する。 // true なら高速モード、false なら同期モード。 @@ -95,7 +99,7 @@ class Syncer : public Device void PutlogRealtime(); // パフォーマンスカウンタの値取得 (UI 表示用) - int GetPerfCounter() const { return perf_counter; } + uint GetPerfCounter() const { return perf_counter; } // モニタ更新の下請け int MonitorUpdateSub(TextScreen& screen, uint64 vtime); @@ -107,16 +111,20 @@ class Syncer : public Device void SyncCallback(Event& ev); // 動作モード変更メッセージ - void ChangeModeCallback(MessageID, uint32); + void ChangeModeMessage(MessageID, uint32); // 同期処理 void DoSync(); void CalcPerf(); - // スケジューラの動作モード。SCHED_* + // スケジューラの動作モード。SYNCMODE_* uint32 mode {}; + uint32 halt {}; // CPU が HALT なら SYNCMODE_CPU_HALT + uint32 cpu_idle {}; // CPU が STOP なら SYNCMODE_CPU_STOP + uint32 dmac_idle {}; // DMAC がアイドルなら SYNCMODE_IDLE + // 実時間の基準となるストップウォッチ Stopwatch realtime {}; @@ -138,14 +146,13 @@ class Syncer : public Device // perfq が移動平均用のバッファ。四捨五入用に10倍値を持っておく // (100% なら 1000)。perf_counter は perfq から求めた実行率で // 小数以下を四捨五入する (のでこっちは 100% なら 100)。 - int perf_counter {}; // 実行率 [%] + uint perf_counter {}; // 実行率 [%] FixedQueue perfq {}; // 移動平均用のバッファ uint64 next_perf_rtime {}; // 次回測定予定の実経過時間 uint64 last_perf_rtime {}; // 前回測定時の実経過時間 uint64 last_perf_vtime {}; // 前回測定時の仮想経過時間 - MainbusDevice *mainbus {}; - MainRAMDevice *mainram {}; + MPU680x0Device *mpu680x0 {}; // 同期イベント Event sync_event { this };