diff options
Diffstat (limited to 'src/kernel/kbd.c')
-rw-r--r-- | src/kernel/kbd.c | 84 |
1 files changed, 78 insertions, 6 deletions
diff --git a/src/kernel/kbd.c b/src/kernel/kbd.c index 47894cd..004706f 100644 --- a/src/kernel/kbd.c +++ b/src/kernel/kbd.c @@ -21,16 +21,36 @@ enum { enum { PS2C_READ_CONFIG = 0x20, PS2C_WRITE_CONFIG = 0x60, + PS2C_AUX_ENABLE = 0xa8, PS2C_DISABLE = 0xad, - PS2C_ENABLE = 0xae + PS2C_ENABLE = 0xae, + PS2C_SEND_AUX = 0xd4 }; enum { - PS2S_CODE_READY = 0x01 + PS2S_CODE_READY = 0x01, + PS2S_DONT_SEND = 0x02, + PS2S_FROM_MOUSE = 0x20 }; enum { - PS2G_XT_COMPAT = 0x40 + PS2G_KBD_IRQ = 0x01, + PS2G_MOUSE_IRQ = 0x02, + PS2G_KBD_OFF = 0x10, + PS2G_MOUSE_OFF = 0x20, + PS2G_XT_COMPAT = 0x40 +}; + +enum { + MFB_BUTTON_ONE = 0x01, + MFB_BUTTON_TWO = 0x02, + MFB_BUTTON_MID = 0x04, + MFB_X_SIGN = 0x10, + MFB_Y_SIGN = 0x20 +}; + +enum { + MC_ENABLE_REPORT = 0xf4 }; static uint32_t n_scantabs; @@ -55,7 +75,16 @@ void init_kbd() { outb(PS2_CMD, PS2C_READ_CONFIG); uint8_t config = inb(PS2_DATA); outb(PS2_CMD, PS2C_WRITE_CONFIG); - outb(PS2_DATA, config | PS2G_XT_COMPAT); + outb(PS2_DATA, (config | PS2G_XT_COMPAT | PS2G_MOUSE_IRQ | PS2G_KBD_IRQ) & ~(PS2G_MOUSE_OFF | PS2G_KBD_OFF)); + + outb(PS2_CMD, PS2C_SEND_AUX); + while (inb(PS2_CMD) & PS2S_DONT_SEND) + ; + outb(PS2_DATA, MC_ENABLE_REPORT); + while (!(inb(PS2_CMD) & PS2S_CODE_READY)) + ; + if (inb(PS2_DATA) != 0xfa) + PANIC("didn't get ACK after enabling mouse reporting"); uint32_t layout_len; if (!try_get_sz_setting("kbd-layout", scantab_path + SCANTAB_DIR_LEN, LAYOUT_NAME_MAX_LEN, &layout_len)) @@ -107,11 +136,54 @@ static inline uint8_t get_next_code_byte() { return cb; } +static inline uint8_t get_wait() { + for (uint32_t i = 0; i < 1000000; ++i) + ; + return inb(PS2_DATA); +} + static enum key_modifiers_t keymods = 0; +bool last_mouse_one = false; +bool last_mouse_two = false; +bool last_mouse_mid = false; + enum kbd_isr_result on_kbd_isr() { -//logf(LOG_INFO, "on_kbd_isr()"); - while (inb(PS2_CMD) & PS2S_CODE_READY) { + uint8_t code; + while ((code = inb(PS2_CMD)) & PS2S_CODE_READY) { + if (code & PS2S_FROM_MOUSE) { + const uint8_t first = get_wait(); + const uint8_t x = get_wait(); + const uint8_t y = get_wait(); + + if (x || y || (first & (MFB_X_SIGN | MFB_Y_SIGN))) + move_mouse_by((first & MFB_Y_SIGN) ? 256 - y : -y, + (first & MFB_X_SIGN) ? x - 256 : x); + + const bool mouse_one = first & MFB_BUTTON_ONE; + const bool mouse_two = first & MFB_BUTTON_TWO; + const bool mouse_mid = first & MFB_BUTTON_MID; + + if (mouse_one && !last_mouse_one) + mouse_button(LEFT, false); + if (mouse_two && !last_mouse_two) + mouse_button(RIGHT, false); + if (mouse_mid && !last_mouse_mid) + mouse_button(MIDDLE, false); + + if (!mouse_one && last_mouse_one) + mouse_button(LEFT, true); + if (!mouse_two && last_mouse_two) + mouse_button(RIGHT, true); + if (!mouse_mid && last_mouse_mid) + mouse_button(MIDDLE, true); + + last_mouse_one = mouse_one; + last_mouse_two = mouse_two; + last_mouse_mid = mouse_mid; + continue; + } + last_code_byte = 0; uint8_t code[256]; uint8_t code_i = 0; |