--- nono/vm/mk48t02.cpp 2026/04/29 17:05:11 1.1.1.12 +++ nono/vm/mk48t02.cpp 2026/04/29 17:05:25 1.1.1.14 @@ -12,7 +12,9 @@ // 必要ならアクセス時に都度変換すること。 // // 仕様は 0x45000000 から 2KB だが、 -// 0x44000000 から 0x48000000 の手前まで 2KB 単位でミラーが見える。 +// LUNA-I では 0x44000000 から 0x47ffffff まで 2KB 単位でミラーが見える。 +// LUNA-88K では 0x44000000 から 0x45ffffff までが +// (こちらはロングワード配置なので) 8KB 単位のミラーに見える。 #include "mk48t02.h" #include "bitops.h" @@ -26,12 +28,12 @@ // コンストラクタ MK48T02Device::MK48T02Device() - : inherited("MK48T02") + : inherited() { - AddAlias("NVRAM"); - AddAlias("RTC"); + SetName("MK48T02"); - devaddr = 0x45000000; + AddAlias("MK48T02"); + AddAlias("NVRAM"); // 今の所 UTC として使うケースだけのようだ。 use_localtime = false; @@ -46,9 +48,14 @@ MK48T02Device::~MK48T02Device() { } +// 初期化 bool MK48T02Device::Init() { + if (inherited::Init() == false) { + return false; + } + struct stat st; // NetBSD/luna68k, OpenBSD/luna88k ともに epoch を 1970年としている @@ -62,7 +69,7 @@ MK48T02Device::Init() } // 雑にチェック if (year_epoch_val < 1900) { - item.Err("must be >= 1900"); + item.Err("Must be >= 1900"); return false; } year_epoch = (uint)year_epoch_val; @@ -83,14 +90,20 @@ MK48T02Device::Init() // // たぶんこのバグはもう修正されることはないだろうから、こちらで補正する // スイッチを用意した。 + if (gMainApp.Has(VMCap::LUNA)) { + if (gConfig->Find("luna-adjust-misused-epoch").AsInt()) { + // エポック年のうるう年カウンタ相当を補正項として持つ + adjust_leap = year_epoch % 4; + } else { + adjust_leap = 0; + } + } - int adjust_misused_epoch; - adjust_misused_epoch = gConfig->Find("luna-adjust-misused-epoch").AsInt(); - if (adjust_misused_epoch) { - // エポック年のうるう年カウンタ相当を補正項として持つ - adjust_leap = year_epoch % 4; - } else { - adjust_leap = 0; + // MSX-DOS モードなら NVRAM 不要なのでここでダミーのメモリだけ用意。 + if (gMainApp.msxdos_mode) { + // XXX アプリケーション寿命まで解放してないけど、まあいいか + mem = (uint8 *)malloc(16 * 1024); + return true; } // ファイルサイズを更新。 @@ -120,7 +133,7 @@ MK48T02Device::Init() return false; } - return inherited::Init(); + return true; } void @@ -146,21 +159,22 @@ MK48T02Device::BCD2num(uint8 bcd) return (bcd >> 4) * 10 + (bcd & 0x0f); } -uint64 +busdata MK48T02Device::Read(uint32 offset) { - uint32 data; + busdata data; data = mem[offset]; - putlog(3, "$%08x -> $%02x", gMPU->GetPaddr(), data); + putlog(3, "$%08x -> $%02x", mpu->GetPaddr(), data.Data()); + // XXX wait? return data; } -uint64 +busdata MK48T02Device::Write(uint32 offset, uint32 data) { - putlog(3, "$%08x <- $%02x", gMPU->GetPaddr(), data); + putlog(3, "$%08x <- $%02x", mpu->GetPaddr(), data); switch (offset - 2040) { case 0: // コントロール @@ -195,15 +209,30 @@ MK48T02Device::Write(uint32 offset, uint mem[offset] = data; + // XXX wait? return 0; } -uint64 +busdata MK48T02Device::Peek(uint32 offset) { return mem[offset]; } +bool +MK48T02Device::Poke(uint32 offset, uint32 data) +{ + // 時計部分にはコントロールレジスタもあるので書き込み不可。 + if (offset >= 2040) { + return false; + } else { + if ((int32)data >= 0) { + mem[offset] = data; + } + return true; + } +} + void MK48T02Device::MonitorUpdate(Monitor *, TextScreen& screen) {