summaryrefslogtreecommitdiff
path: root/src/kernel/kbd.c
diff options
context:
space:
mode:
authorBenji Dial <benji6283@gmail.com>2021-03-03 22:43:17 -0500
committerBenji Dial <benji6283@gmail.com>2021-03-03 22:43:17 -0500
commit81df4702c424f91cca5570ab2554d1d4cbae534d (patch)
treeaa8704b2fdf7a4bd79d85f480dc9fd8f8db02547 /src/kernel/kbd.c
parent43693f88c79467b741b3f899799082e791656d1b (diff)
downloadportland-os-81df4702c424f91cca5570ab2554d1d4cbae534d.tar.gz
64kiB kernel area, ps/2 mouse support, signed decimals in knob format
Diffstat (limited to 'src/kernel/kbd.c')
-rw-r--r--src/kernel/kbd.c84
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;