--- nono/vm/rp5c15.h 2026/04/29 17:04:28 1.1 +++ nono/vm/rp5c15.h 2026/04/29 17:05:10 1.1.1.11 @@ -1,11 +1,17 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt +// + +// +// RTC (RP5C15) // #pragma once #include "device.h" +#include "monitor.h" #include "rtc.h" struct RP5C15 @@ -102,36 +108,75 @@ struct RP5C15 class RP5C15Device : public RTCDevice { - typedef RTCDevice inherited; + using inherited = RTCDevice; public: RP5C15Device(); - virtual ~RP5C15Device(); + virtual ~RP5C15Device() override; - virtual bool InitRTC(); + bool Init() override; - virtual uint64 Read8(uint32 addr); - virtual uint64 Read16(uint32 addr); - virtual uint64 Write8(uint32 addr, uint32 data); - virtual uint64 Write16(uint32 addr, uint32 data); - virtual uint64 Peek8(uint32 addr); - virtual bool MonitorUpdate(); - - // 32Hz クロック入力 - virtual void ClockIn(); + // アラーム端子出力 + // ALARM 端子は負論理(Low active) だが、ここでは + // アサート(L) のとき true とする。 + // アラーム出力は内部のアラーム用 16Hz, 1Hz と + // アラーム時刻一致の alarm_on との OR 論理となっている。 + bool AlarmOut() const { return alarm_16Hz | alarm_1Hz | alarm_on; } + + uint GetSec() const override; // 秒(0-59) + uint GetMin() const override; // 分(0-59) + uint GetHour() const override; // 時(0-23) + uint GetWday() const override; // 曜日(0が日曜) + uint GetMday() const override; // 日(1-31) + uint GetMon() const override; // 月(1-12) + uint GetYear() const override; // 年(西暦) + uint GetLeap() const override; // うるう年カウンタ(0..3) + + protected: + // BusIO インタフェース + static const uint32 NPORT = 16; + uint64 Read(uint32 offset); + uint64 Write(uint32 offset, uint32 data); + uint64 Peek(uint32 offset); + + // 仮想 RTC からのクロック + void Tick32Hz() override; + void Tick2Hz() override; + void Tick1Hz() override; + + void SetSec(uint v) override; + void SetMin(uint v) override; + void SetHour(uint v) override; + void SetWday(uint v) override; + void SetMday(uint v) override; + void SetMon(uint v) override; + void SetYear(uint v) override; + void SetLeap(uint v) override; private: // レジスタを更新 void UpdateReg(uint32); + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + // レジスタ RP5C15 reg {}; - // 現在のバンク - // MODE レジスタの BANK ビットが変更された時にこの値も更新すること。 - int bank = 0; - // CLKOUT 端子の状態 (true なら 'H') - bool clkout = false; - // ALARM 端子の状態 (true なら 'H') - bool alarmout = false; + bool clkout {}; + + // 分周段から秒カウンタへのカウントアップホールド内部信号。 + bool clock_hold {}; + + // CLKOUT 1/60Hz 用の 60秒カウンタ。カレンダとは独立。 + uint32 cnt_60sec {}; + + // 内部アラーム 16Hz 信号。CLKOUT、alarm_1Hz とは独立。 + bool alarm_16Hz {}; + // 内部アラーム 1Hz 信号。CLKOUT、alarm_16Hz とは独立。 + bool alarm_1Hz {}; + // アラーム時刻一致信号。 + // XXX アラーム機能自体は未実装。 + bool alarm_on {}; + + Monitor monitor { this }; };