diff options
Diffstat (limited to 'kernel/src/drivers/ps2mouse.c')
-rw-r--r-- | kernel/src/drivers/ps2mouse.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/kernel/src/drivers/ps2mouse.c b/kernel/src/drivers/ps2mouse.c new file mode 100644 index 0000000..01e10cc --- /dev/null +++ b/kernel/src/drivers/ps2mouse.c @@ -0,0 +1,89 @@ +#include <panic.h> +#include <stdbool.h> +#include <string.h> +#include <sys.h> + +#include "print.h" +#include "ps2mouse.h" +#include "drivers/ps2ctrl.h" +#include "interrupt/pic.h" + +static bool is_init = false; + +static struct MouseEvent last_event; +static uint8_t first_b, second_b, third_b; + +void ps2mouse_init(void) { + + debugk("Loading PS/2 Mouse"); + + is_init = false; + pic_mask(12); + + uint8_t result; + + ps2ctrl_set_port2(); + ps2ctrl_out_data(0xFF); + result = ps2ctrl_in(); + if (result != 0xFA) { + errork("Failed to reset PS/2 mouse: expected 0xFA, got 0x%X", result); + return; + } + result = ps2ctrl_in(); + if (result != 0xAA) { + errork("Failed to reset PS/2 mouse: expected 0xAA, got 0x%X", result); + return; + } + + ps2ctrl_set_port2(); + ps2ctrl_out_data(0xF4); + + pic_unmask(12); + is_init = true; + + succek("PS/2 Mouse has has been loaded"); +} + +static uint8_t packet_num = 0; +void ps2mouse_recv(void) { + if (!ps2ctrl_is_init() || !is_init) { + inb(0x60); + return; + } + + uint8_t packet = ps2ctrl_in(); + switch (packet_num) { + case 0: + first_b = packet; + break; + case 1: + second_b = packet; + break; + case 2: { + third_b = packet; + + int state, d; + state = first_b; + d = second_b; + last_event.relx = d - ((state << 4) & 0x100); + d = third_b; + last_event.rely = d - ((state << 3) & 0x100); + + last_event.lmb = first_b & 0x01; + last_event.rmb = first_b & 0x02; + last_event.mmb = first_b & 0x04; + last_event.updated = true; + break; + } + } + + packet_num += 1; + packet_num %= 3; + +} + +struct MouseEvent ps2mouse_get(void) { + struct MouseEvent event = last_event; + last_event.updated = false; + return event; +} |