|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #pragma once
8:
9: #include "device.h"
10:
11: // 汎用のリアルタイムクロック
12: // RP5C15 と MK48T02 の共通部分。
1.1.1.7 root 13: // これ自体が IODevice である必要はないが派生側が IODevice を必要とするため。
1.1 root 14: class RTCDevice : public IODevice
15: {
1.1.1.3 root 16: using inherited = IODevice;
1.1 root 17:
18: public:
1.1.1.6 root 19: RTCDevice(const std::string& objname_);
1.1.1.4 root 20: virtual ~RTCDevice() override;
1.1 root 21:
1.1.1.7 root 22: bool Init() override;
1.1 root 23:
24: // 32Hz クロック入力。
25: //
26: // 32Hz ごとに呼ばれて、これが RTC の時計を進める処理をするところ。
27: // RTC を実時間に同期して進めるモードなら実時間を計るスケジューラから、
28: // RTC を仮想時間に同期して進めるモードなら VM スケジューラから呼ばれる。
1.1.1.7 root 29: void ClockIn();
30:
31: // 現在の日付時刻を返す。
32: // ここで取得できる値は機種によらず共通のフォーマットだが、
33: // 値は範囲外の状態になる可能性が常にあることに注意。
34: //
35: // RP5C15 の場合、1つのレジスタが10進数一桁ごとを扱っているため、特に
36: // ゲストプログラムが月の更新するしようとするときに一時的に範囲外の
37: // 状態になることが避けられない。
38: // 例えば、もともと12月31日だったものを9月30日に変更する場合、
39: // 上の桁から更新したら(M10,M1,D10,D1)
40: // 12/31 -> 02/31 -> 09/31 -> 09/31 -> 09/30
41: // 下の桁から更新したら(D1,D10,M1,M10)
42: // 12/31 -> 12/30 -> 12/30 -> 19/30 -> 09/30
43: // このように、2/31, 9/31, 19/30 などが中間状態として発生する。
44: virtual uint GetSec() const = 0; // 秒(0-59)
45: virtual uint GetMin() const = 0; // 分(0-59)
46: virtual uint GetHour() const = 0; // 時(0-23)
47: virtual uint GetWday() const = 0; // 曜日(0-6、0が日曜)
48: virtual uint GetMday() const = 0; // 日(1-31)
49: virtual uint GetMon() const = 0; // 月(1-12)
50: virtual uint GetYear() const = 0; // 年(西暦)
51: virtual uint GetLeap() const = 0; // うるう年カウンタ(0-3、0がうるう年)
1.1 root 52:
53: protected:
1.1.1.7 root 54: // 仮想 RTC のクロック出力
1.1 root 55:
1.1.1.7 root 56: // 継承クラス向けに 32Hz で呼び出される。
57: virtual void Tick32Hz() { }
1.1 root 58:
1.1.1.7 root 59: // 継承クラス向けに 2Hz で呼び出される。
60: // タイミングは、0/32秒目と 16/32秒目。
61: virtual void Tick2Hz() { }
62:
63: // 継承クラス向けに 1Hz で呼び出される。
64: // タイミングは、0/32秒目。
65: // この関数から秒カウンタ更新をすること。
66: virtual void Tick1Hz() { }
67:
68: // 秒をカウントアップし、秒以上の繰り上がりを処理する。
69: void CountUpSec();
70: // 分をカウントアップし、分以上の繰り上がりを処理する。
71: // RP5C15 の ADJUST 機能を実現するために秒と分離。
72: void CountUpMin();
73:
74: virtual void SetSec(uint v) = 0;
75: virtual void SetMin(uint v) = 0;
76: virtual void SetHour(uint v) = 0;
77: virtual void SetWday(uint v) = 0;
78: virtual void SetMday(uint v) = 0;
79: virtual void SetMon(uint v) = 0;
80: virtual void SetYear(uint v) = 0;
81: virtual void SetLeap(uint v) = 0;
82:
83: // 32Hz でカウントアップする内部カウンタ
84: uint64 cnt {};
85:
86: // 年エポック。システムに依存。
87: uint year_epoch {};
88:
89: // 時刻設定時に localtime を使う場合は true
90: bool use_localtime {};
91:
92: // レジスタとして読める値を定数にすることで、仮想マシン状態を
93: // 常に同じ状態にするためのパフォーマンス測定用フラグ。
94: // なお NVRAM 部分は影響されない。
95: bool force_fixed {};
96:
97: // 曜日文字列 (0 = "Sun", ...)
98: // MK48T02 の誤運用にも対応するため 0..7 の範囲をとる。
99: static const char * const wdays[8];
100:
101: private:
102: // デバッグオプションの日付時刻文字列を解析する。
103: bool ParseDate(const std::string& str, int *y, int *m, int *d, int *w);
104: bool ParseTime(const std::string& str, int *h, int *m, int *s);
1.1 root 105:
1.1.1.7 root 106: // 現在の月の最終日を返す (月の繰り上がり処理用)
107: int GetLastMday() const;
1.1 root 108: };
109:
1.1.1.2 root 110: extern std::unique_ptr<RTCDevice> gRTC;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.