|
|
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"
1.1.1.3 root 10: #include "mappedfile.h"
1.1.1.9 root 11: #include "monitor.h"
1.1 root 12: #include "rtc.h"
13:
14: // MK48T02 の時計部分のレジスタと内部状態
15: struct MK48T02Clock
16: {
1.1.1.10 root 17: // b7 b6 b5 b4 b3 b2 b1 b0
18: // +----+----+----+----+----+----+----+----+
19: // 7ff | YEAR (4+4bit) | (YEAR: 00..99)
20: // +----+----+----+----+----+----+----+----+
21: // 7fe | 0 0 0 | MONTH (1+4bit) | (MONTH: 01..12)
22: // +----+----+----+----+----+----+----+----+
23: // 7fd | XX | 0 | DATE (2+4bit) | (DATE: 01..31)
24: // +----+----+----+----+----+----+----+----+
25: // 7fc | XX | FT | XX XX | 0 |WEEKDAY (3bit)| (WEEKDAY: 1..7)
26: // +----+----+----+----+----+----+----+----+
27: // 7fb | KS | 0 | HOUR (2+4bit) | (HOURS: 00..23)
28: // +----+----+----+----+----+----+----+----+
1.1.1.11! root 29: // 7fa | ** | MINUTES (3+4bit) | (MINUTES: 00..59)
1.1.1.10 root 30: // +----+----+----+----+----+----+----+----+
31: // 7f9 | ST | SECONDS (3+4bit) | (SECONDS: 00..59)
32: // +----+----+----+----+----+----+----+----+
33: // 7f8 | W | R | CALIBRATION | (CONTROL)
34: // +----+----+----+----+----+----+----+----+
35: //
36: // '0' はデータシートでは '0' で、実際書き込んでも '0' になる。
37: // 'XX' はデータシートでは '0' だが '1' が書き込める。
1.1.1.11! root 38: //
! 39: // +7fa の最上位ビット('**')は MK48T02 のデータシートでは '0' だが、
! 40: // SPARCstation2 の PROM は '1' を期待しているようだ。
! 41: // 互換チップの M48T02 はデータシートも実装も '0' を返す。Issue#75
! 42: //
! 43: // メモ。後継機種にはものによって BLE/BE 拡張と CEB/CB 拡張がある。
! 44: // BLE, BL は Battery Low Enable, Battery Low。
! 45: // CEB, CB は Century Enable Bit, Century Bit。
! 46: //
! 47: // +----+----+----+----+----+----+----+----+
! 48: // 7fd | BLE| BE | DATE (2+4bit) | (DATE: 01..31)
! 49: // +----+----+----+----+----+----+----+----+
! 50: // 7fc | XX | FT | CEB| CB | 0 |WEEKDAY (3bit)| (WEEKDAY: 1..7)
! 51: // +----+----+----+----+----+----+----+----+
1.1.1.10 root 52:
53: // コントロールレジスタは全ビットを保持。
54: // ただし b5-b0 のキャリブレーションは未実装。
1.1 root 55: uint8 ctrl;
56: static const uint8 WRITE = 0x80; // WRITE BIT
57: static const uint8 READ = 0x40; // READ BIT
58:
1.1.1.10 root 59: // 内部のカウンタと毎秒ラッチされるレジスタの2ステージ構成になっている
60: // ここには制御ビット部分は含まない。
61: struct calendar {
62: uint8 sec; // BCD 秒(00-59)
63: uint8 min; // BCD 分(00-59)
64: uint8 hour; // BCD 時(00-23)
65: uint8 wday; // 曜日(1-7; 7=日曜)
66: uint8 mday; // BCD 日(01-31)
67: uint8 mon; // BCD 月(01-12)
68: uint8 year; // BCD 年(00-99; 西暦年の下二桁)
69: };
70: calendar in {}; // 内部カウンタ
71: calendar ex {}; // 外部レジスタ
72:
1.1 root 73: // 秒カウンタの bit7 が STOP ビット
1.1.1.10 root 74: static const uint8 STOP = 0x80;
1.1 root 75: // STOP 状態を保持
1.1.1.10 root 76: uint8 stop {};
1.1 root 77:
78: // 時カウンタの bit7 が KICKSTART ビット
1.1.1.10 root 79: // KICKSTART は内部発振器のスタートに使用するが、改良版である
80: // M48T02 (K なし)では廃止された。動作は実装しない。
81: static const uint8 KICKSTART = 0x80;
1.1 root 82: // KICKSTART 状態を保持
1.1.1.10 root 83: uint8 kickstart {};
1.1 root 84:
1.1.1.10 root 85: // 曜日カウンタの bit6 が Frequency Test ビット
86: // 動作は実装しない。
87: static const uint8 FREQTEST = 0x40;
88: // FreqTest 状態を保持
89: uint8 freqtest {};
1.1 root 90: };
91:
92: class MK48T02Device : public RTCDevice
93: {
1.1.1.3 root 94: using inherited = RTCDevice;
1.1 root 95: public:
96: MK48T02Device();
1.1.1.6 root 97: virtual ~MK48T02Device() override;
1.1 root 98:
1.1.1.3 root 99: bool Init() override;
1.1 root 100:
1.1.1.2 root 101: // 指定したアドレスからの文字列を読み出す (内蔵 ROM からのアクセス用)
102: std::string PeekString(uint32 addr) const;
103: // 指定したアドレスに文字列を書き込む (内蔵 ROM からのアクセス用)
104: bool WriteString(uint32 addr, const std::string& data);
1.1.1.9 root 105: // 全域をゼロクリアする (内蔵 ROM からのアクセス用)
106: void ClearAll();
1.1.1.2 root 107:
108: // BusIO インタフェース
109: // (内蔵 ROM からのアクセス用に特別に public にしてある)
1.1.1.7 root 110: uint64 Read(uint32 offset);
111: uint64 Write(uint32 offset, uint32 data);
112: uint64 Peek(uint32 offset);
113:
1.1.1.10 root 114: // 内蔵カウンタへのアクセス。
115: // ラッチカウンタではないことに注意。
116: uint GetSec() const override; // 秒(0-59)
117: uint GetMin() const override; // 分(0-59)
118: uint GetHour() const override; // 時(0-23)
119: uint GetWday() const override; // 曜日(0が日曜)
120: uint GetMday() const override; // 日(1-31)
121: uint GetMon() const override; // 月(1-12)
122: uint GetYear() const override; // 年(西暦)
123: uint GetLeap() const override; // うるう年カウンタ(0..3)
124:
1.1.1.2 root 125: protected:
126: // BusIO インタフェース
127: static const uint32 NPORT = 2048;
128:
1.1.1.10 root 129: // 仮想RTCからのクロック
130: void Tick1Hz() override;
131:
132: // 内蔵カウンタへのアクセス。
133: void SetSec(uint v) override;
134: void SetMin(uint v) override;
135: void SetHour(uint v) override;
136: void SetWday(uint v) override;
137: void SetMday(uint v) override;
138: void SetMon(uint v) override;
139: void SetYear(uint v) override;
140: void SetLeap(uint v) override;
141:
1.1 root 142: private:
143: // バイナリ <-> BCD 変換
144: static inline uint8 num2BCD(uint8);
145: static inline uint8 BCD2num(uint8);
146:
1.1.1.10 root 147: // 年のデコード。
148: uint DecodeYear(uint bcd_year) const;
149:
1.1 root 150: // コントロールレジスタへの書き込み
151: void WriteCtrl(uint32 data);
152:
1.1.1.9 root 153: DECLARE_MONITOR_CALLBACK(MonitorUpdate);
154:
1.1.1.3 root 155: // ファイル
1.1 root 156: std::string filename {};
1.1.1.3 root 157: MappedFile file {};
158: uint8 *mem {};
1.1 root 159:
160: // 時計
161: MK48T02Clock reg {};
162:
1.1.1.10 root 163: // うるう年補正量
164: uint adjust_leap {};
165:
166: // 外部レジスタをホールド(更新停止)しているときは true
167: bool hold {};
1.1.1.9 root 168:
169: Monitor monitor { this };
1.1 root 170: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.