--- nono/vm/rtc.h 2026/04/29 17:05:06 1.1.1.8 +++ nono/vm/rtc.h 2026/04/29 17:05:11 1.1.1.9 @@ -4,12 +4,16 @@ // Licensed under nono-license.txt // +// +// RTC の共通部分 +// + #pragma once #include "device.h" +#include "event.h" +#include -// 汎用のリアルタイムクロック -// RP5C15 と MK48T02 の共通部分。 // これ自体が IODevice である必要はないが派生側が IODevice を必要とするため。 class RTCDevice : public IODevice { @@ -21,12 +25,14 @@ class RTCDevice : public IODevice bool Init() override; - // 32Hz クロック入力。 - // - // 32Hz ごとに呼ばれて、これが RTC の時計を進める処理をするところ。 - // RTC を実時間に同期して進めるモードなら実時間を計るスケジューラから、 - // RTC を仮想時間に同期して進めるモードなら VM スケジューラから呼ばれる。 - void ClockIn(); + virtual void StartTime(); + + // clock-sync が実時間同期なら true を返す + bool GetSyncRealtime() const { return sync_rt; } + + // 電源 OFF 時の実時間でのクロック入力。 + // 次回のクロック発生までの時間間隔を返す。 + uint64 ClockIn_PowerOff(); // 現在の日付時刻を返す。 // ここで取得できる値は機種によらず共通のフォーマットだが、 @@ -51,19 +57,24 @@ class RTCDevice : public IODevice virtual uint GetLeap() const = 0; // うるう年カウンタ(0-3、0がうるう年) protected: + // 32Hz クロック入力。 + // clock-sync の設定に応じて、実時間または仮想時間で + // 32Hz ごとに呼ばれて、これが RTC の時計を進める処理をするところ。 + void ClockIn(); + // 仮想 RTC のクロック出力 // 継承クラス向けに 32Hz で呼び出される。 - virtual void Tick32Hz() { } + virtual void Tick32Hz(); // 継承クラス向けに 2Hz で呼び出される。 // タイミングは、0/32秒目と 16/32秒目。 - virtual void Tick2Hz() { } + virtual void Tick2Hz(); // 継承クラス向けに 1Hz で呼び出される。 // タイミングは、0/32秒目。 // この関数から秒カウンタ更新をすること。 - virtual void Tick1Hz() { } + virtual void Tick1Hz(); // 秒をカウントアップし、秒以上の繰り上がりを処理する。 void CountUpSec(); @@ -94,6 +105,13 @@ class RTCDevice : public IODevice // なお NVRAM 部分は影響されない。 bool force_fixed {}; + // RTC の入力クロックが実時間の場合は true + // 仮想時間の場合は false + bool sync_rt {}; + + // 設定で指定された日付時刻 + struct tm rtc_tm {}; + // 曜日文字列 (0 = "Sun", ...) // MK48T02 の誤運用にも対応するため 0..7 の範囲をとる。 static const char * const wdays[8]; @@ -105,6 +123,18 @@ class RTCDevice : public IODevice // 現在の月の最終日を返す (月の繰り上がり処理用) int GetLastMday() const; + + // イベントコールバック + void Callback(Event& ev); + + // イベント間隔 + const uint period = 31.25_msec; + + // システムクロックが刻んでいる時刻 + uint64 stime {}; + + // RTC クロック入力 + Event event { this }; }; -extern std::unique_ptr gRTC; +extern RTCDevice *gRTC;