|
|
1.1 root 1: //
2: // nono
1.1.1.4 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.10 root 7: //
8: // LUNA システムクロック
9: //
10:
1.1.1.9 root 11: // システムクロックは実時間または仮想時間のいずれかに同期するため、
12: // システムクロック独自の時刻 stime を持つ。
13: // stime は、割り込みを発生させるごとに、LUNA-I なら 16.67msec、
1.1.1.12! root 14: // LUNA-88K なら 10msec 進行する。
1.1.1.9 root 15:
1.1 root 16: #include "sysclk.h"
1.1.1.6 root 17: #include "config.h"
18: #include "interrupt.h"
1.1.1.10 root 19: #include "rtc.h"
20: #include "scheduler.h"
1.1.1.12! root 21: #include "syncer.h"
1.1 root 22:
1.1.1.10 root 23: // コンストラクタ
1.1 root 24: SysClkDevice::SysClkDevice()
1.1.1.12! root 25: : inherited(OBJ_SYSCLK)
1.1 root 26: {
1.1.1.9 root 27: AddAlias("SysClk");
28:
1.1.1.10 root 29: monitor.func = ToMonitorCallback(&SysClkDevice::MonitorUpdate);
1.1.1.9 root 30: monitor.SetSize(31, 2);
31: monitor.Regist(ID_MONITOR_SYSCLK);
32:
1.1.1.10 root 33: event.func = ToEventCallback(&SysClkDevice::Callback);
1.1 root 34: event.code = 0;
1.1.1.10 root 35: event.Regist("System Clock");
1.1 root 36: }
37:
1.1.1.10 root 38: // デストラクタ
1.1 root 39: SysClkDevice::~SysClkDevice()
40: {
41: }
42:
1.1.1.12! root 43: // 初期化
1.1 root 44: bool
1.1.1.4 root 45: SysClkDevice::Init()
46: {
1.1.1.12! root 47: if (inherited::Init() == false) {
! 48: return false;
! 49: }
! 50:
! 51: interrupt = GetInterruptDevice();
! 52:
1.1.1.4 root 53: // クロックは機種ごとに異なる
54: const ConfigItem& item = gConfig->Find("!sysclk-period");
1.1.1.9 root 55: period = item.AsInt();
56: event.time = period;
57:
58: // クロックの同期方法
1.1.1.12! root 59: sync_rt = GetRTCDevice()->GetSyncRealtime();
1.1.1.9 root 60:
1.1.1.4 root 61: return true;
62: }
63:
1.1.1.10 root 64: // 電源オン/リセット
65: void
66: SysClkDevice::ResetHard(bool poweron)
1.1 root 67: {
1.1.1.10 root 68: // XXX たぶん電源オンだけで作用する?
69: if (poweron) {
70: if (sync_rt) {
1.1.1.12! root 71: stime = GetSyncer()->GetRealTime();
1.1.1.10 root 72: }
73:
74: // 電源オンですぐ起動
75: sysint = false;
1.1.1.12! root 76: scheduler->RestartEvent(event);
1.1.1.9 root 77: }
1.1 root 78: }
79:
80: uint64
1.1.1.7 root 81: SysClkDevice::Read(uint32 offset)
1.1 root 82: {
1.1.1.3 root 83: // 1 ポートしかない
84: return GetInt();
85: }
1.1 root 86:
1.1.1.3 root 87: uint64
1.1.1.7 root 88: SysClkDevice::Write(uint32 offset, uint32 data)
1.1.1.3 root 89: {
90: // 何か書き込まれたら、フラグをクリア
1.1.1.11 root 91: putlog(3, "Clear system clock interrupt");
1.1.1.6 root 92: sysint = false;
1.1.1.12! root 93: interrupt->NegateINT(this);
1.1.1.3 root 94: return 0;
1.1 root 95: }
96:
97: uint64
1.1.1.7 root 98: SysClkDevice::Peek(uint32 offset)
1.1 root 99: {
1.1.1.3 root 100: return GetInt();
101: }
102:
1.1.1.9 root 103: void
104: SysClkDevice::MonitorUpdate(Monitor *, TextScreen& screen)
105: {
106: int y;
107:
108: screen.Clear();
109: y = 0;
110:
111: int width = stime < 86400_sec ? 20 : 25;
112: screen.Print(0, y++, "Sync: %s", sync_rt ? "Real Time" : "Virtual Time");
113: screen.Print(0, y++, "Time: %*s", width, TimeToStr(stime).c_str());
114: }
115:
1.1.1.3 root 116: // 割り込み状態を取得(?)
117: uint8
118: SysClkDevice::GetInt() const
119: {
120: uint8 data = 0;
1.1 root 121:
1.1.1.3 root 122: if (sysint) {
123: data |= 0x80;
1.1 root 124: }
1.1.1.3 root 125: return data;
1.1 root 126: }
127:
128: // イベントハンドラ
129: void
1.1.1.5 root 130: SysClkDevice::Callback(Event& ev)
1.1 root 131: {
1.1.1.11 root 132: putlog(3, "Interrupt occured");
1.1.1.9 root 133:
134: // システムクロックとしての現在時刻。
1.1.1.10 root 135: // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。
1.1.1.9 root 136: stime += period;
137:
1.1.1.10 root 138: sysint = true;
1.1.1.12! root 139: interrupt->AssertINT(this);
1.1.1.9 root 140:
1.1.1.10 root 141: if (sync_rt) {
1.1.1.12! root 142: scheduler->StartRealtimeEvent(ev, stime, period);
1.1.1.9 root 143: } else {
1.1.1.12! root 144: scheduler->StartEvent(ev);
1.1.1.9 root 145: }
1.1 root 146: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.