44 lines
1.4 KiB
C

#include "keyboard.h"
#include "cpu/isr.h"
#include "cpu/memlayout.h"
#include "console.h"
#include "port.h"
#include "kernel/mem.h"
keyboard_interrupt_shared_t kbd_state_shrd;
static void kbd_interrupt_handler(registers_t *r) {
uint8_t scancode = port_byte_in(0x60);
if (kbd_state_shrd.len < KEYBOARD_INTERRUPT_BUF_CAP) {
kbd_state_shrd.buf[kbd_state_shrd.len++] = scancode;
}
}
void init_keyboard() {
kbd_state_shrd.len = 0;
kbd_state_shrd.buf = (uint8_t*)kalloc();
kbd_state_shrd.copy_len = 0;
kbd_state_shrd.copy_buf = (uint8_t*)kalloc();
/* 128/8 actually we need only 16 bytes for that */
memset(kbd_state_shrd.copy_pressed, 0, 16);
register_interrupt_handler(IRQ1, kbd_interrupt_handler);
}
/* reading keyboard */
uint8_t kbd_take_from_copy_buffer() {
check(kbd_state_shrd.copy_len > 0);
uint8_t key_event_code = kbd_state_shrd.copy_buf[--kbd_state_shrd.copy_len];
uint8_t keycode = (key_event_code & 0x7f);
if (key_event_code & 0x80) {
kbd_state_shrd.copy_pressed[keycode >> 3] = kbd_state_shrd.copy_pressed[keycode >> 3] & (~(1u << (keycode & 0x7)));
} else {
kbd_state_shrd.copy_pressed[keycode >> 3] = kbd_state_shrd.copy_pressed[keycode >> 3] | (1u << (keycode & 0x7));
}
return key_event_code;
}
bool kbd_can_take_from_copy_buffer() {
return kbd_state_shrd.copy_len > 0;
}