Annotation of nono/vm/mk48t02.h, revision 1.1.1.17

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: 
1.1.1.12  root        7: //
                      8: // NVRAM/RTC (MK48T02)
                      9: //
                     10: 
1.1       root       11: #pragma once
                     12: 
1.1.1.14  root       13: #include "rtc.h"
1.1.1.3   root       14: #include "mappedfile.h"
1.1       root       15: 
                     16: // MK48T02 の時計部分のレジスタと内部状態
                     17: struct MK48T02Clock
                     18: {
1.1.1.12  root       19:        // MK48T02 の場合:
                     20:        //
1.1.1.10  root       21:        //       b7   b6   b5   b4   b3   b2   b1   b0
                     22:        //     +----+----+----+----+----+----+----+----+
                     23:        // 7ff |              YEAR (4+4bit)            |  (YEAR: 00..99)
                     24:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       25:        // 7fe | XX   XX   XX |      MONTH (1+4bit)    |  (MONTH: 01..12)
1.1.1.10  root       26:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       27:        // 7fd | XX   XX |         DATE (2+4bit)       |  (DATE: 01..31)
1.1.1.10  root       28:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       29:        // 7fc | XX | FT | XX   XX   XX |WEEKDAY (3bit)|  (WEEKDAY: 1..7)
1.1.1.10  root       30:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       31:        // 7fb | KS | XX |         HOUR (2+4bit)       |  (HOURS: 00..23)
1.1.1.10  root       32:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       33:        // 7fa | XX |           MINUTES (3+4bit)       |  (MINUTES: 00..59)
1.1.1.10  root       34:        //     +----+----+----+----+----+----+----+----+
                     35:        // 7f9 | ST |           SECONDS (3+4bit)       |  (SECONDS: 00..59)
                     36:        //     +----+----+----+----+----+----+----+----+
                     37:        // 7f8 |  W |  R |        CALIBRATION          |  (CONTROL)
                     38:        //     +----+----+----+----+----+----+----+----+
                     39:        //
1.1.1.12  root       40:        // 'XX' はデータシートでは '0' だが書き込んだ値が読み返せるようだ。
                     41:        // SPARCstation2 の PROM で少なくとも +7fa の b7 はそう観測されている
                     42:        // ように思える(Issue#75)。他のビットも全部同じ挙動をするかは確認手段
                     43:        // が手元にないので分からないが、内部構造的にはただの SRAM が見えてそう
                     44:        // な気もするので、とりあえずデータシートで '0' になっているところは
                     45:        // 全てメモリとして扱うことにする。何か分かったらまた対応する。
1.1.1.11  root       46:        //
                     47:        //
1.1.1.12  root       48:        // (参考までに) M48T02 の場合:
                     49:        //
                     50:        // 互換チップ M48T02 は、そのデータシート上 '0' のところでも、常に %0
                     51:        // しか読み出せないところ (以下表中 '0')と、書き込んだ値が読み出せる
                     52:        // ところ (以下表中 'XX') とがあるようだ。
                     53:        // また機種によっては以下の位置に BLE/BE 拡張と CEB/CB 拡張がある。
                     54:        // BLE, BL は Battery Low Enable, Battery Low。(BL は Read Only)
1.1.1.11  root       55:        // CEB, CB は Century Enable Bit, Century Bit。
                     56:        //
1.1.1.12  root       57:        //       b7   b6   b5   b4   b3   b2   b1   b0
                     58:        //     +----+----+----+----+----+----+----+----+
                     59:        // 7ff |                  YEAR                 |
                     60:        //     +----+----+----+----+----+----+----+----+
                     61:        // 7fe |  0    0    0 |       MONTH            |
                     62:        //     +----+----+----+----+----+----+----+----+
                     63:        // 7fd | BLE| BL |            DATE             |
1.1.1.11  root       64:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       65:        // 7fc | XX | FT | CEB| CB |  0 |   WEEKDAY    |
1.1.1.11  root       66:        //     +----+----+----+----+----+----+----+----+
1.1.1.12  root       67:        // 7fb | KS |  0 |            HOUR             |
                     68:        //     +----+----+----+----+----+----+----+----+
                     69:        // 7fa |  0 |               MINUTES            |
                     70:        //     +----+----+----+----+----+----+----+----+
                     71:        // 7f9 | ST |               SECONDS            |
                     72:        //     +----+----+----+----+----+----+----+----+
                     73:        // 7f8 |  W |  R |        CALIBRATION          |
1.1.1.11  root       74:        //     +----+----+----+----+----+----+----+----+
1.1.1.10  root       75: 
                     76:        // コントロールレジスタは全ビットを保持。
                     77:        // ただし b5-b0 のキャリブレーションは未実装。
1.1       root       78:        static const uint8 WRITE        = 0x80; // WRITE BIT
                     79:        static const uint8 READ         = 0x40; // READ BIT
                     80: 
1.1.1.16  root       81:        // 内部のカウンタと毎秒ラッチされるレジスタの2ステージ構成になっている。
1.1.1.10  root       82:        // ここには制御ビット部分は含まない。
                     83:        struct calendar {
                     84:                uint8 sec;              // BCD 秒(00-59)
                     85:                uint8 min;              // BCD 分(00-59)
                     86:                uint8 hour;             // BCD 時(00-23)
                     87:                uint8 wday;             // 曜日(1-7; 7=日曜)
                     88:                uint8 mday;             // BCD 日(01-31)
                     89:                uint8 mon;              // BCD 月(01-12)
                     90:                uint8 year;             // BCD 年(00-99; 西暦年の下二桁)
                     91:        };
                     92:        calendar in {}; // 内部カウンタ
                     93: 
1.1.1.16  root       94:        // 秒カウンタの bit7 が STOP ビット。
1.1.1.10  root       95:        static const uint8 STOP = 0x80;
1.1.1.16  root       96:        // STOP 状態を保持。
1.1.1.10  root       97:        uint8 stop {};
1.1       root       98: 
1.1.1.16  root       99:        // 時カウンタの bit7 が KICKSTART ビット。
1.1.1.10  root      100:        // KICKSTART は内部発振器のスタートに使用するが、改良版である
1.1.1.16  root      101:        // M48T02 (K なし)では廃止された。動作は実装しない。
1.1.1.10  root      102:        static const uint8 KICKSTART = 0x80;
1.1       root      103:        // KICKSTART 状態を保持
1.1.1.10  root      104:        uint8 kickstart {};
1.1       root      105: 
1.1.1.16  root      106:        // 曜日カウンタの bit6 が Frequency Test ビット。動作は実装しない。
1.1.1.10  root      107:        static const uint8 FREQTEST = 0x40;
                    108:        // FreqTest 状態を保持
                    109:        uint8 freqtest {};
1.1       root      110: };
                    111: 
                    112: class MK48T02Device : public RTCDevice
                    113: {
1.1.1.3   root      114:        using inherited = RTCDevice;
1.1       root      115:  public:
                    116:        MK48T02Device();
1.1.1.14  root      117:        ~MK48T02Device() override;
1.1       root      118: 
1.1.1.3   root      119:        bool Init() override;
1.1       root      120: 
1.1.1.12  root      121:        void StartTime() override;
                    122: 
1.1.1.2   root      123:        // 指定したアドレスからの文字列を読み出す (内蔵 ROM からのアクセス用)
                    124:        std::string PeekString(uint32 addr) const;
                    125:        // 指定したアドレスに文字列を書き込む (内蔵 ROM からのアクセス用)
                    126:        bool WriteString(uint32 addr, const std::string& data);
1.1.1.9   root      127:        // 全域をゼロクリアする (内蔵 ROM からのアクセス用)
                    128:        void ClearAll();
1.1.1.2   root      129: 
1.1.1.10  root      130:        // 内蔵カウンタへのアクセス。
                    131:        // ラッチカウンタではないことに注意。
                    132:        uint GetSec() const override;   // 秒(0-59)
                    133:        uint GetMin() const override;   // 分(0-59)
                    134:        uint GetHour() const override;  // 時(0-23)
                    135:        uint GetWday() const override;  // 曜日(0が日曜)
                    136:        uint GetMday() const override;  // 日(1-31)
                    137:        uint GetMon() const override;   // 月(1-12)
                    138:        uint GetYear() const override;  // 年(西暦)
                    139:        uint GetLeap() const override;  // うるう年カウンタ(0..3)
                    140: 
1.1.1.2   root      141:        // BusIO インタフェース
1.1.1.15  root      142:        // (内蔵 ROM からのアクセス用に特別に public にしてある)
                    143:        busdata ReadPort(uint32 offset);
                    144:        busdata WritePort(uint32 offset, uint32 data);
                    145:        busdata PeekPort(uint32 offset);
                    146:  protected:
1.1.1.2   root      147:        static const uint32 NPORT = 2048;
1.1.1.15  root      148:        bool PokePort(uint32 offset, uint32 data);
1.1.1.2   root      149: 
1.1.1.10  root      150:        // 仮想RTCからのクロック
                    151:        void Tick1Hz() override;
                    152: 
                    153:        // 内蔵カウンタへのアクセス。
                    154:        void SetSec(uint v) override;
                    155:        void SetMin(uint v) override;
                    156:        void SetHour(uint v) override;
                    157:        void SetWday(uint v) override;
                    158:        void SetMday(uint v) override;
                    159:        void SetMon(uint v) override;
                    160:        void SetYear(uint v) override;
                    161:        void SetLeap(uint v) override;
                    162: 
1.1       root      163:  private:
                    164:        // バイナリ <-> BCD 変換
                    165:        static inline uint8 num2BCD(uint8);
                    166:        static inline uint8 BCD2num(uint8);
                    167: 
1.1.1.10  root      168:        // 年のデコード。
                    169:        uint DecodeYear(uint bcd_year) const;
                    170: 
1.1       root      171:        // コントロールレジスタへの書き込み
                    172:        void WriteCtrl(uint32 data);
                    173: 
1.1.1.12  root      174:        // NVRAM からカレンダへロード
                    175:        MK48T02Clock::calendar Load() const;
                    176: 
                    177:        // カレンダを NVRAM にストア
                    178:        void Store(const MK48T02Clock::calendar& cal);
                    179: 
1.1.1.17! root      180:        DECLARE_MONITOR_SCREEN(MonitorScreen);
1.1.1.9   root      181: 
1.1.1.3   root      182:        // ファイル
1.1       root      183:        std::string filename {};
1.1.1.3   root      184:        MappedFile file {};
                    185:        uint8 *mem {};
1.1       root      186: 
                    187:        // 時計
                    188:        MK48T02Clock reg {};
                    189: 
1.1.1.10  root      190:        // うるう年補正量
                    191:        uint adjust_leap {};
                    192: 
                    193:        // 外部レジスタをホールド(更新停止)しているときは true
                    194:        bool hold {};
1.1.1.9   root      195: 
1.1.1.16  root      196:        Monitor *monitor {};
1.1       root      197: };
1.1.1.13  root      198: 
1.1.1.17! root      199: inline MK48T02Device *GetMK48T02Device() {
1.1.1.13  root      200:        return Object::GetObject<MK48T02Device>(OBJ_RTC);
                    201: }

unix.superglobalmegacorp.com

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