aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/include/ps2_keymaps.h39
-rw-r--r--drivers/include/ps2kbd.h33
-rw-r--r--drivers/ps2_keymaps.c99
-rw-r--r--drivers/ps2kbd.c113
4 files changed, 273 insertions, 11 deletions
diff --git a/drivers/include/ps2_keymaps.h b/drivers/include/ps2_keymaps.h
index 91688c8..0e8ae26 100644
--- a/drivers/include/ps2_keymaps.h
+++ b/drivers/include/ps2_keymaps.h
@@ -1,8 +1,39 @@
#include <stdint.h>
-#define ERROR_KEY 0x00
-#define PRINTING_KEY 0x01
-#define SPECIAL_KEY 0x02
+#define EXTENDED_SCANCODE 0xE0
-extern uint8_t ps2_scancodes_set1[128];
+#define ERROR_KEY 0
+#define PRINTING_KEY 1
+#define SPECIAL_KEY 2
+
+#define SPECIAL_NONE 0
+#define SPECIAL_SHIFT 1
+#define SPECIAL_CTRL 2
+#define SPECIAL_BKSP 3
+#define SPECIAL_ALT 4
+#define SPECIAL_GUI 5
+#define SPECIAL_NUMLOCK 6
+#define SPECIAL_CAPLOCK 7
+#define SPECIAL_SCRLLOCK 8
+#define SPECIAL_UPARROW 9
+#define SPECIAL_DNARROW 10
+#define SPECIAL_LFTARROW 11
+#define SPECIAL_RTARROW 12
+#define SPECIAL_ESC 13
+#define SPECIAL_F1 21
+#define SPECIAL_F2 22
+#define SPECIAL_F3 23
+#define SPECIAL_F4 24
+#define SPECIAL_F5 25
+#define SPECIAL_F6 26
+#define SPECIAL_F7 27
+#define SPECIAL_F8 28
+#define SPECIAL_F9 29
+#define SPECIAL_F10 30
+#define SPECIAL_F11 31
+#define SPECIAL_F12 32
+
+extern uint8_t ps2_set1_scancodes[128];
extern char ps2_set1_ascii[128];
+extern char ps2_set1_shift[128];
+extern uint8_t ps2_set1_special[128];
diff --git a/drivers/include/ps2kbd.h b/drivers/include/ps2kbd.h
index dcde1d8..bf4871d 100644
--- a/drivers/include/ps2kbd.h
+++ b/drivers/include/ps2kbd.h
@@ -1,5 +1,8 @@
/* this is both a PS/2 keyboard AND a PS/2 MOUSE driver */
+#ifndef _PS2KBD_H_
+#define _PS2KBD_H_
+#include <stdbool.h>
#include <stdint.h>
#define PS2_SCROLL_LOCK (1 << 0)
@@ -16,6 +19,34 @@
#define MODIFIER_CTRL (1 << 1)
#define MODIFIER_ALT (1 << 2)
+struct ps2_specialkeys_t {
+ int shift :1;
+ int ctrl :1;
+ int bksp :1;
+ int alt :1;
+ int gui :1;
+ int numlock :1;
+ int capslock :1;
+ int scrllock :1;
+ int uparrow :1;
+ int downarrow :1;
+ int leftarrow :1;
+ int rightarrow :1;
+ int esc :1;
+ int f1 :1;
+ int f2 :1;
+ int f3 :1;
+ int f4 :1;
+ int f5 :1;
+ int f6 :1;
+ int f7 :1;
+ int f8 :1;
+ int f9 :1;
+ int f10 :1;
+ int f11 :1;
+ int f12 :1;
+};
+
/* returns which arrow keys are down */
uint8_t ps2kbd_button_get(void);
@@ -24,3 +55,5 @@ uint8_t ps2kbd_modifier_get(void);
void ps2kbd_set_leds(uint8_t status);
void ps2kbd_init(void);
+
+#endif
diff --git a/drivers/ps2_keymaps.c b/drivers/ps2_keymaps.c
index cd7fd08..1e685c0 100644
--- a/drivers/ps2_keymaps.c
+++ b/drivers/ps2_keymaps.c
@@ -1,7 +1,7 @@
#include <stdint.h>
#include "ps2_keymaps.h"
-uint8_t ps2_scancodes_set1[128] = {
+uint8_t ps2_set1_scancodes[128] = {
ERROR_KEY, /* error */
SPECIAL_KEY, /* esc */
PRINTING_KEY, /* 1 */
@@ -192,6 +192,7 @@ char ps2_set1_ascii[128] = {
'\0',
'\0',
};
+
char ps2_set1_shift[128] = {
'\0',
'\0',
@@ -287,3 +288,99 @@ char ps2_set1_shift[128] = {
'\0',
'\0',
};
+
+uint8_t ps2_set1_special[128] = {
+ 0, /* error */
+ SPECIAL_ESC, /* esc */
+ 0, /* 1 */
+ 0, /* 2 */
+ 0, /* 3 */
+ 0, /* 4 */
+ 0, /* 5 */
+ 0, /* 6 */
+ 0, /* 7 */
+ 0, /* 8 */
+ 0, /* 9 */
+ 0, /* 0 */
+ 0, /* - */
+ 0, /* = */
+ SPECIAL_BKSP, /* backspace */
+ 0, /* tab */
+ 0, /* Q */
+ 0, /* W */
+ 0, /* E */
+ 0, /* R */
+ 0, /* T */
+ 0, /* Y */
+ 0, /* U */
+ 0, /* I */
+ 0, /* O */
+ 0, /* P */
+ 0, /* [ */
+ 0, /* ] */
+ 0, /* enter */
+ SPECIAL_CTRL, /* left ctrl */
+ 0, /* A */
+ 0, /* S */
+ 0, /* D */
+ 0, /* F */
+ 0, /* G */
+ 0, /* H */
+ 0, /* J */
+ 0, /* K */
+ 0, /* L */
+ 0, /* ; */
+ 0, /* ' */
+ 0, /* ` */
+ SPECIAL_SHIFT, /* left shift */
+ 0, /* \ (backslash) */
+ 0, /* Z */
+ 0, /* X */
+ 0, /* C */
+ 0, /* V */
+ 0, /* B */
+ 0, /* N */
+ 0, /* M */
+ 0, /* , */
+ 0, /* . */
+ 0, /* / */
+ SPECIAL_SHIFT, /* right shift */
+ 0, /* keypad * */
+ SPECIAL_ALT, /* right alt */
+ 0, /* space */
+ SPECIAL_CAPLOCK, /* caps lock */
+ SPECIAL_F1, /* F1 */
+ SPECIAL_F2, /* F2 */
+ SPECIAL_F3, /* F3 */
+ SPECIAL_F4, /* F4 */
+ SPECIAL_F5, /* F5 */
+ SPECIAL_F6, /* F6 */
+ SPECIAL_F7, /* F7 */
+ SPECIAL_F8, /* F8 */
+ SPECIAL_F9, /* F9 */
+ SPECIAL_F10, /* F10 */
+ SPECIAL_NUMLOCK, /* num lock */
+ SPECIAL_SCRLLOCK, /* scroll lock */
+ 0, /* keypad 7 */
+ 0, /* keypad 8 */
+ 0, /* keypad 9 */
+ 0, /* keypad - */
+ 0, /* keypad 4 */
+ 0, /* keypad 5 */
+ 0, /* keypad 6 */
+ 0, /* keypad + */
+ 0, /* keypad 1 */
+ 0, /* keypad 2 */
+ 0, /* keypad 3 */
+ 0, /* keypad 0 */
+ 0, /* keypad . */
+ 0, /* 0x54 */
+ 0, /* 0x55 */
+ 0, /* 0x56 */
+ SPECIAL_F11, /* F11 */
+ SPECIAL_F12, /* F12 */
+ 0,
+ 0,
+ 0,
+ 0
+};
diff --git a/drivers/ps2kbd.c b/drivers/ps2kbd.c
index 73b75d1..40b06ac 100644
--- a/drivers/ps2kbd.c
+++ b/drivers/ps2kbd.c
@@ -1,6 +1,7 @@
-/* this is both a PS/2 keyboard driver */
+/* this is a PS/2 keyboard driver */
#include <stdint.h>
#include <stdio.h>
+#include <string.h>
#include "io.h"
#include "isr.h"
#include "ps2kbd.h"
@@ -57,23 +58,122 @@ uint8_t ps2kbd_modifier_get(void)
return ret;
}
+static struct ps2_specialkeys_t special_keys;
+
+static void handle_special_key(uint8_t scancode, int release)
+{
+ int press = ~release;
+ switch(ps2_set1_special[scancode])
+ {
+ case SPECIAL_SHIFT:
+ special_keys.shift = press;
+ break;
+ case SPECIAL_CTRL:
+ special_keys.ctrl = press;
+ break;
+ case SPECIAL_BKSP:
+ special_keys.bksp = press;
+ break;
+ case SPECIAL_ALT:
+ special_keys.alt = press;
+ break;
+ case SPECIAL_NUMLOCK:
+ special_keys.numlock = ~special_keys.numlock;
+ ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock);
+ break;
+ case SPECIAL_CAPLOCK:
+ special_keys.capslock = ~special_keys.capslock;
+ ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock);
+ break;
+ case SPECIAL_SCRLLOCK:
+ special_keys.scrllock = ~special_keys.scrllock;
+ ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock);
+ break;
+ case SPECIAL_ESC:
+ special_keys.esc = press;
+ break;
+ case SPECIAL_F1:
+ special_keys.f1 = press;
+ break;
+ case SPECIAL_F2:
+ special_keys.f2 = press;
+ break;
+ case SPECIAL_F3:
+ special_keys.f3 = press;
+ break;
+ case SPECIAL_F4:
+ special_keys.f4 = press;
+ break;
+ case SPECIAL_F5:
+ special_keys.f5 = press;
+ break;
+ case SPECIAL_F6:
+ special_keys.f6 = press;
+ break;
+ case SPECIAL_F7:
+ special_keys.f7 = press;
+ break;
+ case SPECIAL_F8:
+ special_keys.f8 = press;
+ break;
+ case SPECIAL_F9:
+ special_keys.f9 = press;
+ break;
+ case SPECIAL_F10:
+ special_keys.f10 = press;
+ break;
+ case SPECIAL_F11:
+ special_keys.f11 = press;
+ break;
+ case SPECIAL_F12:
+ special_keys.f12 = press;
+ break;
+ }
+}
+
+static void handle_extended_scancode(void)
+{
+ uint8_t temp = inb(0x60);
+ //printf("Extended scancode: 0x%x\n", temp);
+}
+
static void key_handler(struct regs_t *regs)
{
(void) regs;
uint8_t scancode = inb(0x60);
- if(scancode == 0xE0)
- /* extended, forget it! */
+ //printf("INTR SCAN: 0x%x\n", scancode);
+ if(scancode == EXTENDED_SCANCODE)
+ {
+ handle_extended_scancode();
return;
+ }
+
/* AND by 0x7F to get in the range of [0,128) */
- int type = ps2_scancodes_set1[scancode & 0x7F];
- int release = (scancode & 0x80) >> 7;
+
+ int type = ps2_set1_scancodes[scancode & 0x7F];
+ int release = (scancode & (1<<7)) >> 7;
switch(type)
{
case PRINTING_KEY:
+ {
if(!release)
- putchar(ps2_set1_ascii[scancode]);
+ {
+ int capitals = special_keys.capslock;
+ if(special_keys.shift)
+ capitals = ~capitals;
+ if(capitals)
+ putchar(ps2_set1_shift[scancode]);
+ else
+ putchar(ps2_set1_ascii[scancode]);
+ }
+ break;
+ }
+ case SPECIAL_KEY:
+ handle_special_key(scancode & 0x7F, release);
break;
}
+ if(special_keys.bksp)
+ putchar('\b');
}
static void ps2_set_scancode_set(uint8_t set)
@@ -87,6 +187,7 @@ static void keyboard_init(void)
{
set_interrupt_handler(IRQ(1), key_handler);
ps2_set_scancode_set(1);
+ memset(&special_keys, 0, sizeof(special_keys));
}
void ps2kbd_init(void)