Index: boot/arch/ia64/loader/gefi/HelenOS/mkimage.c
===================================================================
--- boot/arch/ia64/loader/gefi/HelenOS/mkimage.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
+++ boot/arch/ia64/loader/gefi/HelenOS/mkimage.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -0,0 +1,17 @@
+#include<stdio.h>
+#include<stdlib.h>
+
+int main(int argc,char** argv)
+{
+	FILE *fi,*fo;
+	int count=0;
+	int ch;
+	fi=fopen("image.bin","rb");
+	fo=fopen("image.c","wb");
+	fprintf(fo,"char HOSimage[]={\n");
+	if((ch=getc(fi))!=EOF) {fprintf(fo,"0x%02X",ch);count++;}
+	while((ch=getc(fi))!=EOF) {fprintf(fo,",0x%02X",ch);count++;}
+	fprintf(fo,"};\nint HOSimagesize=%d;\n",count);
+	return EXIT_SUCCESS;
+}
+
Index: kernel/Makefile
===================================================================
--- kernel/Makefile	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/Makefile	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -127,6 +127,14 @@
 endif
 
+ifeq ($(CONFIG_I8042_INTERRUPT_DRIVEN),y)
+	DEFS += -DCONFIG_I8042_INTERRUPT_DRIVEN
+endif
+
 ifeq ($(CONFIG_NS16550_INTERRUPT_DRIVEN),y)
 	DEFS += -DCONFIG_NS16550_INTERRUPT_DRIVEN
+endif
+
+ifeq ($(CONFIG_IOSAPIC),y)
+	DEFS += -DCONFIG_IOSAPIC
 endif
 
Index: kernel/arch/ia64/include/drivers/kbd.h
===================================================================
--- kernel/arch/ia64/include/drivers/kbd.h	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
+++ kernel/arch/ia64/include/drivers/kbd.h	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar, Jakub Vana
+ * 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 ia6464	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef KERN_ia64_KBD_H_
+#define KERN_ia64_KBD_H_
+
+
+typedef enum {
+	KBD_UNKNOWN,
+	KBD_SKI,
+	KBD_LEGACY,
+	KBD_NS16550
+} kbd_type_t;
+
+#endif
+
+/** @}
+ */
Index: kernel/arch/ia64/include/interrupt.h
===================================================================
--- kernel/arch/ia64/include/interrupt.h	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/arch/ia64/include/interrupt.h	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -57,4 +57,5 @@
 #define IRQ_MOUSE		252
 #define INTERRUPT_SPURIOUS	15
+#define LAGACY_INTERRUPT_BASE	0x20
 
 /** General Exception codes. */
@@ -153,4 +154,5 @@
 extern void disabled_fp_register(uint64_t vector, istate_t *istate);
 
+
 #endif
 
Index: kernel/arch/ia64/src/drivers/ega.c
===================================================================
--- kernel/arch/ia64/src/drivers/ega.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/arch/ia64/src/drivers/ega.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -95,4 +95,5 @@
 	sysinfo_set_item_val("fb.width", NULL, ROW);
 	sysinfo_set_item_val("fb.height", NULL, ROWS);
+	sysinfo_set_item_val("fb.blinking", NULL, true);
 	sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM & 0xffffffff);
 	
Index: kernel/arch/ia64/src/ia64.c
===================================================================
--- kernel/arch/ia64/src/ia64.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/arch/ia64/src/ia64.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -64,8 +64,10 @@
 
 /*NS16550 as a COM 1*/
-#define NS16550_IRQ 4
+#define NS16550_IRQ (4+LAGACY_INTERRUPT_BASE)
 #define NS16550_PORT 0x3f8
 
 bootinfo_t *bootinfo;
+
+static uint64_t iosapic_base=0xfec00000;
 
 void arch_pre_main(void)
@@ -112,8 +114,34 @@
 }
 
+static void iosapic_init(void)
+{
+
+	uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base))|FW_OFFSET;
+	int i;
+	
+	
+	for(i=0;i<16;i++)
+	{
+	
+		if(i==2) continue;	 //Disable Cascade interrupt
+		((uint32_t*)(IOSAPIC+0x00))[0]=0x10+2*i;
+		srlz_d();
+		((uint32_t*)(IOSAPIC+0x10))[0]=LAGACY_INTERRUPT_BASE+i;
+		srlz_d();
+		((uint32_t*)(IOSAPIC+0x00))[0]=0x10+2*i+1;
+		srlz_d();
+		((uint32_t*)(IOSAPIC+0x10))[0]=1<<(56-32);
+		srlz_d();
+	}
+
+}
+
+
 void arch_post_mm_init(void)
 {
 	if(config.cpu_active==1)
 	{
+		iosapic_init();
+	
 		irq_init(INR_COUNT, INR_COUNT);
 #ifdef SKI
@@ -123,5 +151,6 @@
 #endif	
 	}
-	it_init();	
+	it_init();
+		
 }
 
@@ -143,5 +172,7 @@
 		i8042_poll();
 #ifdef CONFIG_NS16550
+	#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN
 		ns16550_poll();
+	#endif	
 #endif
 		thread_usleep(POLL_INTERVAL);
@@ -149,4 +180,11 @@
 }
 #endif
+
+
+static void end_of_irq_void(void *cir_arg __attribute__((unused)),inr_t inr __attribute__((unused)))
+{
+	return;
+}
+
 
 void arch_post_smp_init(void)
@@ -172,5 +210,5 @@
 
 #ifdef CONFIG_NS16550
-		ns16550_init(kbd, NS16550_IRQ, NS16550_PORT); // as a COM 1
+		ns16550_init(kbd, NS16550_IRQ, NS16550_PORT,end_of_irq_void,NULL); // as a COM 1
 #else
 #endif
@@ -188,4 +226,8 @@
 	sysinfo_set_item_val("ia64_iospace.address", NULL, true);
 	sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
+
+
+
+
 
 }
@@ -238,4 +280,10 @@
 #ifdef SKI
 	ski_kbd_grab();
+#else
+	i8042_grab();
+	#ifdef CONFIG_NS16550
+		ns16550_grab();
+	#endif	
+		
 #endif	
 }
@@ -247,4 +295,10 @@
 #ifdef SKI
 	ski_kbd_release();
+	i8042_release();
+#else	
+	#ifdef CONFIG_NS16550
+		ns16550_release();
+	#endif	
+
 #endif
 }
Index: kernel/arch/ia64/src/interrupt.c
===================================================================
--- kernel/arch/ia64/src/interrupt.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/arch/ia64/src/interrupt.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -236,5 +236,5 @@
 }
 
-static void end_of_local_irq()
+static void end_of_local_irq(void)
 {
 	asm volatile ("mov cr.eoi=r0;;");
@@ -244,5 +244,4 @@
 void external_interrupt(uint64_t vector, istate_t *istate)
 {
-	irq_t *irq;
 	cr_ivr_t ivr;
 	
@@ -250,9 +249,4 @@
 	srlz_d();
 
-	irq = irq_dispatch_and_lock(ivr.vector);
-	if (irq) {
-		irq->handler(irq, irq->arg);
-		spinlock_unlock(&irq->lock);
-	} else {
 		switch (ivr.vector) {
 		case INTERRUPT_SPURIOUS:
@@ -271,9 +265,37 @@
 
 		default:
-			panic("\nUnhandled External Interrupt Vector %d\n",
-			    ivr.vector);
+			{
+
+				int ack=false;
+				irq_t *irq = irq_dispatch_and_lock(ivr.vector);
+				if (irq) {
+					/*
+					 * The IRQ handler was found.
+					 */
+		 
+					if (irq->preack) {
+						/* Send EOI before processing the interrupt */
+						end_of_local_irq();
+						ack=true;
+					}
+					irq->handler(irq, irq->arg);
+					spinlock_unlock(&irq->lock);
+				} else {
+					/*
+					 * Unhandled interrupt.
+					 */
+					end_of_local_irq();
+					ack=true;
+#ifdef CONFIG_DEBUG
+					printf("\nUnhandled External Interrupt Vector %d\n",ivr.vector);
+#endif
+				}
+				if(!ack) end_of_local_irq();
+
+			}	
+
+
 			break;
 		}
-	}
 }
 
Index: kernel/arch/ia64/src/ski/ski.c
===================================================================
--- kernel/arch/ia64/src/ski/ski.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/arch/ia64/src/ski/ski.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -45,4 +45,5 @@
 #include <synch/spinlock.h>
 #include <arch/asm.h>
+#include <drivers/kbd.h>
 
 #define SKI_KBD_INR	0
@@ -228,4 +229,5 @@
 	sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR);
 	sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno);
+	sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
 }
 
Index: kernel/genarch/src/kbd/ns16550.c
===================================================================
--- kernel/genarch/src/kbd/ns16550.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/genarch/src/kbd/ns16550.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -39,6 +39,6 @@
 #include <genarch/kbd/scanc.h>
 #include <genarch/kbd/scanc_sun.h>
+#include <arch/drivers/kbd.h>
 #ifndef ia64
-#include <arch/drivers/kbd.h>
 #include <arch/drivers/ns16550.h>
 #endif
@@ -131,12 +131,16 @@
 	ns16550_irq.cir_arg = cir_arg;
 	irq_register(&ns16550_irq);
+
+
+	while ((ns16550_lsr_read(&ns16550) & LSR_DATA_READY)) 
+		ns16550_rbr_read(&ns16550);
+
 	
 	sysinfo_set_item_val("kbd", NULL, true);
-#ifndef ia64
 	sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
-#endif
 	sysinfo_set_item_val("kbd.devno", NULL, devno);
 	sysinfo_set_item_val("kbd.inr", NULL, inr);
 	sysinfo_set_item_val("kbd.address.virtual", NULL, port);
+	sysinfo_set_item_val("kbd.port", NULL, port);
 
 #ifdef CONFIG_NS16550_INTERRUPT_DRIVEN
@@ -148,4 +152,5 @@
 #ifdef ia64
     	uint8_t c;
+    	// This switches rbr & ier to mode when accept baudrate constant
     	c = ns16550_lcr_read(&ns16550);
     	ns16550_lcr_write(&ns16550, 0x80 | c);
Index: kernel/generic/src/ipc/irq.c
===================================================================
--- kernel/generic/src/ipc/irq.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/generic/src/ipc/irq.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -101,5 +101,5 @@
 			    code->cmds[i].value;
 			break;
-#if defined(ia32) || defined(amd64)
+#if defined(ia32) || defined(amd64) || defined(ia64)
 		case CMD_PORT_READ_1:
 			dstval = inb((long) code->cmds[i].addr);
Index: kernel/kernel.config
===================================================================
--- kernel/kernel.config	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ kernel/kernel.config	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -142,6 +142,12 @@
 ! [ARCH=sparc64|ARCH=ia64] CONFIG_NS16550 (y/n)
 
+# IOSapic on default address support (including legacy IRQ)
+! [ARCH=ia64] CONFIG_IOSAPIC (y/n)
+
+# Interrupt-driven driver for Legacy Keyboard?
+! [CONFIG_IOSAPIC=y] CONFIG_I8042_INTERRUPT_DRIVEN (y/n)
+
 # Interrupt-driven driver for NS16550?
-! [CONFIG_NS16550=y] CONFIG_NS16550_INTERRUPT_DRIVEN (n/y)
+! [CONFIG_NS16550=y&((ARCH!=ia64)|CONFIG_IOSAPIC=y)] CONFIG_NS16550_INTERRUPT_DRIVEN (y/n)
 
 # Virtually indexed D-cache support
Index: uspace/lib/libc/arch/ia64/include/ddi.h
===================================================================
--- uspace/lib/libc/arch/ia64/include/ddi.h	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
+++ uspace/lib/libc/arch/ia64/include/ddi.h	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2005 Jakub Jermar, Jakub Vana
+ * 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 ia64	
+ * @{
+ */
+/** @file
+ */
+
+#ifndef LIBC_ia64_DDI_H_
+#define LIBC_ia64_DDI_H_
+
+#include <libarch/types.h>
+
+typedef uint64_t ioport_t;
+
+uint64_t get_ia64_iospace_address(void);
+
+extern uint64_t ia64_iospace_address;
+
+#define IA64_IOSPACE_ADDRESS (ia64_iospace_address?ia64_iospace_address:(ia64_iospace_address=get_ia64_iospace_address()))
+
+static inline void  outb(ioport_t port,uint8_t v)
+{
+	*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
+
+	asm volatile ("mf\n" ::: "memory");
+}
+
+static inline void  outw(ioport_t port,uint16_t v)
+{
+	*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
+
+	asm volatile ("mf\n" ::: "memory");
+}
+
+static inline void  outl(ioport_t port,uint32_t v)
+{
+	*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
+
+	asm volatile ("mf\n" ::: "memory");
+}
+
+
+
+static inline uint8_t inb(ioport_t port)
+{
+	asm volatile ("mf\n" ::: "memory");
+
+	return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
+}
+
+static inline uint16_t inw(ioport_t port)
+{
+	asm volatile ("mf\n" ::: "memory");
+
+	return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 ))));
+}
+
+static inline uint32_t inl(ioport_t port)
+{
+	asm volatile ("mf\n" ::: "memory");
+
+	return *((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
+}
+
+
+
+
+#endif
+
+/** @}
+ */
Index: uspace/lib/libc/arch/ia64/src/ddi.c
===================================================================
--- uspace/lib/libc/arch/ia64/src/ddi.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
+++ uspace/lib/libc/arch/ia64/src/ddi.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -0,0 +1,13 @@
+#include <libarch/ddi.h>
+#include <sysinfo.h>
+
+uint64_t ia64_iospace_address=0;
+
+
+uint64_t get_ia64_iospace_address(void)
+{
+
+	return sysinfo_value("ia64_iospace.address.virtual");
+
+}
+
Index: uspace/srv/fb/ega.c
===================================================================
--- uspace/srv/fb/ega.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ uspace/srv/fb/ega.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -65,6 +65,9 @@
 #define EGA_IO_SIZE 2
 
-#define NORMAL_COLOR       0x0f
-#define INVERTED_COLOR     0xf0
+int ega_normal_color=0x0f;
+int ega_inverted_color=0xf0;
+
+#define NORMAL_COLOR		ega_normal_color       
+#define INVERTED_COLOR		ega_inverted_color
 
 #define EGA_STYLE(fg,bg) ((fg) > (bg) ? NORMAL_COLOR : INVERTED_COLOR)
@@ -77,5 +80,5 @@
 static char *scr_addr;
 
-static unsigned int style = NORMAL_COLOR;
+static unsigned int style;
 
 static void clrscr(void)
@@ -313,4 +316,11 @@
 	scr_width = sysinfo_value("fb.width");
 	scr_height = sysinfo_value("fb.height");
+	if(sysinfo_value("fb.blinking"))
+	{
+			ega_normal_color&=0x77;
+			ega_inverted_color&=0x77;
+	}
+	style = NORMAL_COLOR;
+
 	iospace_enable(task_get_id(), (void *) EGA_IO_ADDRESS, 2);
 
Index: uspace/srv/kbd/arch/ia64/src/kbd.c
===================================================================
--- uspace/srv/kbd/arch/ia64/src/kbd.c	(revision 57e76cb2b99587198056fdcf3441d24f54f93a56)
+++ uspace/srv/kbd/arch/ia64/src/kbd.c	(revision 323a5aaf36674c20719d102e0508c32ef466bfa3)
@@ -40,4 +40,22 @@
 #include <kbd.h>
 #include <keys.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <unistd.h>
+#include <align.h>
+#include <async.h>
+#include <ipc/ipc.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ddi.h>
+#include <sysinfo.h>
+#include <as.h>
+#include <ipc/fb.h>
+#include <ipc/ipc.h>
+#include <ipc/ns.h>
+#include <ipc/services.h>
+#include <libarch/ddi.h>
+
 
 #define KEY_F1 0x504f1b
@@ -54,5 +72,42 @@
 #define KEY_F12 0x7e34325b1b
 
+
+
+
+#define NSKEY_F1 0x415b5b1b
+#define NSKEY_F2 0x425b5b1b
+#define NSKEY_F3 0x435b5b1b
+#define NSKEY_F4 0x445b5b1b
+#define NSKEY_F5 0x455b5b1b
+#define NSKEY_F6 0x37315b1b
+#define NSKEY_F7 0x38315b1b
+#define NSKEY_F8 0x39315b1b
+#define NSKEY_F9 0x30325b1b
+#define NSKEY_F10 0x31325b1b
+#define NSKEY_F11 0x33325b1b
+#define NSKEY_F12 0x34325b1b
+
+
 #define FUNCTION_KEYS 0x100
+
+
+#define KBD_SKI 1
+#define	KBD_LEGACY 2
+#define	KBD_NS16550 3
+
+
+
+
+/* NS16550 registers */
+#define RBR_REG		0	/** Receiver Buffer Register. */
+#define IER_REG		1	/** Interrupt Enable Register. */
+#define IIR_REG		2	/** Interrupt Ident Register (read). */
+#define FCR_REG		2	/** FIFO control register (write). */
+#define LCR_REG		3	/** Line Control register. */
+#define MCR_REG		4	/** Modem Control Register. */
+#define LSR_REG		5	/** Line Status Register. */
+
+
+
 
 irq_cmd_t ski_cmds[1] = {
@@ -65,8 +120,30 @@
 };
 
+
+
+irq_cmd_t ns16550_cmds[1] = {
+	{ CMD_PORT_READ_1, 0, 0, 2 },
+};
+
+irq_code_t ns16550_kbd = {
+	1,
+	ns16550_cmds
+};
+
+
+uint16_t ns16550_port;
+
+int kbd_type;
+
 int kbd_arch_init(void)
 {
 	if (sysinfo_value("kbd")) {
-		ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ski_kbd);
+		kbd_type=sysinfo_value("kbd.type");
+		if(kbd_type==KBD_SKI) ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ski_kbd);
+		if(kbd_type==KBD_NS16550) {
+			ns16550_kbd.cmds[0].addr= (void *)  (sysinfo_value("kbd.port")+RBR_REG);
+			ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd);
+			iospace_enable(task_get_id(),ns16550_port=sysinfo_value("kbd.port"),8);
+		}	
 		return 0;
 	}	
@@ -82,6 +159,154 @@
 }
 */
-
-int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) 
+#define LSR_DATA_READY	0x01
+
+int kbd_ns16550_process(keybuffer_t *keybuffer, ipc_call_t *call) 
+{
+	static unsigned long buf = 0;
+	static int count = 0, esc_count=0;	
+
+	int scan_code = IPC_GET_ARG2(*call);
+
+	if (scan_code == 0x1b) {
+		esc_count++;
+		if (esc_count == 3) {
+			__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE);
+		}	
+	} else {
+		esc_count = 0;
+	}
+
+	if(scan_code==0x0d) return 1;	//Delete CR
+
+	if(scan_code == 0x7e) {
+		switch (buf) {
+		case NSKEY_F6:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 6);
+			buf = count = 0;
+			return 1;
+		case NSKEY_F7:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 7);
+			buf = count = 0;
+			return 1;
+		case NSKEY_F8:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 8);
+			buf = count = 0;
+			return 1;
+		case NSKEY_F9:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 9);
+			buf = count = 0;
+			return 1;
+		case NSKEY_F10:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 10);
+			buf = count = 0;
+			return 1;
+		case NSKEY_F11:
+			keybuffer_push(keybuffer,FUNCTION_KEYS | 11);
+			buf = count = 0;
+			return 1;
+		case NSKEY_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) != (NSKEY_F1 & 0xff)) {
+		keybuffer_push(keybuffer, buf);
+		buf = count = 0;
+		return 1;
+	}
+
+	if (count <= 1) 
+		return 1;
+
+	if ((buf & 0xffff) != (NSKEY_F1 & 0xffff))  {
+
+		keybuffer_push(keybuffer, buf & 0xff);
+		keybuffer_push(keybuffer, (buf >> 8) &0xff);
+		buf = count = 0;
+		return 1;
+	}
+
+	if (count <= 2) 
+		return 1;
+
+
+	if ((buf & 0xffffff) != (NSKEY_F1 & 0xffffff) 
+		&& (buf & 0xffffff) != (NSKEY_F6 & 0xffffff) 
+		&& (buf & 0xffffff) != (NSKEY_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 NSKEY_F1:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 1);
+		buf = count = 0;
+		return 1;
+	case NSKEY_F2:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 2);
+		buf = count = 0;
+		return 1;
+	case NSKEY_F3:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 3);
+		buf = count = 0;
+		return 1;
+	case NSKEY_F4:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 4);
+		buf = count = 0;
+		return 1;
+	case NSKEY_F5:
+		keybuffer_push(keybuffer,FUNCTION_KEYS | 5);
+		buf = count = 0;
+		return 1;
+	}
+
+
+	
+	switch (buf) {
+	case NSKEY_F6:
+	case NSKEY_F7:
+	case NSKEY_F8:
+	case NSKEY_F9:
+	case NSKEY_F10:
+	case NSKEY_F11:
+	case NSKEY_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;
+}
+
+
+
+
+
+
+
+int kbd_ski_process(keybuffer_t *keybuffer, ipc_call_t *call) 
 {
 	static unsigned long long buf = 0;
@@ -89,5 +314,5 @@
 	static int esc_count = 0;
 	int scan_code = IPC_GET_ARG2(*call);
-
+	
 	/*
 	 * Please preserve this code (it can be used to determine scancodes)
@@ -98,4 +323,5 @@
 	//keybuffer_push(keybuffer, ' ');
 	//*/
+
 	
 	if (scan_code) {
@@ -156,7 +382,17 @@
 		buf = count = 0;
 	}
-
 	return 	1;
 }
+
+int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) 
+{
+	printf("KBD Key pressed: %x(%c)\n",IPC_GET_ARG2(*call),IPC_GET_ARG2(*call));
+	if(kbd_type==KBD_SKI) return kbd_ski_process(keybuffer,call);
+	if(kbd_type==KBD_NS16550) return kbd_ns16550_process(keybuffer,call);
+
+	
+}
+
+
 
 /**
