--- nono/vm/mpu.cpp 2026/04/29 17:04:32 1.1.1.2 +++ nono/vm/mpu.cpp 2026/04/29 17:05:09 1.1.1.9 @@ -1,22 +1,88 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // +// // MPU 共通部 +// #include "mpu.h" +#include "config.h" +#include "scheduler.h" -std::unique_ptr gMPU; +// グローバル参照用 +MPUDevice *gMPU; // コンストラクタ -MPUDevice::MPUDevice() +MPUDevice::MPUDevice(const std::string& objname_) + : inherited(objname_) { - logname = "mpu"; - devname = "MPU"; + ClearAlias(); + AddAlias("MPU"); + + exec_event.Regist("MPU Execute"); } // デストラクタ MPUDevice::~MPUDevice() { + gMPU = NULL; +} + +bool +MPUDevice::Init() +{ + gScheduler->ConnectMessage(MessageID::MPU_TRACE, this, + ToMessageCallback(&MPUDevice::TraceMessage)); + + // MPU クロック + const ConfigItem& item = gConfig->Find("mpu-clock"); + const std::string& val = item.AsString(); + if (val.empty()) { + item.Err(); + return false; + } + // 文字列を double に変換 + char *end; + errno = 0; + double f = strtod(val.c_str(), &end); + if (end == val.c_str() || end[0] != '\0' || errno == ERANGE) { + item.Err(); + return false; + } + // 設定の "mpu-clock" は MHz 単位だが、変数 clock_khz は kHz 単位。 + clock_khz = (int)(f * 1000); + // 1MHz 未満はエラー。実際 10MHz 未満でもいい気がするけど + if (clock_khz < 1000) { + item.Err(); + return false; + } + clock_nsec = 1000 * 1000 / clock_khz; + + return true; } + +void +MPUDevice::PowerOff() +{ + gScheduler->StopEvent(exec_event); +} + +// MPU トレース状態設定要求メッセージ +void +MPUDevice::TraceMessage(MessageID msgid, uint32 arg) +{ + // デバッガから MPU のトレース状態を設定してくれと言われた + SetTrace((bool)arg); +} + +// Round Mode (モニタ表示用) +/*static*/ const char * const +MPUDevice::rmstr[4] = { + "Near", + "Zero", + "Minus", + "Plus", +};