--- nono/vm/goldfish_rtc.cpp 2026/04/29 17:05:25 1.1 +++ nono/vm/goldfish_rtc.cpp 2026/04/29 17:06:00 1.1.1.5 @@ -20,6 +20,9 @@ // 同じものを使うらしい。 #include "goldfish_rtc.h" +#include "event.h" +#include "mainbus.h" +#include "mytime.h" #include "textscreen.h" // @@ -37,46 +40,56 @@ GFRTCDevice::~GFRTCDevice() { } -// 初期化 -bool -GFRTCDevice::Init() -{ - if (inherited::Init() == false) { - return false; - } - - return true; -} - // リセット void GFRTCDevice::ResetHard(bool poweron) { - time_nsec = 0; + time_nsec.q = 0; } busdata -GFRTCDevice::Read32(uint32 addr) +GFRTCDevice::ReadPort(uint32 offset) { - uint32 offset = addr & 0xfff; busdata data; switch (offset) { case GFRTC::TIME_LOW: - time_nsec = (uint64)MkTime() * 1000'000'000U; - data = (uint32)time_nsec; + time_nsec.q = sec_to_nsec(MkTime()); + data = time_nsec.l; if (__predict_false(loglevel >= 1)) { if (loglevel >= 3) { putlogn("TIME_LOW -> $%08x", data.Data()); } else { - putlogn("TIME -> $%08x'%08x", - (uint32)(time_nsec >> 32), data.Data()); + putlogn("TIME -> $%08x'%08x", time_nsec.h, data.Data()); + } + + if (loglevel >= 2) { + struct tm tm, tr; + time_t t = (time_t)nsec_to_sec(time_nsec.q); + gmtime_r(&t, &tm); + putlogn("TIME / 1e9: %4u/%02u/%02u %02u:%02u:%02u", + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); + + time_t u = (time_t)get_hosttime_sec(); + gmtime_r(&u, &tr); + putlogn("system_clock: %4u/%02u/%02u %02u:%02u:%02u", + tr.tm_year + 1900, + tr.tm_mon + 1, + tr.tm_mday, + tr.tm_hour, + tr.tm_min, + tr.tm_sec); } } break; case GFRTC::TIME_HIGH: - data = (uint32)(time_nsec >> 32); + data = time_nsec.h; putlog(3, "TIME_HIGH -> $%08x", data.Data()); break; @@ -91,34 +104,34 @@ GFRTCDevice::Read32(uint32 addr) break; default: - putlog(1, "Read unknown $%08x", addr); + putlog(1, "Read unknown $%08x", GetMainbusDevice()->GetPaddr()); data.SetBusErr(); break; } + + data |= BusData::Size4; return data; } busdata -GFRTCDevice::Write32(uint32 addr, uint32 data) +GFRTCDevice::WritePort(uint32 offset, uint32 data) { - uint32 offset = addr & 0xfff; busdata r; switch (offset) { case GFRTC::TIME_LOW: { - time_nsec |= data; + time_nsec.l = data; if (__predict_false(loglevel >= 1)) { if (loglevel >= 2) { - putlogn("TIME_LOW <- $%08x", (uint32)time_nsec); + putlogn("TIME_LOW <- $%08x", time_nsec.l); } else { - putlogn("TIME <- $%08x'%08x", - (uint32)(time_nsec >> 32), (uint32)time_nsec); + putlogn("TIME <- $%08x'%08x", time_nsec.h, time_nsec.l); } } - time_t t = time_nsec / 1000'000'000U; + time_t t = nsec_to_sec(time_nsec.q); struct tm tm; gmtime_r(&t, &tm); SetYear(tm.tm_year + 1900); @@ -132,7 +145,7 @@ GFRTCDevice::Write32(uint32 addr, uint32 case GFRTC::TIME_HIGH: putlog(2, "TIME_HIGH <- $%08x", data); - time_nsec = (uint64)data << 32; + time_nsec.h = data; break; case GFRTC::ALARM_LOW: @@ -156,73 +169,41 @@ GFRTCDevice::Write32(uint32 addr, uint32 break; default: - putlog(1, "Write unknown $%08x <- $%08x", addr, data); + putlog(1, "Write unknown $%08x <- $%08x", + GetMainbusDevice()->GetPaddr(), data); r.SetBusErr(); break; } + + r |= BusData::Size4; return r; } busdata -GFRTCDevice::Peek8(uint32 addr) +GFRTCDevice::PeekPort(uint32 offset) { - uint32 offset = addr & 0xfff; - switch (offset) { - case GFRTC::TIME_LOW + 0: - case GFRTC::TIME_LOW + 1: - case GFRTC::TIME_LOW + 2: - case GFRTC::TIME_LOW + 3: - case GFRTC::TIME_HIGH + 0: - case GFRTC::TIME_HIGH + 1: - case GFRTC::TIME_HIGH + 2: - case GFRTC::TIME_HIGH + 3: + case GFRTC::TIME_LOW: { - uint64 now = MkTime() * 1000'000'000U; - - switch (offset) { - case GFRTC::TIME_LOW + 0: - return (now >> 24) & 0xff; - case GFRTC::TIME_LOW + 1: - return (now >> 16) & 0xff; - case GFRTC::TIME_LOW + 2: - return (now >> 8) & 0xff; - case GFRTC::TIME_LOW + 3: - return now & 0xff; - - case GFRTC::TIME_HIGH + 0: - return (now >> 56) & 0xff; - case GFRTC::TIME_HIGH + 1: - return (now >> 48) & 0xff; - case GFRTC::TIME_HIGH + 2: - return (now >> 40) & 0xff; - case GFRTC::TIME_HIGH + 3: - return (now >> 32) & 0xff; - default: - __unreachable(); - } + uint64 now = sec_to_nsec(MkTime()); + return now & 0xffffffffU; } - - case GFRTC::INTR_STATUS + 0: - case GFRTC::INTR_STATUS + 1: - case GFRTC::INTR_STATUS + 2: - case GFRTC::INTR_STATUS + 3: - return 0; - - case GFRTC::ALARM_STATUS + 0: - case GFRTC::ALARM_STATUS + 1: - case GFRTC::ALARM_STATUS + 2: - case GFRTC::ALARM_STATUS + 3: + case GFRTC::TIME_HIGH: + { + uint64 now = sec_to_nsec(MkTime()); + return now >> 32; + } + case GFRTC::INTR_STATUS: + case GFRTC::ALARM_STATUS: return 0; - default: - return busdata::BusErr; + return BusData::BusErr; } } // モニタの下請け。(GFTimer から呼ばれる) int -GFRTCDevice::MonitorUpdateRTC(TextScreen& screen, int y) const +GFRTCDevice::MonitorScreenRTC(TextScreen& screen, int y) const { screen.Puts(0, y++, ""); screen.Print(0, y++, "%04u/%02u/%02u(%s) %02u:%02u:%02u",