Kernel: Improve keyboard input by a lot
Seems to work on my 2 computerss
This commit is contained in:
parent
7ebe727a29
commit
e62a626b39
|
@ -36,6 +36,7 @@ kernel/Keyboard.o \
|
|||
kernel/kmalloc.o \
|
||||
kernel/PIC.o \
|
||||
kernel/PIT.o \
|
||||
kernel/RTC.o \
|
||||
kernel/Serial.o \
|
||||
kernel/SSP.o \
|
||||
icxxabi.o \
|
||||
|
|
|
@ -18,18 +18,30 @@ namespace Keyboard
|
|||
Dollar, Pound, Euro, Currency, Enter, Space, Tab, Backspace, LessThan, MoreThan, Tick, BackTick, Section, Half, At, Pipe,
|
||||
End, Home, Insert, Delete, Super, PageUp, PageDown, PrintScreen, Left, Right, Up, Down,
|
||||
|
||||
LeftShift, RightShift, CapsLock, Ctrl, Alt, NumLock, Escape,
|
||||
LeftShift, RightShift, CapsLock, LeftCtrl, RightCtrl, LeftAlt, RightAlt, NumLock, ScrollLock, Escape,
|
||||
|
||||
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
|
||||
NumpadComma, NumpadPlus, NumpadMult, NumpadDiv, NumpadMinus,
|
||||
NumpadSep, NumpadPlus, NumpadMult, NumpadDiv, NumpadMinus, NumpadEnter,
|
||||
|
||||
Mute, VolumeDown, VolumeUp, Calculator, PlayPause, Stop, PreviousTrack, NextTrack,
|
||||
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
void initialize(void (*callback)(Key, uint8_t, bool));
|
||||
struct KeyEvent
|
||||
{
|
||||
Key key;
|
||||
uint8_t modifiers;
|
||||
bool pressed;
|
||||
};
|
||||
|
||||
char key_to_ascii(Key, uint8_t);
|
||||
bool initialize(void (*callback)(KeyEvent));
|
||||
void update_keyboard();
|
||||
|
||||
char key_event_to_ascii(KeyEvent);
|
||||
|
||||
void led_disco();
|
||||
|
||||
}
|
|
@ -5,412 +5,519 @@
|
|||
namespace Keyboard
|
||||
{
|
||||
|
||||
static Key scs2_to_key_altgr[0xFF]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
constexpr Key scan_code_to_key_extended[0xFF]
|
||||
{
|
||||
Key::INVALID,
|
||||
Key::F9,
|
||||
Key::INVALID,
|
||||
Key::F5,
|
||||
Key::F3,
|
||||
Key::F1,
|
||||
Key::F2,
|
||||
Key::F12,
|
||||
Key::INVALID,
|
||||
Key::F10,
|
||||
Key::F8,
|
||||
Key::F6,
|
||||
Key::F4,
|
||||
Key::Tab,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Alt,
|
||||
Key::LeftShift,
|
||||
Key::INVALID,
|
||||
Key::Ctrl,
|
||||
Key::Q,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::PreviousTrack,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::NextTrack,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::NumpadEnter,
|
||||
Key::RightCtrl,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Mute,
|
||||
Key::Calculator,
|
||||
Key::PlayPause,
|
||||
Key::INVALID,
|
||||
Key::Stop,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::VolumeDown,
|
||||
Key::INVALID,
|
||||
Key::VolumeUp,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::NumpadDiv,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::RightAlt,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Home,
|
||||
Key::Up,
|
||||
Key::PageUp,
|
||||
Key::INVALID,
|
||||
Key::Left,
|
||||
Key::INVALID,
|
||||
Key::Right,
|
||||
Key::INVALID,
|
||||
Key::End,
|
||||
Key::Down,
|
||||
Key::PageDown,
|
||||
Key::Insert,
|
||||
Key::Delete,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Super,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
};
|
||||
|
||||
constexpr Key scan_code_to_key_altgr[0xFF]
|
||||
{
|
||||
Key::INVALID,
|
||||
Key::Escape,
|
||||
Key::None,
|
||||
Key::At,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Pound,
|
||||
Key::Dollar,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::OpenBracket,
|
||||
Key::OpenBrace,
|
||||
Key::CloseBrace,
|
||||
Key::CloseBracket,
|
||||
Key::BackSlash,
|
||||
Key::BackTick,
|
||||
Key::Backspace,
|
||||
Key::Tab,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::Euro,
|
||||
Key::Dollar,
|
||||
Key::Pound,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Space,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::OpenBrace,
|
||||
Key::OpenBracket,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::CloseBrace,
|
||||
Key::CloseBracket,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::BackSlash,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::CapsLock,
|
||||
Key::RightShift,
|
||||
Key::Enter,
|
||||
Key::Tilde,
|
||||
Key::INVALID,
|
||||
Key::Enter,
|
||||
Key::LeftCtrl,
|
||||
Key::None,
|
||||
Key::INVALID,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::LeftShift,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::RightShift,
|
||||
Key::NumpadMult,
|
||||
Key::LeftAlt,
|
||||
Key::Space,
|
||||
Key::CapsLock,
|
||||
Key::F1,
|
||||
Key::F2,
|
||||
Key::F3,
|
||||
Key::F4,
|
||||
Key::F5,
|
||||
Key::F6,
|
||||
Key::F7,
|
||||
Key::F8,
|
||||
Key::F9,
|
||||
Key::F10,
|
||||
Key::NumLock,
|
||||
Key::ScrollLock,
|
||||
Key::Numpad7,
|
||||
Key::Numpad8,
|
||||
Key::Numpad9,
|
||||
Key::NumpadMinus,
|
||||
Key::Numpad4,
|
||||
Key::Numpad5,
|
||||
Key::Numpad6,
|
||||
Key::NumpadPlus,
|
||||
Key::Numpad1,
|
||||
Key::Numpad2,
|
||||
Key::Numpad3,
|
||||
Key::Numpad0,
|
||||
Key::NumpadSep,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Pipe,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Backspace,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Numpad1,
|
||||
Key::INVALID,
|
||||
Key::Numpad4,
|
||||
Key::Numpad7,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Numpad0,
|
||||
Key::NumpadComma,
|
||||
Key::Numpad2,
|
||||
Key::Numpad5,
|
||||
Key::Numpad6,
|
||||
Key::Numpad8,
|
||||
Key::Escape,
|
||||
Key::NumLock,
|
||||
Key::F11,
|
||||
Key::NumpadPlus,
|
||||
Key::Numpad3,
|
||||
Key::NumpadMinus,
|
||||
Key::NumpadMult,
|
||||
Key::Numpad9,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::F7,
|
||||
Key::F12,
|
||||
};
|
||||
|
||||
static Key scs2_to_key_shift[0xFF]
|
||||
constexpr Key scan_code_to_key_shift[0xFF]
|
||||
{
|
||||
Key::INVALID,
|
||||
Key::F9,
|
||||
Key::INVALID,
|
||||
Key::F5,
|
||||
Key::F3,
|
||||
Key::F1,
|
||||
Key::F2,
|
||||
Key::F12,
|
||||
Key::INVALID,
|
||||
Key::F10,
|
||||
Key::F8,
|
||||
Key::F6,
|
||||
Key::F4,
|
||||
Key::Tab,
|
||||
Key::Half,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Alt,
|
||||
Key::LeftShift,
|
||||
Key::INVALID,
|
||||
Key::Ctrl,
|
||||
Key::Q,
|
||||
Key::Escape,
|
||||
Key::ExclamationMark,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Z,
|
||||
Key::S,
|
||||
Key::A,
|
||||
Key::W,
|
||||
Key::DoubleQuote,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::C,
|
||||
Key::X,
|
||||
Key::D,
|
||||
Key::E,
|
||||
Key::Currency,
|
||||
Key::Hashtag,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Space,
|
||||
Key::V,
|
||||
Key::F,
|
||||
Key::T,
|
||||
Key::R,
|
||||
Key::Currency,
|
||||
Key::Percent,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::N,
|
||||
Key::B,
|
||||
Key::H,
|
||||
Key::G,
|
||||
Key::Y,
|
||||
Key::Ampersand,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::M,
|
||||
Key::J,
|
||||
Key::U,
|
||||
Key::Slash,
|
||||
Key::OpenParen,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Semicolon,
|
||||
Key::K,
|
||||
Key::CloseParen,
|
||||
Key::Equals,
|
||||
Key::QuestionMark,
|
||||
Key::BackTick,
|
||||
Key::Backspace,
|
||||
Key::Tab,
|
||||
Key::Q,
|
||||
Key::W,
|
||||
Key::E,
|
||||
Key::R,
|
||||
Key::T,
|
||||
Key::Y,
|
||||
Key::U,
|
||||
Key::I,
|
||||
Key::O,
|
||||
Key::Equals,
|
||||
Key::CloseParen,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Colon,
|
||||
Key::Underscore,
|
||||
Key::P,
|
||||
Key::A_Dot,
|
||||
Key::Caret,
|
||||
Key::Enter,
|
||||
Key::LeftCtrl,
|
||||
Key::A,
|
||||
Key::S,
|
||||
Key::D,
|
||||
Key::F,
|
||||
Key::G,
|
||||
Key::H,
|
||||
Key::J,
|
||||
Key::K,
|
||||
Key::L,
|
||||
Key::O_Dots,
|
||||
Key::P,
|
||||
Key::QuestionMark,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::A_Dots,
|
||||
Key::INVALID,
|
||||
Key::A_Dot,
|
||||
Key::BackTick,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::CapsLock,
|
||||
Key::RightShift,
|
||||
Key::Enter,
|
||||
Key::Caret,
|
||||
Key::INVALID,
|
||||
Key::Half,
|
||||
Key::LeftShift,
|
||||
Key::Asterix,
|
||||
Key::INVALID,
|
||||
Key::Z,
|
||||
Key::X,
|
||||
Key::C,
|
||||
Key::V,
|
||||
Key::B,
|
||||
Key::N,
|
||||
Key::M,
|
||||
Key::Semicolon,
|
||||
Key::Colon,
|
||||
Key::Underscore,
|
||||
Key::RightShift,
|
||||
Key::NumpadMult,
|
||||
Key::LeftAlt,
|
||||
Key::Space,
|
||||
Key::CapsLock,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::None,
|
||||
Key::NumLock,
|
||||
Key::ScrollLock,
|
||||
Key::Home,
|
||||
Key::Up,
|
||||
Key::PageUp,
|
||||
Key::NumpadMinus,
|
||||
Key::Left,
|
||||
Key::None,
|
||||
Key::Right,
|
||||
Key::NumpadPlus,
|
||||
Key::End,
|
||||
Key::Down,
|
||||
Key::PageDown,
|
||||
Key::Insert,
|
||||
Key::Delete,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::MoreThan,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Backspace,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::End,
|
||||
Key::INVALID,
|
||||
Key::Left,
|
||||
Key::Right,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Insert,
|
||||
Key::Delete,
|
||||
Key::Down,
|
||||
Key::None,
|
||||
Key::Right,
|
||||
Key::Up,
|
||||
Key::Escape,
|
||||
Key::NumLock,
|
||||
Key::F11,
|
||||
Key::NumpadPlus,
|
||||
Key::PageDown,
|
||||
Key::NumpadMinus,
|
||||
Key::NumpadMult,
|
||||
Key::PageUp,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::F7,
|
||||
Key::None,
|
||||
};
|
||||
|
||||
static Key scs2_to_key[0xFF]
|
||||
constexpr Key scan_code_to_key_normal[0xFF]
|
||||
{
|
||||
Key::INVALID,
|
||||
Key::F9,
|
||||
Key::INVALID,
|
||||
Key::F5,
|
||||
Key::F3,
|
||||
Key::F1,
|
||||
Key::F2,
|
||||
Key::F12,
|
||||
Key::INVALID,
|
||||
Key::F10,
|
||||
Key::F8,
|
||||
Key::F6,
|
||||
Key::F4,
|
||||
Key::Tab,
|
||||
Key::Section,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Alt,
|
||||
Key::LeftShift,
|
||||
Key::INVALID,
|
||||
Key::Ctrl,
|
||||
Key::Q,
|
||||
Key::Escape,
|
||||
Key::_1,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Z,
|
||||
Key::S,
|
||||
Key::A,
|
||||
Key::W,
|
||||
Key::_2,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::C,
|
||||
Key::X,
|
||||
Key::D,
|
||||
Key::E,
|
||||
Key::_4,
|
||||
Key::_3,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Space,
|
||||
Key::V,
|
||||
Key::F,
|
||||
Key::T,
|
||||
Key::R,
|
||||
Key::_4,
|
||||
Key::_5,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::N,
|
||||
Key::B,
|
||||
Key::H,
|
||||
Key::G,
|
||||
Key::Y,
|
||||
Key::_6,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::M,
|
||||
Key::J,
|
||||
Key::U,
|
||||
Key::_7,
|
||||
Key::_8,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Comma,
|
||||
Key::K,
|
||||
Key::_9,
|
||||
Key::_0,
|
||||
Key::Plus,
|
||||
Key::Tick,
|
||||
Key::Backspace,
|
||||
Key::Tab,
|
||||
Key::Q,
|
||||
Key::W,
|
||||
Key::E,
|
||||
Key::R,
|
||||
Key::T,
|
||||
Key::Y,
|
||||
Key::U,
|
||||
Key::I,
|
||||
Key::O,
|
||||
Key::_0,
|
||||
Key::_9,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Period,
|
||||
Key::Hyphen,
|
||||
Key::P,
|
||||
Key::A_Dot,
|
||||
Key::Caret,
|
||||
Key::Enter,
|
||||
Key::LeftCtrl,
|
||||
Key::A,
|
||||
Key::S,
|
||||
Key::D,
|
||||
Key::F,
|
||||
Key::G,
|
||||
Key::H,
|
||||
Key::J,
|
||||
Key::K,
|
||||
Key::L,
|
||||
Key::O_Dots,
|
||||
Key::P,
|
||||
Key::Plus,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::A_Dots,
|
||||
Key::INVALID,
|
||||
Key::A_Dot,
|
||||
Key::Tick,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::CapsLock,
|
||||
Key::RightShift,
|
||||
Key::Enter,
|
||||
Key::Caret,
|
||||
Key::INVALID,
|
||||
Key::Section,
|
||||
Key::LeftShift,
|
||||
Key::SingleQuote,
|
||||
Key::INVALID,
|
||||
Key::Z,
|
||||
Key::X,
|
||||
Key::C,
|
||||
Key::V,
|
||||
Key::B,
|
||||
Key::N,
|
||||
Key::M,
|
||||
Key::Comma,
|
||||
Key::Period,
|
||||
Key::Hyphen,
|
||||
Key::RightShift,
|
||||
Key::NumpadMult,
|
||||
Key::LeftAlt,
|
||||
Key::Space,
|
||||
Key::CapsLock,
|
||||
Key::F1,
|
||||
Key::F2,
|
||||
Key::F3,
|
||||
Key::F4,
|
||||
Key::F5,
|
||||
Key::F6,
|
||||
Key::F7,
|
||||
Key::F8,
|
||||
Key::F9,
|
||||
Key::F10,
|
||||
Key::NumLock,
|
||||
Key::ScrollLock,
|
||||
Key::Numpad7,
|
||||
Key::Numpad8,
|
||||
Key::Numpad9,
|
||||
Key::NumpadMinus,
|
||||
Key::Numpad4,
|
||||
Key::Numpad5,
|
||||
Key::Numpad6,
|
||||
Key::NumpadPlus,
|
||||
Key::Numpad1,
|
||||
Key::Numpad2,
|
||||
Key::Numpad3,
|
||||
Key::Numpad0,
|
||||
Key::NumpadSep,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::LessThan,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Backspace,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Numpad1,
|
||||
Key::INVALID,
|
||||
Key::Numpad4,
|
||||
Key::Numpad7,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::Numpad0,
|
||||
Key::NumpadComma,
|
||||
Key::Numpad2,
|
||||
Key::Numpad5,
|
||||
Key::Numpad6,
|
||||
Key::Numpad8,
|
||||
Key::Escape,
|
||||
Key::NumLock,
|
||||
Key::F11,
|
||||
Key::NumpadPlus,
|
||||
Key::Numpad3,
|
||||
Key::NumpadMinus,
|
||||
Key::NumpadMult,
|
||||
Key::Numpad9,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::INVALID,
|
||||
Key::F7,
|
||||
Key::F12,
|
||||
};
|
||||
|
||||
}
|
|
@ -1,50 +1,89 @@
|
|||
#include <kernel/IDT.h>
|
||||
#include <kernel/IO.h>
|
||||
#include <kernel/Keyboard.h>
|
||||
#include <kernel/PIC.h>
|
||||
#include <kernel/kprint.h>
|
||||
#include <kernel/PIC.h>
|
||||
#include <kernel/PIT.h>
|
||||
#include <kernel/Queue.h>
|
||||
#include <kernel/Serial.h>
|
||||
|
||||
#include <kernel/KeyboardLayout/FI.h>
|
||||
|
||||
#define I8042_DATA_PORT 0x60
|
||||
#define I8042_STATUS_REGISTER 0x64
|
||||
#define I8042_COMMAND_REGISTER 0x64
|
||||
#define KB_DEBUG_PRINT 1
|
||||
|
||||
#define I8042_READ_BYTE0 0x20
|
||||
#define I8042_WRITE_BYTE0 0x60
|
||||
#define I8042_DATA_PORT 0x60
|
||||
#define I8042_STATUS_REGISTER 0x64
|
||||
#define I8042_COMMAND_REGISTER 0x64
|
||||
|
||||
#define I8042_ENABLE_FIRST 0xAE
|
||||
#define I8042_ENABLE_SECOND 0xA8
|
||||
#define I8042_DISABLE_FIRST 0xAD
|
||||
#define I8042_DISABLE_SECOND 0xA7
|
||||
#define I8042_STATUS_OUT_FULL (1 << 0)
|
||||
#define I8042_STATUS_IN_FULL (1 << 1)
|
||||
|
||||
#define I8042_TEST_CONTROLLER 0xAA
|
||||
#define I8042_CONTROLLER_TEST_PASS 0x55
|
||||
#define I8042_READ_CONFIG 0x20
|
||||
#define I8042_WRITE_CONFIG 0x60
|
||||
|
||||
#define I8042_TEST_FIRST_PORT 0xAB
|
||||
#define I8042_FIRST_PORT_TEST_PASS 0x00
|
||||
#define I8042_CONFING_IRQ_FIRST (1 << 0)
|
||||
#define I8042_CONFING_IRQ_SECOND (1 << 1)
|
||||
#define I8042_CONFING_TRANSLATION (1 << 6)
|
||||
|
||||
#define I8042_TEST_SECOND 0xA9
|
||||
#define I8042_SECOND_PORT_TEST_PASS 0x00
|
||||
#define I8042_ENABLE_FIRST 0xAE
|
||||
#define I8042_ENABLE_SECOND 0xA8
|
||||
#define I8042_DISABLE_FIRST 0xAD
|
||||
#define I8042_DISABLE_SECOND 0xA7
|
||||
|
||||
#define I8042_ACK 0xfa
|
||||
#define I8042_TEST_CONTROLLER 0xAA
|
||||
#define I8042_TEST_CONTROLLER_PASS 0x55
|
||||
|
||||
#define KEYBOARD_IRQ 0x01
|
||||
#define I8042_TEST_FIRST_PORT 0xAB
|
||||
#define I8042_TEST_FIRST_PORT_PASS 0x00
|
||||
|
||||
#define MOD_ALT 0b0001
|
||||
#define MOD_CTRL 0b0010
|
||||
#define MOD_SHIFT 0b0100
|
||||
#define MOD_ALTGR 0b1000
|
||||
#define I8042_TEST_SECOND_PORT 0xA9
|
||||
#define I8042_TEST_SECOND_PORT_PASS 0x00
|
||||
|
||||
#define KEYBOARD_FI
|
||||
#define I8042_KB_ACK 0xFA
|
||||
#define I8042_KB_RESEND 0xFE
|
||||
#define I8042_KB_RESET 0xFF
|
||||
#define I8042_KB_SELF_TEST_PASS 0xAA
|
||||
#define I8042_KB_SET_SCAN_CODE_SET 0xF0
|
||||
#define I8042_KB_SET_LEDS 0xED
|
||||
#define I8042_KB_TIMEOUT_MS 1000
|
||||
#define I8042_KB_LED_SCROLL_LOCK (1 << 0)
|
||||
#define I8042_KB_LED_NUM_LOCK (1 << 1)
|
||||
#define I8042_KB_LED_CAPS_LOCK (1 << 2)
|
||||
|
||||
#define KEYBOARD_IRQ 0x01
|
||||
|
||||
#define MOD_ALT (1 << 0)
|
||||
#define MOD_CTRL (1 << 1)
|
||||
#define MOD_SHIFT (1 << 2)
|
||||
#define MOD_ALTGR (1 << 3)
|
||||
#define MOD_CAPS (1 << 4)
|
||||
|
||||
namespace Keyboard
|
||||
{
|
||||
|
||||
static bool s_keyboard_state[0xFF] = {};
|
||||
static uint8_t s_modifiers = 0;
|
||||
|
||||
static void (*s_key_callback)(Key, uint8_t, bool) = nullptr;
|
||||
struct Command
|
||||
{
|
||||
uint8_t command = 0;
|
||||
uint8_t data = 0;
|
||||
bool has_data = false;
|
||||
bool extra = false;
|
||||
uint8_t _sent = 0;
|
||||
uint8_t _ack = 0;
|
||||
bool _done = false;
|
||||
};
|
||||
static Queue<Command> s_keyboard_command_queue;
|
||||
static uint8_t s_keyboard_command_extra = 0x00;
|
||||
|
||||
static Queue<KeyEvent> s_key_event_queue;
|
||||
static uint8_t s_keyboard_key_buffer[10] = {};
|
||||
static uint8_t s_keyboard_key_buffer_size = 0;
|
||||
|
||||
static uint8_t s_led_states = 0b000;
|
||||
static uint8_t s_modifiers = 0x00;
|
||||
|
||||
static void (*s_key_callback)(KeyEvent) = nullptr;
|
||||
|
||||
static char s_key_to_char[]
|
||||
{
|
||||
|
@ -59,110 +98,263 @@ namespace Keyboard
|
|||
'$', '\0', '\0', '\0', '\n', ' ', '\t', '\b', '<', '>', '\0', '`', '\0', '\0', '@', '|',
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
',', '+', '*', '/', '-',
|
||||
',', '+', '*', '/', '-', '\n',
|
||||
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
|
||||
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
};
|
||||
static_assert(sizeof(s_key_to_char) == static_cast<int>(Key::Count));
|
||||
|
||||
static uint8_t kb_read()
|
||||
static uint8_t wait_and_read()
|
||||
{
|
||||
while (!(IO::inb(I8042_STATUS_REGISTER) & 0x01))
|
||||
while ((IO::inb(I8042_STATUS_REGISTER) & I8042_STATUS_OUT_FULL) == 0)
|
||||
continue;
|
||||
return IO::inb(I8042_DATA_PORT);
|
||||
}
|
||||
|
||||
static bool kb_try_read(uint8_t& out)
|
||||
static void i8042_controller_command(uint8_t command)
|
||||
{
|
||||
if (IO::inb(I8042_STATUS_REGISTER) & 0x01)
|
||||
{
|
||||
out = IO::inb(I8042_DATA_PORT);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void kb_command(uint8_t command)
|
||||
{
|
||||
IO::io_wait();
|
||||
IO::outb(I8042_COMMAND_REGISTER, command);
|
||||
}
|
||||
|
||||
static void kb_command(uint8_t command, uint8_t data)
|
||||
static void i8042_controller_command(uint8_t command, uint8_t data)
|
||||
{
|
||||
IO::io_wait();
|
||||
IO::outb(I8042_COMMAND_REGISTER, command);
|
||||
IO::io_wait();
|
||||
while ((IO::inb(I8042_STATUS_REGISTER) & I8042_STATUS_IN_FULL) != 0)
|
||||
continue;
|
||||
IO::outb(I8042_DATA_PORT, data);
|
||||
}
|
||||
|
||||
void irq_handler()
|
||||
static bool i8042_keyboard_command(uint8_t command)
|
||||
{
|
||||
uint8_t ch;
|
||||
while (kb_try_read(ch))
|
||||
auto timeout = PIT::ms_since_boot() + I8042_KB_TIMEOUT_MS;
|
||||
|
||||
while (PIT::ms_since_boot() < timeout)
|
||||
{
|
||||
bool multimedia = false, pressed = true;
|
||||
|
||||
if (ch == 0xE0)
|
||||
if ((IO::inb(I8042_STATUS_REGISTER) & I8042_STATUS_IN_FULL) == 0)
|
||||
{
|
||||
multimedia = true;
|
||||
ch = kb_read();
|
||||
IO::outb(I8042_DATA_PORT, command);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void update_keyboard()
|
||||
{
|
||||
if (!s_keyboard_command_queue.Empty())
|
||||
{
|
||||
auto& command = s_keyboard_command_queue.Front();
|
||||
|
||||
if (command._sent == 0 && command._ack == 0)
|
||||
{
|
||||
if (!i8042_keyboard_command(command.command))
|
||||
Kernel::panic("oof 1");
|
||||
command._sent++;
|
||||
}
|
||||
|
||||
if (ch == 0xF0)
|
||||
if (command._sent == 1 && command._ack == 1 && command.has_data)
|
||||
{
|
||||
pressed = false;
|
||||
ch = kb_read();
|
||||
if (!i8042_keyboard_command(command.data))
|
||||
Kernel::panic("oof 2");
|
||||
command._sent++;
|
||||
}
|
||||
|
||||
// TODO: Handle multimedia keys
|
||||
if (multimedia)
|
||||
if (command._done)
|
||||
{
|
||||
if (ch == 17)
|
||||
pressed ? (s_modifiers |= MOD_ALTGR) : (s_modifiers &= ~MOD_ALTGR);
|
||||
if (pressed && false)
|
||||
kprint("<M{}>", ch);
|
||||
continue;
|
||||
switch (command.command)
|
||||
{
|
||||
case I8042_KB_RESET:
|
||||
if (s_keyboard_command_extra != I8042_KB_SELF_TEST_PASS)
|
||||
Kernel::panic("PS/2 Keyboard self test failed");
|
||||
break;
|
||||
case I8042_KB_SET_SCAN_CODE_SET:
|
||||
break;
|
||||
case I8042_KB_SET_LEDS:
|
||||
break;
|
||||
}
|
||||
s_keyboard_command_queue.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
s_keyboard_state[ch] = pressed;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case 17:
|
||||
pressed ? (s_modifiers |= MOD_ALT) : (s_modifiers &= ~MOD_ALT);
|
||||
break;
|
||||
case 18:
|
||||
case 89:
|
||||
pressed ? (s_modifiers |= MOD_SHIFT) : (s_modifiers &= ~MOD_SHIFT);
|
||||
break;
|
||||
case 20:
|
||||
pressed ? (s_modifiers |= MOD_CTRL) : (s_modifiers &= ~MOD_CTRL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Key key;
|
||||
if (s_modifiers & MOD_ALTGR)
|
||||
key = scs2_to_key_altgr[ch];
|
||||
else if (s_modifiers & MOD_SHIFT)
|
||||
key = scs2_to_key_shift[ch];
|
||||
else
|
||||
key = scs2_to_key[ch];
|
||||
|
||||
// Debug print for unregistered keys
|
||||
if (key == Key::INVALID && pressed)
|
||||
kprint("<{}>", ch);
|
||||
|
||||
s_key_callback(key, s_modifiers, pressed);
|
||||
while (!s_key_event_queue.Empty())
|
||||
{
|
||||
s_key_callback(s_key_event_queue.Front());
|
||||
s_key_event_queue.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
void initialize(void (*callback)(Key, uint8_t, bool))
|
||||
static void keyboard_new_key()
|
||||
{
|
||||
uint8_t index = 0;
|
||||
bool extended = (s_keyboard_key_buffer[index] == 0xE0);
|
||||
if (extended)
|
||||
index++;
|
||||
|
||||
bool pressed = (s_keyboard_key_buffer[index] & 0x80) == 0;
|
||||
uint8_t ch = s_keyboard_key_buffer[index] & ~0x80;
|
||||
|
||||
Key key = Key::INVALID;
|
||||
|
||||
if (extended)
|
||||
{
|
||||
key = scan_code_to_key_extended[ch];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s_modifiers & MOD_SHIFT)
|
||||
key = scan_code_to_key_shift[ch];
|
||||
else if (s_modifiers & MOD_ALTGR)
|
||||
key = scan_code_to_key_altgr[ch];
|
||||
else
|
||||
key = scan_code_to_key_normal[ch];
|
||||
}
|
||||
|
||||
if ((s_led_states & I8042_KB_LED_NUM_LOCK))
|
||||
{
|
||||
switch (key)
|
||||
{
|
||||
case Key::Numpad0: key = Key::Insert; break;
|
||||
case Key::Numpad1: key = Key::End; break;
|
||||
case Key::Numpad2: key = Key::Down; break;
|
||||
case Key::Numpad3: key = Key::PageDown; break;
|
||||
case Key::Numpad4: key = Key::Left; break;
|
||||
case Key::Numpad5: key = Key::None; break;
|
||||
case Key::Numpad6: key = Key::Right; break;
|
||||
case Key::Numpad7: key = Key::Home; break;
|
||||
case Key::Numpad8: key = Key::Up; break;
|
||||
case Key::Numpad9: key = Key::PageUp; break;
|
||||
case Key::NumpadSep: key = Key::Delete; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if KB_DEBUG_PRINT
|
||||
if (key == Key::INVALID)
|
||||
kprintln("{} {}", ch, extended ? 'E' : ' ');
|
||||
#endif
|
||||
|
||||
s_keyboard_state[static_cast<int>(key)] = pressed;
|
||||
|
||||
bool update_leds = false;
|
||||
switch (key)
|
||||
{
|
||||
case Key::ScrollLock:
|
||||
update_leds = pressed;
|
||||
if (update_leds)
|
||||
s_led_states ^= I8042_KB_LED_SCROLL_LOCK;
|
||||
break;
|
||||
case Key::NumLock:
|
||||
update_leds = pressed;
|
||||
if (update_leds)
|
||||
s_led_states ^= I8042_KB_LED_NUM_LOCK;
|
||||
break;
|
||||
case Key::CapsLock:
|
||||
update_leds = pressed;
|
||||
if (update_leds)
|
||||
s_led_states ^= I8042_KB_LED_CAPS_LOCK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (update_leds)
|
||||
{
|
||||
s_keyboard_command_queue.Push({
|
||||
.command = I8042_KB_SET_LEDS,
|
||||
.data = s_led_states,
|
||||
.has_data = true,
|
||||
});
|
||||
}
|
||||
|
||||
uint8_t modifiers = 0;
|
||||
if (s_keyboard_state[(int)Key::LeftShift] || s_keyboard_state[(int)Key::RightShift])
|
||||
modifiers |= MOD_SHIFT;
|
||||
if (s_keyboard_state[(int)Key::LeftCtrl] || s_keyboard_state[(int)Key::RightCtrl])
|
||||
modifiers |= MOD_CTRL;
|
||||
if (s_keyboard_state[(int)Key::LeftAlt])
|
||||
modifiers |= MOD_ALT;
|
||||
if (s_keyboard_state[(int)Key::RightAlt])
|
||||
modifiers |= MOD_ALTGR;
|
||||
if (s_led_states & I8042_KB_LED_CAPS_LOCK)
|
||||
modifiers |= MOD_CAPS;
|
||||
s_modifiers = modifiers;
|
||||
|
||||
if (key != Key::INVALID)
|
||||
{
|
||||
auto error_or = s_key_event_queue.Push({ .key = key, .modifiers = modifiers, .pressed = pressed });
|
||||
if (error_or.HasError())
|
||||
dprintln("PS/2 Keyboard: {}", error_or.GetError().message);
|
||||
}
|
||||
s_keyboard_key_buffer_size -= index + 1;
|
||||
memmove(s_keyboard_key_buffer, s_keyboard_key_buffer + index, s_keyboard_key_buffer_size);
|
||||
}
|
||||
|
||||
void keyboard_irq_handler()
|
||||
{
|
||||
uint8_t raw = IO::inb(I8042_DATA_PORT);
|
||||
|
||||
bool command_waiting = false;
|
||||
if (!s_keyboard_command_queue.Empty())
|
||||
{
|
||||
auto& command = s_keyboard_command_queue.Front();
|
||||
command_waiting = (command._sent > 0 && !command._done);
|
||||
}
|
||||
|
||||
if (command_waiting)
|
||||
{
|
||||
auto& command = s_keyboard_command_queue.Front();
|
||||
if (raw == I8042_KB_RESEND)
|
||||
{
|
||||
dprintln("PS/2 Keyboard: Resend 0x{H}", command._sent == 2 ? command.data : command.command);
|
||||
command._sent--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (raw == I8042_KB_ACK)
|
||||
{
|
||||
command._ack++;
|
||||
if (command.extra > 0)
|
||||
return;
|
||||
command._done = command.has_data ? (command._ack == 2) : true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (raw == 0x00)
|
||||
{
|
||||
dprintln("\e[33mKey detection error or internal buffer overrun\e[m");
|
||||
command._sent = 0;
|
||||
command._ack = 0;
|
||||
command._done = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (raw == 0xEE && command.command == 0xEE)
|
||||
{
|
||||
s_keyboard_command_queue.Pop();
|
||||
return;
|
||||
}
|
||||
|
||||
s_keyboard_command_extra = raw;
|
||||
command._done = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_keyboard_key_buffer[s_keyboard_key_buffer_size++] = raw;
|
||||
if (raw != 0xE0)
|
||||
keyboard_new_key();
|
||||
}
|
||||
}
|
||||
|
||||
bool initialize(void (*callback)(KeyEvent))
|
||||
{
|
||||
// https://wiki.osdev.org/%228042%22_PS/2_Controller
|
||||
|
||||
|
@ -175,74 +367,102 @@ namespace Keyboard
|
|||
// TODO
|
||||
|
||||
// Step 3: Disable Devices
|
||||
kb_command(I8042_DISABLE_FIRST);
|
||||
kb_command(I8042_DISABLE_SECOND);
|
||||
i8042_controller_command(I8042_DISABLE_FIRST);
|
||||
i8042_controller_command(I8042_DISABLE_SECOND);
|
||||
|
||||
// Step 4: Flush The Ouput Buffer
|
||||
uint8_t tmp;
|
||||
while(kb_try_read(tmp))
|
||||
continue;
|
||||
while ((IO::inb(I8042_STATUS_REGISTER) & I8042_STATUS_OUT_FULL) != 0)
|
||||
IO::inb(I8042_DATA_PORT);
|
||||
|
||||
// Step 5: Set the Controller Configuration Byte
|
||||
kb_command(I8042_READ_BYTE0);
|
||||
uint8_t conf = kb_read();
|
||||
conf &= 0b10111100;
|
||||
kb_command(I8042_WRITE_BYTE0, conf);
|
||||
i8042_controller_command(I8042_READ_CONFIG);
|
||||
uint8_t config = wait_and_read();
|
||||
config &= ~(I8042_CONFING_IRQ_FIRST | I8042_CONFING_IRQ_SECOND);
|
||||
i8042_controller_command(I8042_WRITE_CONFIG, config);
|
||||
|
||||
// Step 6: Perform Controller Self Test
|
||||
kb_command(I8042_TEST_CONTROLLER);
|
||||
uint8_t resp = kb_read();
|
||||
if (resp != I8042_CONTROLLER_TEST_PASS)
|
||||
i8042_controller_command(I8042_TEST_CONTROLLER);
|
||||
if (wait_and_read() != I8042_TEST_CONTROLLER_PASS)
|
||||
{
|
||||
kprint("ERROR: PS/2 self test failed\n");
|
||||
return;
|
||||
kprintln("\e[33mERROR: PS/2 controller self test failed\e[m");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 7: Determine If There Are 2 Channels
|
||||
|
||||
// Step 8: Perform Interface Tests
|
||||
kb_command(I8042_TEST_FIRST_PORT);
|
||||
resp = kb_read();
|
||||
if (resp != I8042_FIRST_PORT_TEST_PASS)
|
||||
i8042_controller_command(I8042_TEST_FIRST_PORT);
|
||||
if (wait_and_read() != I8042_TEST_FIRST_PORT_PASS)
|
||||
{
|
||||
kprint("ERROR: PS/2 interface test failed\n");
|
||||
return;
|
||||
kprintln("\e[33mERROR: PS/2 first port test failed\e[m");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Step 9: Enable Devices
|
||||
kb_command(I8042_WRITE_BYTE0, conf | 0x01); // enable IRQs
|
||||
kb_command(I8042_ENABLE_FIRST);
|
||||
config |= I8042_CONFING_IRQ_FIRST;
|
||||
i8042_controller_command(I8042_WRITE_CONFIG, config);
|
||||
i8042_controller_command(I8042_ENABLE_FIRST);
|
||||
|
||||
// Step 10: Reset Devices
|
||||
/* TODO: doesnt seem to respond
|
||||
kb_command(0xFF);
|
||||
resp = kb_read();
|
||||
if (resp != PS2_ACK)
|
||||
{
|
||||
kprint("ERROR: PS/2 could not restart devices\n");
|
||||
return;
|
||||
}
|
||||
*/
|
||||
MUST(s_keyboard_command_queue.Push({
|
||||
.command = I8042_KB_RESET,
|
||||
.extra = true,
|
||||
}));
|
||||
|
||||
// Set scan code set 2
|
||||
MUST(s_keyboard_command_queue.Push({
|
||||
.command = I8042_KB_SET_SCAN_CODE_SET,
|
||||
.data = 0x02,
|
||||
.has_data = true,
|
||||
}));
|
||||
|
||||
// Turn LEDs off
|
||||
MUST(s_keyboard_command_queue.Push({
|
||||
.command = I8042_KB_SET_LEDS,
|
||||
.data = s_led_states,
|
||||
.has_data = true,
|
||||
}));
|
||||
|
||||
// Register callback and IRQ
|
||||
s_key_callback = callback;
|
||||
IDT::register_irq_handler(KEYBOARD_IRQ, irq_handler);
|
||||
IDT::register_irq_handler(KEYBOARD_IRQ, keyboard_irq_handler);
|
||||
PIC::unmask(KEYBOARD_IRQ);
|
||||
|
||||
kb_command(0xED, 0b111);
|
||||
IO::io_wait();
|
||||
while (kb_try_read(tmp));
|
||||
return true;
|
||||
}
|
||||
|
||||
char key_to_ascii(Key key, uint8_t modifiers)
|
||||
char key_event_to_ascii(KeyEvent event)
|
||||
{
|
||||
char res = s_key_to_char[static_cast<uint8_t>(key)];
|
||||
char res = s_key_to_char[static_cast<uint8_t>(event.key)];
|
||||
|
||||
if (!(modifiers & MOD_SHIFT))
|
||||
if (!(event.modifiers & (MOD_SHIFT | MOD_CAPS)))
|
||||
if (res >= 'A' && res <= 'Z')
|
||||
res = res - 'A' + 'a';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void led_disco()
|
||||
{
|
||||
uint64_t time = PIT::ms_since_boot();
|
||||
uint64_t freq = 100;
|
||||
bool state = false;
|
||||
for(;;)
|
||||
{
|
||||
if (PIT::ms_since_boot() > time + freq)
|
||||
{
|
||||
time += freq;
|
||||
state = !state;
|
||||
|
||||
MUST(s_keyboard_command_queue.Push({
|
||||
.command = I8042_KB_SET_LEDS,
|
||||
.data = (uint8_t)(state ? 0b111 : 0b000),
|
||||
.has_data = true,
|
||||
}));
|
||||
}
|
||||
|
||||
update_keyboard();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -62,7 +62,8 @@ void kernel_main(multiboot_info_t* mbi, uint32_t magic)
|
|||
IDT::initialize();
|
||||
|
||||
PIT::initialize();
|
||||
Keyboard::initialize(on_key_press);
|
||||
if (!Keyboard::initialize(on_key_press))
|
||||
return;
|
||||
|
||||
auto time = RTC::GetCurrentTime();
|
||||
kprintln("Today is {2}:{2}:{2} {2}.{2}.{4}", time.hour, time.minute, time.second, time.day, time.month, time.year);
|
||||
|
@ -71,8 +72,9 @@ void kernel_main(multiboot_info_t* mbi, uint32_t magic)
|
|||
|
||||
ENABLE_INTERRUPTS();
|
||||
|
||||
|
||||
for (;;)
|
||||
{
|
||||
asm("hlt");
|
||||
Keyboard::update_keyboard();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue