Index: uspace/app/init/Makefile
===================================================================
--- uspace/app/init/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/init/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,87 @@
+#
+# Copyright (c) 2005 Martin Decky
+# 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.
+#
+
+include ../../../version
+include ../../Makefile.config
+
+## Setup toolchain
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I../../srv/kbd/include
+
+LIBS = $(LIBC_PREFIX)/libc.a
+DEFS += -DRELEASE=\"$(RELEASE)\"
+
+ifdef REVISION
+	DEFS += "-DREVISION=\"$(REVISION)\""
+endif
+
+ifdef TIMESTAMP
+	DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
+endif
+
+## Sources
+#
+
+OUTPUT = init
+SOURCES = \
+	init.c \
+	version.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all clean depend disasm
+
+all: $(OUTPUT) disasm
+
+-include Makefile.depend
+
+clean:
+	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
+
+depend:
+	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+disasm:
+	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
+
+%.o: %.S
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/app/init/init.c
===================================================================
--- uspace/app/init/init.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/init/init.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2005 Martin Decky
+ * 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 init Init
+ * @brief	Init process for testing purposes.
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#include "version.h"
+#include <stdio.h>
+
+static void test_console(void)
+{
+	int c;
+
+	while ((c = getchar()) != EOF)
+		putchar(c);
+}
+
+int main(int argc, char *argv[])
+{
+	version_print();
+
+	printf("This is init\n");
+	
+	test_console();
+
+	printf("\nBye.\n");
+
+	return 0;
+}
+
+/** @}
+ */
+
Index: uspace/app/init/init.h
===================================================================
--- uspace/app/init/init.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/init/init.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * 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 init
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#ifndef __INIT_H__
+#define __INIT_H__
+
+#include "version.h"
+
+#endif
+
+/** @}
+ */
+
Index: uspace/app/init/version.c
===================================================================
--- uspace/app/init/version.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/init/version.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006 Jakub Jermar
+ * 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 init
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include "version.h"
+
+char *release = RELEASE;
+
+#ifdef REVISION
+	char *revision = ", revision " REVISION;
+#else
+	char *revision = "";
+#endif
+
+#ifdef TIMESTAMP
+	char *timestamp = "\nBuilt on " TIMESTAMP;
+#else
+	char *timestamp = "";
+#endif
+
+/** Print version information. */
+void version_print(void)
+{
+	printf("HelenOS init\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp);
+}
+
+/** @}
+ */
Index: uspace/app/init/version.h
===================================================================
--- uspace/app/init/version.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/init/version.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2006 Martin Decky
+ * 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 init
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#ifndef __VERSION_H__
+#define __VERSION_H__
+
+extern void version_print(void);
+
+#endif
+
+/** @}
+ */
+
Index: uspace/app/klog/Makefile
===================================================================
--- uspace/app/klog/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/klog/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,73 @@
+#
+# Copyright (c) 2005 Martin Decky
+# 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.
+#
+
+## Setup toolchain
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+LIBS = $(LIBC_PREFIX)/libc.a
+
+## Sources
+#
+
+OUTPUT = klog
+SOURCES = \
+	klog.c
+
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all clean depend disasm
+
+all: $(OUTPUT) disasm
+
+-include Makefile.depend
+
+clean:
+	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
+
+depend:
+	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+disasm:
+	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
+
+%.o: %.S
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/app/klog/klog.c
===================================================================
--- uspace/app/klog/klog.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/klog/klog.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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 klog KLog
+ * @brief	HelenOS KLog
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#include <stdio.h>
+#include <ipc/ipc.h>
+#include <async.h>
+#include <ipc/services.h>
+#include <as.h>
+#include <sysinfo.h>
+
+/* Pointer to klog area */
+static char *klog;
+
+static void interrupt_received(ipc_callid_t callid, ipc_call_t *call)
+{
+	int i;
+	
+	async_serialize_start();
+	for (i=0; klog[i + IPC_GET_ARG1(*call)] && i < IPC_GET_ARG2(*call); i++)
+		putchar(klog[i + IPC_GET_ARG1(*call)]);
+	putchar('\n');
+	async_serialize_end();
+}
+
+int main(int argc, char *argv[])
+{
+	int res;
+	void *mapping;
+
+	printf("Kernel console output.\n");
+	
+	mapping = as_get_mappable_page(PAGE_SIZE);
+	res = ipc_call_sync_3(PHONE_NS, IPC_M_AS_AREA_RECV, 
+			      (sysarg_t) mapping, PAGE_SIZE, SERVICE_MEM_KLOG,
+			      NULL, NULL, NULL);
+	if (res) {
+		printf("Failed to initialize klog memarea\n");
+		_exit(1);
+	}
+	klog = mapping;
+
+	int inr = sysinfo_value("klog.inr");
+	int devno = sysinfo_value("klog.devno");
+	if (ipc_register_irq(inr, devno, 0, NULL)) {
+		printf("Error registering for klog service.\n");
+		return 0;
+	}
+
+	async_set_interrupt_received(interrupt_received);
+
+	async_manager();
+
+	return 0;
+}
+
+/** @}
+ */
Index: uspace/app/tester/Makefile
===================================================================
--- uspace/app/tester/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,83 @@
+#
+# Copyright (c) 2005 Martin Decky
+# 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.
+#
+
+## Setup toolchain
+#
+
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+CFLAGS += -I../../srv/kbd/include
+
+LIBS = $(LIBC_PREFIX)/libc.a
+
+## Sources
+#
+
+OUTPUT = tester
+SOURCES = tester.c \
+	thread/thread1.c \
+	print/print1.c \
+	fault/fault1.c \
+	fault/fault2.c \
+	ipc/register.c \
+	ipc/connect.c \
+	ipc/send_async.c \
+	ipc/send_sync.c \
+	ipc/answer.c \
+	ipc/hangup.c
+
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all clean depend disasm
+
+all: $(OUTPUT) disasm
+
+-include Makefile.depend
+
+clean:
+	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend
+
+depend:
+	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+disasm:
+	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
+
+%.o: %.S
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/app/tester/fault/fault1.c
===================================================================
--- uspace/app/tester/fault/fault1.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/fault/fault1.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * Copyright (c) 2005 Jakub Jermar
+ * 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.
+ */
+
+#include "../tester.h"
+
+char * test_fault1(bool quiet)
+{
+	((int *)(0))[1] = 0;
+	
+	return "Survived write to NULL";
+}
Index: uspace/app/tester/fault/fault1.def
===================================================================
--- uspace/app/tester/fault/fault1.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/fault/fault1.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"fault1",
+	"Write to NULL",
+	&test_fault1,
+	false
+},
Index: uspace/app/tester/fault/fault2.c
===================================================================
--- uspace/app/tester/fault/fault2.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/fault/fault2.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * Copyright (c) 2005 Jakub Jermar
+ * 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.
+ */
+
+#include "../tester.h"
+
+char * test_fault2(bool quiet)
+{
+	volatile long long var;
+	volatile int var1;
+	
+	var1 = *((int *) (((char *) (&var)) + 1));
+	
+	return "Survived unaligned read";
+}
Index: uspace/app/tester/fault/fault2.def
===================================================================
--- uspace/app/tester/fault/fault2.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/fault/fault2.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"fault2",
+	"Unaligned read",
+	&test_fault2,
+	false
+},
Index: uspace/app/tester/ipc/answer.c
===================================================================
--- uspace/app/tester/ipc/answer.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/answer.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "../tester.h"
+
+char * test_answer(bool quiet)
+{
+	int i,cnt, errn = 0;
+	char c;
+
+	cnt = 0;
+	for (i = 0;i < 50; i++) {
+		if (callids[i]) {
+			printf("%d: %P\n", cnt, callids[i]);
+			cnt++;
+		}
+		if (cnt >= 10)
+			break;
+	}
+	if (!cnt)
+		return;
+	printf("Choose message:\n");
+	do {
+		c = getchar();
+	} while (c < '0' || (c-'0') >= cnt);
+	cnt = c - '0' + 1;
+	
+	for (i = 0; cnt; i++)
+		if (callids[i])
+			cnt--;
+	i -= 1;
+
+	printf("Normal (n) or hangup (h) or error(e) message?\n");
+	do {
+		c = getchar();
+	} while (c != 'n' && c != 'h' && c != 'e');
+	if (c == 'n')
+		errn = 0;
+	else if (c == 'h')
+		errn = EHANGUP;
+	else if (c == 'e')
+		errn = ENOENT;
+	printf("Answering %P\n", callids[i]);
+	ipc_answer_fast(callids[i], errn, 0, 0);
+	callids[i] = 0;
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/answer.def
===================================================================
--- uspace/app/tester/ipc/answer.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/answer.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"answer",
+	"IPC answer message test",
+	&test_answer,
+	true
+},
Index: uspace/app/tester/ipc/connect.c
===================================================================
--- uspace/app/tester/ipc/connect.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/connect.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+
+char * test_connect(bool quiet)
+{
+	char c;
+	int svc;
+	int phid;
+
+	printf("Choose one service: 0:10000....9:10009\n");
+	do {
+		c = getchar();
+	} while (c < '0' || c > '9');
+	
+	svc = IPC_TEST_START + c - '0';
+	if (svc == myservice)
+		return "Currently cannot connect to myself, update test";
+	
+	printf("Connecting to %d..", svc);
+	phid = ipc_connect_me_to(PHONE_NS, svc, 0);
+	if (phid > 0) {
+		printf("phoneid: %d\n", phid);
+		phones[phid] = 1;
+	} else
+		return "Error";
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/connect.def
===================================================================
--- uspace/app/tester/ipc/connect.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/connect.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"connect",
+	"IPC connection test (connect to other service)",
+	&test_connect,
+	true
+},
Index: uspace/app/tester/ipc/hangup.c
===================================================================
--- uspace/app/tester/ipc/hangup.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/hangup.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include "../tester.h"
+
+char * test_hangup(bool quiet)
+{
+	char c;
+	int res;
+	int phoneid;
+
+	printf("Select phoneid to hangup: 2-9\n");
+	do {
+		c = getchar();
+	} while (c < '2' || c > '9');
+	phoneid = c - '0';
+	
+	printf("Hanging up...");
+	res = ipc_hangup(phoneid);
+	printf("done: %d\n", phoneid);	
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/hangup.def
===================================================================
--- uspace/app/tester/ipc/hangup.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/hangup.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"hangup",
+	"IPC hangup test",
+	&test_hangup,
+	true
+},
Index: uspace/app/tester/ipc/register.c
===================================================================
--- uspace/app/tester/ipc/register.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/register.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <async.h>
+#include "../tester.h"
+
+static void client_connection(ipc_callid_t iid, ipc_call_t *icall)
+{
+	ipc_callid_t callid;
+	ipc_call_t call;
+	ipcarg_t phonehash = icall->in_phone_hash;
+	int retval;
+	int i;
+
+	printf("Connected phone: %P, accepting\n", icall->in_phone_hash);
+	ipc_answer_fast(iid, 0, 0, 0);
+	for (i = 0; i < 1024; i++)
+		if (!connections[i]) {
+			connections[i] = phonehash;
+			break;
+		}
+	
+	while (1) {
+		callid = async_get_call(&call);
+		switch (IPC_GET_METHOD(call)) {
+		case IPC_M_PHONE_HUNGUP:
+			printf("Phone (%P) hung up.\n", phonehash);
+			retval = 0;
+			break;
+		default:
+			printf("Received message from %P: %X\n", phonehash,callid);
+			for (i = 0; i < 1024; i++)
+				if (!callids[i]) {
+					callids[i] = callid;
+					break;
+				}
+			continue;
+		}
+		ipc_answer_fast(callid, retval, 0, 0);
+	}
+}
+
+char * test_register(bool quiet)
+{
+	int i;
+	
+	async_set_client_connection(client_connection);
+
+	for (i = IPC_TEST_START; i < IPC_TEST_START + 10; i++) {
+		ipcarg_t phonead;
+		int res = ipc_connect_to_me(PHONE_NS, i, 0, &phonead);
+		if (!res)
+			break;
+		printf("Failed registering as %d..:%d\n", i, res);
+	}
+	printf("Registered as service: %d\n", i);
+	myservice = i;
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/register.def
===================================================================
--- uspace/app/tester/ipc/register.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/register.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"register",
+	"IPC registration test",
+	&test_register,
+	true
+},
Index: uspace/app/tester/ipc/send_async.c
===================================================================
--- uspace/app/tester/ipc/send_async.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/send_async.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+
+static void callback(void *_private, int retval, ipc_call_t *data)
+{
+	printf("Received response to msg %d - retval: %d.\n", _private, retval);
+}
+
+char * test_send_async(bool quiet)
+{
+	int phoneid;
+	int res;
+	static int msgid = 1;
+	char c;
+
+	printf("Select phoneid to send msg: 2-9\n");
+	do {
+		c = getchar();
+	} while (c < '2' || c > '9');
+	phoneid = c - '0';
+
+	ipc_call_async(phoneid, 2000, 0, (void *) msgid, callback, 1);
+	printf("Async sent - msg %d\n", msgid);
+	msgid++;
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/send_async.def
===================================================================
--- uspace/app/tester/ipc/send_async.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/send_async.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"send_async",
+	"IPC send async message test",
+	&test_send_async,
+	true
+},
Index: uspace/app/tester/ipc/send_sync.c
===================================================================
--- uspace/app/tester/ipc/send_sync.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/send_sync.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+
+char * test_send_sync(bool quiet)
+{
+	int phoneid;
+	int res;
+	static int msgid = 1;
+	char c;
+
+	printf("Select phoneid to send msg: 2-9\n");
+	do {
+		c = getchar();
+	} while (c < '2' || c > '9');
+	phoneid = c - '0';
+	
+	printf("Sending msg...");
+	res = ipc_call_sync_2(phoneid, 2000, 0, 0, NULL, NULL);
+	printf("done: %d\n", res);
+	
+	return NULL;
+}
Index: uspace/app/tester/ipc/send_sync.def
===================================================================
--- uspace/app/tester/ipc/send_sync.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/ipc/send_sync.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"send_sync",
+	"IPC send sync message test",
+	&test_send_sync,
+	true
+},
Index: uspace/app/tester/print/print1.c
===================================================================
--- uspace/app/tester/print/print1.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/print/print1.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+
+#define BUFFER_SIZE 32
+
+char * test_print1(bool quiet)
+{
+	if (!quiet) {
+		int retval;
+		unsigned int nat = 0x12345678u;
+		
+		char buffer[BUFFER_SIZE];
+		
+		printf(" text 10.8s %*.*s \n", 5, 3, "text");
+		printf(" very long text 10.8s %10.8s \n", "very long text");
+		printf(" text 8.10s %8.10s \n", "text");
+		printf(" very long text 8.10s %8.10s \n", "very long text");
+		
+		printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' );
+		printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 );
+		printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 );
+		printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 );
+		
+		printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
+		
+		printf(" Print to NULL '%s'\n", NULL);
+		
+		retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
+		printf("Result is: '%s', retval = %d\n", buffer, retval);
+		
+		retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
+		printf("Result is: '%s', retval = %d\n", buffer, retval);
+		
+		printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
+		retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
+		printf("Result is: '%s', retval = %d\n", buffer, retval);
+		
+		printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
+		retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
+		printf("Result is: '%s', retval = %d\n", buffer, retval);
+	}
+	
+	return NULL;
+}
Index: uspace/app/tester/print/print1.def
===================================================================
--- uspace/app/tester/print/print1.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/print/print1.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"print1",
+	"Printf test",
+	&test_print1,
+	true
+},
Index: uspace/app/tester/tester.c
===================================================================
--- uspace/app/tester/tester.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/tester.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2006 Ondrej Palkovsky
+ * Copyright (c) 2007 Martin Decky
+ * 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 tester User space Tester
+ * @brief	User space testing infrastructure.
+ * @{
+ */ 
+/**
+ * @file
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include "tester.h"
+
+int myservice = 0;
+int phones[MAX_PHONES];
+int connections[MAX_CONNECTIONS];
+ipc_callid_t callids[MAX_CONNECTIONS];
+
+test_t tests[] = {
+#include "thread/thread1.def"
+#include "print/print1.def"
+#include "fault/fault1.def"
+#include "fault/fault2.def"
+#include "ipc/register.def"
+#include "ipc/connect.def"
+#include "ipc/send_async.def"
+#include "ipc/send_sync.def"
+#include "ipc/answer.def"
+#include "ipc/hangup.def"
+	{NULL, NULL, NULL}
+};
+
+static bool run_test(test_t *test)
+{
+	printf("%s\t\t%s\n", test->name, test->desc);
+	
+	/* Execute the test */
+	char * ret = test->entry(false);
+	
+	if (ret == NULL) {
+		printf("Test passed\n\n");
+		return true;
+	}
+
+	printf("%s\n\n", ret);
+	return false;
+}
+
+static void run_safe_tests(void)
+{
+}
+
+static void list_tests(void)
+{
+	test_t *test;
+	char c = 'a';
+	
+	for (test = tests; test->name != NULL; test++, c++)
+		printf("%c\t%s\t\t%s%s\n", c, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
+	
+	printf("*\t\t\tRun all safe tests\n");
+}
+
+int main(void)
+{
+	while (1) {
+		char c;
+		test_t *test;
+		
+		list_tests();
+		printf("> ");
+		
+		c = getchar();
+		printf("%c\n", c);
+		
+		if ((c >= 'a') && (c <= 'z')) {
+			for (test = tests; test->name != NULL; test++, c--)
+				if (c == 'a')
+					break;
+			
+			if (c > 'a')
+				printf("Unknown test\n\n");
+			else
+				run_test(test);
+		} else if (c == '*')
+			run_safe_tests();
+		else
+			printf("Invalid test\n\n");
+	}
+}
+
+/** @}
+ */
Index: uspace/app/tester/tester.h
===================================================================
--- uspace/app/tester/tester.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/tester.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2007 Martin Decky
+ * 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 tester
+ * @{
+ */
+/** @file
+ */
+
+#ifndef TESTER_H_
+#define TESTER_H_
+
+#include <types.h>
+#include <bool.h>
+#include <ipc/ipc.h>
+
+#define IPC_TEST_START	10000
+#define MAX_PHONES		20
+#define MAX_CONNECTIONS 50
+
+extern int myservice;
+extern int phones[MAX_PHONES];
+extern int connections[MAX_CONNECTIONS];
+extern ipc_callid_t callids[MAX_CONNECTIONS];
+
+typedef char * (* test_entry_t)(bool);
+
+typedef struct {
+	char * name;
+	char * desc;
+	test_entry_t entry;
+	bool safe;
+} test_t;
+
+extern char * test_thread1(bool quiet);
+extern char * test_print1(bool quiet);
+extern char * test_fault1(bool quiet);
+extern char * test_fault2(bool quiet);
+extern char * test_register(bool quiet);
+extern char * test_connect(bool quiet);
+extern char * test_send_async(bool quiet);
+extern char * test_send_sync(bool quiet);
+extern char * test_answer(bool quiet);
+extern char * test_hangup(bool quiet);
+
+extern test_t tests[];
+
+#endif
+
+/** @}
+ */
Index: uspace/app/tester/thread/thread1.c
===================================================================
--- uspace/app/tester/thread/thread1.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/thread/thread1.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2005 Jakub Vana
+ * Copyright (c) 2005 Jakub Jermar
+ * 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.
+ */
+
+#define THREADS 5
+
+#include <atomic.h>
+#include <thread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "../tester.h"
+
+static atomic_t finish;
+static atomic_t threads_finished;
+static bool sh_quiet;
+
+static void threadtest(void *data)
+{
+	thread_detach(thread_get_id());
+
+	while (atomic_get(&finish)) {
+		if (!sh_quiet)
+			printf("%llu ", thread_get_id());
+		usleep(100000);
+	}
+	atomic_inc(&threads_finished);
+}
+
+char * test_thread1(bool quiet)
+{
+	unsigned int i, total = 0;
+	sh_quiet = quiet;
+	
+	atomic_set(&finish, 1);
+	atomic_set(&threads_finished, 0);
+
+	for (i = 0; i < THREADS; i++) {  
+		if (thread_create(threadtest, NULL, "threadtest", NULL) < 0) {
+			if (!quiet)
+				printf("Could not create thread %d\n", i);
+			break;
+		}
+		total++;
+	}
+	
+	if (!quiet)
+		printf("Running threads for 10 seconds...\n");
+	sleep(10);
+	
+	atomic_set(&finish, 0);
+	while (atomic_get(&threads_finished) < total) {
+		if (!quiet)
+			printf("Threads left: %d\n", total - atomic_get(&threads_finished));
+		sleep(1);
+	}
+	
+	return NULL;
+}
Index: uspace/app/tester/thread/thread1.def
===================================================================
--- uspace/app/tester/thread/thread1.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tester/thread/thread1.def	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,6 @@
+{
+	"thread1",
+	"Thread test",
+	&test_thread1,
+	true
+},
Index: uspace/app/tetris/Makefile
===================================================================
--- uspace/app/tetris/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/Makefile	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,35 @@
+LIBC_PREFIX = ../../lib/libc
+SOFTINT_PREFIX = ../../lib/softint
+include $(LIBC_PREFIX)/Makefile.toolchain
+
+LIBS = $(LIBC_PREFIX)/libc.a
+
+OUTPUT = tetris
+SOURCES = shapes.c scores.c input.c tetris.c screen.c
+OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))
+
+.PHONY: all clean depend disasm
+
+all: $(OUTPUT) disasm
+
+-include Makefile.depend
+
+depend:
+	$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend
+
+$(OUTPUT): $(OBJECTS) $(LIBS)
+	$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map
+
+clean:
+	-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o
+disasm:
+	$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm
+
+%.o: %.S
+	$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o: %.c
+	$(CC) $(DEFS) $(CFLAGS) -c $< -o $@
Index: uspace/app/tetris/input.c
===================================================================
--- uspace/app/tetris/input.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/input.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,187 @@
+/*	$OpenBSD: input.c,v 1.12 2005/04/13 02:33:08 deraadt Exp $	*/
+/*    $NetBSD: input.c,v 1.3 1996/02/06 22:47:33 jtc Exp $    */
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)input.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+/*
+ * Tetris input.
+ */
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "input.h"
+#include "tetris.h"
+
+#include <async.h>
+#include "../../srv/console/console.h"
+
+/* return true iff the given timeval is positive */
+#define	TV_POS(tv) \
+	((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
+
+/* subtract timeval `sub' from `res' */
+#define	TV_SUB(res, sub) \
+	(res)->tv_sec -= (sub)->tv_sec; \
+	(res)->tv_usec -= (sub)->tv_usec; \
+	if ((res)->tv_usec < 0) { \
+		(res)->tv_usec += 1000000; \
+		(res)->tv_sec--; \
+	}
+
+/* We will use a hack here - if lastchar is non-zero, it is
+ * the last character read. We will somehow simulate the select
+ * semantics.
+ */
+static aid_t getchar_inprog = 0;
+static char lastchar = '\0';
+
+/*
+ * Do a `read wait': select for reading from stdin, with timeout *tvp.
+ * On return, modify *tvp to reflect the amount of time spent waiting.
+ * It will be positive only if input appeared before the time ran out;
+ * otherwise it will be zero or perhaps negative.
+ *
+ * If tvp is nil, wait forever, but return if select is interrupted.
+ *
+ * Return 0 => no input, 1 => can read() from stdin
+ *
+ */
+int
+rwait(struct timeval *tvp)
+{
+	struct timeval starttv, endtv, *s;
+	static ipc_call_t charcall;
+	ipcarg_t rc;
+
+	/*
+	 * Someday, select() will do this for us.
+	 * Just in case that day is now, and no one has
+	 * changed this, we use a temporary.
+	 */
+	if (tvp) {
+		(void) gettimeofday(&starttv, NULL);
+		endtv = *tvp;
+		s = &endtv;
+	} else
+		s = NULL;
+
+	if (!lastchar) {
+		if (!getchar_inprog)
+			getchar_inprog = async_send_2(1,CONSOLE_GETCHAR,0,0,&charcall);
+		if (!s) 
+			async_wait_for(getchar_inprog, &rc);
+		else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) {
+			tvp->tv_sec = 0;
+			tvp->tv_usec = 0;
+			return (0);
+		}
+		getchar_inprog = 0;
+		if (rc) {
+			stop("end of file, help");
+		}
+		lastchar = IPC_GET_ARG1(charcall);
+	}
+	if (tvp) {
+		/* since there is input, we may not have timed out */
+		(void) gettimeofday(&endtv, NULL);
+		TV_SUB(&endtv, &starttv);
+		TV_SUB(tvp, &endtv);	/* adjust *tvp by elapsed time */
+	}
+	return (1);
+}
+
+/*
+ * `sleep' for the current turn time (using select).
+ * Eat any input that might be available.
+ */
+void
+tsleep(void)
+{
+	struct timeval tv;
+
+	tv.tv_sec = 0;
+	tv.tv_usec = fallrate;
+	while (TV_POS(&tv))
+		if (rwait(&tv)) {
+			lastchar = '\0';
+		} else
+			break;
+}
+
+/*
+ * getchar with timeout.
+ */
+int
+tgetchar(void)
+{
+	static struct timeval timeleft;
+	char c;
+
+	/*
+	 * Reset timeleft to fallrate whenever it is not positive.
+	 * In any case, wait to see if there is any input.  If so,
+	 * take it, and update timeleft so that the next call to
+	 * tgetchar() will not wait as long.  If there is no input,
+	 * make timeleft zero or negative, and return -1.
+	 *
+	 * Most of the hard work is done by rwait().
+	 */
+	if (!TV_POS(&timeleft)) {
+		faster();	/* go faster */
+		timeleft.tv_sec = 0;
+		timeleft.tv_usec = fallrate;
+	}
+	if (!rwait(&timeleft))
+		return (-1);
+	c = lastchar;
+	lastchar = '\0';
+	return ((int)(unsigned char)c);
+}
+
+/** @}
+ */
+
Index: uspace/app/tetris/input.h
===================================================================
--- uspace/app/tetris/input.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/input.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,50 @@
+/*	$OpenBSD: input.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: input.h,v 1.2 1995/04/22 07:42:36 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)input.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+int	rwait(struct timeval *);
+int	tgetchar(void);
+void	tsleep(void);
+
+/** @}
+ */
+
Index: uspace/app/tetris/pathnames.h
===================================================================
--- uspace/app/tetris/pathnames.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/pathnames.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,49 @@
+/*	$OpenBSD: pathnames.h,v 1.3 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: pathnames.h,v 1.2 1995/04/22 07:42:37 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)pathnames.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+#define _PATH_SCOREFILE	"/var/games/tetris.scores"
+
+
+/** @}
+ */
+
Index: uspace/app/tetris/scores.c
===================================================================
--- uspace/app/tetris/scores.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/scores.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,543 @@
+/*	$OpenBSD: scores.c,v 1.11 2006/04/20 03:25:36 ray Exp $	*/
+/*	$NetBSD: scores.c,v 1.2 1995/04/22 07:42:38 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)scores.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+/*
+ * Score code for Tetris, by Darren Provine (kilroy@gboro.glassboro.edu)
+ * modified 22 January 1992, to limit the number of entries any one
+ * person has.
+ *
+ * Major whacks since then.
+ */
+#include <errno.h>
+/* #include <err.h> */
+/* #include <fcntl.h> */
+/* #include <pwd.h> */
+ #include <stdio.h>
+/* #include <stdlib.h> */
+#include <string.h>
+/* #include <time.h> */
+/* #include <term.h> */
+/* #include <unistd.h> */
+/* #include <sys/param.h> */
+/* #include <sys/stat.h> */
+/* #include <sys/types.h> */
+
+#include "pathnames.h"
+#include "screen.h"
+#include "tetris.h"
+#include "scores.h"
+
+/*
+ * Within this code, we can hang onto one extra "high score", leaving
+ * room for our current score (whether or not it is high).
+ *
+ * We also sometimes keep tabs on the "highest" score on each level.
+ * As long as the scores are kept sorted, this is simply the first one at
+ * that level.
+ */
+#define NUMSPOTS (MAXHISCORES + 1)
+#define	NLEVELS (MAXLEVEL + 1)
+
+/* static time_t now; */
+/* static int nscores; */
+/* static int gotscores; */
+/* static struct highscore scores[NUMSPOTS]; */
+static struct highscore scores[NUMSPOTS];
+
+/* static int checkscores(struct highscore *, int); */
+/* static int cmpscores(const void *, const void *); */
+/* static void getscores(FILE **); */
+/* static void printem(int, int, struct highscore *, int, const char *); */
+/* static char *thisuser(void); */
+
+void showscores(int firstgame)
+{
+	int i;
+	
+	clear_screen();
+	moveto(10, 0);
+	printf("\tRank \tLevel \tName\t                     points\n");
+	printf("\t========================================================\n");
+	for (i = 0; i < NUMSPOTS - 1; i++) {
+		printf("\t%6d %6d %-16s %20d\n", i+1, scores[i].hs_level, scores[i].hs_name, scores[i].hs_score);
+	}
+	if (!firstgame) {
+		printf("\t========================================================\n");
+		printf("\t  Last %6d %-16s %20d\n", scores[NUMSPOTS - 1].hs_level, scores[NUMSPOTS - 1].hs_name, scores[NUMSPOTS - 1].hs_score);
+	}
+	printf("\n\n\n\n\tPress any key to return to main menu.");
+	getchar();
+}
+
+/** Copy from hiscore table score with index src to dest
+ *
+ */
+static void copyhiscore(int dest, int src)
+{
+	strcpy(scores[dest].hs_name, scores[src].hs_name);
+	scores[dest].hs_score = scores[src].hs_score; 	
+	scores[dest].hs_level = scores[src].hs_level; 
+}
+
+void insertscore(int score, int level)
+{
+	int i,j;
+	int key;
+
+	
+	clear_screen();
+	moveto(10 , 10);
+	puts("Insert your name: ");
+	strncpy(scores[NUMSPOTS - 1].hs_name, "Player", MAXLOGNAME);
+	i = 6;
+
+	moveto(10 , 28);
+	printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................");
+	key = getchar();	
+	while(key != '\n') {
+		if (key == '\b') {
+			if (i > 0) 
+				scores[NUMSPOTS - 1].hs_name[--i] = '\0';	
+		} else {
+			if (i < (MAXLOGNAME - 1))
+				scores[NUMSPOTS - 1].hs_name[i++] = key;	
+				scores[NUMSPOTS - 1].hs_name[i] = '\0';	
+		}
+		
+		moveto(10 , 28);
+		printf("%s%.*s",scores[NUMSPOTS - 1].hs_name,MAXLOGNAME-i,"........................................");
+	
+		key = getchar();	
+	}
+	
+	scores[NUMSPOTS - 1].hs_score = score;	
+	scores[NUMSPOTS - 1].hs_level = level;
+	
+	i = NUMSPOTS-1;	
+	while ((i > 0) && (scores[i - 1].hs_score < score))
+		i--;
+
+	for (j = NUMSPOTS - 2; j > i; j--) {
+		copyhiscore(j,j-1);
+	}
+	copyhiscore(i, NUMSPOTS - 1);	
+}
+
+void initscores(void)
+{
+	int i;
+	for(i = 0; i < NUMSPOTS; i++) {
+		strncpy(scores[i].hs_name, "HelenOS Team", MAXLOGNAME);
+		scores[i].hs_score = (NUMSPOTS - i) * 200;	
+		scores[i].hs_level = (i + 1 > MAXLEVEL?MAXLEVEL:i + 1);
+	}
+}
+
+/*
+ * Read the score file.  Can be called from savescore (before showscores)
+ * or showscores (if savescore will not be called).  If the given pointer
+ * is not NULL, sets *fpp to an open file pointer that corresponds to a
+ * read/write score file that is locked with LOCK_EX.  Otherwise, the
+ * file is locked with LOCK_SH for the read and closed before return.
+ *
+ * Note, we assume closing the stdio file releases the lock.
+ */
+/* static void */
+/* getscores(FILE **fpp) */
+/* { */
+/* 	int sd, mint, lck, mask, i; */
+/* 	char *mstr, *human; */
+/* 	FILE *sf; */
+
+/* 	if (fpp != NULL) { */
+/* 		mint = O_RDWR | O_CREAT; */
+/* 		mstr = "r+"; */
+/* 		human = "read/write"; */
+/* 		lck = LOCK_EX; */
+/* 	} else { */
+/* 		mint = O_RDONLY; */
+/* 		mstr = "r"; */
+/* 		human = "reading"; */
+/* 		lck = LOCK_SH; */
+/* 	} */
+/* 	setegid(egid); */
+/* 	mask = umask(S_IWOTH); */
+/* 	sd = open(_PATH_SCOREFILE, mint, 0666); */
+/* 	(void)umask(mask); */
+/* 	setegid(gid); */
+/* 	if (sd < 0) { */
+/* 		if (fpp == NULL) { */
+/* 			nscores = 0; */
+/* 			return; */
+/* 		} */
+/* 		err(1, "cannot open %s for %s", _PATH_SCOREFILE, human); */
+/* 	} */
+/* 	setegid(egid); */
+/* 	if ((sf = fdopen(sd, mstr)) == NULL) */
+/* 		err(1, "cannot fdopen %s for %s", _PATH_SCOREFILE, human); */
+/* 	setegid(gid); */
+
+/* 	/\* */
+/* 	 * Grab a lock. */
+/* 	 *\/ */
+/* 	if (flock(sd, lck)) */
+/* 		warn("warning: score file %s cannot be locked", */
+/* 		    _PATH_SCOREFILE); */
+
+/* 	nscores = fread(scores, sizeof(scores[0]), MAXHISCORES, sf); */
+/* 	if (ferror(sf)) */
+/* 		err(1, "error reading %s", _PATH_SCOREFILE); */
+/* 	for (i = 0; i < nscores; i++) */
+/* 		if (scores[i].hs_level < MINLEVEL || */
+/* 		    scores[i].hs_level > MAXLEVEL) */
+/* 			errx(1, "scorefile %s corrupt", _PATH_SCOREFILE); */
+
+/* 	if (fpp) */
+/* 		*fpp = sf; */
+/* 	else */
+/* 		(void)fclose(sf); */
+/* } */
+
+void
+savescore(int level)
+{
+	return;
+}
+/* 	struct highscore *sp; */
+/* 	int i; */
+/* 	int change; */
+/* 	FILE *sf; */
+/* 	const char *me; */
+
+/* 	getscores(&sf); */
+/* 	gotscores = 1; */
+/* 	(void)time(&now); */
+
+/* 	/\* */
+/* 	 * Allow at most one score per person per level -- see if we */
+/* 	 * can replace an existing score, or (easiest) do nothing. */
+/* 	 * Otherwise add new score at end (there is always room). */
+/* 	 *\/ */
+/* 	change = 0; */
+/* 	me = thisuser(); */
+/* 	for (i = 0, sp = &scores[0]; i < nscores; i++, sp++) { */
+/* 		if (sp->hs_level != level || strcmp(sp->hs_name, me) != 0) */
+/* 			continue; */
+/* 		if (score > sp->hs_score) { */
+/* 			(void)printf("%s bettered %s %d score of %d!\n", */
+/* 			    "\nYou", "your old level", level, */
+/* 			    sp->hs_score * sp->hs_level); */
+/* 			sp->hs_score = score;	/\* new score *\/ */
+/* 			sp->hs_time = now;	/\* and time *\/ */
+/* 			change = 1; */
+/* 		} else if (score == sp->hs_score) { */
+/* 			(void)printf("%s tied %s %d high score.\n", */
+/* 			    "\nYou", "your old level", level); */
+/* 			sp->hs_time = now;	/\* renew it *\/ */
+/* 			change = 1;		/\* gotta rewrite, sigh *\/ */
+/* 		} /\* else new score < old score: do nothing *\/ */
+/* 		break; */
+/* 	} */
+/* 	if (i >= nscores) { */
+/* 		strlcpy(sp->hs_name, me, sizeof sp->hs_name); */
+/* 		sp->hs_level = level; */
+/* 		sp->hs_score = score; */
+/* 		sp->hs_time = now; */
+/* 		nscores++; */
+/* 		change = 1; */
+/* 	} */
+
+/* 	if (change) { */
+/* 		/\* */
+/* 		 * Sort & clean the scores, then rewrite. */
+/* 		 *\/ */
+/* 		nscores = checkscores(scores, nscores); */
+/* 		rewind(sf); */
+/* 		if (fwrite(scores, sizeof(*sp), nscores, sf) != nscores || */
+/* 		    fflush(sf) == EOF) */
+/* 			warnx("error writing %s: %s\n\t-- %s", */
+/* 			    _PATH_SCOREFILE, strerror(errno), */
+/* 			    "high scores may be damaged"); */
+/* 	} */
+/* 	(void)fclose(sf);	/\* releases lock *\/ */
+/* } */
+
+/*
+ * Get login name, or if that fails, get something suitable.
+ * The result is always trimmed to fit in a score.
+ */
+/* static char * */
+/* thisuser(void) */
+/* { */
+/* 	const char *p; */
+/* 	struct passwd *pw; */
+/* 	static char u[sizeof(scores[0].hs_name)]; */
+
+/* 	if (u[0]) */
+/* 		return (u); */
+/* 	p = getlogin(); */
+/* 	if (p == NULL || *p == '\0') { */
+/* 		pw = getpwuid(getuid()); */
+/* 		if (pw != NULL) */
+/* 			p = pw->pw_name; */
+/* 		else */
+/* 			p = "  ???"; */
+/* 	} */
+/* 	strlcpy(u, p, sizeof(u)); */
+/* 	return (u); */
+/* } */
+
+/*
+ * Score comparison function for qsort.
+ *
+ * If two scores are equal, the person who had the score first is
+ * listed first in the highscore file.
+ */
+/* static int */
+/* cmpscores(const void *x, const void *y) */
+/* { */
+/* 	const struct highscore *a, *b; */
+/* 	long l; */
+
+/* 	a = x; */
+/* 	b = y; */
+/* 	l = (long)b->hs_level * b->hs_score - (long)a->hs_level * a->hs_score; */
+/* 	if (l < 0) */
+/* 		return (-1); */
+/* 	if (l > 0) */
+/* 		return (1); */
+/* 	if (a->hs_time < b->hs_time) */
+/* 		return (-1); */
+/* 	if (a->hs_time > b->hs_time) */
+/* 		return (1); */
+/* 	return (0); */
+/* } */
+
+/*
+ * If we've added a score to the file, we need to check the file and ensure
+ * that this player has only a few entries.  The number of entries is
+ * controlled by MAXSCORES, and is to ensure that the highscore file is not
+ * monopolised by just a few people.  People who no longer have accounts are
+ * only allowed the highest score.  Scores older than EXPIRATION seconds are
+ * removed, unless they are someone's personal best.
+ * Caveat:  the highest score on each level is always kept.
+ */
+/* static int */
+/* checkscores(struct highscore *hs, int num) */
+/* { */
+/* 	struct highscore *sp; */
+/* 	int i, j, k, numnames; */
+/* 	int levelfound[NLEVELS]; */
+/* 	struct peruser { */
+/* 		char *name; */
+/* 		int times; */
+/* 	} count[NUMSPOTS]; */
+/* 	struct peruser *pu; */
+
+/* 	/\* */
+/* 	 * Sort so that highest totals come first. */
+/* 	 * */
+/* 	 * levelfound[i] becomes set when the first high score for that */
+/* 	 * level is encountered.  By definition this is the highest score. */
+/* 	 *\/ */
+/* 	qsort((void *)hs, nscores, sizeof(*hs), cmpscores); */
+/* 	for (i = MINLEVEL; i < NLEVELS; i++) */
+/* 		levelfound[i] = 0; */
+/* 	numnames = 0; */
+/* 	for (i = 0, sp = hs; i < num;) { */
+/* 		/\* */
+/* 		 * This is O(n^2), but do you think we care? */
+/* 		 *\/ */
+/* 		for (j = 0, pu = count; j < numnames; j++, pu++) */
+/* 			if (strcmp(sp->hs_name, pu->name) == 0) */
+/* 				break; */
+/* 		if (j == numnames) { */
+/* 			/\* */
+/* 			 * Add new user, set per-user count to 1. */
+/* 			 *\/ */
+/* 			pu->name = sp->hs_name; */
+/* 			pu->times = 1; */
+/* 			numnames++; */
+/* 		} else { */
+/* 			/\* */
+/* 			 * Two ways to keep this score: */
+/* 			 * - Not too many (per user), still has acct, & */
+/* 			 *	score not dated; or */
+/* 			 * - High score on this level. */
+/* 			 *\/ */
+/* 			if ((pu->times < MAXSCORES && */
+/* 			     getpwnam(sp->hs_name) != NULL && */
+/* 			     sp->hs_time + EXPIRATION >= now) || */
+/* 			    levelfound[sp->hs_level] == 0) */
+/* 				pu->times++; */
+/* 			else { */
+/* 				/\* */
+/* 				 * Delete this score, do not count it, */
+/* 				 * do not pass go, do not collect $200. */
+/* 				 *\/ */
+/* 				num--; */
+/* 				for (k = i; k < num; k++) */
+/* 					hs[k] = hs[k + 1]; */
+/* 				continue; */
+/* 			} */
+/* 		} */
+/* 		levelfound[sp->hs_level] = 1; */
+/* 		i++, sp++; */
+/* 	} */
+/* 	return (num > MAXHISCORES ? MAXHISCORES : num); */
+/* } */
+
+/*
+ * Show current scores.  This must be called after savescore, if
+ * savescore is called at all, for two reasons:
+ * - Showscores munches the time field.
+ * - Even if that were not the case, a new score must be recorded
+ *   before it can be shown anyway.
+ */
+/*
+void
+showscores(int level)
+{
+	return;
+}
+*/
+/* 	struct highscore *sp; */
+/* 	int i, n, c; */
+/* 	const char *me; */
+/* 	int levelfound[NLEVELS]; */
+
+/* 	if (!gotscores) */
+/* 		getscores((FILE **)NULL); */
+/* 	(void)printf("\n\t\t    Tetris High Scores\n"); */
+
+/* 	/\* */
+/* 	 * If level == 0, the person has not played a game but just asked for */
+/* 	 * the high scores; we do not need to check for printing in highlight */
+/* 	 * mode.  If SOstr is null, we can't do highlighting anyway. */
+/* 	 *\/ */
+/* 	me = level && SOstr ? thisuser() : NULL; */
+
+/* 	/\* */
+/* 	 * Set times to 0 except for high score on each level. */
+/* 	 *\/ */
+/* 	for (i = MINLEVEL; i < NLEVELS; i++) */
+/* 		levelfound[i] = 0; */
+/* 	for (i = 0, sp = scores; i < nscores; i++, sp++) { */
+/* 		if (levelfound[sp->hs_level]) */
+/* 			sp->hs_time = 0; */
+/* 		else { */
+/* 			sp->hs_time = 1; */
+/* 			levelfound[sp->hs_level] = 1; */
+/* 		} */
+/* 	} */
+
+/* 	/\* */
+/* 	 * Page each screenful of scores. */
+/* 	 *\/ */
+/* 	for (i = 0, sp = scores; i < nscores; sp += n) { */
+/* 		n = 20; */
+/* 		if (i + n > nscores) */
+/* 			n = nscores - i; */
+/* 		printem(level, i + 1, sp, n, me); */
+/* 		if ((i += n) < nscores) { */
+/* 			(void)printf("\nHit RETURN to continue."); */
+/* 			(void)fflush(stdout); */
+/* 			while ((c = getchar()) != '\n') */
+/* 				if (c == EOF) */
+/* 					break; */
+/* 			(void)printf("\n"); */
+/* 		} */
+/* 	} */
+
+/* 	if (nscores == 0) */
+/* 		printf("\t\t\t      - none to date.\n"); */
+/* } */
+
+/* static void */
+/* printem(int level, int offset, struct highscore *hs, int n, const char *me) */
+/* { */
+/* 	struct highscore *sp; */
+/* 	int row, highlight, i; */
+/* 	char buf[100]; */
+/* #define	TITLE "Rank  Score   Name                          (points/level)" */
+/* #define	TITL2 "==========================================================" */
+
+/* 	printf("%s\n%s\n", TITLE, TITL2); */
+
+/* 	highlight = 0; */
+
+/* 	for (row = 0; row < n; row++) { */
+/* 		sp = &hs[row]; */
+/* 		(void)snprintf(buf, sizeof(buf), */
+/* 		    "%3d%c %6d  %-31s (%6d on %d)\n", */
+/* 		    row + offset, sp->hs_time ? '*' : ' ', */
+/* 		    sp->hs_score * sp->hs_level, */
+/* 		    sp->hs_name, sp->hs_score, sp->hs_level); */
+/* 		/\* Print leaders every three lines *\/ */
+/* 		if ((row + 1) % 3 == 0) { */
+/* 			for (i = 0; i < sizeof(buf); i++) */
+/* 				if (buf[i] == ' ') */
+/* 					buf[i] = '_'; */
+/* 		} */
+/* 		/\* */
+/* 		 * Highlight if appropriate.  This works because */
+/* 		 * we only get one score per level. */
+/* 		 *\/ */
+/* 		if (me != NULL && */
+/* 		    sp->hs_level == level && */
+/* 		    sp->hs_score == score && */
+/* 		    strcmp(sp->hs_name, me) == 0) { */
+/* 			putpad(SOstr); */
+/* 			highlight = 1; */
+/* 		} */
+/* 		(void)printf("%s", buf); */
+/* 		if (highlight) { */
+/* 			putpad(SEstr); */
+/* 			highlight = 0; */
+/* 		} */
+/* 	} */
+/* } */
+
+/** @}
+ */
+
Index: uspace/app/tetris/scores.h
===================================================================
--- uspace/app/tetris/scores.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/scores.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,67 @@
+/*	$OpenBSD: scores.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: scores.h,v 1.2 1995/04/22 07:42:40 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)scores.h	8.1 (Berkeley) 5/31/93
+ */
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+
+/*
+ * Tetris scores.
+ */
+#include <sys/time.h>
+#define MAXLOGNAME 16
+struct highscore {
+	char	hs_name[MAXLOGNAME + 1];	/* login name */
+	int	hs_score;	/* raw score */
+	int	hs_level;	/* play level */
+//	time_t	hs_time;	/* time at game end */
+};
+
+#define MAXHISCORES	10
+//#define MAXSCORES	9	/* maximum high score entries per person */
+//#define	EXPIRATION	(5L * 365 * 24 * 60 * 60)
+
+void savescore(int);
+void showscores(int);
+void insertscore(int score, int level);
+void initscores(void);
+
+/** @}
+ */
+
Index: uspace/app/tetris/screen.c
===================================================================
--- uspace/app/tetris/screen.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/screen.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,312 @@
+/*	$OpenBSD: screen.c,v 1.13 2006/04/20 03:25:36 ray Exp $	*/
+/*	$NetBSD: screen.c,v 1.4 1995/04/29 01:11:36 mycroft Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)screen.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+/*
+ * Tetris screen control.
+ */
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <io/stream.h>
+
+
+#include <async.h>
+#include "screen.h"
+#include "tetris.h"
+#include "../../srv/console/console.h"
+
+static cell curscreen[B_SIZE];	/* 1 => standout (or otherwise marked) */
+static int curscore;
+static int isset;		/* true => terminal is in game mode */
+
+
+/*
+ * putstr() is for unpadded strings (either as in termcap(5) or
+ * simply literal strings); 
+ */
+static inline void putstr(char *s)
+{
+	while (*s)
+		putchar(*(s++));
+}
+
+static int con_phone;
+
+
+
+static void set_style(int fgcolor, int bgcolor)
+{
+	async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
+}
+
+static void start_standout(void)
+{
+	set_style(0xf0f0f0, 0);
+}
+
+static void resume_normal(void)
+{
+	set_style(0, 0xf0f0f0);
+}
+
+
+void clear_screen(void)
+{
+	async_msg(con_phone, CONSOLE_CLEAR, 0);
+	moveto(0,0);
+}
+
+/*
+ * Clear the screen, forgetting the current contents in the process.
+ */
+void
+scr_clear(void)
+{
+
+	resume_normal();
+	async_msg(con_phone, CONSOLE_CLEAR, 0);
+	curscore = -1;
+	memset((char *)curscreen, 0, sizeof(curscreen));
+}
+
+/*
+ * Set up screen
+ */
+void
+scr_init(void)
+{
+	con_phone = get_fd_phone(1);
+	async_msg(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
+	resume_normal();
+	scr_clear();
+}
+
+void moveto(int r, int c)
+{
+	async_msg_2(con_phone, CONSOLE_GOTO, r, c);
+}
+
+static void fflush(void)
+{
+	async_msg(con_phone, CONSOLE_FLUSH, 0);
+}
+
+winsize_t winsize;
+
+static int get_display_size(winsize_t *ws)
+{
+	return async_req_2(con_phone, CONSOLE_GETSIZE, 0, 0, &ws->ws_row, &ws->ws_col);
+}
+
+/*
+ * Set up screen mode.
+ */
+void
+scr_set(void)
+{
+	winsize_t ws;
+
+	Rows = 0, Cols = 0;
+	if (get_display_size(&ws) == 0) {
+		Rows = ws.ws_row;
+		Cols = ws.ws_col;
+	}
+	if (Rows < MINROWS || Cols < MINCOLS) {
+		char smallscr[55];
+
+		snprintf(smallscr, sizeof(smallscr),
+		    "the screen is too small (must be at least %dx%d)",
+		    MINROWS, MINCOLS);
+		stop(smallscr);
+	}
+	isset = 1;
+
+	scr_clear();
+}
+
+/*
+ * End screen mode.
+ */
+void
+scr_end(void)
+{
+}
+
+void
+stop(char *why)
+{
+
+	if (isset)
+		scr_end();
+	errx(1, "aborting: %s", why);
+}
+
+
+/*
+ * Update the screen.
+ */
+void
+scr_update(void)
+{
+	cell *bp, *sp;
+	cell so, cur_so = 0;
+	int i, ccol, j;
+	static const struct shape *lastshape;
+
+	/* always leave cursor after last displayed point */
+	curscreen[D_LAST * B_COLS - 1] = -1;
+
+	if (score != curscore) {
+		moveto(0, 0);
+		printf("Score: %d", score);
+		curscore = score;
+	}
+
+	/* draw preview of next pattern */
+	if (showpreview && (nextshape != lastshape)) {
+		int i;
+		static int r=5, c=2;
+		int tr, tc, t;
+
+		lastshape = nextshape;
+
+		/* clean */
+		resume_normal();
+		moveto(r-1, c-1); putstr("          ");
+		moveto(r,   c-1); putstr("          ");
+		moveto(r+1, c-1); putstr("          ");
+		moveto(r+2, c-1); putstr("          ");
+
+		moveto(r-3, c-2);
+		putstr("Next shape:");
+
+		/* draw */
+		start_standout();
+		moveto(r, 2 * c);
+		putstr("  ");
+		for (i = 0; i < 3; i++) {
+			t = c + r * B_COLS;
+			t += nextshape->off[i];
+
+			tr = t / B_COLS;
+			tc = t % B_COLS;
+
+			moveto(tr, 2*tc);
+			putstr("  ");
+		}
+		resume_normal();
+	}
+
+	bp = &board[D_FIRST * B_COLS];
+	sp = &curscreen[D_FIRST * B_COLS];
+	for (j = D_FIRST; j < D_LAST; j++) {
+		ccol = -1;
+		for (i = 0; i < B_COLS; bp++, sp++, i++) {
+			if (*sp == (so = *bp))
+				continue;
+			*sp = so;
+			if (i != ccol) {
+				if (cur_so) {
+					resume_normal();
+					cur_so = 0;
+				}
+				moveto(RTOD(j), CTOD(i));
+			}
+			if (so != cur_so) {
+				if (so)
+					start_standout();
+				else
+					resume_normal();
+				cur_so = so;
+			}
+			putstr("  ");
+
+			ccol = i + 1;
+			/*
+			 * Look ahead a bit, to avoid extra motion if
+			 * we will be redrawing the cell after the next.
+			 * Motion probably takes four or more characters,
+			 * so we save even if we rewrite two cells
+			 * `unnecessarily'.  Skip it all, though, if
+			 * the next cell is a different color.
+			 */
+#define	STOP (B_COLS - 3)
+			if (i > STOP || sp[1] != bp[1] || so != bp[1])
+				continue;
+			if (sp[2] != bp[2])
+				sp[1] = -1;
+			else if (i < STOP && so == bp[2] && sp[3] != bp[3]) {
+				sp[2] = -1;
+				sp[1] = -1;
+			}
+		}
+	}
+	if (cur_so)
+		resume_normal();
+ 	fflush();
+}
+
+/*
+ * Write a message (set!=0), or clear the same message (set==0).
+ * (We need its length in case we have to overwrite with blanks.)
+ */
+void
+scr_msg(char *s, int set)
+{
+	
+	int l = strlen(s);
+	
+	moveto(Rows - 2, ((Cols - l) >> 1) - 1);
+	if (set)
+		putstr(s);
+	else
+		while (--l >= 0)
+			(void) putchar(' ');
+}
+
+/** @}
+ */
+
Index: uspace/app/tetris/screen.h
===================================================================
--- uspace/app/tetris/screen.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/screen.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,71 @@
+/*	$OpenBSD: screen.h,v 1.5 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: screen.h,v 1.2 1995/04/22 07:42:42 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)screen.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+/*
+ * putpad() is for padded strings with count=1.
+ */
+#define	putpad(s)	tputs(s, 1, put)
+
+#include <async.h>
+
+typedef struct {
+	ipcarg_t ws_row;
+	ipcarg_t ws_col;
+} winsize_t;
+
+extern winsize_t winsize;
+
+void moveto(int r, int c);
+void clear_screen(void);
+
+int	put(int);			/* just calls putchar; for tputs */
+void	scr_clear(void);
+void	scr_end(void);
+void	scr_init(void);
+void	scr_msg(char *, int);
+void	scr_set(void);
+void	scr_update(void);
+
+/** @}
+ */
+
Index: uspace/app/tetris/shapes.c
===================================================================
--- uspace/app/tetris/shapes.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/shapes.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,116 @@
+/*	$OpenBSD: shapes.c,v 1.8 2004/07/10 07:26:24 deraadt Exp $	*/
+/*	$NetBSD: shapes.c,v 1.2 1995/04/22 07:42:44 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)shapes.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+/*
+ * Tetris shapes and related routines.
+ *
+ * Note that the first 7 are `well known'.
+ */
+
+#include <unistd.h>
+#include "tetris.h"
+
+#define	TL	-B_COLS-1	/* top left */
+#define	TC	-B_COLS		/* top center */
+#define	TR	-B_COLS+1	/* top right */
+#define	ML	-1		/* middle left */
+#define	MR	1		/* middle right */
+#define	BL	B_COLS-1	/* bottom left */
+#define	BC	B_COLS		/* bottom center */
+#define	BR	B_COLS+1	/* bottom right */
+
+const struct shape shapes[] = {
+	/* 0*/	{ 7,	7,	{ TL, TC, MR } },
+	/* 1*/	{ 8,	8,	{ TC, TR, ML } },
+	/* 2*/	{ 9,	11,	{ ML, MR, BC } },
+	/* 3*/	{ 3,	3,	{ TL, TC, ML } },
+	/* 4*/	{ 12,	14,	{ ML, BL, MR } },
+	/* 5*/	{ 15,	17,	{ ML, BR, MR } },
+	/* 6*/	{ 18,	18,	{ ML, MR, 2  } }, /* sticks out */
+	/* 7*/	{ 0,	0,	{ TC, ML, BL } },
+	/* 8*/	{ 1,	1,	{ TC, MR, BR } },
+	/* 9*/	{ 10,	2,	{ TC, MR, BC } },
+	/*10*/	{ 11,	9,	{ TC, ML, MR } },
+	/*11*/	{ 2,	10,	{ TC, ML, BC } },
+	/*12*/	{ 13,	4,	{ TC, BC, BR } },
+	/*13*/	{ 14,	12,	{ TR, ML, MR } },
+	/*14*/	{ 4,	13,	{ TL, TC, BC } },
+	/*15*/	{ 16,	5,	{ TR, TC, BC } },
+	/*16*/	{ 17,	15,	{ TL, MR, ML } },
+	/*17*/	{ 5,	16,	{ TC, BC, BL } },
+	/*18*/	{ 6,	6,	{ TC, BC, 2*B_COLS } }/* sticks out */
+};
+
+/*
+ * Return true iff the given shape fits in the given position,
+ * taking the current board into account.
+ */
+int
+fits_in(const struct shape *shape, int pos)
+{
+	int *o = shape->off;
+
+	if (board[pos] || board[pos + *o++] || board[pos + *o++] ||
+	    board[pos + *o])
+		return 0;
+	return 1;
+}
+
+/*
+ * Write the given shape into the current board, turning it on
+ * if `onoff' is 1, and off if `onoff' is 0.
+ */
+void
+place(const struct shape *shape, int pos, int onoff)
+{
+	int *o = shape->off;
+
+	board[pos] = onoff;
+	board[pos + *o++] = onoff;
+	board[pos + *o++] = onoff;
+	board[pos + *o] = onoff;
+}
+
+/** @}
+ */
+
Index: uspace/app/tetris/tetris.c
===================================================================
--- uspace/app/tetris/tetris.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/tetris.c	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,469 @@
+/*	$OpenBSD: tetris.c,v 1.21 2006/04/20 03:24:12 ray Exp $	*/
+/*	$NetBSD: tetris.c,v 1.2 1995/04/22 07:42:47 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)tetris.c	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris Tetris
+ * @brief	Tetris ported from OpenBSD
+ * @{ 
+ */
+/** @file
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 1992, 1993\n\
+	The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+/*
+ * Tetris (or however it is spelled).
+ */
+
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "input.h"
+#include "scores.h"
+#include "screen.h"
+#include "tetris.h"
+
+cell	board[B_SIZE];
+int	Rows, Cols;
+const struct shape *curshape;
+const struct shape *nextshape;
+long	fallrate;
+int	score;
+//gid_t	gid, egid;
+char	key_msg[100];
+int	showpreview, classic;
+
+static void	elide(void);
+static void	setup_board(void);
+const struct shape *randshape(void);
+void	onintr(int);
+void	usage(void);
+
+/*
+ * Set up the initial board.  The bottom display row is completely set,
+ * along with another (hidden) row underneath that.  Also, the left and
+ * right edges are set.
+ */
+static void
+setup_board(void)
+{
+	int i;
+	cell *p;
+
+	p = board;
+	for (i = B_SIZE; i; i--)
+		*p++ = i <= (2 * B_COLS) || (i % B_COLS) < 2;
+}
+
+/*
+ * Elide any full active rows.
+ */
+static void
+elide(void)
+{
+	int rows = 0;
+	int i, j, base;
+	cell *p;
+
+	for (i = A_FIRST; i < A_LAST; i++) {
+		base = i * B_COLS + 1;
+		p = &board[base];
+		for (j = B_COLS - 2; *p++ != 0;) {
+			if (--j <= 0) {
+				/* this row is to be elided */
+				rows++;
+				memset(&board[base], 0, B_COLS - 2);
+				scr_update();
+				tsleep();
+				while (--base != 0)
+					board[base + B_COLS] = board[base];
+				scr_update();
+				tsleep();
+				break;
+			}
+		}
+	}
+	switch (rows) {
+	case 1:
+		score += 10;
+		break;
+	case 2:
+		score += 30;
+		break;
+	case 3:
+		score += 70;
+		break;
+	case 4:
+		score += 150;
+		break;
+	default:
+		break;
+	}
+}
+
+const struct shape *
+randshape(void)
+{
+	const struct shape *tmp;
+	int i, j;
+
+	tmp = &shapes[random() % 7];
+	j = random() % 4;
+	for (i = 0; i < j; i++)
+		tmp = &shapes[classic? tmp->rotc : tmp->rot];
+	return (tmp);
+}
+
+static void srandomdev(void)
+{
+	struct timeval tv;
+
+	gettimeofday(&tv, NULL);
+	srandom(tv.tv_sec + tv.tv_usec / 100000);
+}
+
+static void tetris_menu_draw(int level) 
+{
+		clear_screen();
+		moveto(5,10);
+		puts("Tetris\n\n");
+			
+		moveto(8,10);
+		printf("Level = %d (press keys 1 - 9 to change)",level);
+		moveto(9,10);
+		printf("Preview is %s (press 'p' to change)", (showpreview?"on ":"off"));
+		moveto(12,10);
+		printf("Press 'h' to show hiscore table.");
+		moveto(13,10);
+		printf("Press 's' to start game.");
+		moveto(14,10);
+		printf("Press 'q' to quit game.");
+		moveto(20,10);
+		printf("In game controls:");
+		moveto(21,0);
+		puts(key_msg);
+}
+
+static int tetris_menu(int *level) 
+{
+	static int firstgame = 1;
+	int i;
+/*	if (showpreview == 0)
+		(void)printf("Your score:  %d point%s  x  level %d  =  %d\n",
+		    score, score == 1 ? "" : "s", level, score * level);
+	else {
+ 		(void)printf("Your score:  %d point%s x level %d x preview penalty %0.3f = %d\n", 
+ 		    score, score == 1 ? "" : "s", level, (double)PRE_PENALTY, 
+ 		    (int)(score * level * PRE_PENALTY)); 
+ 		score = score * PRE_PENALTY; 
+	}
+	savescore(level);
+
+	showscores(level);
+	
+	printf("\nHit 's' to new game, 'q' to quit.\n");
+*/
+	tetris_menu_draw(*level);
+	while (1) {
+	
+		i = getchar();
+		
+		switch(i) {
+			case 'p':
+				showpreview = !showpreview;
+				moveto(9,21);
+				if (showpreview)
+					printf("on ");
+				else
+					printf("off");
+					
+				break;
+			case 'h':
+				showscores(firstgame);
+				tetris_menu_draw(*level);
+				break;
+			case 's':
+				firstgame = 0;
+				return 1;
+			case 'q':
+				return 0;
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':		
+			case '7':
+			case '8':
+			case '9':
+				*level = i - '0';
+				moveto(8,18);
+				printf("%d", *level);
+				break;
+		}
+	}
+	
+}
+
+int
+main(int argc, char *argv[])
+{
+	int pos, c;
+	char *keys;
+	int level = 2;
+	char key_write[6][10];
+	int i, j;
+
+	keys = "jkl pq";
+
+//	gid = getgid();
+//	egid = getegid();
+//	setegid(gid);
+
+	classic = 0;
+	showpreview = 1; 
+
+/* 	while ((ch = getopt(argc, argv, "ck:l:ps")) != -1) */
+/* 		switch(ch) { */
+/* 		case 'c': */
+/* 			/\* */
+/* 			 * this means: */
+/* 			 *	- rotate the other way; */
+/* 			 *	- no reverse video. */
+/* 			 *\/ */
+/* 			classic = 1; */
+/* 			break; */
+/* 		case 'k': */
+/* 			if (strlen(keys = optarg) != 6) */
+/* 				usage(); */
+/* 			break; */
+/* 		case 'l': */
+/* 			level = (int)strtonum(optarg, MINLEVEL, MAXLEVEL, */
+/* 			    &errstr); */
+/* 			if (errstr) */
+/* 				errx(1, "level must be from %d to %d", */
+/* 				    MINLEVEL, MAXLEVEL); */
+/* 			break; */
+/* 		case 'p': */
+/* 			showpreview = 1; */
+/* 			break; */
+/* 		case 's': */
+/* 			showscores(0); */
+/* 			exit(0); */
+/* 		default: */
+/* 			usage(); */
+/* 		} */
+
+/* 	argc -= optind; */
+/* 	argv += optind; */
+
+/* 	if (argc) */
+/* 		usage(); */
+
+	
+
+	for (i = 0; i <= 5; i++) {
+		for (j = i+1; j <= 5; j++) {
+			if (keys[i] == keys[j])
+				errx(1, "duplicate command keys specified.");
+		}
+		if (keys[i] == ' ')
+			strncpy(key_write[i], "<space>", sizeof key_write[i]);
+		else {
+			key_write[i][0] = keys[i];
+			key_write[i][1] = '\0';
+		}
+	}
+
+	snprintf(key_msg, sizeof key_msg,
+"%s - left   %s - rotate   %s - right   %s - drop   %s - pause   %s - quit",
+		key_write[0], key_write[1], key_write[2], key_write[3],
+		key_write[4], key_write[5]);
+
+	scr_init();
+	initscores();
+	while (tetris_menu(&level)) {
+		fallrate = 1000000 / level;
+		
+		scr_clear();
+		setup_board();
+	
+		srandomdev();
+		scr_set();
+	
+		pos = A_FIRST*B_COLS + (B_COLS/2)-1;
+		nextshape = randshape();
+		curshape = randshape();
+	
+		scr_msg(key_msg, 1);
+	
+		for (;;) {
+			place(curshape, pos, 1);
+			scr_update();
+			place(curshape, pos, 0);
+			c = tgetchar();
+			if (c < 0) {
+				/*
+				 * Timeout.  Move down if possible.
+				 */
+				if (fits_in(curshape, pos + B_COLS)) {
+					pos += B_COLS;
+					continue;
+				}
+	
+				/*
+				 * Put up the current shape `permanently',
+				 * bump score, and elide any full rows.
+				 */
+				place(curshape, pos, 1);
+				score++;
+				elide();
+	
+				/*
+				 * Choose a new shape.  If it does not fit,
+				 * the game is over.
+				 */
+				curshape = nextshape;
+				nextshape = randshape();
+				pos = A_FIRST*B_COLS + (B_COLS/2)-1;
+				if (!fits_in(curshape, pos))
+					break;
+				continue;
+			}
+	
+			/*
+			 * Handle command keys.
+			 */
+			if (c == keys[5]) {
+				/* quit */
+				break;
+			}
+			if (c == keys[4]) {
+				static char msg[] =
+				    "paused - press RETURN to continue";
+	
+				place(curshape, pos, 1);
+				do {
+					scr_update();
+					scr_msg(key_msg, 0);
+					scr_msg(msg, 1);
+	//				(void) fflush(stdout);
+				} while (rwait((struct timeval *)NULL) == -1);
+				scr_msg(msg, 0);
+				scr_msg(key_msg, 1);
+				place(curshape, pos, 0);
+				continue;
+			}
+			if (c == keys[0]) {
+				/* move left */
+				if (fits_in(curshape, pos - 1))
+					pos--;
+				continue;
+			}
+			if (c == keys[1]) {
+				/* turn */
+				const struct shape *new = &shapes[
+				    classic? curshape->rotc : curshape->rot];
+	
+				if (fits_in(new, pos))
+					curshape = new;
+				continue;
+			}
+			if (c == keys[2]) {
+				/* move right */
+				if (fits_in(curshape, pos + 1))
+					pos++;
+				continue;
+			}
+			if (c == keys[3]) {
+				/* move to bottom */
+				while (fits_in(curshape, pos + B_COLS)) {
+					pos += B_COLS;
+					score++;
+				}
+				continue;
+			}
+			if (c == '\f') {
+				scr_clear();
+				scr_msg(key_msg, 1);
+			}
+		}
+		
+		scr_clear();
+		insertscore(score, level);
+		score=0;
+	}
+	
+	scr_clear();
+	printf("\n\n\n\t\tGame over.\n");
+/*	
+	while ((i = getchar()) != '\n')
+		if (i == EOF)
+			break
+*/
+	scr_end();
+
+	return 0;
+}
+
+/* void */
+/* onintr(int signo) */
+/* { */
+/* 	scr_clear();		/\* XXX signal race *\/ */
+/* 	scr_end();		/\* XXX signal race *\/ */
+/* 	_exit(0); */
+/* } */
+
+void
+usage(void)
+{
+	(void)fprintf(stderr, "usage: tetris [-ps] [-k keys] [-l level]\n");
+	exit(1);
+}
+
+/** @}
+ */
+
Index: uspace/app/tetris/tetris.h
===================================================================
--- uspace/app/tetris/tetris.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
+++ uspace/app/tetris/tetris.h	(revision 00acd66d3981789b3f8b04cdd854d29343dd9aa0)
@@ -0,0 +1,188 @@
+/*	$OpenBSD: tetris.h,v 1.9 2003/06/03 03:01:41 millert Exp $	*/
+/*	$NetBSD: tetris.h,v 1.2 1995/04/22 07:42:48 cgd Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek and Darren F. Provine.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ *
+ *	@(#)tetris.h	8.1 (Berkeley) 5/31/93
+ */
+
+/** @addtogroup tetris
+ * @{ 
+ */
+/** @file
+ */
+
+/*
+ * Definitions for Tetris.
+ */
+
+/*
+ * The display (`board') is composed of 23 rows of 12 columns of characters
+ * (numbered 0..22 and 0..11), stored in a single array for convenience.
+ * Columns 1 to 10 of rows 1 to 20 are the actual playing area, where
+ * shapes appear.  Columns 0 and 11 are always occupied, as are all
+ * columns of rows 21 and 22.  Rows 0 and 22 exist as boundary areas
+ * so that regions `outside' the visible area can be examined without
+ * worrying about addressing problems.
+ */
+
+	/* the board */
+#define	B_COLS	12
+#define	B_ROWS	23
+#define	B_SIZE	(B_ROWS * B_COLS)
+
+typedef unsigned char cell;
+extern cell	board[B_SIZE];	/* 1 => occupied, 0 => empty */
+
+	/* the displayed area (rows) */
+#define	D_FIRST	1
+#define	D_LAST	22
+
+	/* the active area (rows) */
+#define	A_FIRST	1
+#define	A_LAST	21
+
+/*
+ * Minimum display size.
+ */
+#define	MINROWS	23
+#define	MINCOLS	40
+
+extern int	Rows, Cols;	/* current screen size */
+
+/*
+ * Translations from board coordinates to display coordinates.
+ * As with board coordinates, display coordiates are zero origin.
+ */
+#define	RTOD(x)	((x) - 1)
+#define	CTOD(x)	((x) * 2 + (((Cols - 2 * B_COLS) >> 1) - 1))
+
+/*
+ * A `shape' is the fundamental thing that makes up the game.  There
+ * are 7 basic shapes, each consisting of four `blots':
+ *
+ *	X.X	  X.X		X.X
+ *	  X.X	X.X	X.X.X	X.X	X.X.X	X.X.X	X.X.X.X
+ *			  X		X	    X
+ *
+ *	  0	  1	  2	  3	  4	  5	  6
+ *
+ * Except for 3 and 6, the center of each shape is one of the blots.
+ * This blot is designated (0,0).  The other three blots can then be
+ * described as offsets from the center.  Shape 3 is the same under
+ * rotation, so its center is effectively irrelevant; it has been chosen
+ * so that it `sticks out' upward and leftward.  Except for shape 6,
+ * all the blots are contained in a box going from (-1,-1) to (+1,+1);
+ * shape 6's center `wobbles' as it rotates, so that while it `sticks out'
+ * rightward, its rotation---a vertical line---`sticks out' downward.
+ * The containment box has to include the offset (2,0), making the overall
+ * containment box range from offset (-1,-1) to (+2,+1).  (This is why
+ * there is only one row above, but two rows below, the display area.)
+ *
+ * The game works by choosing one of these shapes at random and putting
+ * its center at the middle of the first display row (row 1, column 5).
+ * The shape is moved steadily downward until it collides with something:
+ * either  another shape, or the bottom of the board.  When the shape can
+ * no longer be moved downwards, it is merged into the current board.
+ * At this time, any completely filled rows are elided, and blots above
+ * these rows move down to make more room.  A new random shape is again
+ * introduced at the top of the board, and the whole process repeats.
+ * The game ends when the new shape will not fit at (1,5).
+ *
+ * While the shapes are falling, the user can rotate them counterclockwise
+ * 90 degrees (in addition to moving them left or right), provided that the
+ * rotation puts the blots in empty spaces.  The table of shapes is set up
+ * so that each shape contains the index of the new shape obtained by
+ * rotating the current shape.  Due to symmetry, each shape has exactly
+ * 1, 2, or 4 rotations total; the first 7 entries in the table represent
+ * the primary shapes, and the remaining 12 represent their various
+ * rotated forms.
+ */
+struct shape {
+	int	rot;	/* index of rotated version of this shape */
+	int	rotc;	/* -- " -- in classic version  */
+	int	off[3];	/* offsets to other blots if center is at (0,0) */
+};
+
+extern const struct shape shapes[];
+
+extern const struct shape *curshape;
+extern const struct shape *nextshape;
+
+/*
+ * Shapes fall at a rate faster than once per second.
+ *
+ * The initial rate is determined by dividing 1 million microseconds
+ * by the game `level'.  (This is at most 1 million, or one second.)
+ * Each time the fall-rate is used, it is decreased a little bit,
+ * depending on its current value, via the `faster' macro below.
+ * The value eventually reaches a limit, and things stop going faster,
+ * but by then the game is utterly impossible.
+ */
+extern long	fallrate;	/* less than 1 million; smaller => faster */
+#define	faster() (fallrate -= fallrate / 3000)
+
+/*
+ * Game level must be between 1 and 9.  This controls the initial fall rate
+ * and affects scoring.
+ */
+#define	MINLEVEL	1
+#define	MAXLEVEL	9
+
+/*
+ * Scoring is as follows:
+ *
+ * When the shape comes to rest, and is integrated into the board,
+ * we score one point.  If the shape is high up (at a low-numbered row),
+ * and the user hits the space bar, the shape plummets all the way down,
+ * and we score a point for each row it falls (plus one more as soon as
+ * we find that it is at rest and integrate it---until then, it can
+ * still be moved or rotated).
+ *
+ * If previewing has been turned on, the score is multiplied by PRE_PENALTY.
+ */
+#define PRE_PENALTY 0.75
+
+extern int	score;		/* the obvious thing */
+//extern gid_t	gid, egid;
+
+extern char	key_msg[100];
+extern int	showpreview;
+extern int	classic;
+
+int	fits_in(const struct shape *, int);
+void	place(const struct shape *, int, int);
+void	stop(char *);
+
+/** @}
+ */
+
