Index: uspace/srv/kbd/ctl/pc.c
===================================================================
--- uspace/srv/kbd/ctl/pc.c	(revision 5c06c1c2c7f8ec08d0fbfca6238ce9e6285ef01c)
+++ uspace/srv/kbd/ctl/pc.c	(revision 90e3d6a4d64226b489eac123eae27df8c803ecc8)
@@ -41,27 +41,12 @@
 #include <kbd_ctl.h>
 
-static int scanmap_simple[];
-
-void kbd_ctl_parse_scancode(int scancode)
-{
-	kbd_ev_type_t type;
-	unsigned int key;
-
-	if (scancode < 0 || scancode >= 0x100)
-		return;
-
-	if (scancode & 0x80) {
-		scancode &= ~0x80;
-		type = KE_RELEASE;
-	} else {
-		type = KE_PRESS;
-	}
-
-	key = scanmap_simple[scancode];
-	if (key != 0)
-		kbd_push_ev(type, key);
-}
-
-static int scanmap_simple[128] = {
+enum dec_state {
+	ds_s,
+	ds_e
+};
+
+static enum dec_state ds = ds_s;
+
+static int scanmap_simple[] = {
 
 	[0x29] = KC_BACKTICK,
@@ -151,12 +136,84 @@
 	[0x58] = KC_F12,
 
-	[0x1c] = KC_ENTER
-
-/*
-	[0x1] = KC_PRNSCR,
-	[0x1] = KC_SCROLL_LOCK,
-	[0x1] = KC_PAUSE,
-*/
+	[0x1c] = KC_ENTER,
+
+	[0x45] = KC_NUM_LOCK,
+	[0x37] = KC_NTIMES,
+	[0x4a] = KC_NMINUS,
+	[0x4e] = KC_NPLUS,
+	[0x47] = KC_N7,
+	[0x48] = KC_N8,
+	[0x49] = KC_N9,
+	[0x4b] = KC_N4,
+	[0x4c] = KC_N5,
+	[0x4d] = KC_N6,
+	[0x4f] = KC_N1,
+	[0x50] = KC_N2,
+	[0x51] = KC_N3,
+	[0x52] = KC_N0,
+	[0x53] = KC_NPERIOD
 };
+
+static int scanmap_e0[] = {
+	[0x38] = KC_RALT,
+	[0x1d] = KC_RSHIFT,
+
+	[0x37] = KC_PRTSCR,
+	[0x52] = KC_INSERT,
+	[0x49] = KC_PAGE_UP,
+
+	[0x53] = KC_DELETE,
+	[0x4f] = KC_END,
+	[0x51] = KC_PAGE_DOWN,
+
+	[0x48] = KC_UP,
+	[0x4b] = KC_LEFT,
+	[0x50] = KC_DOWN,
+	[0x4d] = KC_RIGHT,
+
+	[0x35] = KC_NSLASH,
+	[0x1c] = KC_NENTER
+};
+
+
+void kbd_ctl_parse_scancode(int scancode)
+{
+	kbd_ev_type_t type;
+	unsigned int key;
+	int *map;
+	size_t map_length;
+
+	if (scancode == 0xe0) {
+		ds = ds_e;
+		return;
+	}
+
+	switch (ds) {
+	case ds_s:
+		map = scanmap_simple;
+		map_length = sizeof(scanmap_simple) / sizeof(int);
+		break;
+	case ds_e:
+		map = scanmap_e0;
+		map_length = sizeof(scanmap_e0) / sizeof(int);
+		break;
+	}
+
+	ds = ds_s;
+
+	if (scancode & 0x80) {
+		scancode &= ~0x80;
+		type = KE_RELEASE;
+	} else {
+		type = KE_PRESS;
+	}
+
+	if (scancode < 0 || scancode >= map_length)
+		return;
+
+	key = map[scancode];
+	if (key != 0)
+		kbd_push_ev(type, key);
+}
 
 /**
Index: uspace/srv/kbd/generic/kbd.c
===================================================================
--- uspace/srv/kbd/generic/kbd.c	(revision 5c06c1c2c7f8ec08d0fbfca6238ce9e6285ef01c)
+++ uspace/srv/kbd/generic/kbd.c	(revision 90e3d6a4d64226b489eac123eae27df8c803ecc8)
@@ -47,4 +47,5 @@
 #include <libadt/fifo.h>
 #include <kbd/kbd.h>
+#include <kbd/keycode.h>
 
 #include <kbd.h>
@@ -61,5 +62,5 @@
 
 /** Currently active modifiers. */
-static unsigned mods;
+static unsigned mods = KM_NUM_LOCK;
 
 void kbd_push_scancode(int scancode)
@@ -69,5 +70,4 @@
 }
 
-#include <kbd/keycode.h>
 void kbd_push_ev(int type, unsigned int key)
 {
Index: uspace/srv/kbd/layout/us_qwerty.c
===================================================================
--- uspace/srv/kbd/layout/us_qwerty.c	(revision 5c06c1c2c7f8ec08d0fbfca6238ce9e6285ef01c)
+++ uspace/srv/kbd/layout/us_qwerty.c	(revision 90e3d6a4d64226b489eac123eae27df8c803ecc8)
@@ -161,5 +161,26 @@
 	[KC_TAB] = '\t',
 	[KC_ENTER] = '\n',
-	[KC_SPACE] = ' '
+	[KC_SPACE] = ' ',
+
+	[KC_NSLASH] = '/',
+	[KC_NTIMES] = '*',
+	[KC_NMINUS] = '-',
+	[KC_NPLUS] = '+',
+	[KC_NENTER] = '\n'
+};
+
+static char map_numeric[] = {
+	[KC_N7] = '7',
+	[KC_N8] = '8',
+	[KC_N9] = '9',
+	[KC_N4] = '4',
+	[KC_N5] = '5',
+	[KC_N6] = '6',
+	[KC_N1] = '1',
+	[KC_N2] = '2',
+	[KC_N3] = '3',
+
+	[KC_N0] = '0',
+	[KC_NPERIOD] = '.'
 };
 
@@ -193,6 +214,12 @@
 		c = translate(ev->key, map_not_shifted, sizeof(map_not_shifted) / sizeof(char));
 
-	if (c != 0 ) return c;
-
+	if (c != 0) return c;
+
+	if ((ev->mods & KM_NUM_LOCK) != 0)
+		c = translate(ev->key, map_numeric, sizeof(map_numeric) / sizeof(char));
+	else
+		c = 0;
+
+	return c;
 }
 
