Index: kernel/arch/sparc64/include/drivers/z8530.h
===================================================================
--- kernel/arch/sparc64/include/drivers/z8530.h	(revision 2d997097cb479dacdfa9e10d61c58c18356dfb14)
+++ kernel/arch/sparc64/include/drivers/z8530.h	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
@@ -37,30 +37,91 @@
 
 #include <arch/types.h>
+#include <typedefs.h>
 #include <arch/drivers/kbd.h>
 
-#define STATUS_REG	4
-#define COMMAND_REG	4
-#define DATA_REG	6
+#define Z8530_CHAN_A	4
+#define Z8530_CHAN_B	0
 
-#define LAST_REG	DATA_REG
+#define WR0	0
+#define WR1	1
+#define WR2	2
+#define WR3	3
+#define WR4	4
+#define WR5	5
+#define WR6	6
+#define WR7	7
+#define WR8	8
+#define WR9	9
+#define WR10	10
+#define WR11	11
+#define WR12	12
+#define WR13	13
+#define WR14	14
+#define WR15	15
 
-static inline void z8530_data_write(uint8_t data)
+#define RR0	0
+#define RR1	1
+#define RR2	2
+#define RR3	3
+#define RR8	8
+#define RR10	10
+#define RR12	12
+#define RR13	13
+#define RR14	14
+#define RR15	15
+
+/* Write Register 1 */
+#define WR1_RID		(0x0<<3)	/** Receive Interrupts Disabled. */
+#define WR1_RIFCSC	(0x1<<3)	/** Receive Interrupt on First Character or Special Condition. */
+#define WR1_IARCSC	(0x2<<3)	/** Interrupt on All Receive Characters or Special Conditions. */
+#define WR1_RISC	(0x3<<3)	/** Receive Interrupt on Special Condition. */
+#define WR1_PISC	(0x1<<2)	/** Parity Is Special Condition. */
+
+/* Write Register 3 */
+#define WR3_RX_ENABLE	(0x1<<0)	/** Rx Enable. */
+#define WR3_RX8BITSCH	(0x3<<6)	/** 8-bits per character. */
+
+/* Write Register 9 */
+#define WR9_MIE		(0x1<<3)	/** Master Interrupt Enable. */
+
+/* Read Register 0 */
+#define RR0_RCA		(0x1<<0)	/** Receive Character Available. */
+
+static inline void z8530_write(index_t chan, uint8_t reg, uint8_t val)
 {
-	kbd_virt_address[DATA_REG] = data;
+	/*
+	 * Registers 8-15 will automatically issue the Point High
+	 * command as their bit 3 is 1.
+	 */
+	kbd_virt_address[WR0+chan] = reg;	/* select register */
+	kbd_virt_address[WR0+chan] = val;	/* write value */
 }
 
-static inline uint8_t z8530_data_read(void)
+static inline void z8530_write_a(uint8_t reg, uint8_t val)
 {
-	return kbd_virt_address[DATA_REG];
+	z8530_write(Z8530_CHAN_A, reg, val);
+}
+static inline void z8530_write_b(uint8_t reg, uint8_t val)
+{
+	z8530_write(Z8530_CHAN_B, reg, val);
 }
 
-static inline uint8_t z8530_status_read(void)
+static inline uint8_t z8530_read(index_t chan, uint8_t reg) 
 {
-	return kbd_virt_address[STATUS_REG];
+	/*
+	 * Registers 8-15 will automatically issue the Point High
+	 * command as their bit 3 is 1.
+	 */
+	kbd_virt_address[WR0+chan] = reg;	/* select register */
+	return kbd_virt_address[WR0+chan];
 }
 
-static inline void z8530_command_write(uint8_t command)
+static inline uint8_t z8530_read_a(uint8_t reg)
 {
-	kbd_virt_address[COMMAND_REG] = command;
+	return z8530_read(Z8530_CHAN_A, reg);
+}
+static inline uint8_t z8530_read_b(uint8_t reg)
+{
+	return z8530_read(Z8530_CHAN_B, reg);
 }
 
Index: kernel/genarch/src/kbd/z8530.c
===================================================================
--- kernel/genarch/src/kbd/z8530.c	(revision 2d997097cb479dacdfa9e10d61c58c18356dfb14)
+++ kernel/genarch/src/kbd/z8530.c	(revision ec2c55a4c241975f1e193ce31dbbbe525c29fdf1)
@@ -33,11 +33,4 @@
  * @file
  * @brief	Zilog 8530 serial port / keyboard driver.
- *
- * Note that this file is derived from the i8042.c.
- * The i8042 driver could be persuaded to control
- * the z8530 at least in the polling mode.
- * As a result, this file may contain inaccurate
- * and z8530-irrelevant constants, code and comments.
- * Still it miraculously works.
  */
 
@@ -47,4 +40,5 @@
 #include <genarch/kbd/scanc_sun.h>
 #include <arch/drivers/z8530.h>
+#include <arch/drivers/kbd.h>
 #include <arch/interrupt.h>
 #include <cpu.h>
@@ -55,31 +49,4 @@
 #include <console/console.h>
 #include <interrupt.h>
-
-/* Keyboard commands. */
-#define KBD_ENABLE	0xf4
-#define KBD_DISABLE	0xf5
-#define KBD_ACK		0xfa
-
-/*
- * 60  Write 8042 Command Byte: next data byte written to port 60h is
- *     placed in 8042 command register. Format:
- *
- *    |7|6|5|4|3|2|1|0|8042 Command Byte
- *     | | | | | | | `---- 1=enable output register full interrupt
- *     | | | | | | `----- should be 0
- *     | | | | | `------ 1=set status register system, 0=clear
- *     | | | | `------- 1=override keyboard inhibit, 0=allow inhibit
- *     | | | `-------- disable keyboard I/O by driving clock line low
- *     | | `--------- disable auxiliary device, drives clock line low
- *     | `---------- IBM scancode translation 0=AT, 1=PC/XT
- *     `----------- reserved, should be 0
- */
-
-#define z8530_SET_COMMAND 	0x60
-#define z8530_COMMAND 		0x69
-
-#define z8530_BUFFER_FULL_MASK	0x01
-#define z8530_WAIT_MASK 	0x02
-#define z8530_MOUSE_DATA        0x20
 
 /*
@@ -98,47 +65,31 @@
 };
 
-static void z8530_interrupt(int n, istate_t *istate);
-static void z8530_wait(void);
+void z8530_interrupt(int n, istate_t *istate);
+void z8530_wait(void);
 
-static iroutine oldvector;
 /** Initialize keyboard and service interrupts using kernel routine */
 void z8530_grab(void)
 {
-	oldvector = exc_register(VECTOR_KBD, "z8530_interrupt", (iroutine) z8530_interrupt);
-	z8530_wait();
-	z8530_command_write(z8530_SET_COMMAND);
-	z8530_wait();
-	z8530_data_write(z8530_COMMAND);
-	z8530_wait();
 }
 /** Resume the former interrupt vector */
 void z8530_release(void)
 {
-	if (oldvector)
-		exc_register(VECTOR_KBD, "user_interrupt", oldvector);
 }
+
+#include <print.h>
 
 /** Initialize z8530. */
 void z8530_init(void)
 {
-	int i;
-
-	z8530_grab();
-        /* Prevent user from accidentaly releasing calling z8530_resume
-	 * and disabling keyboard 
-	 */
-	oldvector = NULL; 
-
-	trap_virtual_enable_irqs(1<<IRQ_KBD);
 	chardev_initialize("z8530_kbd", &kbrd, &ops);
 	stdin = &kbrd;
 
-	/*
-	 * Clear input buffer.
-	 * Number of iterations is limited to prevent infinite looping.
-	 */
-	for (i = 0; (z8530_status_read() & z8530_BUFFER_FULL_MASK) && i < 100; i++) {
-		z8530_data_read();
-	}  
+	z8530_write_a(WR1, WR1_IARCSC);	/* interrupt on all characters */
+	z8530_write_a(WR2, 12);		/* FIXME: IRQ12 ??? */
+
+	/* 8 bits per character and enable receiver */
+	z8530_write_a(WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
+	
+	z8530_write_a(WR9, WR9_MIE);	/* Master Interrupt Enable. */
 }
 
@@ -150,26 +101,8 @@
 void z8530_interrupt(int n, istate_t *istate)
 {
-	uint8_t x;
-	uint8_t status;
-
-	while (((status=z8530_status_read()) & z8530_BUFFER_FULL_MASK)) {
-		x = z8530_data_read();
-
-		if ((status & z8530_MOUSE_DATA))
-			continue;
-
-		if (x & KEY_RELEASE)
-			key_released(x ^ KEY_RELEASE);
-		else
-			key_pressed(x);
-	}
-	trap_virtual_eoi();
 }
 
 /** Wait until the controller reads its data. */
 void z8530_wait(void) {
-	while (z8530_status_read() & z8530_WAIT_MASK) {
-		/* wait */
-	}
 }
 
@@ -190,7 +123,7 @@
 	while(!(ch = active_read_buff_read())) {
 		uint8_t x;
-		while (!(z8530_status_read() & z8530_BUFFER_FULL_MASK))
+		while (!(z8530_read_a(RR0) & RR0_RCA))
 			;
-		x = z8530_data_read();
+		x = z8530_read_a(RR8);
 		if (x != IGNORE_CODE) {
 			if (x & KEY_RELEASE)
@@ -211,6 +144,6 @@
 	uint8_t x;
 
-	while (((x = z8530_status_read() & z8530_BUFFER_FULL_MASK))) {
-		x = z8530_data_read();
+	while (z8530_read_a(RR0) & RR0_RCA) {
+		x = z8530_read_a(RR8);
 		if (x != IGNORE_CODE) {
 			if (x & KEY_RELEASE)
