forked from Bananymous/banan-os
Kernel: Properly handle finnish keyboard layout.
You can now type any basic ascii character from keyboard. Multimedia keys are not yet handled.
This commit is contained in:
parent
5ba7af2cf6
commit
817de9f359
|
@ -32,10 +32,10 @@ BUILDDIR=$(abspath build)
|
||||||
KERNEL_OBJS=\
|
KERNEL_OBJS=\
|
||||||
$(KERNEL_ARCH_OBJS) \
|
$(KERNEL_ARCH_OBJS) \
|
||||||
kernel/kernel.o \
|
kernel/kernel.o \
|
||||||
|
kernel/Keyboard.o \
|
||||||
kernel/kmalloc.o \
|
kernel/kmalloc.o \
|
||||||
kernel/PIC.o \
|
kernel/PIC.o \
|
||||||
kernel/PIT.o \
|
kernel/PIT.o \
|
||||||
kernel/PS2.o \
|
|
||||||
kernel/SSP.o \
|
kernel/SSP.o \
|
||||||
|
|
||||||
OBJS=\
|
OBJS=\
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace Keyboard
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class Key : uint8_t
|
||||||
|
{
|
||||||
|
INVALID, None,
|
||||||
|
_0, _1, _2, _3, _4, _5, _6, _7, _8, _9,
|
||||||
|
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,
|
||||||
|
A_Dot, A_Dots, O_Dots,
|
||||||
|
|
||||||
|
Comma, Colon, Period, Semicolon, Hyphen, Underscore, SingleQuote, Asterix, Caret, Tilde,
|
||||||
|
ExclamationMark, QuestionMark, DoubleQuote, Hashtag, Percent, Ampersand, Slash, BackSlash, Plus, Equals,
|
||||||
|
OpenParen, CloseParen, OpenBracket, CloseBracket, OpenBrace, CloseBrace,
|
||||||
|
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,
|
||||||
|
|
||||||
|
Numpad0, Numpad1, Numpad2, Numpad3, Numpad4, Numpad5, Numpad6, Numpad7, Numpad8, Numpad9,
|
||||||
|
NumpadComma, NumpadPlus, NumpadMult, NumpadDiv, NumpadMinus,
|
||||||
|
|
||||||
|
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||||
|
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
void initialize(void (*callback)(Key, uint8_t, bool));
|
||||||
|
|
||||||
|
char key_to_ascii(Key, uint8_t);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,416 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <kernel/Keyboard.h>
|
||||||
|
|
||||||
|
namespace Keyboard
|
||||||
|
{
|
||||||
|
|
||||||
|
static Key scs2_to_key_altgr[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::None,
|
||||||
|
Key::At,
|
||||||
|
Key::INVALID,
|
||||||
|
Key::INVALID,
|
||||||
|
Key::None,
|
||||||
|
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::None,
|
||||||
|
Key::INVALID,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Key scs2_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::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::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::I,
|
||||||
|
Key::O,
|
||||||
|
Key::Equals,
|
||||||
|
Key::CloseParen,
|
||||||
|
Key::INVALID,
|
||||||
|
Key::INVALID,
|
||||||
|
Key::Colon,
|
||||||
|
Key::Underscore,
|
||||||
|
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::Asterix,
|
||||||
|
Key::INVALID,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
static Key scs2_to_key[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::_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::_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::I,
|
||||||
|
Key::O,
|
||||||
|
Key::_0,
|
||||||
|
Key::_9,
|
||||||
|
Key::INVALID,
|
||||||
|
Key::INVALID,
|
||||||
|
Key::Period,
|
||||||
|
Key::Hyphen,
|
||||||
|
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::SingleQuote,
|
||||||
|
Key::INVALID,
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace PS2
|
|
||||||
{
|
|
||||||
|
|
||||||
void initialize();
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,244 @@
|
||||||
|
#include <kernel/IDT.h>
|
||||||
|
#include <kernel/IO.h>
|
||||||
|
#include <kernel/Keyboard.h>
|
||||||
|
#include <kernel/PIC.h>
|
||||||
|
#include <kernel/kprint.h>
|
||||||
|
|
||||||
|
#include <kernel/KeyboardLayout/FI.h>
|
||||||
|
|
||||||
|
#define I8042_DATA_PORT 0x60
|
||||||
|
#define I8042_STATUS_REGISTER 0x64
|
||||||
|
#define I8042_COMMAND_REGISTER 0x64
|
||||||
|
|
||||||
|
#define I8042_READ_BYTE0 0x20
|
||||||
|
#define I8042_WRITE_BYTE0 0x60
|
||||||
|
|
||||||
|
#define I8042_ENABLE_FIRST 0xAE
|
||||||
|
#define I8042_ENABLE_SECOND 0xA8
|
||||||
|
#define I8042_DISABLE_FIRST 0xAD
|
||||||
|
#define I8042_DISABLE_SECOND 0xA7
|
||||||
|
|
||||||
|
#define I8042_TEST_CONTROLLER 0xAA
|
||||||
|
#define I8042_CONTROLLER_TEST_PASS 0x55
|
||||||
|
|
||||||
|
#define I8042_TEST_FIRST_PORT 0xAB
|
||||||
|
#define I8042_FIRST_PORT_TEST_PASS 0x00
|
||||||
|
|
||||||
|
#define I8042_TEST_SECOND 0xA9
|
||||||
|
#define I8042_SECOND_PORT_TEST_PASS 0x00
|
||||||
|
|
||||||
|
#define I8042_ACK 0xfa
|
||||||
|
|
||||||
|
#define KEYBOARD_IRQ 0x01
|
||||||
|
|
||||||
|
#define MOD_ALT 0b0001
|
||||||
|
#define MOD_CTRL 0b0010
|
||||||
|
#define MOD_SHIFT 0b0100
|
||||||
|
#define MOD_ALTGR 0b1000
|
||||||
|
|
||||||
|
#define KEYBOARD_FI
|
||||||
|
|
||||||
|
namespace Keyboard
|
||||||
|
{
|
||||||
|
|
||||||
|
static bool s_keyboard_state[0xFF] = {};
|
||||||
|
static uint8_t s_modifiers = 0;
|
||||||
|
|
||||||
|
static void (*s_key_callback)(Key, uint8_t, bool) = nullptr;
|
||||||
|
|
||||||
|
static char s_key_to_char[]
|
||||||
|
{
|
||||||
|
'\0', '\0',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'A', 'A', 'O',
|
||||||
|
|
||||||
|
',', ':', '.', ';', '-', '_', '\'', '*', '^', '~',
|
||||||
|
'!', '?', '"', '#', '%', '&', '/', '\\', '+', '=',
|
||||||
|
'(', ')', '[', ']', '{', '}',
|
||||||
|
'$', '\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', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
|
',', '+', '*', '/', '-',
|
||||||
|
|
||||||
|
'\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()
|
||||||
|
{
|
||||||
|
while (!(IO::inb(I8042_STATUS_REGISTER) & 0x01))
|
||||||
|
continue;
|
||||||
|
return IO::inb(I8042_DATA_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool kb_try_read(uint8_t& out)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
IO::io_wait();
|
||||||
|
IO::outb(I8042_COMMAND_REGISTER, command);
|
||||||
|
IO::io_wait();
|
||||||
|
IO::outb(I8042_DATA_PORT, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void irq_handler()
|
||||||
|
{
|
||||||
|
uint8_t ch;
|
||||||
|
while (kb_try_read(ch))
|
||||||
|
{
|
||||||
|
bool multimedia = false, pressed = true;
|
||||||
|
|
||||||
|
if (ch == 0xE0)
|
||||||
|
{
|
||||||
|
multimedia = true;
|
||||||
|
ch = kb_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch == 0xF0)
|
||||||
|
{
|
||||||
|
pressed = false;
|
||||||
|
ch = kb_read();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Handle multimedia keys
|
||||||
|
if (multimedia)
|
||||||
|
{
|
||||||
|
if (ch == 17)
|
||||||
|
pressed ? (s_modifiers |= MOD_ALTGR) : (s_modifiers &= ~MOD_ALTGR);
|
||||||
|
if (pressed && false)
|
||||||
|
kprint("<M{}>", ch);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize(void (*callback)(Key, uint8_t, bool))
|
||||||
|
{
|
||||||
|
// https://wiki.osdev.org/%228042%22_PS/2_Controller
|
||||||
|
|
||||||
|
// TODO: support dual channel
|
||||||
|
|
||||||
|
// Step 1: Initialize USB Controllers
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
// Stem 2: Determine if the PS/2 Controller Exists
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
// Step 3: Disable Devices
|
||||||
|
kb_command(I8042_DISABLE_FIRST);
|
||||||
|
kb_command(I8042_DISABLE_SECOND);
|
||||||
|
|
||||||
|
// Step 4: Flush The Ouput Buffer
|
||||||
|
uint8_t tmp;
|
||||||
|
while(kb_try_read(tmp))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
// Step 6: Perform Controller Self Test
|
||||||
|
kb_command(I8042_TEST_CONTROLLER);
|
||||||
|
uint8_t resp = kb_read();
|
||||||
|
if (resp != I8042_CONTROLLER_TEST_PASS)
|
||||||
|
{
|
||||||
|
kprint("ERROR: PS/2 self test failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
kprint("ERROR: PS/2 interface test failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 9: Enable Devices
|
||||||
|
kb_command(I8042_WRITE_BYTE0, conf | 0x01); // enable IRQs
|
||||||
|
kb_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;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Register callback and IRQ
|
||||||
|
s_key_callback = callback;
|
||||||
|
IDT::register_irq_handler(KEYBOARD_IRQ, irq_handler);
|
||||||
|
PIC::unmask(KEYBOARD_IRQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
char key_to_ascii(Key key, uint8_t modifiers)
|
||||||
|
{
|
||||||
|
char res = s_key_to_char[static_cast<uint8_t>(key)];
|
||||||
|
|
||||||
|
if (!(modifiers & MOD_SHIFT))
|
||||||
|
if (res >= 'A' && res <= 'Z')
|
||||||
|
res = res - 'A' + 'a';
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,361 +0,0 @@
|
||||||
#include <kernel/IDT.h>
|
|
||||||
#include <kernel/IO.h>
|
|
||||||
#include <kernel/PIC.h>
|
|
||||||
#include <kernel/PS2.h>
|
|
||||||
#include <kernel/kprint.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define PS2_DATA_PORT 0x60
|
|
||||||
#define PS2_STATUS_REGISTER 0x64
|
|
||||||
#define PS2_COMMAND_REGISTER 0x64
|
|
||||||
|
|
||||||
#define PS2_ACK 0xfa
|
|
||||||
|
|
||||||
#define PS2_IRQ 0x01
|
|
||||||
|
|
||||||
#define ALT 0
|
|
||||||
#define CTRL 1
|
|
||||||
#define SHIFT 2
|
|
||||||
|
|
||||||
#define KEYBOARD_FI
|
|
||||||
|
|
||||||
namespace PS2
|
|
||||||
{
|
|
||||||
|
|
||||||
static bool s_keyboard_state[0x7f];
|
|
||||||
static uint8_t s_modifiers = 0;
|
|
||||||
|
|
||||||
#ifdef KEYBOARD_FI
|
|
||||||
enum class Key
|
|
||||||
{
|
|
||||||
Key_INVALID,
|
|
||||||
Key_ESC,
|
|
||||||
Key_1,
|
|
||||||
Key_2,
|
|
||||||
Key_3,
|
|
||||||
Key_4,
|
|
||||||
Key_5,
|
|
||||||
Key_6,
|
|
||||||
Key_7,
|
|
||||||
Key_8,
|
|
||||||
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_P,
|
|
||||||
Key_Å,
|
|
||||||
Key_Caret,
|
|
||||||
Key_Enter,
|
|
||||||
Key_Control,
|
|
||||||
Key_A,
|
|
||||||
Key_S,
|
|
||||||
Key_D,
|
|
||||||
Key_F,
|
|
||||||
Key_G,
|
|
||||||
Key_H,
|
|
||||||
Key_J,
|
|
||||||
Key_K,
|
|
||||||
Key_L,
|
|
||||||
Key_Ö,
|
|
||||||
Key_Ä,
|
|
||||||
Key_Section, // §
|
|
||||||
Key_LeftShift,
|
|
||||||
Key_SingleQuote,
|
|
||||||
Key_Z,
|
|
||||||
Key_X,
|
|
||||||
Key_C,
|
|
||||||
Key_V,
|
|
||||||
Key_B,
|
|
||||||
Key_N,
|
|
||||||
Key_M,
|
|
||||||
Key_Comma,
|
|
||||||
Key_Period,
|
|
||||||
Key_Hyphen,
|
|
||||||
Key_RightShift,
|
|
||||||
Key_Unknown, // Maybe other alt
|
|
||||||
Key_Alt,
|
|
||||||
Key_Space,
|
|
||||||
Key_CapsLock,
|
|
||||||
Key_F1,
|
|
||||||
Key_F2,
|
|
||||||
Key_F3,
|
|
||||||
Key_F4,
|
|
||||||
Key_F5,
|
|
||||||
Key_F6,
|
|
||||||
Key_F7,
|
|
||||||
Key_F8,
|
|
||||||
Key_F9,
|
|
||||||
Key_F10,
|
|
||||||
// TODO
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char fi_keymap[0x7f]
|
|
||||||
{
|
|
||||||
'\0',
|
|
||||||
'\0', // esc
|
|
||||||
'1',
|
|
||||||
'2',
|
|
||||||
'3',
|
|
||||||
'4',
|
|
||||||
'5',
|
|
||||||
'6',
|
|
||||||
'7',
|
|
||||||
'8',
|
|
||||||
'9',
|
|
||||||
'0',
|
|
||||||
'+',
|
|
||||||
'`',
|
|
||||||
'\b',
|
|
||||||
'\t', // tab
|
|
||||||
'q',
|
|
||||||
'w',
|
|
||||||
'e',
|
|
||||||
'r',
|
|
||||||
't',
|
|
||||||
'y',
|
|
||||||
'u',
|
|
||||||
'i',
|
|
||||||
'o',
|
|
||||||
'p',
|
|
||||||
'?',
|
|
||||||
'^',
|
|
||||||
'\n', // enter
|
|
||||||
'\0',
|
|
||||||
'a',
|
|
||||||
's',
|
|
||||||
'd',
|
|
||||||
'f',
|
|
||||||
'g',
|
|
||||||
'h',
|
|
||||||
'j',
|
|
||||||
'k',
|
|
||||||
'l',
|
|
||||||
'\0', // ö
|
|
||||||
'\0', // ä
|
|
||||||
'\0', // §
|
|
||||||
'\0',
|
|
||||||
'\'',
|
|
||||||
'z',
|
|
||||||
'x',
|
|
||||||
'c',
|
|
||||||
'v',
|
|
||||||
'b',
|
|
||||||
'n',
|
|
||||||
'm',
|
|
||||||
',',
|
|
||||||
'.',
|
|
||||||
'-',
|
|
||||||
'\0',
|
|
||||||
'\0',
|
|
||||||
'\0',
|
|
||||||
' ',
|
|
||||||
};
|
|
||||||
|
|
||||||
char fi_keymap_shift[0x7f]
|
|
||||||
{
|
|
||||||
'\0',
|
|
||||||
'\0', // esc
|
|
||||||
'!',
|
|
||||||
'"',
|
|
||||||
'#',
|
|
||||||
'\0', // ¤
|
|
||||||
'%',
|
|
||||||
'&',
|
|
||||||
'/',
|
|
||||||
'(',
|
|
||||||
')',
|
|
||||||
'=',
|
|
||||||
'?',
|
|
||||||
'`',
|
|
||||||
'\b',
|
|
||||||
'\t', // tab
|
|
||||||
'Q',
|
|
||||||
'W',
|
|
||||||
'E',
|
|
||||||
'R',
|
|
||||||
'T',
|
|
||||||
'Y',
|
|
||||||
'U',
|
|
||||||
'I',
|
|
||||||
'O',
|
|
||||||
'P',
|
|
||||||
'?',
|
|
||||||
'^',
|
|
||||||
'\n', // enter
|
|
||||||
'\0',
|
|
||||||
'A',
|
|
||||||
'S',
|
|
||||||
'D',
|
|
||||||
'F',
|
|
||||||
'G',
|
|
||||||
'H',
|
|
||||||
'J',
|
|
||||||
'K',
|
|
||||||
'L',
|
|
||||||
'\0', // ö
|
|
||||||
'\0', // ä
|
|
||||||
'\0', // ½
|
|
||||||
'\0',
|
|
||||||
'*',
|
|
||||||
'Z',
|
|
||||||
'X',
|
|
||||||
'C',
|
|
||||||
'V',
|
|
||||||
'B',
|
|
||||||
'N',
|
|
||||||
'M',
|
|
||||||
';',
|
|
||||||
':',
|
|
||||||
'_',
|
|
||||||
'\0',
|
|
||||||
'\0',
|
|
||||||
'\0',
|
|
||||||
' ',
|
|
||||||
};
|
|
||||||
|
|
||||||
void irq_handler()
|
|
||||||
{
|
|
||||||
while (IO::inb(PS2_STATUS_REGISTER) & 0x01)
|
|
||||||
{
|
|
||||||
uint8_t raw = IO::inb(PS2_DATA_PORT);
|
|
||||||
uint8_t ch = raw & 0x7f;
|
|
||||||
bool pressed = !(raw & 0x80);
|
|
||||||
|
|
||||||
switch (ch)
|
|
||||||
{
|
|
||||||
case 0x38: pressed ? (s_modifiers |= 1 << ALT ) : (s_modifiers &= ~(1 << ALT )); break;
|
|
||||||
case 0x1d: pressed ? (s_modifiers |= 1 << CTRL ) : (s_modifiers &= ~(1 << CTRL )); break;
|
|
||||||
case 0x2a: pressed ? (s_modifiers |= 1 << SHIFT) : (s_modifiers &= ~(1 << SHIFT)); break;
|
|
||||||
default:
|
|
||||||
s_keyboard_state[ch] = pressed;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pressed)
|
|
||||||
{
|
|
||||||
char c = s_modifiers & (1 << SHIFT) ? fi_keymap_shift[ch] : fi_keymap[ch];
|
|
||||||
if (c) kprint("{}", c);
|
|
||||||
}
|
|
||||||
|
|
||||||
IO::io_wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void initialize()
|
|
||||||
{
|
|
||||||
// Clear keyboard buffer
|
|
||||||
while (IO::inb(PS2_STATUS_REGISTER) & 0x01)
|
|
||||||
IO::inb(PS2_DATA_PORT);
|
|
||||||
|
|
||||||
memset(s_keyboard_state, 0, sizeof(s_keyboard_state));
|
|
||||||
|
|
||||||
IDT::register_irq_handler(PS2_IRQ, irq_handler);
|
|
||||||
PIC::unmask(PS2_IRQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,11 +1,11 @@
|
||||||
#include <kernel/GDT.h>
|
#include <kernel/GDT.h>
|
||||||
#include <kernel/IDT.h>
|
#include <kernel/IDT.h>
|
||||||
|
#include <kernel/Keyboard.h>
|
||||||
#include <kernel/kmalloc.h>
|
#include <kernel/kmalloc.h>
|
||||||
#include <kernel/multiboot.h>
|
#include <kernel/multiboot.h>
|
||||||
#include <kernel/panic.h>
|
#include <kernel/panic.h>
|
||||||
#include <kernel/PIC.h>
|
#include <kernel/PIC.h>
|
||||||
#include <kernel/PIT.h>
|
#include <kernel/PIT.h>
|
||||||
#include <kernel/PS2.h>
|
|
||||||
#include <kernel/tty.h>
|
#include <kernel/tty.h>
|
||||||
#include <kernel/kprint.h>
|
#include <kernel/kprint.h>
|
||||||
#include <kernel/IO.h>
|
#include <kernel/IO.h>
|
||||||
|
@ -18,6 +18,16 @@
|
||||||
|
|
||||||
multiboot_info_t* s_multiboot_info;
|
multiboot_info_t* s_multiboot_info;
|
||||||
|
|
||||||
|
void on_key_press(Keyboard::Key key, uint8_t modifiers, bool pressed)
|
||||||
|
{
|
||||||
|
if (pressed)
|
||||||
|
{
|
||||||
|
char ascii = Keyboard::key_to_ascii(key, modifiers);
|
||||||
|
if (ascii)
|
||||||
|
kprint("{}", ascii);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void kernel_main(multiboot_info_t* mbi, uint32_t magic)
|
void kernel_main(multiboot_info_t* mbi, uint32_t magic)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +47,7 @@ void kernel_main(multiboot_info_t* mbi, uint32_t magic)
|
||||||
IDT::initialize();
|
IDT::initialize();
|
||||||
|
|
||||||
PIT::initialize();
|
PIT::initialize();
|
||||||
PS2::initialize();
|
Keyboard::initialize(on_key_press);
|
||||||
|
|
||||||
kprint("Hello from the kernel!\n");
|
kprint("Hello from the kernel!\n");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue