From 28bd9cf3535ddcf06cce91a8a210d83e573fa8a8 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Wed, 19 Aug 2026 18:46:09 +0300 Subject: [PATCH] Kernel: Fix PS/2 scancode set detection logic If we cannot determine current scancode set because either the keyboard does not respond or responds with bogus value, assume scancode set 1 and mark the scancode set as uncertain. If we receive the byte 0xF0 while having the uncertain flag set, swap to scancode set 2. 0xF0 is unused in scancode set 1 but indicates key release in scancode set 2, so it will be sent after every key press. --- kernel/include/kernel/Input/PS2/Keyboard.h | 1 + kernel/kernel/Input/PS2/Keyboard.cpp | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/kernel/include/kernel/Input/PS2/Keyboard.h b/kernel/include/kernel/Input/PS2/Keyboard.h index 81c8eb02..911f4f49 100644 --- a/kernel/include/kernel/Input/PS2/Keyboard.h +++ b/kernel/include/kernel/Input/PS2/Keyboard.h @@ -36,6 +36,7 @@ namespace Kernel::Input uint8_t m_byte_index { 0 }; bool m_basic { false }; + bool m_scancode_set_uncertain { false }; uint8_t m_scancode_set { 0xFF }; uint16_t m_modifiers { 0 }; diff --git a/kernel/kernel/Input/PS2/Keyboard.cpp b/kernel/kernel/Input/PS2/Keyboard.cpp index 37142245..693e3949 100644 --- a/kernel/kernel/Input/PS2/Keyboard.cpp +++ b/kernel/kernel/Input/PS2/Keyboard.cpp @@ -53,8 +53,9 @@ namespace Kernel::Input if (command_data[0] == Command::CONFIG_SCANCODE_SET && m_scancode_set >= 0xFE) { - dwarnln("Could not detect scancode set, assuming 2"); - m_scancode_set = 2; + dwarnln("Could not detect scancode set, assuming 1"); + m_scancode_set_uncertain = true; + m_scancode_set = 1; m_keymap.initialize(m_scancode_set); append_command_queue(PS2::DeviceCommand::ENABLE_SCANNING, 0); } @@ -89,6 +90,7 @@ namespace Kernel::Input else { dwarnln("Could not detect scancode set, assuming 1"); + m_scancode_set_uncertain = true; m_scancode_set = 1; } m_keymap.initialize(m_scancode_set); @@ -103,6 +105,17 @@ namespace Kernel::Input return; } + // If we could not detect scancode set, we assume it to be 1 + // If we get byte 0xF0 which is indicates release in scancode set 2 + // and nothing in scancode set 1, switch to scancode set 2 + if (m_scancode_set_uncertain && byte == 0xF0) + { + dprintln("Switching to scancode set 2"); + m_scancode_set_uncertain = false; + m_scancode_set = 2; + m_keymap.initialize(m_scancode_set); + } + m_byte_buffer[m_byte_index++] = byte; if (byte == 0xE0) return;