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

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、
                     14: // LUNA88k なら 10msec 進行する。
                     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"
        !            21: #include "sync.h"
1.1.1.6   root       22: 
1.1.1.10! root       23: // グローバル参照用
        !            24: SysClkDevice *gSysClk;
1.1       root       25: 
1.1.1.10! root       26: // コンストラクタ
1.1       root       27: SysClkDevice::SysClkDevice()
1.1.1.9   root       28:        : inherited("SystemClock")
1.1       root       29: {
1.1.1.9   root       30:        AddAlias("SysClk");
                     31: 
1.1       root       32:        devaddr = 0x63000000;
                     33: 
1.1.1.10! root       34:        monitor.func = ToMonitorCallback(&SysClkDevice::MonitorUpdate);
1.1.1.9   root       35:        monitor.SetSize(31, 2);
                     36:        monitor.Regist(ID_MONITOR_SYSCLK);
                     37: 
1.1.1.10! root       38:        event.func = ToEventCallback(&SysClkDevice::Callback);
1.1       root       39:        event.code = 0;
1.1.1.10! root       40:        event.Regist("System Clock");
1.1       root       41: }
                     42: 
1.1.1.10! root       43: // デストラクタ
1.1       root       44: SysClkDevice::~SysClkDevice()
                     45: {
1.1.1.10! root       46:        gSysClk = NULL;
1.1       root       47: }
                     48: 
                     49: bool
1.1.1.4   root       50: SysClkDevice::Init()
                     51: {
                     52:        // クロックは機種ごとに異なる
                     53:        const ConfigItem& item = gConfig->Find("!sysclk-period");
1.1.1.9   root       54:        period = item.AsInt();
                     55:        event.time = period;
                     56: 
                     57:        // クロックの同期方法
1.1.1.10! root       58:        sync_rt = gRTC->GetSyncRealtime();
1.1.1.9   root       59: 
1.1.1.4   root       60:        return true;
                     61: }
                     62: 
1.1.1.10! root       63: // 電源オン/リセット
        !            64: void
        !            65: SysClkDevice::ResetHard(bool poweron)
1.1       root       66: {
1.1.1.10! root       67:        // XXX たぶん電源オンだけで作用する?
        !            68:        if (poweron) {
        !            69:                if (sync_rt) {
        !            70:                        stime = gSync->GetRealTime();
        !            71:                }
        !            72: 
        !            73:                // 電源オンですぐ起動
        !            74:                sysint = false;
        !            75:                gScheduler->RestartEvent(event);
1.1.1.9   root       76:        }
1.1       root       77: }
                     78: 
                     79: uint64
1.1.1.7   root       80: SysClkDevice::Read(uint32 offset)
1.1       root       81: {
1.1.1.3   root       82:        // 1 ポートしかない
                     83:        return GetInt();
                     84: }
1.1       root       85: 
1.1.1.3   root       86: uint64
1.1.1.7   root       87: SysClkDevice::Write(uint32 offset, uint32 data)
1.1.1.3   root       88: {
                     89:        // 何か書き込まれたら、フラグをクリア
                     90:        putlog(1, "システムクロック割り込みクリア");
1.1.1.6   root       91:        sysint = false;
                     92:        gInterrupt->NegateINT(this);
1.1.1.3   root       93:        return 0;
1.1       root       94: }
                     95: 
                     96: uint64
1.1.1.7   root       97: SysClkDevice::Peek(uint32 offset)
1.1       root       98: {
1.1.1.3   root       99:        return GetInt();
                    100: }
                    101: 
1.1.1.9   root      102: void
                    103: SysClkDevice::MonitorUpdate(Monitor *, TextScreen& screen)
                    104: {
                    105:        int y;
                    106: 
                    107:        screen.Clear();
                    108:        y = 0;
                    109: 
                    110:        int width = stime < 86400_sec ? 20 : 25;
                    111:        screen.Print(0, y++, "Sync: %s", sync_rt ? "Real Time" : "Virtual Time");
                    112:        screen.Print(0, y++, "Time: %*s", width, TimeToStr(stime).c_str());
                    113: }
                    114: 
1.1.1.3   root      115: // 割り込み状態を取得(?)
                    116: uint8
                    117: SysClkDevice::GetInt() const
                    118: {
                    119:        uint8 data = 0;
1.1       root      120: 
1.1.1.3   root      121:        if (sysint) {
                    122:                data |= 0x80;
1.1       root      123:        }
1.1.1.3   root      124:        return data;
1.1       root      125: }
                    126: 
                    127: // イベントハンドラ
                    128: void
1.1.1.5   root      129: SysClkDevice::Callback(Event& ev)
1.1       root      130: {
                    131:        putlog(3, "システムクロック割り込み発生");
1.1.1.9   root      132: 
                    133:        // システムクロックとしての現在時刻。
1.1.1.10! root      134:        // 足す前は前回の割り込み発生時刻なので period を足すと現在時刻。
1.1.1.9   root      135:        stime += period;
                    136: 
1.1.1.10! root      137:        sysint = true;
        !           138:        gInterrupt->AssertINT(this);
1.1.1.9   root      139: 
1.1.1.10! root      140:        if (sync_rt) {
        !           141:                gScheduler->StartRealtimeEvent(ev, stime, period);
1.1.1.9   root      142:        } else {
1.1.1.10! root      143:                gScheduler->StartEvent(ev);
1.1.1.9   root      144:        }
1.1       root      145: }

unix.superglobalmegacorp.com

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