Index: uspace/srv/kbd/Makefile
===================================================================
--- uspace/srv/kbd/Makefile	(revision c716d94ef460af2459c35a03b940bfc81915596f)
+++ uspace/srv/kbd/Makefile	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -79,7 +79,9 @@
 ifeq ($(ARCH), sparc64)
 	ARCH_SOURCES += \
-		arch/$(ARCH)/src/scanc.c
+		arch/$(ARCH)/src/scanc.c \
+		arch/$(ARCH)/src/sgcn.c
 	GENARCH_SOURCES = \
-		genarch/src/kbd.c
+		genarch/src/kbd.c \
+		genarch/src/nofb.c
 endif
 ifeq ($(ARCH), arm32)
@@ -87,5 +89,8 @@
 		arch/$(ARCH)/src/kbd_gxemul.c
 endif
-
+ifeq ($(ARCH), mips32)
+	GENARCH_SOURCES += \
+	    genarch/src/nofb.c
+endif
 
 GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
Index: uspace/srv/kbd/arch/mips32/src/kbd.c
===================================================================
--- uspace/srv/kbd/arch/mips32/src/kbd.c	(revision c716d94ef460af2459c35a03b940bfc81915596f)
+++ uspace/srv/kbd/arch/mips32/src/kbd.c	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -35,4 +35,5 @@
  */
 #include <arch/kbd.h>
+#include <genarch/nofb.h>
 #include <ipc/ipc.h>
 #include <sysinfo.h>
@@ -100,144 +101,4 @@
 */
 
-static int kbd_arch_process_no_fb(keybuffer_t *keybuffer, int scan_code)
-{
-
-	static unsigned long buf = 0;
-	static int count = 0;	
-
-	/* Please preserve this code (it can be used to determine scancodes)
-	
-	keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf));
-	keybuffer_push(keybuffer, to_hex(scan_code&0xf));
-	keybuffer_push(keybuffer, ' ');
-	keybuffer_push(keybuffer, ' ');
-	
-	return 1;
-	*/
-	
-	if(scan_code == 0x7e) {
-		switch (buf) {
-		case MSIM_KEY_F5:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F6:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F7:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F8:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F9:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F10:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F11:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
-			buf = count = 0;
-			return 1;
-		case MSIM_KEY_F12:
-			keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
-			buf = count = 0;
-			return 1;
-		default:
-			keybuffer_push(keybuffer, buf & 0xff);
-			keybuffer_push(keybuffer, (buf >> 8) &0xff);
-			keybuffer_push(keybuffer, (buf >> 16) &0xff);
-			keybuffer_push(keybuffer, (buf >> 24) &0xff);
-			keybuffer_push(keybuffer, scan_code);
-			buf = count = 0;
-			return 1;
-		}
-	}
-
-	buf |= ((unsigned long) scan_code)<<(8*(count++));
-	
-	if((buf & 0xff) != (MSIM_KEY_F1 & 0xff)) {
-		keybuffer_push(keybuffer, buf);
-		buf = count = 0;
-		return 1;
-	}
-
-	if (count <= 1) 
-		return 1;
-
-	if ((buf & 0xffff) != (MSIM_KEY_F1 & 0xffff) 
-		&& (buf & 0xffff) != (MSIM_KEY_F5 & 0xffff) ) {
-
-		keybuffer_push(keybuffer, buf & 0xff);
-		keybuffer_push(keybuffer, (buf >> 8) &0xff);
-		buf = count = 0;
-		return 1;
-	}
-
-	if (count <= 2) 
-		return 1;
-
-	switch (buf) {
-	case MSIM_KEY_F1:
-		keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
-		buf = count = 0;
-		return 1;
-	case MSIM_KEY_F2:
-		keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
-		buf = count = 0;
-		return 1;
-	case MSIM_KEY_F3:
-		keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
-		buf = count = 0;
-		return 1;
-	case MSIM_KEY_F4:
-		keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
-		buf = count = 0;
-		return 1;
-	}
-
-
-	if((buf & 0xffffff) != (MSIM_KEY_F5 & 0xffffff)
-		&& (buf & 0xffffff) != (MSIM_KEY_F9 & 0xffffff)) {
-
-		keybuffer_push(keybuffer, buf & 0xff);
-		keybuffer_push(keybuffer, (buf >> 8) & 0xff);
-		keybuffer_push(keybuffer, (buf >> 16) & 0xff);
-		buf=count=0;
-		return 1;
-	}
-
-	if (count <= 3)
-		return 1;
-	
-	switch (buf) {
-	case MSIM_KEY_F5:
-	case MSIM_KEY_F6:
-	case MSIM_KEY_F7:
-	case MSIM_KEY_F8:
-	case MSIM_KEY_F9:
-	case MSIM_KEY_F10:
-	case MSIM_KEY_F11:
-	case MSIM_KEY_F12:
-		return 1;
-	default:
-		keybuffer_push(keybuffer, buf & 0xff);
-		keybuffer_push(keybuffer, (buf >> 8) &0xff);
-		keybuffer_push(keybuffer, (buf >> 16) &0xff);
-		keybuffer_push(keybuffer, (buf >> 24) &0xff);
-		buf = count = 0;
-		return 1;
-	}
-	return 1;
-}
-
-
-
 static int kbd_arch_process_fb(keybuffer_t *keybuffer, int scan_code)
 {
@@ -372,5 +233,5 @@
 		return kbd_arch_process_fb(keybuffer, scan_code);
 
-	return kbd_arch_process_no_fb(keybuffer, scan_code);
+	return kbd_process_no_fb(keybuffer, scan_code);
 }
 /** @}
Index: uspace/srv/kbd/arch/sparc64/include/sgcn.h
===================================================================
--- uspace/srv/kbd/arch/sparc64/include/sgcn.h	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
+++ uspace/srv/kbd/arch/sparc64/include/sgcn.h	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008 Pavel Rimsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kbdsparc64 sparc64
+ * @brief	Serengeti-specific parts of uspace keyboard handler.
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#ifndef KBD_sparc64_SGCN_H_
+#define KBD_sparc64_SGCN_H_
+
+void sgcn_init(void);
+void sgcn_key_pressed(void);
+
+#endif
+
+/** @}
+ */
Index: uspace/srv/kbd/arch/sparc64/src/kbd.c
===================================================================
--- uspace/srv/kbd/arch/sparc64/src/kbd.c	(revision c716d94ef460af2459c35a03b940bfc81915596f)
+++ uspace/srv/kbd/arch/sparc64/src/kbd.c	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -36,4 +36,5 @@
 
 #include <arch/kbd.h>
+#include <arch/sgcn.h>
 #include <ipc/ipc.h>
 #include <sysinfo.h>
@@ -79,4 +80,5 @@
 #define KBD_Z8530	1
 #define KBD_NS16550	2
+#define KBD_SGCN	3
 
 int kbd_arch_init(void)
@@ -92,4 +94,7 @@
 		ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd);
 		break;
+	case KBD_SGCN:
+		sgcn_init();
+		break;
 	default:
 		break;
@@ -101,4 +106,9 @@
 int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call)
 {
+	if (sysinfo_value("kbd.type") == KBD_SGCN) {
+		sgcn_key_pressed();
+		return 1;
+	}
+	
 	int scan_code = IPC_GET_ARG1(*call);
 
Index: uspace/srv/kbd/arch/sparc64/src/sgcn.c
===================================================================
--- uspace/srv/kbd/arch/sparc64/src/sgcn.c	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
+++ uspace/srv/kbd/arch/sparc64/src/sgcn.c	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2008 Pavel Rimsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kbdsparc64 sparc64
+ * @brief	Serengeti-specific parts of uspace keyboard handler.
+ * @ingroup  kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#include <arch/sgcn.h>
+#include <as.h>
+#include <ddi.h>
+#include <ipc/ipc.h>
+#include <kbd.h>
+#include <genarch/nofb.h>
+#include <genarch/kbd.h>
+#include <sysinfo.h>
+#include <stdio.h>
+#include <futex.h>
+
+/**
+ * SGCN buffer header. It is placed at the very beginning of the SGCN
+ * buffer. 
+ */
+typedef struct {
+	/** hard-wired to "CON" */
+	char magic[4];
+	
+	/** we don't need this */
+	char unused[8];
+	
+	/** offset within the SGCN buffer of the input buffer start */
+	uint32_t in_begin;
+	
+	/** offset within the SGCN buffer of the input buffer end */
+	uint32_t in_end;
+	
+	/** offset within the SGCN buffer of the input buffer read pointer */
+	uint32_t in_rdptr;
+	
+	/** offset within the SGCN buffer of the input buffer write pointer */
+	uint32_t in_wrptr;
+} __attribute__ ((packed)) sgcn_buffer_header_t;
+
+/*
+ * Returns a pointer to the object of a given type which is placed at the given
+ * offset from the console buffer beginning.
+ */
+#define SGCN_BUFFER(type, offset) \
+		((type *) (sram_virt_addr + sram_buffer_offset + (offset)))
+
+/** Returns a pointer to the console buffer header. */
+#define SGCN_BUFFER_HEADER	(SGCN_BUFFER(sgcn_buffer_header_t, 0))
+
+extern keybuffer_t keybuffer;
+
+/**
+ * Virtual address mapped to SRAM.
+ */
+static uintptr_t sram_virt_addr;
+
+/**
+ * SGCN buffer offset within SGCN.
+ */
+static uintptr_t sram_buffer_offset;
+
+/**
+ * Initializes the SGCN driver.
+ * Maps the physical memory (SRAM) and registers the interrupt. 
+ */
+void sgcn_init(void)
+{
+	sram_virt_addr = (uintptr_t) as_get_mappable_page(
+		sysinfo_value("sram.area.size"));
+	int result = physmem_map(
+		(void *) sysinfo_value("sram.address.physical"),
+		(void *) sram_virt_addr,
+		sysinfo_value("sram.area.size") / PAGE_SIZE,
+		AS_AREA_READ | AS_AREA_WRITE
+		);
+	if (result != 0) {
+		printf("SGCN: uspace driver could not map physical memory.");
+	}
+	
+	sram_buffer_offset = sysinfo_value("sram.buffer.offset");
+	ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"),
+		0, (void *) 0);
+}
+
+/**
+ * Handler of the "key pressed" event. Reads codes of all the pressed keys from
+ * the buffer. 
+ */
+void sgcn_key_pressed(void)
+{
+	char c;
+	
+	uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
+	uint32_t end = SGCN_BUFFER_HEADER->in_end;
+	uint32_t size = end - begin;
+	
+	volatile char *buf_ptr = (volatile char *)
+		SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+	volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
+	volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
+	
+	while (*in_rdptr_ptr != *in_wrptr_ptr) {
+		c = *buf_ptr;
+		*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
+		buf_ptr = (volatile char *)
+			SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
+		if (c == '\r') {
+                        c = '\n';
+                }
+		kbd_process_no_fb(&keybuffer, c);
+	}
+}
+
+/** @}
+ */
Index: uspace/srv/kbd/genarch/include/nofb.h
===================================================================
--- uspace/srv/kbd/genarch/include/nofb.h	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
+++ uspace/srv/kbd/genarch/include/nofb.h	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008 Pavel Rimsky
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kbd
+ * @{
+ */ 
+/** @file
+ */
+
+#ifndef KBD_genarch_NOFB_H_
+#define KBD_genarch_NOFB_H_
+
+
+#include <key_buffer.h>
+#include <genarch/scanc.h>
+
+extern int kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code);
+
+#endif
+
+/**
+ * @}
+ */ 
Index: uspace/srv/kbd/genarch/src/nofb.c
===================================================================
--- uspace/srv/kbd/genarch/src/nofb.c	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
+++ uspace/srv/kbd/genarch/src/nofb.c	(revision 8af9950eef9c2c7dfd3ef398eb581435b1f15ac1)
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006 Josef Cejka
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * - The name of the author may not be used to endorse or promote products
+ *   derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/** @addtogroup kbdmips32 mips32
+ * @brief	HelenOS mips32 arch dependent parts of uspace keyboard handler.
+ * @ingroup  kbd
+ * @{
+ */ 
+ 
+/** @file
+ */
+
+#include <genarch/nofb.h>
+#include <stdio.h> // DELETE!!!
+
+#define KEY_F1 0x504f1bL
+#define KEY_F2 0x514f1bL
+#define KEY_F3 0x524f1bL
+#define KEY_F4 0x534f1bL
+#define KEY_F5 0x35315b1bL
+#define KEY_F6 0x37315b1bL
+#define KEY_F7 0x38315b1bL
+#define KEY_F8 0x39315b1bL
+#define KEY_F9 0x30325b1bL
+#define KEY_F10 0x31325b1bL
+#define KEY_F11 0x33325b1bL
+#define KEY_F12 0x34325b1bL
+
+/**
+ * Processes the key pressed - pushes the key code into the key buffer.
+ * Used in MSIM and Serengeti, i.e. non-framebuffer consoles.
+ */
+int kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code)
+{
+	static unsigned long buf = 0;
+	static int count = 0;	
+	
+	if(scan_code == 0x7e) {
+		switch (buf) {
+		case KEY_F5:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
+			buf = count = 0;
+			return 1;
+		case KEY_F6:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
+			buf = count = 0;
+			return 1;
+		case KEY_F7:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
+			buf = count = 0;
+			return 1;
+		case KEY_F8:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
+			buf = count = 0;
+			return 1;
+		case KEY_F9:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
+			buf = count = 0;
+			return 1;
+		case KEY_F10:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
+			buf = count = 0;
+			return 1;
+		case KEY_F11:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
+			buf = count = 0;
+			return 1;
+		case KEY_F12:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 12);
+			buf = count = 0;
+			return 1;
+		default:
+			keybuffer_push(keybuffer, buf & 0xff);
+			keybuffer_push(keybuffer, (buf >> 8) &0xff);
+			keybuffer_push(keybuffer, (buf >> 16) &0xff);
+			keybuffer_push(keybuffer, (buf >> 24) &0xff);
+			keybuffer_push(keybuffer, scan_code);
+			buf = count = 0;
+			return 1;
+		}
+	}
+
+	buf |= ((unsigned long) scan_code)<<(8*(count++));
+	
+	if((buf & 0xff) != (KEY_F1 & 0xff)) {
+		keybuffer_push(keybuffer, buf);
+		buf = count = 0;
+		return 1;
+	}
+
+	if (count <= 1) 
+		return 1;
+
+	if ((buf & 0xffff) != (KEY_F1 & 0xffff) 
+		&& (buf & 0xffff) != (KEY_F5 & 0xffff) ) {
+
+		keybuffer_push(keybuffer, buf & 0xff);
+		keybuffer_push(keybuffer, (buf >> 8) &0xff);
+		buf = count = 0;
+		return 1;
+	}
+
+	if (count <= 2) 
+		return 1;
+
+	switch (buf) {
+	case KEY_F1:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
+		buf = count = 0;
+		return 1;
+	case KEY_F2:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
+		buf = count = 0;
+		return 1;
+	case KEY_F3:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
+		buf = count = 0;
+		return 1;
+	case KEY_F4:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
+		buf = count = 0;
+		return 1;
+	}
+
+
+	if((buf & 0xffffff) != (KEY_F5 & 0xffffff)
+		&& (buf & 0xffffff) != (KEY_F9 & 0xffffff)) {
+
+		keybuffer_push(keybuffer, buf & 0xff);
+		keybuffer_push(keybuffer, (buf >> 8) & 0xff);
+		keybuffer_push(keybuffer, (buf >> 16) & 0xff);
+		buf=count=0;
+		return 1;
+	}
+
+	if (count <= 3)
+		return 1;
+	
+	switch (buf) {
+	case KEY_F5:
+	case KEY_F6:
+	case KEY_F7:
+	case KEY_F8:
+	case KEY_F9:
+	case KEY_F10:
+	case KEY_F11:
+	case KEY_F12:
+		return 1;
+	default:
+		keybuffer_push(keybuffer, buf & 0xff);
+		keybuffer_push(keybuffer, (buf >> 8) &0xff);
+		keybuffer_push(keybuffer, (buf >> 16) &0xff);
+		keybuffer_push(keybuffer, (buf >> 24) &0xff);
+		buf = count = 0;
+		return 1;
+	}
+
+	return 1;
+}
+
+/** @}
+ */
