--- nono/vm/rp5c15.cpp 2026/04/29 17:04:28 1.1 +++ nono/vm/rp5c15.cpp 2026/04/29 17:04:55 1.1.1.8 @@ -1,9 +1,11 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "rp5c15.h" +#include "mpu.h" #include // アラームは未実装 @@ -11,21 +13,23 @@ // XXX RTC の読み書きはロックしたほうがいいような気がする RP5C15Device::RP5C15Device() + : inherited("RTC") { - logname = "rtc"; - devname = "RTC"; devaddr = 0xe8a000; devlen = 0x2000; - monitor.Init(30, 17); + + monitor.func = (MonitorCallback_t)&RP5C15Device::MonitorUpdate; + monitor.SetSize(30, 17); + monitor.Regist(ID_MONITOR_RTC); } RP5C15Device::~RP5C15Device() { } -// RTC を初期化 +// 初期化 bool -RP5C15Device::InitRTC() +RP5C15Device::Init() { // ホストの時刻をローカル時刻で取得 LoadHostRTC(true); @@ -37,17 +41,15 @@ RP5C15Device::InitRTC() } uint64 -RP5C15Device::Read8(uint32 addr) +RP5C15Device::Read(uint32 offset) { uint8 data; int n; - // 偶数アドレスへのアクセスは先にエラーにする - if (addr % 2 == 0) - return (uint64)-1; + gMPU->AddCycle(29); // InsideOut p.135 - // Bank0 を 0..15、Bank1 を 16..31 に並べる - n = ((addr - devaddr) / 2) + bank * 0x10; + // バンクを展開する + n = bank * 0x10 + offset; // XXX 14, 15 は write only らしいが何が読めるか @@ -61,39 +63,29 @@ RP5C15Device::Read8(uint32 addr) case 0x00 ... 0x1c: data = reg.r[n]; break; - default: - putlog(2, "RTC $%06x 未実装領域読み込み", addr); - return 0xf0; + __unreachable(); } // 下位4ビット(RP5C15) の中の未実装ビットは %0 だが // 上位4ビットは %1 になる。 data |= 0xf0; - putlog(2, "RTC Bank%d $%x -> $%02x", bank, (n & 0x0f), data); + putlog(2, "RTC Bank%d $%x -> $%02x", bank, offset, data); return data; } uint64 -RP5C15Device::Read16(uint32 addr) -{ - return 0xff00 | Read8(addr + 1); -} - -uint64 -RP5C15Device::Write8(uint32 addr, uint32 data) +RP5C15Device::Write(uint32 offset, uint32 data) { int n; - // 偶数アドレスへのアクセスは先にエラーにする - if (addr % 2 == 0) - return (uint64)-1; + gMPU->AddCycle(38); // InsideOut p.135 - // Bank0 を 0..15、Bank1 を 16..31 に並べる - n = ((addr - devaddr) / 2) + bank * 0x10; + // バンクを展開する + n = bank * 0x10 + offset; - putlog(2, "RTC Bank%d $%x <- $%x", bank, (n & 0x0f), (data & 0x0f)); + putlog(2, "RTC Bank%d $%x <- $%x", bank, offset, (data & 0x0f)); switch (n) { case RP5C15::SEC1: @@ -235,22 +227,12 @@ RP5C15Device::Write8(uint32 addr, uint32 } uint64 -RP5C15Device::Write16(uint32 addr, uint32 data) -{ - return Write8(addr + 1, data); -} - -uint64 -RP5C15Device::Peek8(uint32 addr) +RP5C15Device::Peek(uint32 offset) { int n; - // 偶数アドレスへのアクセスを先に弾く - if (addr % 2 == 0) { - return (uint64)-1; - } - - n = ((addr - devaddr) / 2) + bank * 0x10; + // バンクを展開する + n = bank * 0x10 + offset; switch (n) { case RP5C15::MODE_BANK1: @@ -264,12 +246,12 @@ RP5C15Device::Peek8(uint32 addr) return reg.r[n] | 0xf0; default: - return 0xf0; + __unreachable(); } } -bool -RP5C15Device::MonitorUpdate() +void +RP5C15Device::MonitorUpdate(Monitor *, TextScreen& screen) { int x; int y; @@ -282,15 +264,15 @@ RP5C15Device::MonitorUpdate() // Bank0 0 1 2 3 4 5 6 7 8 9 a b c d e f // Bank1 - monitor.Clear(); + screen.Clear(); - monitor.Print(0, 0, " #0 #1"); + screen.Puts(0, 0, " #0 #1"); y = 1; for (int i = 0; i < 13; i++, y++) { - monitor.Print(0, y, "%X:%x %x", i, reg.r[i], reg.r[i + 16]); + screen.Print(0, y, "%X:%x %x", i, reg.r[i], reg.r[i + 16]); } for (int i = 13; i < 16; i++, y++) { - monitor.Print(0, y, "%X:%x", i, reg.r[i]); + screen.Print(0, y, "%X:%x", i, reg.r[i]); } x = 8; @@ -299,7 +281,7 @@ RP5C15Device::MonitorUpdate() int year = reg.year10 * 10 + reg.year1 + 1980; int mon = reg.mon10 * 10 + reg.mon1; int day = reg.day10 * 10 + reg.day1; - monitor.Print(x, y, "%04d/%02d/%02d(%s)", + screen.Print(x, y, "%04d/%02d/%02d(%s)", year, mon, day, wdays[reg.wday]); y++; @@ -308,23 +290,21 @@ RP5C15Device::MonitorUpdate() hour = reg.hour10 * 10 + reg.hour1; } else { hour = (reg.hour10 & 1) * 10 + reg.hour1; - monitor.Print(x, y, "%s", (reg.hour10 & 2) == 0 ? "AM" : "PM"); + screen.Puts(x, y, (reg.hour10 & 2) == 0 ? "AM" : "PM"); } int min = reg.min10 * 10 + reg.min1; int sec = reg.sec10 * 10 + reg.sec1; - monitor.Print(x + 3, y, "%02d:%02d:%02d", hour, min, sec); + screen.Print(x + 3, y, "%02d:%02d:%02d", hour, min, sec); y++; - monitor.Print(x, y++, "Leap %d", reg.leap); + screen.Print(x, y++, "Leap %d", reg.leap); y++; - monitor.Print(x, y++, "CLKOUT %c", clkout ? 'H' : 'L'); - monitor.Print(x, y++, "ALARM %c", alarmout ? 'H' : 'L'); + screen.Print(x, y++, "CLKOUT %c", clkout ? 'H' : 'L'); + screen.Print(x, y++, "ALARM %c", alarmout ? 'H' : 'L'); y++; - monitor.Print(x, y++, "cnt %2d", rtc.cnt); - - return true; + screen.Print(x, y++, "cnt %2d", rtc.cnt); } // 32Hz クロック入力