--- nono/vm/lunakbd.cpp 2026/04/29 17:05:10 1.1.1.13 +++ nono/vm/lunakbd.cpp 2026/04/29 17:05:33 1.1.1.16 @@ -11,8 +11,12 @@ // キーボード/マウスからシリアルポートへの入力は、1バイトの送信自体に約1msec // (9600bps、スタートビット1、ストップビット1) で送信後に 1msec 空けるそう // なので、ここでは単純に 2msec を1スロットとする。 +// +// ブザー発声はキー入力とは本来あまり関係ないが、ブザー発声中もキー入力中と +// 同様に高速走行を抑制したいため、キー扱いとしていることに留意。 #include "lunakbd.h" +#include "monitor.h" #include "scheduler.h" #include "sio.h" #include "uimessage.h" @@ -22,12 +26,9 @@ LunaKeyboard::LunaKeyboard() { led.resize(2); - event.func = ToEventCallback(&LunaKeyboard::Callback); - event.Regist("Keyboard/Mouse"); - - monitor.func = ToMonitorCallback(&LunaKeyboard::MonitorUpdate); - monitor.SetSize(40, 4); - monitor.Regist(ID_MONITOR_KEYBOARD); + monitor = gMonitorManager->Regist(ID_MONITOR_KEYBOARD, this); + monitor->func = ToMonitorCallback(&LunaKeyboard::MonitorUpdate); + monitor->SetSize(40, 4); } // デストラクタ @@ -35,6 +36,23 @@ LunaKeyboard::~LunaKeyboard() { } +// 初期化 +bool +LunaKeyboard::Init() +{ + if (inherited::Init() == false) { + return false; + } + + sio = GetSIODevice(); + + event.func = ToEventCallback(&LunaKeyboard::Callback); + event.SetName("Keyboard/Mouse"); + scheduler->RegistEvent(event); + + return true; +} + // キーボード接続時の MD 固有処理 void LunaKeyboard::MDConnect() @@ -51,7 +69,7 @@ LunaKeyboard::MDConnect() prev_m = false; // ブザー停止状態で初期化すると定義されている - buzzer_on = false; + BreakKey(KC_buzzer); // デフォルトでマウス有効 MouseOn(); @@ -62,10 +80,10 @@ void LunaKeyboard::MDDisconnect() { // 動作中のタイマーは停止 - gScheduler->StopEvent(event); + scheduler->StopEvent(event); // 電源が切れるのでブザー停止 - buzzer_on = false; + BreakKey(KC_buzzer); // マウスサンプリングは停止 MouseOff(); @@ -93,7 +111,7 @@ LunaKeyboard::MonitorUpdate(Monitor *, T screen.Puts(x + 4, y, TA::OnOff(led[0]), "Kana"); y++; screen.Puts(0, y, "Buzzer:"); - screen.Print(x, y, buzzer_on ? TA::Normal : TA::Disable, + screen.Print(x, y, IsPressed(KC_buzzer) ? TA::Normal : TA::Disable, "%umsec %uHz", buzzer_msec, buzzer_freq); y++; @@ -249,12 +267,12 @@ LunaKeyboard::SendStart() void LunaKeyboard::Start(uint64 period) { - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); uint64 target = ((now / period) + 1) * period; // XXX メンバの event.vtime 参照してるけどどうするかね if (event.IsRunning() == false || target < event.vtime) { event.time = target - now; - gScheduler->RestartEvent(event); + scheduler->RestartEvent(event); } } @@ -264,7 +282,7 @@ LunaKeyboard::Start(uint64 period) void LunaKeyboard::Callback(Event& ev) { - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); uint mdkey; // マウスサンプリングオンなら 20msec ごとにサンプリングを行う。 @@ -275,15 +293,15 @@ LunaKeyboard::Callback(Event& ev) // キューから取り出す。ここで取り出せるのは MDKey またはマウスデータ if (sendqueue.Dequeue(&mdkey)) { // 送信 - gSIO->Rx(1, mdkey); + sio->Rx(1, mdkey); } - if (buzzer_on && now > buzzer_end) { - buzzer_on = false; - Release(); + if (IsPressed(KC_buzzer) && now > buzzer_end) { + // VM スレッド内なので BreakKey() ではなくこっちを直接呼ぶ + KeyInput(KC_buzzer | KC_FLAG_BREAK); } - if (sendqueue.Empty() == false || buzzer_on) { + if (sendqueue.Empty() == false || IsPressed(KC_buzzer)) { // 送信データが残っていれば次は 2msec 後 Start(2_msec); } else if (mouse_on) { @@ -417,13 +435,13 @@ LunaKeyboard::Command(uint32 data) uint f = data & 7; buzzer_msec = buzzer_msec_table[t]; buzzer_freq = buzzer_freq_table[f]; - putlog(1, "Command $%02x Buzzer %dmsec, %dHz", + putlog(1, "Command $%02x Buzzer %umsec, %uHz", data, buzzer_msec, buzzer_freq); - uint64 now = gScheduler->GetVirtTime(); + uint64 now = scheduler->GetVirtTime(); buzzer_end = now + buzzer_msec * 1_msec; - buzzer_on = true; - Acquire(); + // VM スレッド内なので MakeKey() ではなく KeyInput() を直接呼ぶ + KeyInput(KC_buzzer | KC_FLAG_MAKE); Start(2_msec); break; } @@ -507,7 +525,7 @@ LunaKeyboard::keycode2lunakey_table[KC_m LunaKey_minus, // [2c] LunaKey_circum, // [2d] LunaKey_backslash, // [2e] - NoKey, // [2f] + LunaKey_buzzer, // [2f] NoKey, // [30] NoKey, // [31]