--- nono/vm/x68kkbd.cpp 2026/04/29 17:05:14 1.1.1.11 +++ nono/vm/x68kkbd.cpp 2026/04/29 17:05:42 1.1.1.17 @@ -23,6 +23,7 @@ #include "x68kkbd.h" #include "mfp.h" +#include "monitor.h" #include "scc.h" #include "scheduler.h" #include "sysport.h" @@ -32,16 +33,9 @@ X68030Keyboard::X68030Keyboard() { led.resize(7); - rept_event.func = ToEventCallback(&X68030Keyboard::ReptCallback); - rept_event.time = 0; - rept_event.Regist("Keyboard Repeat"); - - mouse_event.func = ToEventCallback(&X68030Keyboard::MouseCallback); - mouse_event.Regist("Mouse"); - - monitor.func = ToMonitorCallback(&X68030Keyboard::MonitorUpdate); - monitor.SetSize(47, 5); - monitor.Regist(ID_MONITOR_KEYBOARD); + monitor = gMonitorManager->Regist(ID_MONITOR_KEYBOARD, this); + monitor->func = ToMonitorCallback(&X68030Keyboard::MonitorUpdate); + monitor->SetSize(47, 5); } // デストラクタ @@ -49,6 +43,30 @@ X68030Keyboard::~X68030Keyboard() { } +// 初期化 +bool +X68030Keyboard::Init() +{ + if (inherited::Init() == false) { + return false; + } + + mfp = GetMFPDevice(); + scc = GetSCCDevice(); + sysport = GetSysportDevice(); + + rept_event.func = ToEventCallback(&X68030Keyboard::ReptCallback); + rept_event.time = 0; + rept_event.SetName("Keyboard Repeat"); + scheduler->RegistEvent(rept_event); + + mouse_event.func = ToEventCallback(&X68030Keyboard::MouseCallback); + mouse_event.SetName("Mouse"); + scheduler->RegistEvent(mouse_event); + + return true; +} + // キーボード接続時の MD 固有処理 void X68030Keyboard::MDConnect() @@ -58,12 +76,12 @@ X68030Keyboard::MDConnect() rept_time_data = 4; rept_time = 110_msec; rept_key = KC_none; - gScheduler->StopEvent(rept_event); + scheduler->StopEvent(rept_event); led_darkness = 0; // XXX マウスの接続取り外しは未定 - gScheduler->StopEvent(mouse_event); + scheduler->StopEvent(mouse_event); mouse_event.code = 0; } @@ -71,8 +89,8 @@ X68030Keyboard::MDConnect() void X68030Keyboard::MDDisconnect() { - gScheduler->StopEvent(rept_event); - gScheduler->StopEvent(mouse_event); + scheduler->StopEvent(rept_event); + scheduler->StopEvent(mouse_event); mouse_event.code = 0; } @@ -91,17 +109,17 @@ X68030Keyboard::MonitorUpdate(Monitor *, // Ctrl Enable: OPT.2 Enable: % // Key Repeat: Delay $x(????msec) // Repeat $x(????msec) - // LED: Zen Hira INS CAPS Code Roma Kana ($xx) + // LED: $xx Zen Hira INS CAPS Code Roma Kana // LED Darkness: x // KEY_EN, CTRL_EN, OPT2_EN, MSCTRL は未実装 // キーリピート screen.Puts(0, y, "Key Repeat:"); - screen.Print(12, y++, "Delay $%x(%4dmsec)", - rept_delay_data, (int)(rept_delay / 1_msec)); - screen.Print(12, y++, "Repeat $%x(%4dmsec)", - rept_time_data, (int)(rept_time / 1_msec)); + screen.Print(12, y++, "Delay $%x(%4umsec)", + rept_delay_data, (uint)(rept_delay / 1_msec)); + screen.Print(12, y++, "Repeat $%x(%4umsec)", + rept_time_data, (uint)(rept_time / 1_msec)); // マウス int mx = mouse_x; @@ -129,16 +147,16 @@ X68030Keyboard::MonitorUpdate(Monitor *, uint val = 0x80; for (int i = 0; i < 7; i++) { int n = 6 - i; - screen.Puts(7 + i * 5, y, TA::OnOff(led[n]), ledname[i]); + screen.Puts(12 + i * 5, y, TA::OnOff(led[n]), ledname[i]); if (led[n] == 0) { val |= 1 << n; } } - screen.Print(42, y, "($%02x)", val); + screen.Print(5, y, "$%02x", val); y++; // LED の明るさ (というより暗さ) - screen.Print(0, y++, "LED Darkness: %d", led_darkness); + screen.Print(0, y++, "LED Darkness: %u", led_darkness); } // 共通 keystat を X680x0 キーコードに変換して返す。 @@ -181,12 +199,10 @@ X68030Keyboard::KeyInput(uint keystat) // どのキーコードで問い合わせをされても KC_SHIFT_L と KC_SHIFT_R の OR が // [SHIFT] キーの状態である。 if (keycode == KC_SHIFT_L || keycode == KC_SHIFT_R) { - // KC_SHIFT_L, R に対する pressed は内部の OR 処理用 - pressed[keycode] = ismake; - if (keycode == KC_SHIFT_L && pressed[KC_SHIFT_R]) { - return; - } - if (keycode == KC_SHIFT_R && pressed[KC_SHIFT_L]) { + // それぞれのシフトキーが押されたことは覚えておく。 + SetPressed(keycode, ismake); + // 反対側のキーが押されていたら、いま押した・離したほうは無視する + if (IsPressed(keycode ^ 1)) { return; } keycode = KC_SHIFT; @@ -207,11 +223,11 @@ X68030Keyboard::KeyInput(uint keystat) // いま起きているリピートは中止 rept_key = keycode; rept_event.time = rept_delay; - gScheduler->RestartEvent(rept_event); + scheduler->RestartEvent(rept_event); } else { if (keycode == rept_key) { // 同じキーのブレークでのみリピートを終了する - gScheduler->StopEvent(rept_event); + scheduler->StopEvent(rept_event); rept_key = KC_none; } } @@ -226,7 +242,7 @@ X68030Keyboard::ReptCallback(Event& ev) // 二回目以降のリピートは rept_time 間隔で発生 rept_event.time = rept_time; - gScheduler->StartEvent(rept_event); + scheduler->StartEvent(rept_event); } // MFP、システムポートと、キーボードの関係。 @@ -252,7 +268,7 @@ X68030Keyboard::ReptCallback(Event& ev) void X68030Keyboard::SendStart() { - if (gMFP->RxIsReady()) { + if (mfp->RxIsReady()) { // 本体が Ready ならここで送信 Ready(); } else { @@ -267,7 +283,7 @@ X68030Keyboard::SendStart() void X68030Keyboard::Ready() { - if (gSysport->GetKeyCtrl()) { + if (sysport->GetKeyCtrl()) { // KEYCTRL が有効なら処理する // ここで取り出せるのは MDKey。 @@ -276,12 +292,12 @@ X68030Keyboard::Ready() // あれば送信 // 呼ばれたからには送信できるはず - assert(gMFP->RxIsReady() == true); + assert(mfp->RxIsReady() == true); assert(x68kkey != 0); // 送信 - gMFP->Rx(x68kkey); + mfp->Rx(x68kkey); } else { // なければ何もせず終了 } @@ -346,9 +362,10 @@ X68030Keyboard::MouseSendStart() mouse_y = 0; // 1バイト目は MSCTRL が立ち下がってから 700us 以上後から送信。 - mouse_event.time = 700_usec; + // さらに1バイトの送信に 2.3msec かかる(このすぐ下参照)。 + mouse_event.time = 700_usec + 2300_usec; mouse_event.code = 1; - gScheduler->RestartEvent(mouse_event); + scheduler->RestartEvent(mouse_event); } // マウスデータのイベントコールバック @@ -358,22 +375,20 @@ X68030Keyboard::MouseCallback(Event& ev) // マウスは 4800bps で、ストップビット 2 なので11ビット。 // 1/4800 * 11 = 2.29166 msec なので、1バイトあたり 2.3 msec にしておく。 - // code は 1 なら1バイト目 ([0]) - // : - // code が 4 なら送らずに終了 - - if (mouse_event.code < 4) { - // 1, 2, 3 バイト目送信 - gSCC->Rx(1, mouse_data[mouse_event.code - 1]); + // code 1 なら1バイト目 (mouse_data[0]) の送信完了時刻が来た。 + // code 2 なら2バイト目 (mouse_data[1]) の送信完了時刻が来た。 + // code 3 なら3バイト目 (mouse_data[2]) の送信完了時刻が来た。 + // 3バイト目を送信してイベントループ終了。 + + scc->Rx(1, mouse_data[mouse_event.code - 1]); + if (mouse_event.code < 3) { // 次のイベント mouse_event.time = 2300_usec; mouse_event.code++; - gScheduler->StartEvent(mouse_event); + scheduler->StartEvent(mouse_event); } else { - // 3 バイト目の送信が終わって、1文字送信分の時間が経過したので - // ここで code を 0 に戻す。 - // XXX 実際のタイミングがどうかは知らない。 + // 3 バイト目の送信が終わった。 mouse_event.code = 0; } } @@ -390,46 +405,46 @@ X68030Keyboard::Command(uint32 data) } else if (data < 0x48) { // $40-$47 MSCTRL 信号制御 // こいつは頻度が高いのでログレベルを上げておく - putlog(3, "Command MSCTRL control %d", (data & 1)); + putlog(3, "Command MSCTRL control %u", (data & 1)); } else if (data < 0x50) { // $48-$4f キーデータ送出許可 - putlog(1, "Command Key send enable %d (NOT IMPLEMENTED)", (data & 1)); + putlog(1, "Command Key send enable %u (NOT IMPLEMENTED)", (data & 1)); } else if (data < 0x54) { // $50-$53 ディスプレイ制御モード選択 // (実装不要) - putlog(2, "Command Display control mode %d", (data & 1)); + putlog(2, "Command Display control mode %u", (data & 1)); } else if (data < 0x58) { // $54-$57 LED 明るさ選択 // 0 が明るく 3 が暗いので、明るさというより暗さ。 led_darkness = (data & 3); - putlog(1, "Command LED brightness %d", led_darkness); + putlog(1, "Command LED brightness %u", led_darkness); } else if (data < 0x5c) { // $58-$5b 本体からのディスプレイ制御許可 // (実装不要) - putlog(2, "Command Display control enable %d", (data & 1)); + putlog(2, "Command Display control enable %u", (data & 1)); } else if (data < 0x60) { // $5c-$5f OPT.2 によるディスプレイ制御許可 // (実装不要) - putlog(2, "Command OPT2 control enable %d", (data & 1)); + putlog(2, "Command OPT2 control enable %u", (data & 1)); } else if (data < 0x70) { // $60-$6f リピートまでの時間 rept_delay_data = data & 15; rept_delay = 200_msec + rept_delay_data * 100_msec; - putlog(1, "Command Repeat Delay %d (%d msec)", rept_delay_data, - (int)(rept_delay / 1_msec)); + putlog(1, "Command Repeat Delay %u (%u msec)", rept_delay_data, + (uint)(rept_delay / 1_msec)); } else if (data < 0x80) { // $70-$7f リピート間隔 rept_time_data = data & 15; rept_time = 30_msec + rept_time_data * rept_time_data * 5_msec; - putlog(1, "Command Repeat time %d (%d msec)", rept_time_data, - (int)(rept_time / 1_msec)); + putlog(1, "Command Repeat time %d (%u msec)", rept_time_data, + (uint)(rept_time / 1_msec)); } else { // $80-$ff LED 制御