--- nono/host/hostcom.cpp 2026/04/29 17:05:11 1.1.1.1 +++ nono/host/hostcom.cpp 2026/04/29 17:05:39 1.1.1.6 @@ -12,14 +12,12 @@ // // VM thread : Host thread // -// 各シリアルデバイス::Tx() : -// | -// SerialDevice::Tx() : +// 各デバイス::Tx() : // | // HostCOMDevice::Tx() : HostDevice::ThreadRun // | -// +-------------->| queue |----+ -// +-------------->| pipe |----+ +// +-------------->| queue |----+ … 送信キューに追加し +// +-------------->| pipe |----+ … パイプでホストスレッドに通知 // | | // <-+ : v // --- kevent @@ -43,12 +41,17 @@ // : | // HostCOMDevice::Read() // | -// +---------------| queue |<---+ -// +---------------| event |<---+ +// | queue |<---+ … 受信キューに追加 +// ‖ +// ‖ HostCOMDevice::*(rx_func)() +// | +// +-------------| Message |<---+ … メッセージで VM スレッドに通知 // v -// SerialDevice::Callback() -// | -// 各シリアルデバイス::Rx() +// 各デバイス::RxMessage() ‖ … メッセージコールバック +// | ‖ +// 各デバイス::Rx() ‖ … イベントコールバック +// | ‖ +// HostCOMDevice::Rx() <==++ … ここで queue から読み出す // ログ名 // MPSCC HostDevice COMDriver @@ -63,19 +66,23 @@ #include "hostcom.h" +#include "comdriver_cons.h" #include "comdriver_none.h" #include "comdriver_stdio.h" #include "comdriver_tcp.h" #include "config.h" #include "mainapp.h" +#include "monitor.h" // コンストラクタ // // objname_ は "HostCOM" とか (スレッド名も同じになる)。 // 設定ファイルキーワードプレフィックスはこれを小文字にしたもの("hostcom")。 -HostCOMDevice::HostCOMDevice(const std::string& objname_) - : inherited(objname_) +HostCOMDevice::HostCOMDevice(Device *parent_, const std::string& objname_) + : inherited(parent_, OBJ_NONE) { + SetName(objname_); + // 親が hostcom* か debugger かによっていろいろ動作が違う。 if (GetName() == "Debugger") { // デバッガコンソールならログレベルは親に準じるため、こっちは不要。 @@ -87,9 +94,9 @@ HostCOMDevice::HostCOMDevice(const std:: // のログレベルは独立。 // モニタは hostcom* のみ必要。 - monitor.func = ToMonitorCallback(&HostCOMDevice::MonitorUpdate); - monitor.SetSize(30, 16); - monitor.Regist(ID_MONITOR_HOSTCOM); + monitor = gMonitorManager->Regist(ID_MONITOR_HOSTCOM, this); + monitor->func = ToMonitorCallback(&HostCOMDevice::MonitorUpdate); + monitor->SetSize(30, 17); } } @@ -109,11 +116,11 @@ HostCOMDevice::SetLogLevel(int loglevel_ } } -// 初期化 +// 動的コンストラクションその2 bool -HostCOMDevice::Init() +HostCOMDevice::Create2() { - if (inherited::Init() == false) { + if (inherited::Create2() == false) { return false; } @@ -146,13 +153,11 @@ HostCOMDevice::SelectDriver() const ConfigItem& dditem = gConfig->Find("debugger-driver"); const std::string& ddtype = dditem.AsString(); if (ddtype == "stdio") { - const char *opt; - if (gMainApp.opt_D) { - opt = "-D"; - } else { - opt = "'-V debugger-driver=stdio'"; + auto where = dditem.GetWhere(); + if (where == "-V") { + where += " debugger-driver=stdio"; } - item.Err("cannot be used with %s option", opt); + item.Err("stdio driver conflicts with " + where); return false; } } @@ -168,6 +173,19 @@ HostCOMDevice::SelectDriver() driver.reset(); } + } else if (type == "cons") { + // console デバイスのいない機種では指定出来ない。 + if (gMainApp.FindObject(OBJ_CONSOLE) == NULL) { + item.Err("cannot be specified on vmtype=%s", + gMainApp.GetVMTypeStr().c_str()); + return false; + } + + driver.reset(new COMDriverCons(this)); + if ((bool)driver && driver->InitDriver() == false) { + driver.reset(); + } + } else { // 知らないドライバ種別 item.Err(); @@ -231,8 +249,8 @@ HostCOMDevice::Dispatch(int udata) // ...のだが、Dispatch(LISTEN_SOCKET) は着信を受け付けた時には // LISTEN_SOCKET を返し、それを受けてここで通知処理を行う。 if (udata == LISTEN_SOCKET) { - if (dev && accept_func) { - (dev->*accept_func)(); + if (accept_func) { + (parent->*accept_func)(); } udata = DONE; } @@ -263,7 +281,7 @@ HostCOMDevice::Tx(uint32 data) stat.tx_bytes++; // ざっくりピーク値 - stat.txq_peak = std::max((int)txq.Length(), stat.txq_peak); + stat.txq_peak = std::max((uint)txq.Length(), stat.txq_peak); // パイプに通知 (値はダミー) return WritePipe(0); @@ -313,7 +331,7 @@ HostCOMDevice::Read() } // ざっくりピーク値 - stat.rxq_peak = std::max((int)rxq.Length(), stat.rxq_peak); + stat.rxq_peak = std::max((uint)rxq.Length(), stat.rxq_peak); return 1; } @@ -339,11 +357,12 @@ HostCOMDevice::MonitorUpdate(Monitor *, { screen.Clear(); - screen.Print(0, 0, "HostCOM Driver: %s", driver->GetDriverName()); + screen.Print(0, 0, "Parent Device : %s", parent->GetName().c_str()); + screen.Print(0, 1, "HostCOM Driver: %s", driver->GetDriverName()); // 次の1行はドライバ依存情報 - driver->MonitorUpdateMD(screen); + driver->MonitorUpdateMD(screen, 2); - int y = 3; + int y = 4; screen.Print(0, y++, "%-17s%13s", "", "Bytes"); screen.Print(0, y++, "%-17s%13s", "VM sends", format_number(stat.tx_bytes).c_str()); @@ -363,8 +382,8 @@ HostCOMDevice::MonitorUpdate(Monitor *, y++; screen.Print(5, y++, "Capacity Peak"); - screen.Print(0, y++, "TxQ %4d/%4d %4d", - (int)txq.Length(), (int)txq.Capacity(), stat.txq_peak); - screen.Print(0, y++, "RxQ %4d/%4d %4d", - (int)rxq.Length(), (int)rxq.Capacity(), stat.rxq_peak); + screen.Print(0, y++, "TxQ %4u/%4u %4u", + (uint)txq.Length(), (uint)txq.Capacity(), stat.txq_peak); + screen.Print(0, y++, "RxQ %4u/%4u %4u", + (uint)rxq.Length(), (uint)rxq.Capacity(), stat.rxq_peak); }