--- nono/vm/mpu64180.cpp 2026/04/29 17:05:29 1.1.1.4 +++ nono/vm/mpu64180.cpp 2026/04/29 17:05:46 1.1.1.6 @@ -9,8 +9,10 @@ // #include "mpu64180.h" +#include "config.h" #include "debugger.h" #include "hd647180.h" +#include "hd647180asci.h" #include "pio.h" #include "scheduler.h" #include "ssg.h" @@ -24,23 +26,20 @@ MPU64180Device::MPU64180Device() AddAlias("XP"); AddAlias("HD647180"); - // 6.144MHz = 162.7604… [nsec] - clock_nsec = 163; - // レジスタモニター - reg_monitor.func = ToMonitorCallback(&MPU64180Device::MonitorUpdateReg); - reg_monitor.SetSize(38, 6); - reg_monitor.Regist(ID_MONITOR_XPREG); + reg_monitor = gMonitorManager->Regist(ID_MONITOR_XPREG, this); + reg_monitor->func = ToMonitorCallback(&MPU64180Device::MonitorUpdateReg); + reg_monitor->SetSize(38, 6); // I/O モニター - io_monitor.func = ToMonitorCallback(&MPU64180Device::MonitorUpdateIO); - io_monitor.SetSize(55, 20); - io_monitor.Regist(ID_MONITOR_XPIO); + io_monitor = gMonitorManager->Regist(ID_MONITOR_XPIO, this); + io_monitor->func = ToMonitorCallback(&MPU64180Device::MonitorUpdateIO); + io_monitor->SetSize(55, 20); // 割り込みモニター - intr_monitor.func = ToMonitorCallback(&MPU64180Device::MonitorUpdateIntr); - intr_monitor.SetSize(64, 18); - intr_monitor.Regist(ID_MONITOR_XPINTR); + intr_monitor = gMonitorManager->Regist(ID_MONITOR_XPINTR, this); + intr_monitor->func = ToMonitorCallback(&MPU64180Device::MonitorUpdateIntr); + intr_monitor->SetSize(64, 18); } // デストラクタ @@ -74,6 +73,20 @@ MPU64180Device::putlogn(const char *fmt, WriteLog(buf); } +bool +MPU64180Device::Create() +{ + try { + asci.reset(new HD647180ASCIDevice()); + } catch (...) { } + if ((bool)asci == false) { + warnx("Failed to initialize HD647180ASCIDevice at %s", __method__); + return false; + } + + return true; +} + // 初期化 bool MPU64180Device::Init() @@ -82,6 +95,28 @@ MPU64180Device::Init() return false; } + // MPU クロック。 + // "xp-clock" は MHz 単位だが、変数は kHz 単位。 + int clock_khz; + const ConfigItem& xp_clock_item = gConfig->Find("xp-clock"); + if (xp_clock_item.TryFixedDecimal(&clock_khz, 3) == false) { + xp_clock_item.Err(); + return false; + } + // 適当な下限値でエラーにする? + if (clock_khz < 100) { + xp_clock_item.Err(); + return false; + } + // 6.144MHz = 162.76… [nsec] であり、変数導入前は 163 をハードコード + // して使っていたので、それとの互換性のため四捨五入する。 + clock_nsec = 1000 * 1000 * 10 / clock_khz; + clock_nsec = (clock_nsec + 5) / 10; + if (clock_nsec < 1) { + xp_clock_item.Err("Clock speed too high"); + return false; + } + pio0 = GetPIO0Device(); xpbus = GetXPbusDevice();