Annotation of nono/vm/sysclk.cpp, revision 1.1.1.12

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.