diff --git a/BuildConf/armv7/Makefile.cfg b/BuildConf/armv7/Makefile.cfg
index a2e4cc5b68b2727c053a0f44cfb933e15153d89b..3180234a859e2f9cbc78b2252dd8261ca3d1e68d 100644
--- a/BuildConf/armv7/Makefile.cfg
+++ b/BuildConf/armv7/Makefile.cfg
@@ -1,13 +1,9 @@
 
+TRIPLET = arm-pc-acess2
 ARM_CPUNAME = gerneric-armv7
-CC = arm-eabi-gcc -mcpu=$(ARM_CPUNAME)
-AS = arm-eabi-gcc -mcpu=$(ARM_CPUNAME) -c
-CXX = arm-eabi-g++ -mcpu=$(ARM_CPUNAME)
-LD = arm-eabi-ld
-OBJDUMP = arm-eabi-objdump
+#AS = $(TRIPLET)-gcc -mcpu=$(ARM_CPUNAME) -c
 DISASM := $(OBJDUMP) -d -S
 ARCHDIR = armv7
-STRIP = arm-eabi-strip
 
 ASSUFFIX = S
 
diff --git a/BuildConf/x86_64/Makefile.cfg b/BuildConf/x86_64/Makefile.cfg
index ee10d852b3fc694ef99cf8c08257791784ff326b..20dcbb2025032c96110b8e5d8e928b923d41de61 100644
--- a/BuildConf/x86_64/Makefile.cfg
+++ b/BuildConf/x86_64/Makefile.cfg
@@ -1,5 +1,6 @@
 
 TRIPLET = x86_64-pc-acess2
+AS = nasm
 
 KERNEL_CFLAGS := -mcmodel=kernel -nostdlib -mno-red-zone -Wall -mno-sse
 DYNMOD_CFLAGS := -mcmodel=small -fPIC -mno-red-zone -mno-sse
diff --git a/Externals/cross-compiler/Makefile b/Externals/cross-compiler/Makefile
index 831ea4da1ab4954f898e0423dd94d298ea9bd032..ae2df5ae1c5cd6819319a0e9dc2452d213df7e0d 100644
--- a/Externals/cross-compiler/Makefile
+++ b/Externals/cross-compiler/Makefile
@@ -35,6 +35,7 @@ $(BDIR_GCC)/Makefile: Makefile $(addprefix $(GCC_DIR)/,$(GCC_CHANGES)) $(GCC_DIR
 
 $(PREFIX)/bin/$(TARGET)-gcc: $(BDIR_GCC)/Makefile
 	@$(ENVVARS) make -C $(BDIR_GCC) $(GCC_TARGETS:%=all-%) -j $(PARLEVEL)
+	@$(ENVVARS) make -C $(BDIR_GCC)libstdc++-v3/ all-target-libsupc++ -j $(PARLEVEL)
 	@$(ENVVARS) make -C $(BDIR_GCC) $(GCC_TARGETS:%=install-%)
 
 
diff --git a/Externals/cross-compiler/Makefile.common.mk b/Externals/cross-compiler/Makefile.common.mk
index f34faa7be5aea24ca4ae257aa11843fb7d81bc29..b986044d2ac6e45580b0cc0af8cd89f1e765a64b 100644
--- a/Externals/cross-compiler/Makefile.common.mk
+++ b/Externals/cross-compiler/Makefile.common.mk
@@ -17,7 +17,7 @@ ifeq ($(BINUTILS_ARCHIVE),)
  $(error No archive found)
 endif
 
-BINUTILS_CHANGES := config.sub bfd/config.bfd gas/configure.tgt ld/configure.tgt ld/emulparams/acess2_i386.sh ld/emulparams/acess2_amd64.sh ld/Makefile.in
+BINUTILS_CHANGES := config.sub bfd/config.bfd gas/configure.tgt ld/configure.tgt ld/emulparams/acess2_i386.sh ld/emulparams/acess2_amd64.sh ld/emulparams/acess2_arm.sh ld/Makefile.in
 GCC_CHANGES := config.sub gcc/config.gcc gcc/config/acess2.h libgcc/config.host gcc/config/acess2.opt
 # libstdc++-v3/crossconfig.m4 config/override.m4
 
diff --git a/Externals/cross-compiler/patches/binutils/bfd/config.bfd.patch b/Externals/cross-compiler/patches/binutils/bfd/config.bfd.patch
index 6b61642485013e25d47e91d24fb2aebcea3e0126..0c0183101e6135c310aadfd2fba0b4b92a73e4b1 100644
--- a/Externals/cross-compiler/patches/binutils/bfd/config.bfd.patch
+++ b/Externals/cross-compiler/patches/binutils/bfd/config.bfd.patch
@@ -12,7 +12,7 @@
 +    want64=true
 +    ;;
 +  arm-*-acess2)
-+    targ_defvec=bfd_elf32_arm_vec
-+    targ_selvecs="bfd_elf32_arm_vec"
++    targ_defvec=bfd_elf32_littlearm_vec
++    targ_selvecs="bfd_elf32_bigarm_vec"
 +    ;;
  # END OF targmatch.h
diff --git a/Externals/cross-compiler/patches/binutils/gas/configure.tgt.patch b/Externals/cross-compiler/patches/binutils/gas/configure.tgt.patch
index a024c0805ee535b43e4b73821eb0bf87cf03e301..6148df197182ced812f85879b7742cbf63b80073 100644
--- a/Externals/cross-compiler/patches/binutils/gas/configure.tgt.patch
+++ b/Externals/cross-compiler/patches/binutils/gas/configure.tgt.patch
@@ -1,6 +1,7 @@
 --- gas/configure.tgt 2011-07-29 00:00:00.000000 +0000
 +++ gas/configure.tgt 2013-03-01 10:45:00.000000 +0800
-@@ -173,2 +173,3 @@
+@@ -173,2 +173,4 @@
    i386-sequent-bsd*)			fmt=aout em=dynix ;;
 +  i386-*-acess2*)    fmt=elf ;;
++  arm-*-acess2*)    fmt=elf ;;
    i386-*-beospe*)			fmt=coff em=pe ;;
diff --git a/Externals/cross-compiler/patches/binutils/ld/Makefile.in.patch b/Externals/cross-compiler/patches/binutils/ld/Makefile.in.patch
index 76439619c5cbf79f0515b40ad4ef22a2681cbfb5..becadff7eca3e7385d676604ed1db05ce320ab3b 100644
--- a/Externals/cross-compiler/patches/binutils/ld/Makefile.in.patch
+++ b/Externals/cross-compiler/patches/binutils/ld/Makefile.in.patch
@@ -1,9 +1,11 @@
 --- ld/Makefile.in
 +++ ld/Makefile.in
-@@ -2627,2 +2627,6 @@
+@@ -2627,2 +2627,8 @@
  	${GENSCRIPTS} elf32xtensa "$(tdir_elf32xtensa)"
 +eacess2_i386.c: $(srcdir)/emulparams/acess2_i386.sh $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 +	${GENSCRIPTS} acess2_i386 "$(tdir_acess2_i386)"
 +eacess2_amd64.c: $(srcdir)/emulparams/acess2_amd64.sh $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
 +	${GENSCRIPTS} acess2_amd64 "$(tdir_acess2_amd64)"
++eacess2_arm.c: $(srcdir)/emulparams/acess2_arm.sh $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
++	${GENSCRIPTS} acess2_arm "$(tdir_acess2_arm)"
  eelf_i386.c: $(srcdir)/emulparams/elf_i386.sh \
diff --git a/Externals/cross-compiler/patches/binutils/ld/configure.tgt.patch b/Externals/cross-compiler/patches/binutils/ld/configure.tgt.patch
index cc3dc88b813e9b3bee05d05100e246f3c0a1f1f7..1d5a4853b67268c5735114e26be6d3a61db1bd86 100644
--- a/Externals/cross-compiler/patches/binutils/ld/configure.tgt.patch
+++ b/Externals/cross-compiler/patches/binutils/ld/configure.tgt.patch
@@ -1,7 +1,8 @@
 --- ld/configure.tgt
 +++ ld/configure.tgt
-@@ -167,1 +167,3 @@
+@@ -167,1 +167,4 @@
  i[3-7]86-*-nto-qnx*)    targ_emul=i386nto ;;
 +i[3-7]86-*-acess2*)    targ_emul=acess2_i386 ;;
 +x86_64-*-acess2*)      targ_emul=acess2_amd64 ;;
++arm-*-acess2*)         targ_emul=acess2_arm ;;
 
diff --git a/Externals/cross-compiler/patches/binutils/ld/emulparams/acess2_arm.sh b/Externals/cross-compiler/patches/binutils/ld/emulparams/acess2_arm.sh
new file mode 100644
index 0000000000000000000000000000000000000000..87ef5df09814887fca8e978f2833f2c3251d402d
--- /dev/null
+++ b/Externals/cross-compiler/patches/binutils/ld/emulparams/acess2_arm.sh
@@ -0,0 +1,19 @@
+SCRIPT_NAME=elf
+OUTPUT_FORMAT="elf32-littlearm"
+BIG_OUTPUT_FORMAT="elf32-bigarm"
+LITTLE_OUTPUT_FORMAT="elf32-littlearm"
+TEXT_START_ADDR=0x8000
+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
+COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
+TEMPLATE_NAME=elf32
+
+ARCH=arm
+MACHINE=
+GENERATE_SHLIB_SCRIPT=yes
+GENERATE_PIE_SCRIPT=yes
+
+NO_SMALL_DATA=yes
+SEPARATE_GOTPLT=12
+
+ELF_INTERPRETER_NAME=\"/Acess/Libs/ld-acess.so\"
+
diff --git a/Externals/cross-compiler/patches/gcc/gcc/config.gcc.patch b/Externals/cross-compiler/patches/gcc/gcc/config.gcc.patch
index 9c7087ab22e17f17d9618c5e45b0902ef74dd7e8..c6f085ec7e81ef700e0e12bad4a7e227ab738ac7 100644
--- a/Externals/cross-compiler/patches/gcc/gcc/config.gcc.patch
+++ b/Externals/cross-compiler/patches/gcc/gcc/config.gcc.patch
@@ -14,7 +14,7 @@
 +  ;;
  *-*-darwin*)
 
-@@ -1192,2 +1196,12 @@
+@@ -1192,2 +1196,17 @@
  	;;
 +i[3-7]86-*-acess2*)
 +	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h i386/i386elf.h newlib-stdint.h acess2.h"
@@ -25,5 +25,10 @@
 +	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h acess2.h"
 +	tmake_file="i386/t-i386elf i386/t-crtstuff t-svr4"
 +	use_fixproto=yes
++	;;
++arm-*-acess2*)
++	tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/bpabi.h newlib-stdint.h acess2.h arm/aout.h arm/arm.h"
++	tmake_file="arm/t-arm arm/t-arm-elf arm/t-bpabi"
++	use_fixproto=yes
 +	;;
  i[34567]86-*-elf*)
diff --git a/Externals/cross-compiler/patches/gcc/libgcc/config.host.patch b/Externals/cross-compiler/patches/gcc/libgcc/config.host.patch
index e250c6033b5b1dba14cb60d4c6c643f31317e0c1..52725e33b9bb35504dca5efc53707263bc1ffbfb 100644
--- a/Externals/cross-compiler/patches/gcc/libgcc/config.host.patch
+++ b/Externals/cross-compiler/patches/gcc/libgcc/config.host.patch
@@ -1,6 +1,6 @@
 --- libgcc/config.host
 +++ libgcc/config.host
-@@ -523,4 +523,12 @@
+@@ -523,4 +523,18 @@
  x86_64-*-elf*)
  	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
  	;;
@@ -11,6 +11,12 @@
 +x86_64-*-acess2*)
 +	extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o crtendT.o"
 +	tmake_file="$tmake_file i386/t-crtstuff t-crtstuff-pic t-libgcc-pic"
++	;;
++arm-*-acess2*)
++	extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o crtendT.o"
++	tmake_file="${tmake_file} arm/t-arm arm/t-elf t-fixedpoint-gnu-prefix arm/t-bpabi t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp"
++	tm_file="$tm_file arm/bpabi-lib.h"
++	unwind_header=config/arm/unwind-arm.h
 +	;;
  i[34567]86-*-freebsd*)
 
diff --git a/Externals/glib/Makefile b/Externals/glib/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..953ef038da4bdd37888d3de358d15a7feb798e8d
--- /dev/null
+++ b/Externals/glib/Makefile
@@ -0,0 +1,17 @@
+#
+# Acess2 Externals - glib
+# - Patches and Makefile by John Hodge (thePowersGang)
+#
+
+DEPS := libffi
+_NAME := glib
+TARBALL_PATTERN := $(_NAME)-*.tar.xz
+TARBALL_TO_DIR_L := $(_NAME)-%.tar.xz
+TARBALL_TO_DIR_R := $(_NAME)-%
+PATCHES := config.sub
+CONFIGURE_ARGS := glib_cv_stack_grows=no ac_cv_func_posix_getpwuid_r=no ac_cv_func_posix_getgrgid_r=no
+CONFIGURE_ARGS += LDFLAGS=-lpsocket
+
+include ../common_automake.mk
+
+
diff --git a/Externals/glib/patches/config.sub.patch b/Externals/glib/patches/config.sub.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f600ad4b374acc30a81e55937316788e8affe64d
--- /dev/null
+++ b/Externals/glib/patches/config.sub.patch
@@ -0,0 +1,8 @@
+--- glib/config.sub
++++ glib/config.sub
+@@ -1335,2 +1335,5 @@
+		;;
++	-acess2)
++		os=-acess2
++		;;
+	-solaris)
diff --git a/Externals/pkgconfig/Makefile b/Externals/pkgconfig/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..bcd63052eaa9e21ac5d7aae09f906e557989b035
--- /dev/null
+++ b/Externals/pkgconfig/Makefile
@@ -0,0 +1,17 @@
+#
+# Acess2 Externals - pkgconfig
+# - Patches and Makefile by John Hodge (thePowersGang)
+#
+
+DEPS := 
+TARBALL_PATTERN := pkg-config-*.tar.gz
+TARBALL_TO_DIR_L := pkg-config-%.tar.gz
+TARBALL_TO_DIR_R := pkg-config-%
+PATCHES := 
+CONFIGURE_LINE = $(SDIR)/configure --prefix=$(BUILD_OUTDIR) --with-internal-glib
+
+include ../common_automake.mk
+
+
+
+
diff --git a/Externals/pkgconfig/patches/config.sub.patch b/Externals/pkgconfig/patches/config.sub.patch
new file mode 100644
index 0000000000000000000000000000000000000000..b2d73891f75db2ec5941170f972abc91da6ce25f
--- /dev/null
+++ b/Externals/pkgconfig/patches/config.sub.patch
@@ -0,0 +1,7 @@
+--- bochs-2.6.2_orig/config.sub	2013-06-17 11:39:39.670720710 +0800
++++ bochs-2.6.2/config.sub	2013-06-17 11:48:09.149384231 +0800
+@@ -1344,2 +1344,3 @@
+ 	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
++	      | -acess2 \
+ 	      | -aos* | -aros* \
+
diff --git a/Externals/pkgconfig/patches/glib/config.sub.patch b/Externals/pkgconfig/patches/glib/config.sub.patch
new file mode 100644
index 0000000000000000000000000000000000000000..f600ad4b374acc30a81e55937316788e8affe64d
--- /dev/null
+++ b/Externals/pkgconfig/patches/glib/config.sub.patch
@@ -0,0 +1,8 @@
+--- glib/config.sub
++++ glib/config.sub
+@@ -1335,2 +1335,5 @@
+		;;
++	-acess2)
++		os=-acess2
++		;;
+	-solaris)
diff --git a/KernelLand/Kernel/Makefile b/KernelLand/Kernel/Makefile
index 93536b8a6e7cf83edbb7eac998f7538f1e986c29..34e6bcfd24d7fc2470d2e921ff833df1d572a1be 100644
--- a/KernelLand/Kernel/Makefile
+++ b/KernelLand/Kernel/Makefile
@@ -57,7 +57,7 @@ OBJ := $(addprefix arch/$(ARCHDIR)/,$(A_OBJ))
 OBJ += pmemmap.o
 OBJ += heap.o logging.o debug.o lib.o libc.o adt.o time.o utf16.o debug_hooks.o
 OBJ += drvutil_video.o drvutil_disk.o memfs_helpers.o
-OBJ += messages.o modules.o syscalls.o system.o
+OBJ += messages.o modules.o syscalls.o system.o emergency_console.o
 OBJ += threads.o mutex.o semaphore.o workqueue.o events.o rwlock.o
 OBJ += drv/zero-one.o drv/proc.o drv/fifo.o drv/dgram_pipe.o drv/iocache.o drv/pci.o drv/vpci.o
 OBJ += drv/vterm.o drv/vterm_font.o drv/vterm_vt100.o drv/vterm_output.o drv/vterm_input.o drv/vterm_termbuf.o
diff --git a/KernelLand/Kernel/arch/x86/common.inc.asm b/KernelLand/Kernel/arch/x86/common.inc.asm
new file mode 100644
index 0000000000000000000000000000000000000000..ec7f8441028186cf503ae8e8447d495d0dee3971
--- /dev/null
+++ b/KernelLand/Kernel/arch/x86/common.inc.asm
@@ -0,0 +1,24 @@
+%macro PUSH_CC	0
+	; Don't bother being too picky, just take the time
+	pusha
+%endmacro
+%macro PUSH_SEG	0
+	push ds
+	push es
+	push fs
+	push gs
+	mov ax, 0x10
+	mov ds, ax
+	mov es, ax
+	mov fs, ax
+	mov gs, ax
+%endmacro
+%macro POP_CC	0
+	popa
+%endmacro
+%macro POP_SEG	0
+	pop gs
+	pop fs
+	pop es
+	pop ds
+%endmacro
diff --git a/KernelLand/Kernel/arch/x86/desctab.asm b/KernelLand/Kernel/arch/x86/desctab.asm
index 354a001eb375b3a1e747d7930aa3f18694f3a02c..338253474392d1efa09152c76122b9b3a017cf6e 100644
--- a/KernelLand/Kernel/arch/x86/desctab.asm
+++ b/KernelLand/Kernel/arch/x86/desctab.asm
@@ -1,6 +1,7 @@
 ; AcessOS Microkernel Version
 ;
 ; desctab.asm
+%include "arch/x86/common.inc.asm"
 [BITS 32]
 
 
@@ -182,14 +183,14 @@ Isr0xED:
 	jmp .jmp
 
 [global Isr0xEE]
-[extern SchedulerBase]
+[extern Proc_EventTimer_LAPIC]
 ; AP's Timer Interrupt
 Isr0xEE:
 	push eax	; Line up with interrupt number
 	mov eax, dr1	; CPU Number
 	push eax
 	mov eax, [esp+4]	; Load EAX back
-	jmp SchedulerBase
+	jmp Proc_EventTimer_LAPIC
 ; Spurious Interrupt
 [global Isr0xEF]
 Isr0xEF:
@@ -201,7 +202,7 @@ Isr0xEF:
 ; - Timer
 [global Isr240]
 [global Isr240.jmp]
-[extern SchedulerBase]
+[extern Proc_EventTimer_PIT]
 [extern SetAPICTimerCount]
 Isr240:
 	push 0	; Line up with Argument in errors
@@ -211,7 +212,7 @@ Isr240.jmp:
 	%if USE_MP
 	jmp SetAPICTimerCount	; This is reset once the bus speed has been calculated
 	%else
-	jmp SchedulerBase
+	jmp Proc_EventTimer_PIT
 	%endif
 ; - Assignable
 %assign i	0xF1
@@ -254,11 +255,8 @@ ErrorCommon:
 ; --------------------------
 [extern SyscallHandler]
 SyscallCommon:
-	pusha
-	push ds
-	push es
-	push fs
-	push gs
+	PUSH_CC	; Actually a pusha
+	PUSH_SEG
 	
 	push esp
 	call SyscallHandler
@@ -286,17 +284,8 @@ SyscallCommon:
 [global IRQCommon_handled]
 IRQCommon_handled equ IRQCommon.handled
 IRQCommon:
-	pusha
-	push ds
-	push es
-	push fs
-	push gs
-	
-	mov ax, 0x10
-	mov ds, ax
-	mov es, ax
-	mov fs, ax
-	mov gs, ax
+	PUSH_CC
+	PUSH_SEG
 	
 	push esp
 	call IRQ_Handler
diff --git a/KernelLand/Kernel/arch/x86/proc.asm b/KernelLand/Kernel/arch/x86/proc.asm
index be4c10d37b2bd61b4047a2bb0a4a5d7c6af2dd13..1987166d6c2ff1d6e5a8a120eaea6b62c7e89288 100644
--- a/KernelLand/Kernel/arch/x86/proc.asm
+++ b/KernelLand/Kernel/arch/x86/proc.asm
@@ -1,5 +1,6 @@
 ; AcessOS Microkernel Version
 ; Start.asm
+%include "arch/x86/common.inc.asm"
 
 [bits 32]
 
@@ -11,19 +12,6 @@ KSTACK_USERSTATE_SIZE	equ	(4+8+1+5)*4	; SRegs, GPRegs, CPU, IRET
 
 [section .text]
 
-[global NewTaskHeader]
-NewTaskHeader:
-	mov eax, [esp]
-	mov dr0, eax
-
-	mov eax, [esp+4]
-	add esp, 12	; Thread, Function, Arg Count
-	call eax
-	
-	push eax	; Ret val
-	push 0  	; 0 = This Thread
-	call Threads_Exit
-
 [extern MM_Clone]
 [global Proc_CloneInt]
 Proc_CloneInt:
@@ -53,7 +41,7 @@ Proc_CloneInt:
 ; +16 = Old RIP save loc
 ; +20 = CR3
 SwitchTasks:
-	pusha
+	PUSH_CC
 	
 	; Old IP
 	mov eax, [esp+0x20+16]
@@ -78,7 +66,7 @@ SwitchTasks:
 	jmp ecx
 
 .restore:
-	popa
+	POP_CC
 	xor eax, eax
 	ret
 
@@ -122,17 +110,8 @@ Proc_RestoreSSE:
 [extern Isr240.jmp]
 [global SetAPICTimerCount]
 SetAPICTimerCount:
-	pusha
-	push ds
-	push es
-	push fs
-	push gs
-	
-	mov ax, 0x10
-	mov ds, ax
-	mov es, ax
-	mov fs, ax
-	mov gs, ax
+	PUSH_CC
+	PUSH_SEG
 	
 	mov eax, [gpMP_LocalAPIC]
 	mov ecx, [eax+0x320]
@@ -152,7 +131,7 @@ SetAPICTimerCount:
 	mov DWORD [eax+0x380], 0
 
 	; Update Timer IRQ to the IRQ code
-	mov eax, SchedulerBase
+	mov eax, Proc_EventTimer_PIT
 	sub eax, Isr240.jmp+5
 	mov DWORD [Isr240.jmp+1], eax
 
@@ -160,72 +139,55 @@ SetAPICTimerCount:
 .ret:
 	mov dx, 0x20
 	mov al, 0x20
-	out dx, al		; ACK IRQ
-	pop gs
-	pop fs
-	pop es
-	pop ds
-	popa
+	out 0x20, al		; ACK IRQ
+	POP_SEG
+	POP_CC
 	add esp, 8	; CPU ID / Error Code
 	iret
 %endif
-; --------------
-; Task Scheduler
-; --------------
-[extern Proc_Scheduler]
-[global SchedulerBase]
-SchedulerBase:
-	pusha
-	push ds
-	push es
-	push fs
-	push gs
+
+%if USE_MP
+[global Proc_EventTimer_LAPIC]
+Proc_EventTimer_LAPIC:
+	push eax
+	mov eax, SS:[gpMP_LocalAPIC]
+	mov DWORD SS:[eax + 0xB0], 0
+	pop eax
+	jmp Proc_EventTimer_Common
+%endif
+[global Proc_EventTimer_PIT]
+Proc_EventTimer_PIT:
+	push eax
+	mov al, 0x20
+	out 0x20, al		; ACK IRQ
+	pop eax
+	jmp Proc_EventTimer_Common
+[extern Proc_HandleEventTimer]
+[global Proc_EventTimer_Common]
+Proc_EventTimer_Common:
+	PUSH_CC
+	PUSH_SEG
 	
+	; Clear the Trace/Trap flag
 	pushf
 	and BYTE [esp+1], 0xFE	; Clear Trap Flag
 	popf
-	
-	mov eax, dr0
-	push eax	; Debug Register 0, Current Thread
-	
-	mov ax, 0x10
-	mov ds, ax
-	mov es, ax
-	mov fs, ax
-	mov gs, ax
+	; Re-enable interrupts
+	; - TODO: This is quite likely racy, if we get an interrupt flood
+	sti
 	
 	%if USE_MP
 	call GetCPUNum
-	mov ebx, eax
 	push eax	; Push as argument
 	%else
 	push 0
 	%endif
 	
-	call Proc_Scheduler
+	call Proc_HandleEventTimer
 [global scheduler_return]
 scheduler_return:	; Used by some hackery in Proc_DumpThreadCPUState
-	
 	add esp, 4	; Remove CPU Number (thread is poped later)
 
-	%if USE_MP
-	test ebx, ebx
-	jnz .sendEOI
-	%endif
-	
-	mov al, 0x20
-	out 0x20, al		; ACK IRQ
-
-	%if USE_MP
-	jmp .ret
-.sendEOI:
-	mov eax, DWORD [gpMP_LocalAPIC]
-	mov DWORD [eax+0x0B0], 0
-	%endif
-.ret:
-	pop eax	; Debug Register 0, Current Thread
-	mov dr0, eax
-	
 	jmp ReturnFromInterrupt
 
 ;
diff --git a/KernelLand/Kernel/arch/x86/proc.c b/KernelLand/Kernel/arch/x86/proc.c
index 999ac679ed6234dbde6710f007648819c0a84632..b1dcb99dc1180ae1f993d2d438c92452d9ca0458 100644
--- a/KernelLand/Kernel/arch/x86/proc.c
+++ b/KernelLand/Kernel/arch/x86/proc.c
@@ -44,7 +44,6 @@ extern tGDT	gGDT[];
 extern tIDT	gIDT[];
 extern void	APWait(void);	// 16-bit AP pause code
 extern void	APStartup(void);	// 16-bit AP startup code
-extern void	NewTaskHeader(tThread *Thread, void *Fcn, int nArgs, ...);	// Actually takes cdecl args
 extern Uint	Proc_CloneInt(Uint *ESP, Uint32 *CR3, int bNoUserClone);
 extern Uint32	gaInitPageDir[1024];	// start.asm
 extern char	Kernel_Stack_Top[];
@@ -71,6 +70,7 @@ void	Proc_IdleThread(void *Ptr);
 //tThread	*Proc_GetCurThread(void);
 void	Proc_ChangeStack(void);
 // int	Proc_NewKThread(void (*Fcn)(void*), void *Data);
+void	NewTaskHeader(tThread *Thread, void (*Fcn)(void*), void *Data);	// Actually takes cdecl args
 // int	Proc_Clone(Uint *Err, Uint Flags);
 Uint	Proc_MakeUserStack(void);
 //void	Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize);
@@ -78,7 +78,7 @@ void	Proc_StartProcess(Uint16 SS, Uint Stack, Uint Flags, Uint16 CS, Uint IP) NO
 void	Proc_CallUser(Uint32 UserIP, Uint32 UserSP, const void *StackData, size_t StackDataLen);
 //void	Proc_CallFaultHandler(tThread *Thread);
 //void	Proc_DumpThreadCPUState(tThread *Thread);
-void	Proc_Scheduler(int CPU);
+void	Proc_HandleEventTimer(int CPU);
 
 // === GLOBALS ===
 // --- Multiprocessing ---
@@ -307,10 +307,12 @@ void Proc_IdleThread(void *Ptr)
 	cpu->Current->ThreadName = strdup("Idle Thread");
 	Threads_SetPriority( cpu->Current, -1 );	// Never called randomly
 	cpu->Current->Quantum = 1;	// 1 slice quantum
-	for(;;) {
+	LOG("Idle thread for CPU %i ready", GetCPUNum());
+	for(;;)
+	{
 		__asm__ __volatile__ ("sti");	// Make sure interrupts are enabled
-		__asm__ __volatile__ ("hlt");
-		Proc_Reschedule();
+		Proc_Reschedule();	// Reshedule
+		__asm__ __volatile__ ("hlt");	// And wait for an interrupt if we get scheduled again
 	}
 }
 
@@ -432,10 +434,7 @@ void Proc_ClearThread(tThread *Thread)
 
 tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
 {
-	Uint	esp;
-	tThread	*newThread;
-	
-	newThread = Threads_CloneTCB(0);
+	tThread *newThread = Threads_CloneTCB(0);
 	if(!newThread)	return -1;
 	
 	// Create new KStack
@@ -445,12 +444,14 @@ tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
 		free(newThread);
 		return -1;
 	}
+	
+	LOG("%p(%i %s) SP=%p", newThread, newThread->TID, newThread->ThreadName, newThread->KernelStack);
 
-	esp = newThread->KernelStack;
+	Uint esp = newThread->KernelStack;
 	*(Uint*)(esp-=4) = (Uint)Data;	// Data (shadowed)
-	*(Uint*)(esp-=4) = 1;	// Number of params
 	*(Uint*)(esp-=4) = (Uint)Fcn;	// Function to call
 	*(Uint*)(esp-=4) = (Uint)newThread;	// Thread ID
+	*(Uint*)(esp-=4) = (Uint)0;	// Empty return address
 	
 	newThread->SavedState.ESP = esp;
 	newThread->SavedState.EIP = (Uint)&NewTaskHeader;
@@ -463,13 +464,16 @@ tTID Proc_NewKThread(void (*Fcn)(void*), void *Data)
 	return newThread->TID;
 }
 
-#if 0
-tPID Proc_NewProcess(Uint Flags, void (*Fcn)(void*), size_t SaveSize, const void *Data)
+void NewTaskHeader(tThread *NewThread, void (*Fcn)(void*), void *Data)
 {
-	tThread	*newThread = Threads_CloneTCB(CLONE_VM);
-	return 0;
+	LOG("NewThread=%p, Fcn=%p, Data=%p", NewThread, Fcn, Data);
+	__asm__ __volatile__ ("mov %0, %%dr0" : : "r"(NewThread));
+	SHORTREL(&glThreadListLock);
+	Fcn(Data);
+	
+	Threads_Exit(0, 0);
+	for(;;);
 }
-#endif
 
 /**
  * \fn int Proc_Clone(Uint *Err, Uint Flags)
@@ -477,9 +481,7 @@ tPID Proc_NewProcess(Uint Flags, void (*Fcn)(void*), size_t SaveSize, const void
  */
 tPID Proc_Clone(Uint Flags)
 {
-	tThread	*newThread;
 	tThread	*cur = Proc_GetCurThread();
-	Uint	eip;
 
 	// Sanity, please
 	if( !(Flags & CLONE_VM) ) {
@@ -488,17 +490,17 @@ tPID Proc_Clone(Uint Flags)
 	}
 	
 	// New thread
-	newThread = Threads_CloneTCB(Flags);
+	tThread *newThread = Threads_CloneTCB(Flags);
 	if(!newThread)	return -1;
 	ASSERT(newThread->Process);
-	//ASSERT(CheckMem(newThread->Process, sizeof(tProcess)));
-	//LOG("newThread->Process = %p", newThread->Process);
 
 	newThread->KernelStack = cur->KernelStack;
 
 	// Clone state
-	eip = Proc_CloneInt(&newThread->SavedState.ESP, &newThread->Process->MemState.CR3, Flags & CLONE_NOUSER);
+	Uint eip = Proc_CloneInt(&newThread->SavedState.ESP, &newThread->Process->MemState.CR3, Flags & CLONE_NOUSER);
 	if( eip == 0 ) {
+		SHORTREL( &glThreadListLock );
+		LOG("In new thread");
 		return 0;
 	}
 	//ASSERT(newThread->Process);
@@ -536,12 +538,13 @@ tThread *Proc_SpawnWorker(void (*Fcn)(void*), void *Data)
 		Warning("Proc_SpawnWorker - Out of heap space!\n");
 		return NULL;
 	}
+	LOG("new = (%i %s)", new->TID, new->ThreadName);
 
 	// Create the stack contents
 	stack_contents[3] = (Uint)Data;
-	stack_contents[2] = 1;
-	stack_contents[1] = (Uint)Fcn;
-	stack_contents[0] = (Uint)new;
+	stack_contents[2] = (Uint)Fcn;
+	stack_contents[1] = (Uint)new;
+	stack_contents[0] = 0;
 	
 	// Create a new worker stack (in PID0's address space)
 	new->KernelStack = MM_NewWorkerStack(stack_contents, sizeof(stack_contents));
@@ -774,82 +777,82 @@ void Proc_DumpThreadCPUState(tThread *Thread)
 
 void Proc_Reschedule(void)
 {
-	tThread	*nextthread, *curthread;
 	 int	cpu = GetCPUNum();
 
 	// TODO: Wait for the lock?
-	if(IS_LOCKED(&glThreadListLock))        return;
+	if(IS_LOCKED(&glThreadListLock)) {
+		LOG("Thread list locked, not rescheduling");
+		return;
+	}
 	
-	curthread = Proc_GetCurThread();
-
-	nextthread = Threads_GetNextToRun(cpu, curthread);
-
-	if(!nextthread || nextthread == curthread)
-		return ;
-
-	#if DEBUG_TRACE_SWITCH
-	// HACK: Ignores switches to the idle threads
-	if( nextthread->TID == 0 || nextthread->TID > giNumCPUs )
+	SHORTLOCK(&glThreadListLock);
+	
+	tThread *curthread = Proc_GetCurThread();
+	tThread *nextthread = Threads_GetNextToRun(cpu, curthread);
+	
+	if(nextthread && nextthread != curthread)
 	{
-		LogF("\nSwitching CPU %i to %p (%i %s) - CR3 = 0x%x, EIP = %p, ESP = %p\n",
-			GetCPUNum(),
-			nextthread, nextthread->TID, nextthread->ThreadName,
-			nextthread->Process->MemState.CR3,
-			nextthread->SavedState.EIP,
-			nextthread->SavedState.ESP
-			);
-		LogF("OldCR3 = %P\n", curthread->Process->MemState.CR3);
-	}
-	#endif
+		#if DEBUG_TRACE_SWITCH
+		// HACK: Ignores switches to the idle threads
+		//if( nextthread->TID == 0 || nextthread->TID > giNumCPUs )
+		{
+			LogF("\nSwitching CPU %i to %p (%i %s) - CR3 = 0x%x, EIP = %p, ESP = %p\n",
+				GetCPUNum(),
+				nextthread, nextthread->TID, nextthread->ThreadName,
+				nextthread->Process->MemState.CR3,
+				nextthread->SavedState.EIP,
+				nextthread->SavedState.ESP
+				);
+			LogF(" from %p (%i %s) - CR3 = 0x%x, EIP = %p, ESP = %p\n",
+				curthread, curthread->TID, curthread->ThreadName,
+				curthread->Process->MemState.CR3,
+				curthread->SavedState.EIP,
+				curthread->SavedState.ESP
+				);
+		}
+		#endif
 
-	// Update CPU state
-	gaCPUs[cpu].Current = nextthread;
-	gaCPUs[cpu].LastTimerThread = NULL;
-	gTSSs[cpu].ESP0 = nextthread->KernelStack-4;
-	__asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) );
+		// Update CPU state
+		gaCPUs[cpu].Current = nextthread;
+		gaCPUs[cpu].LastTimerThread = NULL;
+		gTSSs[cpu].ESP0 = nextthread->KernelStack-4;
+		__asm__ __volatile__("mov %0, %%db0\n\t" : : "r"(nextthread) );
 
-	// Save FPU/MMX/XMM/SSE state
-	if( curthread && curthread->SavedState.SSE )
-	{
-		Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF );
-		curthread->SavedState.bSSEModified = 0;
-		Proc_DisableSSE();
-	}
+		// Save FPU/MMX/XMM/SSE state
+		if( curthread && curthread->SavedState.SSE )
+		{
+			Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF );
+			curthread->SavedState.bSSEModified = 0;
+			Proc_DisableSSE();
+		}
 
-	if( curthread )
-	{
-		SwitchTasks(
-			nextthread->SavedState.ESP, &curthread->SavedState.ESP,
-			nextthread->SavedState.EIP, &curthread->SavedState.EIP,
-			nextthread->Process->MemState.CR3
-			);
-	}
-	else
-	{
-		SwitchTasks(
-			nextthread->SavedState.ESP, 0,
-			nextthread->SavedState.EIP, 0,
-			nextthread->Process->MemState.CR3
-			);
+		if( curthread )
+		{
+			SwitchTasks(
+				nextthread->SavedState.ESP, &curthread->SavedState.ESP,
+				nextthread->SavedState.EIP, &curthread->SavedState.EIP,
+				nextthread->Process->MemState.CR3
+				);
+		}
+		else
+		{
+			SwitchTasks(
+				nextthread->SavedState.ESP, 0,
+				nextthread->SavedState.EIP, 0,
+				nextthread->Process->MemState.CR3
+				);
+		}
 	}
-
-	return ;
+	
+	SHORTREL(&glThreadListLock);
 }
 
 /**
- * \fn void Proc_Scheduler(int CPU)
- * \brief Swap current thread and clears dead threads
+ * \brief Handle the per-CPU timer ticking
+ 
  */
-void Proc_Scheduler(int CPU)
+void Proc_HandleEventTimer(int CPU)
 {
-	#if USE_MP
-	if( GetCPUNum() )
-		gpMP_LocalAPIC->EOI.Val = 0;
-	else
-	#endif
-		outb(0x20, 0x20);
-	__asm__ __volatile__ ("sti");	
-
 	// Call the timer update code
 	Timer_CallTimers();
 
@@ -857,6 +860,8 @@ void Proc_Scheduler(int CPU)
 	// If two ticks happen within the same task, and it's not an idle task, swap
 	if( gaCPUs[CPU].Current->TID > giNumCPUs && gaCPUs[CPU].Current == gaCPUs[CPU].LastTimerThread )
 	{
+		const tThread* const t = gaCPUs[CPU].Current;
+		LOG("Preempting thread %p(%i %s)", t, t->TID, t->ThreadName);
 		Proc_Reschedule();
 	}
 	
diff --git a/KernelLand/Kernel/arch/x86/vm8086.c b/KernelLand/Kernel/arch/x86/vm8086.c
index 93ea63ae5b6022fdb6feff0a31d489fc6439b61b..f1b50059989a0590d0871a35b296d512f5912be1 100644
--- a/KernelLand/Kernel/arch/x86/vm8086.c
+++ b/KernelLand/Kernel/arch/x86/vm8086.c
@@ -68,16 +68,14 @@ Uint32	gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32];
 // === FUNCTIONS ===
 int VM8086_Install(char **Arguments)
 {
-	tPID	pid;	
-
 	Semaphore_Init(&gVM8086_TasksToDo, 0, 10, "VM8086", "TasksToDo");
 	
 	// Lock to avoid race conditions
 	Mutex_Acquire( &glVM8086_Process );
 	
 	// Create BIOS Call process
-	pid = Proc_Clone(CLONE_VM);
-	//Log_Debug("VM8086", "pid = %i", pid);
+	tPID pid = Proc_Clone(CLONE_VM);
+	LOG("pid = %i", pid);
 	if(pid == -1)
 	{
 		Log_Error("VM8086", "Unable to clone kernel into VM8086 worker");
@@ -87,15 +85,14 @@ int VM8086_Install(char **Arguments)
 	{
 		Uint	* volatile stacksetup;	// Initialising Stack
 		Uint16	* volatile rmstack;	// Real Mode Stack
-		 int	i;
 
-		//Log_Debug("VM8086", "Initialising worker");	
+		LOG("Initialising worker");
 	
 		// Set Image Name
 		Threads_SetName("VM8086");
 
 		// Map ROM Area
-		for(i=0xA0;i<0x100;i++) {
+		for(unsigned int i = 0xA0;i<0x100;i++) {
 			MM_RefPhys(i * 0x1000);
 			MM_Map( (void*)(i * 0x1000), i * 0x1000 );
 		}
@@ -150,6 +147,7 @@ int VM8086_Install(char **Arguments)
 		stacksetup--;	*stacksetup = 0x20|3;	// ES - Kernel
 		stacksetup--;	*stacksetup = 0x20|3;	// FS
 		stacksetup--;	*stacksetup = 0x20|3;	// GS
+		LOG("stacksetup = %p, entering vm8086");
 		__asm__ __volatile__ (
 		"mov %%eax,%%esp;\n\t"	// Set stack pointer
 		"pop %%gs;\n\t"
@@ -164,6 +162,7 @@ int VM8086_Install(char **Arguments)
 	gVM8086_WorkerPID = pid;
 
 	// It's released when the GPF fires
+	LOG("Waiting for worker %i to start", gVM8086_WorkerPID);
 	Mutex_Acquire( &glVM8086_Process );
 	Mutex_Release( &glVM8086_Process );
 	
diff --git a/KernelLand/Kernel/arch/x86_64/lib.c b/KernelLand/Kernel/arch/x86_64/lib.c
index 85dda82438452ab445a553ce5c8362d24499c841..60770f63679495e9b3d991330cd221d309ea7765 100644
--- a/KernelLand/Kernel/arch/x86_64/lib.c
+++ b/KernelLand/Kernel/arch/x86_64/lib.c
@@ -88,6 +88,8 @@ void SHORTLOCK(struct sShortSpinlock *Lock)
 		Lock->Depth ++;
 		return ;
 	}
+	#else
+	ASSERT( !CPU_HAS_LOCK(Lock) );
 	#endif
 	
 	// Wait for another CPU to release
diff --git a/KernelLand/Kernel/arch/x86_64/proc.asm b/KernelLand/Kernel/arch/x86_64/proc.asm
index aff670aca173c7ac61d6d37b935c26784c6849bd..afde3544dc9c821848cb51ea9e68332f9c926dc3 100644
--- a/KernelLand/Kernel/arch/x86_64/proc.asm
+++ b/KernelLand/Kernel/arch/x86_64/proc.asm
@@ -6,6 +6,8 @@
 [section .text]
 
 [extern Threads_Exit]
+[extern glThreadListLock]
+[extern SHORTREL]
 
 [global GetRIP]
 GetRIP:
@@ -18,6 +20,9 @@ NewTaskHeader:
 	; [rsp+0x08]: Function
 	; [rsp+0x10]: Argument
 
+	mov rdi, glThreadListLock
+	call SHORTREL
+	
 	mov rdi, [rsp+0x10]
 	mov rax, [rsp+0x8]
 	add rsp, 0x10	; Reclaim stack space (thread/fcn)
diff --git a/KernelLand/Kernel/arch/x86_64/proc.c b/KernelLand/Kernel/arch/x86_64/proc.c
index 50b5054894d8987eab5d9f46bbba4143b5d1ced6..7c73bf9f6ac6ad274d8d2d9ef2acd1409d6d18e7 100644
--- a/KernelLand/Kernel/arch/x86_64/proc.c
+++ b/KernelLand/Kernel/arch/x86_64/proc.c
@@ -508,7 +508,10 @@ tTID Proc_Clone(Uint Flags)
 	
 	// Save core machine state
 	rip = Proc_CloneInt(&newThread->SavedState.RSP, &newThread->Process->MemState.CR3, !!(Flags & CLONE_NOUSER));
-	if(rip == 0)	return 0;	// Child
+	if(rip == 0) {
+		SHORTREL(&glThreadListLock);
+		return 0;	// Child
+	}
 	newThread->KernelStack = cur->KernelStack;
 	newThread->SavedState.RIP = rip;
 	newThread->SavedState.SSE = NULL;
@@ -735,62 +738,61 @@ void Proc_DumpThreadCPUState(tThread *Thread)
 
 void Proc_Reschedule(void)
 {
-	tThread	*nextthread, *curthread;
 	 int	cpu = GetCPUNum();
 
-	// TODO: Wait for it?
-	if(IS_LOCKED(&glThreadListLock))        return;
-	
-	curthread = gaCPUs[cpu].Current;
-
-	nextthread = Threads_GetNextToRun(cpu, curthread);
+	if(CPU_HAS_LOCK(&glThreadListLock))
+		return;
+	SHORTLOCK(&glThreadListLock);
 
-	if(nextthread == curthread)	return ;
+	tThread	*curthread = gaCPUs[cpu].Current;
+	tThread	*nextthread = Threads_GetNextToRun(cpu, curthread);
+	
 	if(!nextthread)
 		nextthread = gaCPUs[cpu].IdleThread;
-	if(!nextthread)
-		return ;
-
-	#if DEBUG_TRACE_SWITCH
-	LogF("\nSwitching to task CR3 = 0x%x, RIP = %p, RSP = %p - %i (%s)\n",
-		nextthread->Process->MemState.CR3,
-		nextthread->SavedState.RIP,
-		nextthread->SavedState.RSP,
-		nextthread->TID,
-		nextthread->ThreadName
-		);
-	#endif
-
-	// Update CPU state
-	gaCPUs[cpu].Current = nextthread;
-	gTSSs[cpu].RSP0 = nextthread->KernelStack-sizeof(void*);
-	__asm__ __volatile__ ("mov %0, %%db0" : : "r" (nextthread));
 
-	if( curthread )
+	if(nextthread && nextthread != curthread)
 	{
-		// Save FPU/MMX/XMM/SSE state
-		if( curthread->SavedState.SSE )
+		#if DEBUG_TRACE_SWITCH
+		LogF("\nSwitching to task CR3 = 0x%x, RIP = %p, RSP = %p - %i (%s)\n",
+			nextthread->Process->MemState.CR3,
+			nextthread->SavedState.RIP,
+			nextthread->SavedState.RSP,
+			nextthread->TID,
+			nextthread->ThreadName
+			);
+		#endif
+
+		// Update CPU state
+		gaCPUs[cpu].Current = nextthread;
+		gTSSs[cpu].RSP0 = nextthread->KernelStack-sizeof(void*);
+		__asm__ __volatile__ ("mov %0, %%db0" : : "r" (nextthread));
+
+		if( curthread )
 		{
-			Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF );
-			curthread->SavedState.bSSEModified = 0;
-			Proc_DisableSSE();
+			// Save FPU/MMX/XMM/SSE state
+			if( curthread->SavedState.SSE )
+			{
+				Proc_SaveSSE( ((Uint)curthread->SavedState.SSE + 0xF) & ~0xF );
+				curthread->SavedState.bSSEModified = 0;
+				Proc_DisableSSE();
+			}
+			SwitchTasks(
+				nextthread->SavedState.RSP, &curthread->SavedState.RSP,
+				nextthread->SavedState.RIP, &curthread->SavedState.RIP,
+				nextthread->Process->MemState.CR3
+				);
+		}
+		else
+		{
+			Uint	tmp;
+			SwitchTasks(
+				nextthread->SavedState.RSP, &tmp,
+				nextthread->SavedState.RIP, &tmp,
+				nextthread->Process->MemState.CR3
+				);
 		}
-		SwitchTasks(
-			nextthread->SavedState.RSP, &curthread->SavedState.RSP,
-			nextthread->SavedState.RIP, &curthread->SavedState.RIP,
-			nextthread->Process->MemState.CR3
-			);
-	}
-	else
-	{
-		Uint	tmp;
-		SwitchTasks(
-			nextthread->SavedState.RSP, &tmp,
-			nextthread->SavedState.RIP, &tmp,
-			nextthread->Process->MemState.CR3
-			);
 	}
-	return ;
+	SHORTREL(&glThreadListLock);
 }
 
 /**
diff --git a/KernelLand/Kernel/drv/vterm_input.c b/KernelLand/Kernel/drv/vterm_input.c
index 6c25cc81974a888863f4b653a9630f6d8abd8500..aa517d9df69758af9832d6a905124c955f655d9f 100644
--- a/KernelLand/Kernel/drv/vterm_input.c
+++ b/KernelLand/Kernel/drv/vterm_input.c
@@ -95,20 +95,30 @@ void VT_KBCallBack(Uint32 Codepoint)
 		
 //		Log_Debug("VTerm", "Magic Ctrl-Alt-0x%x", term->RawScancode);	
 
+		const unsigned int scroll_step = term->TextHeight / 2;
+		// Note the lack of giVT_Scrollback+1, view top can't go above size-onescreen
+		const unsigned int scroll_max = term->TextHeight * giVT_Scrollback;
 		switch(term->RawScancode)
 		{
-		// Scrolling
+		// VTerm scrolling
+		// - Scrolls half a screen at a time
+		// - View up (text goes down)
 		case KEYSYM_PGUP:
 			if( term->Flags & VT_FLAG_ALTBUF )
 				return ;
-			term->ViewTopRow = MAX(0, term->ViewTopRow - 1);
+			Log_Debug("VTerm", "ScrollUp - Old=%i, step=%i", term->ViewTopRow, scroll_step);
+			term->ViewTopRow = (term->ViewTopRow > scroll_step ? term->ViewTopRow - scroll_step : 0);
+			Log_Debug("VTerm", "ScrollUp - New=%i", term->ViewTopRow);
 			VT_int_UpdateScreen(term, 1);
 			return;
+		// - View down (text goes up)
 		case KEYSYM_PGDN:
 			if( term->Flags & VT_FLAG_ALTBUF )
 				return ;
-			// Note the lack of giVT_Scrollback+1, view top can't go above size-onescreen
-			term->ViewTopRow = MIN(term->ViewTopRow + 1, term->Height * giVT_Scrollback);
+			
+			Log_Debug("VTerm", "ScrollDown - Old=%i, max=%i", term->ViewTopRow, scroll_max);
+			term->ViewTopRow = MIN(term->ViewTopRow + scroll_step, scroll_max);
+			Log_Debug("VTerm", "ScrollDown - New=%i", term->ViewTopRow);
 			VT_int_UpdateScreen(term, 1);
 			return;
 		}
diff --git a/KernelLand/Kernel/emergency_console.c b/KernelLand/Kernel/emergency_console.c
new file mode 100644
index 0000000000000000000000000000000000000000..dd6d708b31c2c22fbea3c808167af3ce41733dfd
--- /dev/null
+++ b/KernelLand/Kernel/emergency_console.c
@@ -0,0 +1,226 @@
+/*
+ * Acess 2 Kernel
+ * - By John Hodge (thePowersGang)
+ * 
+ * emergency_console.c
+ * - Kernel-land emergency console/shell
+ */
+#include <acess.h>
+#include <stdarg.h>
+
+#define STDIN	0
+#define STDOUT	1
+#define STDERR	2
+
+// === PROTOTYPES ===
+void EmergencyConsole(void);
+// -- Commands
+void Command_ls(const char* path);
+void Command_hd(const char* path);
+void Command_mount(const char *fs, const char *dev, const char *point);
+// --
+static char **split_args(char *line);
+static char *read_line(int fd);
+static int dprintf(int fd, const char *fmt, ...);// __attribute__((printf(2,3)));
+
+// === CODE ===
+void EmergencyConsole(void)
+{
+	for(;;)
+	{
+		dprintf(STDOUT, "(kernel)$ ");
+		char *line = read_line(STDIN);
+		
+		// Explode line into args
+		char **args = split_args(line);
+		// Get command from first arg
+		ASSERT(args);
+		ASSERT(args[0]);
+		if( strcmp(args[0], "help") == 0 ) {
+			dprintf(STDOUT,
+				"Commands:\n"
+				"ls <path> - List the contents of a directory\n"
+				"hd <path> - Dump a file in a 16 bytes/line hex format\n"
+				"mount <fs> <device> <point> - Mount a filesystem\n"
+				);
+		}
+		else if( strcmp(args[0], "ls") == 0 ) {
+			Command_ls(args[1]); 
+		}
+		else if( strcmp(args[0], "hd") == 0 ) {
+			Command_hd(args[1]);
+		}
+		else if( strcmp(args[0], "mount") == 0 ) {
+			Command_mount(args[1], args[2], args[3]);
+		}
+		else
+		{
+			dprintf(STDERR, "Unknown command '%s'\n", args[0]);
+		}
+		// Free args
+		free(args);
+		free(line);
+	}
+}
+
+void Command_ls(const char* path)
+{
+	dprintf(STDERR, "ls: TODO - Implement\n");
+}
+void Command_hd(const char* path)
+{
+	dprintf(STDERR, "hd: TODO - Implement\n");
+}
+void Command_mount(const char *fs, const char *dev, const char *point)
+{
+	dprintf(STDERR, "mount: TODO - Implement\n");
+}
+
+// Allocates return array (NUL terminated), but mangles input string
+static int split_args_imp(char *line, char **buf)
+{
+	 int	argc = 0;
+	 int	pos = 0;
+	enum {
+		MODE_SPACE,
+		MODE_NORM,
+		MODE_SQUOTE,
+		MODE_DQUOTE,
+	} mode = MODE_SPACE;
+	for( char *chp = line; *chp; chp ++ )
+	{
+		if( *chp == ' ' ) {
+			if( mode != MODE_SPACE ) {
+				if(buf) buf[argc][pos] = '\0';
+				argc ++;
+			}
+			mode = MODE_SPACE;
+			continue ;
+		}
+		
+		switch( mode )
+		{
+		case MODE_SPACE:
+			if( buf )
+				buf[argc] = chp;
+			pos = 0;
+		case MODE_NORM:
+			switch( *chp )
+			{
+			case '"':
+				mode = MODE_DQUOTE;
+				break;
+			case '\'':
+				mode = MODE_SQUOTE;
+				break;
+			case '\\':
+				chp ++;
+				switch( *chp )
+				{
+				case '\0':
+					dprintf(STDERR, "err: Trailing '\\'\n");
+					break;
+				case '\\':
+				case '\'':
+				case '"':
+					if(buf)	buf[argc][pos++] = *chp;
+					break;
+				default:
+					dprintf(STDERR, "err: Unkown escape '%c'\n", *chp);
+					break;
+				}
+				break;
+			default:
+				if(buf)	buf[argc][pos++] = *chp;
+				break;
+			}
+			break;
+		case MODE_SQUOTE:
+			switch( *chp )
+			{
+			case '\'':
+				mode = MODE_NORM;
+				break;
+			case '\0':
+				dprintf(STDERR, "err: Unterminated \' string\n");
+				break;
+			default:
+				if(buf)	buf[argc][pos++] = *chp;
+				break;
+			}
+			break;
+		case MODE_DQUOTE:
+			switch( *chp )
+			{
+			case '\"':
+				mode = MODE_NORM;
+				break;
+			case '\\':
+				chp ++;
+				switch(*chp)
+				{
+				case '\0':
+					dprintf(STDERR, "err: Trailing '\\' in \" string\n");
+					break;
+				case '\\':
+				case '"':
+					if(buf)	buf[argc][pos++] = *chp;
+					break;
+				default:
+					dprintf(STDERR, "err: Unkown escape '%c'\n", *chp);
+					break;
+				}
+				break;
+			case '\0':
+				dprintf(STDERR, "err: Unterminated \" string\n");
+				break;
+			default:
+				if(buf)	buf[argc][pos++] = *chp;
+				break;
+			}
+			break;
+		}
+	}
+
+	if(buf) buf[argc][pos++] = '\0';
+	argc ++;
+	return argc;
+}
+static char **split_args(char *line)
+{
+	// 1. Count
+	int count = split_args_imp(line, NULL);
+	char **ret = malloc( (count + 1) * sizeof(char*) );
+	
+	split_args_imp(line, ret);
+	ret[count] = NULL;
+	return ret;
+}
+
+static char *read_line(int fd)
+{
+	// Read line (or up to ~128 bytes)
+	// - This assumes a default PTY state (i.e. line buffered, echo on)
+	char *ret = malloc(128);
+	size_t len = VFS_Read(STDIN, 128, ret);
+	ret[len] = 0;
+	return ret;
+}
+
+static int dprintf(int fd, const char *fmt, ...)
+{
+	va_list	args;
+	va_start(args, fmt);
+	size_t len = vsnprintf(NULL, 0, fmt, args);
+	va_end(args);
+	
+	char buf[len+1];
+	va_start(args, fmt);
+	vsnprintf(buf, len+1, fmt, args);
+	va_end(args);
+	
+	VFS_Write(fd, len, buf);
+	
+	return len;
+}
+
diff --git a/KernelLand/Kernel/events.c b/KernelLand/Kernel/events.c
index ec47a169e543856c787cd99e097413858e2a0d2d..a572d43362d1e66628a7cd258a7bdfee581892fa 100644
--- a/KernelLand/Kernel/events.c
+++ b/KernelLand/Kernel/events.c
@@ -87,7 +87,7 @@ Uint32 Threads_WaitEvents(Uint32 EventMask)
 	{
 		Threads_int_Sleep(THREAD_STAT_EVENTSLEEP, NULL, EventMask,
 			&us, NULL, &us->IsLocked);
-		// Woken when lock is acquired
+		// Woken when an event fires
 		SHORTLOCK( &us->IsLocked );
 	}
 	
diff --git a/KernelLand/Kernel/system.c b/KernelLand/Kernel/system.c
index 748c744f0c0abf0a2e3330fb1d823b7df4b664fe..9892af3725deb6c964be7f1ea30e2f8a602101f5 100644
--- a/KernelLand/Kernel/system.c
+++ b/KernelLand/Kernel/system.c
@@ -14,6 +14,7 @@ extern int	Modules_LoadBuiltins(void);
 extern void	Modules_SetBuiltinParams(char *Name, char *ArgString);
 extern void	Debug_SetKTerminal(const char *File);
 extern void	Timer_CallbackThread(void *);
+extern void	EmergencyConsole(void);
 
 // === PROTOTYPES ===
 void	System_Init(char *Commandline);
@@ -22,6 +23,7 @@ void	System_ExecuteCommandLine(void);
 void	System_ParseVFS(char *Arg);
 void	System_ParseModuleArgs(char *Arg);
 void	System_ParseSetting(char *Arg);
+void	System_EmergencyConsole(void);
 
 // === GLOBALS ===
 const char	*gsInitBinary = "/Acess/SBin/init";
@@ -41,6 +43,7 @@ void System_Init(char *CommandLine)
 	Modules_LoadBuiltins();
 	Arch_LoadBootModules();
 	
+	Log_Log("Config", "Running command line '%s", CommandLine);
 	System_ExecuteCommandLine();
 	
 	// - Execute the Config Script
@@ -52,6 +55,9 @@ void System_Init(char *CommandLine)
 		VFS_Open("/Devices/pts/vt0", VFS_OPENFLAG_WRITE|VFS_OPENFLAG_USER);	// 1: stdout
 		VFS_DuplicateFD(1, 2);	// 2: stderr
 		Proc_Execve(gsInitBinary, args, &args[1], 0);
+		
+		System_EmergencyConsole();
+		
 		Log_KernelPanic("System", "Unable to spawn init '%s'", gsInitBinary);
 	}
 	
@@ -274,3 +280,8 @@ void System_ParseSetting(char *Arg)
 	}
 }
 
+void System_EmergencyConsole(void)
+{
+	// TODO: Support an emergency kernel-land console (with FS viewing support)
+	EmergencyConsole();
+}
diff --git a/KernelLand/Kernel/threads.c b/KernelLand/Kernel/threads.c
index 80b2796680d39dba3c344d1b54aec7dc2f8b8140..469c5ec18dd3beae6afe01d71d9f4c14a1a67009 100644
--- a/KernelLand/Kernel/threads.c
+++ b/KernelLand/Kernel/threads.c
@@ -4,6 +4,7 @@
  * threads.c
  * - Common Thread Control
  */
+#define DEBUG	0
 #include <acess.h>
 #include <threads.h>
 #include <threads_int.h>
@@ -329,11 +330,10 @@ void Threads_SetPriority(tThread *Thread, int Pri)
  */
 tThread *Threads_CloneTCB(Uint Flags)
 {
-	tThread	*cur, *new;
-	cur = Proc_GetCurThread();
+	tThread *cur = Proc_GetCurThread();
 	
 	// Allocate and duplicate
-	new = malloc(sizeof(tThread));
+	tThread *new = malloc(sizeof(tThread));
 	if(new == NULL) { errno = -ENOMEM; return NULL; }
 	memcpy(new, cur, sizeof(tThread));
 	
@@ -760,6 +760,7 @@ void Threads_Yield(void)
 void Threads_int_WaitForStatusEnd(enum eThreadStatus Status)
 {
 	tThread	*us = Proc_GetCurThread();
+	LOG("us = %p(%i %s), status=%i", us, us->TID, us->ThreadName, Status);
 	ASSERT(Status != THREAD_STAT_ACTIVE);
 	ASSERT(Status != THREAD_STAT_DEAD);
 	while( us->Status == Status )
@@ -1472,6 +1473,7 @@ tThread *Threads_int_GetRunnable(void)
 	// Single-list round-robin
 	// -----------------------------------
 	tThread *thread = gActiveThreads.Head;
+	LOG("thread = %p", thread);
 	if( thread )
 	{
 		gActiveThreads.Head = thread->Next;
@@ -1493,23 +1495,20 @@ tThread *Threads_int_GetRunnable(void)
  */
 tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 {
-	// If this CPU has the lock, we must let it complete
-	if( CPU_HAS_LOCK( &glThreadListLock ) )
-		return Last;
+	ASSERT( CPU_HAS_LOCK(&glThreadListLock) );
 	
 	// Don't change threads if the current CPU has switches disabled
-	if( gaThreads_NoTaskSwitch[CPU] )
+	if( gaThreads_NoTaskSwitch[CPU] ) {
+		LOG("- Denied");
 		return Last;
-
-	// Lock thread list
-	SHORTLOCK( &glThreadListLock );
+	}
 	
 	// Make sure the current (well, old) thread is marked as de-scheduled	
 	if(Last)	Last->CurCPU = -1;
 
 	// No active threads, just take a nap
 	if(giNumActiveThreads == 0) {
-		SHORTREL( &glThreadListLock );
+		LOG("- No active");
 		#if DEBUG_TRACE_TICKETS
 		Log("No active threads");
 		#endif
@@ -1552,7 +1551,7 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 
 	// Call actual scheduler	
 	tThread	*thread = Threads_int_GetRunnable();
-		
+	
 	// Anything to do?
 	if( thread )
 	{
@@ -1578,8 +1577,6 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
 		Warning("No runnable thread for CPU%i", CPU);
 	}
 	
-	SHORTREL( &glThreadListLock );
-	
 	return thread;
 }
 
diff --git a/KernelLand/Kernel/time.c b/KernelLand/Kernel/time.c
index 15b61907216536d3af5b50b178c8ace8866f431d..478c41f3d1410070e3bea1ddd922f1fd5eab70e1 100644
--- a/KernelLand/Kernel/time.c
+++ b/KernelLand/Kernel/time.c
@@ -76,8 +76,9 @@ void Timer_CallTimers()
 {
 	// Tick the random number generator every time timers are checked
 	rand();
-	
+
 	SHORTLOCK(&gTimers_ListLock);
+	LOG("gTimers = %p (%lli ms)", gTimers, (gTimers ? gTimers->FiresAfter : 0));
 	while( gTimers && gTimers->FiresAfter < now() )
 	{
 		ASSERT( gTimers != gTimers->Next );	
diff --git a/KernelLand/Modules/IPStack/tcp.c b/KernelLand/Modules/IPStack/tcp.c
index b431686d0760cff98206da9aedc3f175adb01dcd..a8a059ac61dd3fc5b715743c369a305e4ee07b88 100644
--- a/KernelLand/Modules/IPStack/tcp.c
+++ b/KernelLand/Modules/IPStack/tcp.c
@@ -1267,6 +1267,8 @@ void TCP_INT_SendDataPacket(tTCPConnection *Connection, size_t Length, const voi
 	
 	TCP_SendPacket( Connection, packet, Length, Data );
 	
+	// TODO: Start a retransmit time (if data is not ACKed in x seconds, send again)
+	
 	Connection->NextSequenceSend += Length;
 }
 
diff --git a/KernelLand/Modules/Interfaces/UDI/trans/gfx.udic b/KernelLand/Modules/Interfaces/UDI/trans/gfx.udic
index 796228a1d71e2d3e1d5aa9bf9e99f6c1b36e4924..d61579d484c292703180e24bbdaa63d557f9a0ea 100644
--- a/KernelLand/Modules/Interfaces/UDI/trans/gfx.udic
+++ b/KernelLand/Modules/Interfaces/UDI/trans/gfx.udic
@@ -26,7 +26,7 @@ void usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
 	
 }
 
-@GFX_CLIENT channel_event_ind(udi_channel_event_cb_t *cb)
+@1=GFX_CLIENT channel_event_ind(udi_channel_event_cb_t *cb)
 {
 	udi_gfx_bind_cb_t	*bind_cb = cb->params.parent_bound.bind_cb;
 	switch(cb->event)
@@ -74,3 +74,5 @@ void usage_ind(udi_usage_cb_t *cb, udi_ubit8_t resource_level)
 
 // === UDI Bindings ===
 
+
+// vim: ft=c
diff --git a/Makefile.cfg b/Makefile.cfg
index 1eedf8ec876cbaa7b9262f7b68b0c8d2c5a9f7dc..d12710cf90852936131825e5ad44055a786b681c 100644
--- a/Makefile.cfg
+++ b/Makefile.cfg
@@ -2,6 +2,8 @@
 # Acess2 Build Configuration
 #
 
+V ?= @
+
 ACESSDIR := $(dir $(lastword $(MAKEFILE_LIST)))
 ACESSDIR := $(shell cd $(ACESSDIR) && pwd)
 
@@ -17,7 +19,6 @@ xMKDIR := mmd -D s
 # Default build programs
 #CC := gcc
 #LD := ld
-AS := nasm
 DISASM := objdump -d -S
 RM := @rm -f
 STRIP := strip
@@ -42,6 +43,9 @@ CC  = $(COMPILERDIR)bin/$(TRIPLET)-gcc
 CXX = $(COMPILERDIR)bin/$(TRIPLET)-g++
 LD  = $(COMPILERDIR)bin/$(TRIPLET)-ld
 OBJDUMP = $(COMPILERDIR)bin/$(TRIPLET)-objdump
+ ifeq ($(AS),as)
+  AS = $(COMPILERDIR)bin/$(TRIPLET)-gcc -c
+ endif
 endif
 
 ifneq ($(ARCH),host)
diff --git a/Notes/TODO b/Notes/TODO
index e63c01e479e8a390ec495fc752730a85930da1d7..dbc46fada578b5071019302a1e5a021017baead3 100644
--- a/Notes/TODO
+++ b/Notes/TODO
@@ -1,6 +1,5 @@
 Fix TCP code
 Get IPv6 working
-Get UDI working (udiref)
 Finalise AxWin API structure
 Implement input in AxWin
 Write TFTP filesystem driver
diff --git a/RunQemu b/RunQemu
index e69a55ee9b796956ff2da5d806a6a7d0bdcd1b25..1202613f7ed1ec99ca592dfd7ae2b842b78dae22 100755
--- a/RunQemu
+++ b/RunQemu
@@ -80,6 +80,11 @@ while [ $# -ne 0 ]; do
 		QEMU_PARAMS=$QEMU_PARAMS" -device pci-serial,chardev=serial2"
 		QEMU_PARAMS=$QEMU_PARAMS" -chardev socket,id=serial2,host=localhost,port=10023,server,telnet"
 		;;
+	-sata)
+		QEMU_PARAMS=$QEMU_PARAMS" -device ich9-ahci,id=ahci"
+		QEMU_PARAMS=$QEMU_PARAMS" -drive if=none,id=sata_disk,file=HDD_sata.img"
+		QEMU_PARAMS=$QEMU_PARAMS" -device ide-drive,drive=sata_disk,bus=ahci.0"
+		;;
 	esac
 	shift
 done
diff --git a/Tools/NetTest_Runner/test_tcp.c b/Tools/NetTest_Runner/test_tcp.c
index 5aef206149e849fcc7f7b530ebea6a937ff7c6d4..42aa2d5032c77c6bf480d14e55812452d74c6959 100644
--- a/Tools/NetTest_Runner/test_tcp.c
+++ b/Tools/NetTest_Runner/test_tcp.c
@@ -4,6 +4,7 @@
  *
  * test_tcp.c
  * - Tests for the behavior of the "Transmission Control Protocol"
+ * - These tests are written off RFC793
  */
 #include "test.h"
 #include "tests.h"
@@ -338,7 +339,47 @@ bool Test_TCP_WindowSizes(void)
 	TEST_ASSERT_REL(len, ==, 1);
 	testconn.RSeq += len;
 	// 2. Test remote handling our window being 0 (should only send ACKs)
+	// TODO: 
 	// 3. Test that remote drops data outside of its RX window
 	// 3.1. Ensure that data that wraps the end of the RX window is handled correctly
+	// TODO: 
+	return false;
+}
+
+// RFC793 pg41
+bool Test_TCP_Retransmit(void)
+{
+	TEST_HEADER;
+	tTCPConn	testconn = {
+		.IFNum = 0,
+		.AF = 4,
+		.LAddr = BLOB(HOST_IP),
+		.RAddr = BLOB(TEST_IP),
+		.LPort = 44359,
+		.RPort = 9,
+		.LSeq = 0x600,
+		.RSeq = 0x600,
+		.Window = 128
+	};
+	char	testdata[128];
+	memset(testdata, 0xAB, sizeof(testdata));
+
+	TEST_STEP("1. Open and connect to TCP server");
+	Stack_SendCommand("tcp_echo_server %i", testconn.RPort);
+	TEST_ASSERT( Test_TCP_int_OpenConnection(&testconn) );
+	
+	
+	TEST_STEP("2. Send data and expect it to be echoed");
+	TCP_SendC(&testconn, TCP_PSH, sizeof(testdata), testdata);
+	testconn.LSeq += sizeof(testdata);
+	TEST_ASSERT_rx();
+	TEST_ASSERT( TCP_Pkt_CheckC(rxlen, rxbuf, &ofs, &len, &testconn, TCP_ACK|TCP_PSH) );
+	
+	TEST_STEP("3. Expect nothing for TCP_RTX_TIMEOUT_1");
+	TEST_ASSERT( Net_Receive(0, sizeof(rxbuf), rxbuf, RETX_TIMEOUT-100) == 0 );
+	
+	TEST_STEP("4. Expect a retransmit");
+	TEST_ASSERT_rx();
+	
 	return false;
 }
diff --git a/UDI/drivers/helpers.h b/UDI/drivers/helpers.h
index 134cb8e5727811e897a9fb537e6fae56e7c60596..dde98164c6cff4952c611d11e28ce44affbe8155 100644
--- a/UDI/drivers/helpers.h
+++ b/UDI/drivers/helpers.h
@@ -63,4 +63,25 @@ struct s_pio_ops {
 	udi_ubit32_t	length;
 };
 #define UDIH_PIO_OPS_ENTRY(list, attr, regset, base, len)	{list, ARRAY_COUNT(list), attr, regset, base, len}
+
+
+#define UDIH_INIT_PIO(fcnname, _array, index_field, final_code) \
+	void fcnname(udi_cb_t *gcb, udi_pio_handle_t new_pio_handle) {\
+		rdata_t	*rdata = gcb->context; \
+		if( rdata->index_field != (udi_index_t)-1 ) { \
+			rdata->pio_handles[rdata->index_field] = new_pio_handle; \
+		}\
+		rdata->index_field ++; \
+		if( rdata->index_field < sizeof(_array)/sizeof(_array[0]) ) { \
+			const struct s_pio_ops	*ops = &pio_ops[rdata->index_field]; \
+			udi_pio_map(bus_dev_bind__pio_map, gcb, \
+				ops->regset_idx, ops->base_offset, ops->length, \
+				ops->trans_list, ops->list_length, \
+				UDI_PIO_LITTLE_ENDIAN, 0, 0 \
+				); \
+			return ; \
+		} \
+		final_code \
+	}
+
 #endif
diff --git a/UDI/include/udi_gfx.h b/UDI/include/udi_gfx.h
index 4416fc9285e8326b77c1c56b8dc6ae2d9edccf3f..cd7db759f2002fb130d51860f775571057430bde 100644
--- a/UDI/include/udi_gfx.h
+++ b/UDI/include/udi_gfx.h
@@ -9,10 +9,10 @@
  *     <Public Domain>
  *
  * Origin:
- *     http://www.d-rift.nl/combuster/mos3/?p=viewsource&file=/include/common/udi_gfx.h
+ *     http:/*www.d-rift.nl/combuster/mos3/?p=viewsource&file=/include/common/udi_gfx.h*/
  */
 
-/* note that the specification, and thus, the contents of this file is not fixed. */
+/* note that the specification, and thus, the contents of this file is not fixed.*/
 
 #ifndef __UDI_GFX_H__
 #define __UDI_GFX_H__
@@ -30,6 +30,7 @@
  * Lists the various UDI properties
  */
 
+/* General state properties*/
 /* Constant: UDI_GFX_PROP_ENABLE
  *
  * Valid values:
@@ -129,7 +130,7 @@
  */
 #define UDI_GFX_PROP_CUSTOM 1024
 
-/* engine properties */
+/* engine properties*/
 
 /* Constant: UDI_GFX_PROP_CLIP
  *
@@ -272,26 +273,26 @@
 #define UDI_GFX_PROP_OPERATOR_COUNT 28
 
 #if 0
-/* properties for removal: */
-#define UDI_GFX_PROP_STORE_COUNT 24       // not generic
-#define UDI_GFX_PROP_STORE_WIDTH 9        // not generic
-#define UDI_GFX_PROP_STORE_HEIGHT 10      // not generic
-#define UDI_GFX_PROP_STORE_BITS 11        // not generic
-#define UDI_GFX_PROP_PALETTE 1024         // optional, can be derived from the operator tree
-#define UDI_GFX_PROP_BUFFER 1025          // optional, can be derived from the operator tree
-#define UDI_GFX_PROP_TILESHEET 1026       // optional, can be derived from the operator tree
-#define UDI_GFX_PROP_OPERATOR_INDEX 17    // deprecated for dedicated methods
-#define UDI_GFX_PROP_OPERATOR_OPCODE 18   // deprecated for dedicated methods
-#define UDI_GFX_PROP_OPERATOR_ARG_1 19    // deprecated for dedicated methods
-#define UDI_GFX_PROP_OPERATOR_ARG_2 20    // deprecated for dedicated methods
-#define UDI_GFX_PROP_OPERATOR_ARG_3 21    // deprecated for dedicated methods
-#define UDI_GFX_PROP_SOURCE_WIDTH 12      // should have been documented when I still knew what it did.
-#define UDI_GFX_PROP_SOURCE_HEIGHT 13     // should have been documented when I still knew what it did.
-#define UDI_GFX_PROP_INPUTX 25            // should have been documented when I still knew what it did.
-#define UDI_GFX_PROP_INPUTY 26            // should have been documented when I still knew what it did.
+/* properties for removal:*/
+#define UDI_GFX_PROP_STORE_COUNT 24       /* not generic*/
+#define UDI_GFX_PROP_STORE_WIDTH 9        /* not generic*/
+#define UDI_GFX_PROP_STORE_HEIGHT 10      /* not generic*/
+#define UDI_GFX_PROP_STORE_BITS 11        /* not generic*/
+#define UDI_GFX_PROP_PALETTE 1024         /* optional, can be derived from the operator tree*/
+#define UDI_GFX_PROP_BUFFER 1025          /* optional, can be derived from the operator tree*/
+#define UDI_GFX_PROP_TILESHEET 1026       /* optional, can be derived from the operator tree*/
+#define UDI_GFX_PROP_OPERATOR_INDEX 17    /* deprecated for dedicated methods*/
+#define UDI_GFX_PROP_OPERATOR_OPCODE 18   /* deprecated for dedicated methods*/
+#define UDI_GFX_PROP_OPERATOR_ARG_1 19    /* deprecated for dedicated methods*/
+#define UDI_GFX_PROP_OPERATOR_ARG_2 20    /* deprecated for dedicated methods*/
+#define UDI_GFX_PROP_OPERATOR_ARG_3 21    /* deprecated for dedicated methods*/
+#define UDI_GFX_PROP_SOURCE_WIDTH 12      /* should have been documented when I still knew what it did.*/
+#define UDI_GFX_PROP_SOURCE_HEIGHT 13     /* should have been documented when I still knew what it did.*/
+#define UDI_GFX_PROP_INPUTX 25            /* should have been documented when I still knew what it did.*/
+#define UDI_GFX_PROP_INPUTY 26            /* should have been documented when I still knew what it did.*/
 #endif
 
-/* connector properties */
+/* connector properties*/
 #define UDI_GFX_PROP_SIGNAL 23
 #define UDI_GFX_PROP_CONNECTOR_TYPE 24
 #define UDI_GFX_PROP_VGA_H_FRONT_PORCH 25
@@ -341,9 +342,6 @@
 /**
  * Enumeration: UDI_GFX_OPERATOR
  * Lists the display output operator
- * 
- * a1/a2/a3 represents taking the output of a previous operation
- * v1/v2/v3 represents the literal value of that argument
  */
 #define UDI_GFX_OPERATOR_RGB     0 /* output = (color) red(a1) + green(a2) + blue(a3) (each component is UDI_GFX_PROP_COLOR_BITS*/
 #define UDI_GFX_OPERATOR_YUV     1 /* output = (color) Y(a1) + U(a2) + V(a3)*/
@@ -402,180 +400,179 @@
 #define UDI_GFX_STOCK_FORMAT_B5G5R5X1 8
 #define UDI_GFX_STOCK_FORMAT_N8 9
 
-/*
- * Enumeration: UDI_GFX_BUFFER_INFO_FLAG
- * Lists behavioural patterns for direct buffer accesses.
- */
+/* Enumeration: UDI_GFX_BUFFER_INFO_FLAG*/
+/* Lists behavioural patterns for direct buffer accesses.*/
+/**/
 #define UDI_GFX_BUFFER_INFO_FLAG_R              0x0001  /* buffer can be read*/
 #define UDI_GFX_BUFFER_INFO_FLAG_W              0x0002  /* buffer can be written*/
 #define UDI_GFX_BUFFER_INFO_FLAG_BITALIGN_ENTRY 0x0004  /* for non-multiple-of-eight buffer slot sizes, align on byte boundary every unit*/
 #define UDI_GFX_BUFFER_INFO_FLAG_BITALIGN_ROW   0x0008  /* for non-multiple-of-eight buffer slot sizes, align only the start of the row*/
 
 
-// Constant: UDI_GFX_PROVIDER_OPS_NUM
-// the ops number used for the graphics driver
+/* Constant: UDI_GFX_PROVIDER_OPS_NUM*/
+/* the ops number used for the graphics driver*/
 #define UDI_GFX_PROVIDER_OPS_NUM 1
 
-// Constant: UDI_GFX_CLIENT_OPS_NUM
-// the ops number used for the graphics application
+/* Constant: UDI_GFX_CLIENT_OPS_NUM*/
+/* the ops number used for the graphics application*/
 #define UDI_GFX_CLIENT_OPS_NUM 2
 
-// Structure: udi_gfx_bind_cb_t
-// Contains the operations of a driver binding request
+/* Structure: udi_gfx_bind_cb_t*/
+/* Contains the operations of a driver binding request*/
 typedef struct {
-    // Variable: gcb
-    // The main control block
+    /* Variable: gcb*/
+    /* The main control block*/
     udi_cb_t gcb;    
 } udi_gfx_bind_cb_t;
 #define UDI_GFX_BIND_CB_NUM 1
 
-// Function: udi_block_bind_req
-// function pointer prototype for connecting to a block device
-// 
-// in:
-//     cb - A pointer to a <udi_block_bind_cb_t>
-//
+/* Function: udi_block_bind_req*/
+/* function pointer prototype for connecting to a block device*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_block_bind_cb_t>*/
+/**/
 typedef void udi_gfx_bind_req_op_t (udi_gfx_bind_cb_t *cb );
 udi_gfx_bind_req_op_t udi_gfx_bind_req;
 
-// Function: udi_gfx_bind_ack
-// function pointer prototype for acknowledging a connection request
-// 
-// in:
-//     cb      - A pointer to a <udi_gfx_bind_cb_t>
-//     sockets - The number of addressable socket components
-//     engines - The number of addressable engine components
-//     status  - The result of the bind operation
-//
+/* Function: udi_gfx_bind_ack*/
+/* function pointer prototype for acknowledging a connection request*/
+/* */
+/* in:*/
+/*     cb      - A pointer to a <udi_gfx_bind_cb_t>*/
+/*     sockets - The number of addressable socket components*/
+/*     engines - The number of addressable engine components*/
+/*     status  - The result of the bind operation*/
+/**/
 typedef void udi_gfx_bind_ack_op_t (udi_gfx_bind_cb_t *cb, udi_index_t sockets, udi_index_t engines, udi_status_t status );
 udi_gfx_bind_ack_op_t udi_gfx_bind_ack;
 
-// Function: udi_gfx_unbind_req
-// function pointer prototype for disconnecting a block device
-// 
-// in:
-//     cb - A pointer to a <udi_block_bind_cb_t>
-//
+/* Function: udi_gfx_unbind_req*/
+/* function pointer prototype for disconnecting a block device*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_block_bind_cb_t>*/
+/**/
 typedef void udi_gfx_unbind_req_op_t (udi_gfx_bind_cb_t *cb );
 udi_gfx_unbind_req_op_t udi_gfx_unbind_req;
 
-// Function: udi_gfx_unbind_ack
-// function pointer prototype for connecting to a block device
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_bind_cb_t>
-//
+/* Function: udi_gfx_unbind_ack*/
+/* function pointer prototype for connecting to a block device*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_bind_cb_t>*/
+/**/
 typedef void udi_gfx_unbind_ack_op_t (udi_gfx_bind_cb_t *cb );
 udi_gfx_unbind_ack_op_t udi_gfx_unbind_ack;
 
-// Structure: udi_gfx_state_cb_t
-// Contains the operations of a read/write transaction
+/* Structure: udi_gfx_state_cb_t*/
+/* Contains the operations of a read/write transaction*/
 typedef struct {
-    // Variable: gcb
-    // The main control block
+    /* Variable: gcb*/
+    /* The main control block*/
     udi_cb_t gcb;    
     udi_ubit32_t subsystem;
     udi_ubit32_t attribute;
 } udi_gfx_state_cb_t;
 #define UDI_GFX_STATE_CB_NUM 2
 
-// Function: udi_gfx_set_engine_req
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_set_engine_req*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_set_engine_req_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
 udi_gfx_set_engine_req_op_t udi_gfx_set_engine_req;
 
-// Function: udi_gfx_set_connector_req
-// function pointer prototype for setting an connector state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_set_connector_req*/
+/* function pointer prototype for setting an connector state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_set_connector_req_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
 udi_gfx_set_connector_req_op_t udi_gfx_set_connector_req;
 
-// Function: udi_gfx_set_engine_ack
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_set_engine_ack*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_set_engine_ack_op_t (udi_gfx_state_cb_t *cb );
 udi_gfx_set_engine_ack_op_t udi_gfx_set_engine_ack;
 
-// Function: udi_gfx_set_connector_ack
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_set_connector_ack*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_set_connector_ack_op_t (udi_gfx_state_cb_t *cb );
 udi_gfx_set_connector_ack_op_t udi_gfx_set_connector_ack;
 
-// Function: udi_gfx_get_engine_req
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_get_engine_req*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_get_engine_req_op_t (udi_gfx_state_cb_t *cb );
 udi_gfx_get_engine_req_op_t udi_gfx_get_engine_req;
 
-// Function: udi_gfx_get_connector_req
-// function pointer prototype for setting an connector state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_get_connector_req*/
+/* function pointer prototype for setting an connector state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_get_connector_req_op_t (udi_gfx_state_cb_t *cb );
 udi_gfx_get_connector_req_op_t udi_gfx_get_connector_req;
 
-// Function: udi_gfx_get_engine_ack
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_get_engine_ack*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_get_engine_ack_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
 udi_gfx_get_engine_ack_op_t udi_gfx_get_engine_ack;
 
-// Function: udi_gfx_get_connector_ack
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_get_connector_ack*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_get_connector_ack_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
 udi_gfx_get_connector_ack_op_t udi_gfx_get_connector_ack;
 
-// Function: udi_gfx_set_engine_nak
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb     - A pointer to a <udi_gfx_state_cb_t>
-//     status - An UDI status value indicative of the error
-//
-typedef void udi_gfx_set_engine_nak_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t status);
+/* Function: udi_gfx_set_engine_nak*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb     - A pointer to a <udi_gfx_state_cb_t>*/
+/*     status - An UDI status value indicative of the error*/
+/**/
+typedef void udi_gfx_set_engine_nak_op_t (udi_gfx_state_cb_t *cb, udi_status_t status);
 udi_gfx_set_engine_nak_op_t udi_gfx_set_engine_nak;
 
-// Function: udi_gfx_set_connector_nak
-// function pointer prototype for setting an engine state
-// 
-// in:
-//     cb     - A pointer to a <udi_gfx_state_cb_t>
-//     status - An UDI status value indicative of the error
-//
-typedef void udi_gfx_set_connector_nak_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t status);
+/* Function: udi_gfx_set_connector_nak*/
+/* function pointer prototype for setting an engine state*/
+/* */
+/* in:*/
+/*     cb     - A pointer to a <udi_gfx_state_cb_t>*/
+/*     status - An UDI status value indicative of the error*/
+/**/
+typedef void udi_gfx_set_connector_nak_op_t (udi_gfx_state_cb_t *cb, udi_status_t status);
 udi_gfx_set_connector_nak_op_t udi_gfx_get_connector_nak;
 
-// Structure: udi_gfx_range_cb_t
-// Contains the operations of a range request transaction
+/* Structure: udi_gfx_range_cb_t*/
+/* Contains the operations of a range request transaction*/
 typedef struct {
-    // Variable: gcb
-    // The main control block
+    /* Variable: gcb*/
+    /* The main control block*/
     udi_cb_t gcb;    
     udi_ubit32_t subsystem;
     udi_ubit32_t attribute;
@@ -583,151 +580,151 @@ typedef struct {
 } udi_gfx_range_cb_t;
 #define UDI_GFX_RANGE_CB_NUM 3
 
-// Function: udi_gfx_range_engine_req
-// function pointer prototype for getting an engine property range
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_range_cb_t>
-//
+/* Function: udi_gfx_range_engine_req*/
+/* function pointer prototype for getting an engine property range*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_range_cb_t>*/
+/**/
 typedef void udi_gfx_range_engine_req_op_t (udi_gfx_range_cb_t *cb );
 udi_gfx_range_engine_req_op_t udi_gfx_range_engine_req;
 
-// Function: udi_gfx_range_connector_req
-// function pointer prototype for getting a connector property range
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_range_cb_t>
-//
+/* Function: udi_gfx_range_connector_req*/
+/* function pointer prototype for getting a connector property range*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_range_cb_t>*/
+/**/
 typedef void udi_gfx_range_connector_req_op_t (udi_gfx_range_cb_t *cb );
 udi_gfx_range_connector_req_op_t udi_gfx_range_connector_req;
 
-// Function: udi_gfx_range_engine_ack
-// function pointer prototype for replying an engine property range
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_range_cb_t>
-//
+/* Function: udi_gfx_range_engine_ack*/
+/* function pointer prototype for replying an engine property range*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_range_cb_t>*/
+/**/
 typedef void udi_gfx_range_engine_ack_op_t (udi_gfx_range_cb_t *cb );
 udi_gfx_range_engine_ack_op_t udi_gfx_range_engine_ack;
 
-// Function: udi_gfx_range_connector_ack
-// function pointer prototype for replying a connector property range
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_range_cb_t>
-//
+/* Function: udi_gfx_range_connector_ack*/
+/* function pointer prototype for replying a connector property range*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_range_cb_t>*/
+/**/
 typedef void udi_gfx_range_connector_ack_op_t (udi_gfx_range_cb_t *cb );
 udi_gfx_range_connector_ack_op_t udi_gfx_range_connector_ack;
 
-// Function: udi_gfx_get_engine_operator_req
-// function pointer prototype for requesting the engine operator layout
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_state_cb_t>
-//
+/* Function: udi_gfx_get_engine_operator_req*/
+/* function pointer prototype for requesting the engine operator layout*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_state_cb_t>*/
+/**/
 typedef void udi_gfx_get_engine_operator_req_op_t (udi_gfx_range_cb_t *cb );
 udi_gfx_get_engine_operator_req_op_t udi_gfx_get_engine_operator_req;
 
-// Function: udi_gfx_get_engine_operator_ack
-// function pointer prototype for replying the engine operator layout
-// 
-// in:
-//     cb   - A pointer to a <udi_gfx_state_cb_t>
-//     op   - The operator performed at this index
-//     arg1 - the first argument to this operator
-//     arg2 - the second argument to this operator
-//     arg3 - the third argument to this operator
-//
+/* Function: udi_gfx_get_engine_operator_ack*/
+/* function pointer prototype for replying the engine operator layout*/
+/* */
+/* in:*/
+/*     cb   - A pointer to a <udi_gfx_state_cb_t>*/
+/*     op   - The operator performed at this index*/
+/*     arg1 - the first argument to this operator*/
+/*     arg2 - the second argument to this operator*/
+/*     arg3 - the third argument to this operator*/
+/**/
 typedef void udi_gfx_get_engine_operator_ack_op_t (udi_gfx_range_cb_t *cb, udi_ubit32_t op, udi_ubit32_t arg1, udi_ubit32_t arg2, udi_ubit32_t arg3 );
 udi_gfx_get_engine_operator_ack_op_t udi_gfx_get_engine_operator_ack;
 
 
 
-// Structure: udi_gfx_command_cb_t
-// Contains the operations of a command sequence
+/* Structure: udi_gfx_command_cb_t*/
+/* Contains the operations of a command sequence*/
 typedef struct {
-    // Variable: gcb
-    // The main control block
+    /* Variable: gcb*/
+    /* The main control block*/
     udi_cb_t gcb;    
     udi_buf_t * commanddata;
 } udi_gfx_command_cb_t;
 #define UDI_GFX_COMMAND_CB_NUM 4
 
-// Function: udi_gfx_connector_command_req
-// function pointer prototype for sending command data to the output connector
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_command_cb_t>
-//
+/* Function: udi_gfx_connector_command_req*/
+/* function pointer prototype for sending command data to the output connector*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_command_cb_t>*/
+/**/
 typedef void udi_gfx_connector_command_req_op_t (udi_gfx_command_cb_t *cb );
 udi_gfx_connector_command_req_op_t udi_gfx_connector_command_req;
 
-// Function: udi_gfx_engine_command_req
-// function pointer prototype for sending command data to the engine
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_command_cb_t>
-//
+/* Function: udi_gfx_engine_command_req*/
+/* function pointer prototype for sending command data to the engine*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_command_cb_t>*/
+/**/
 typedef void udi_gfx_engine_command_req_op_t (udi_gfx_command_cb_t *cb );
 udi_gfx_engine_command_req_op_t udi_gfx_engine_command_req;
 
-// Function: udi_gfx_connector_command_ack
-// function pointer prototype for sending command data replies
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_command_cb_t>
-//
+/* Function: udi_gfx_connector_command_ack*/
+/* function pointer prototype for sending command data replies*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_command_cb_t>*/
+/**/
 typedef void udi_gfx_connector_command_ack_op_t (udi_gfx_command_cb_t *cb);
 udi_gfx_connector_command_ack_op_t udi_gfx_connector_command_ack;
 
-// Function: udi_gfx_engine_command_ack
-// function pointer prototype for sending engine data replies
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_command_cb_t>
-//
+/* Function: udi_gfx_engine_command_ack*/
+/* function pointer prototype for sending engine data replies*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_command_cb_t>*/
+/**/
 typedef void udi_gfx_engine_command_ack_op_t (udi_gfx_command_cb_t *cb);
 udi_gfx_engine_command_ack_op_t udi_gfx_engine_command_ack;
 
-// Structure: udi_gfx_buffer_cb_t
-// Contains a description of a buffer, or area thereof
+/* Structure: udi_gfx_buffer_cb_t*/
+/* Contains a description of a buffer, or area thereof*/
 typedef struct {
-    // Variable: gcb
-    // The main control block
+    /* Variable: gcb*/
+    /* The main control block*/
     udi_cb_t gcb;    
     udi_ubit32_t buffer_index;
 } udi_gfx_buffer_info_cb_t;
 
-// Function: udi_gfx_buffer_info_req
-// function pointer prototype for getting buffer configuration information
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_command_cb_t>
-//
+/* Function: udi_gfx_buffer_info_req*/
+/* function pointer prototype for getting buffer configuration information*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_command_cb_t>*/
+/**/
 typedef void udi_gfx_buffer_info_req_op_t (udi_gfx_buffer_info_cb_t *cb);
 udi_gfx_buffer_info_req_op_t udi_gfx_buffer_info_req;
 
-// Function: udi_gfx_buffer_info_ack
-// function pointer prototype for getting buffer configuration information
-// 
-// in:
-//     cb       - A pointer to a <udi_gfx_command_cb_t>
-//     width    - The width of the buffer
-//     height   - The height of the buffer
-//     bitsper  - The number of bits read from the buffer per pixel unit
-//     flags    - A bitfield of <UDI_GFX_BUFFER_FLAGS> indicating the exposed 
-//                capabilities of this buffer
-//
-// Note that bitsper might not be a multiple of eight.
-//
+/* Function: udi_gfx_buffer_info_ack*/
+/* function pointer prototype for getting buffer configuration information*/
+/* */
+/* in:*/
+/*     cb       - A pointer to a <udi_gfx_command_cb_t>*/
+/*     width    - The width of the buffer*/
+/*     height   - The height of the buffer*/
+/*     bitsper  - The number of bits read from the buffer per pixel unit*/
+/*     flags    - A bitfield of <UDI_GFX_BUFFER_FLAGS> indicating the exposed */
+/*                capabilities of this buffer*/
+/**/
+/* Note that bitsper might not be a multiple of eight.*/
+/**/
 typedef void udi_gfx_buffer_info_ack_op_t (udi_gfx_buffer_info_cb_t *cb, udi_ubit32_t width, udi_ubit32_t height, udi_ubit32_t bitsper, udi_ubit32_t flags);
 udi_gfx_buffer_info_ack_op_t udi_gfx_buffer_info_ack;
 
-// Structure: udi_gfx_buffer_cb_t
-// Contains a description of a buffer, or area thereof
+/* Structure: udi_gfx_buffer_cb_t*/
+/* Contains a description of a buffer, or area thereof*/
 typedef struct {
-    // Variable: gcb
-    // The main control block
+    /* Variable: gcb*/
+    /* The main control block*/
     udi_cb_t gcb;    
     udi_ubit32_t buffer_index;
     udi_ubit32_t x;
@@ -737,58 +734,58 @@ typedef struct {
     udi_buf_t * buffer;
 } udi_gfx_buffer_cb_t;
 
-// Function: udi_gfx_buffer_write_req_op_t
-// function pointer prototype for writing raw hardware buffers
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_buffer_cb_t>
-//
+/* Function: udi_gfx_buffer_write_req_op_t*/
+/* function pointer prototype for writing raw hardware buffers*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_buffer_cb_t>*/
+/**/
 typedef void udi_gfx_buffer_write_req_op_t (udi_gfx_buffer_cb_t *cb);
 udi_gfx_buffer_write_req_op_t udi_gfx_buffer_write_req;
 
-// Function: udi_gfx_buffer_write_req_op_t
-// function pointer prototype for reading raw hardware buffers
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_buffer_cb_t>
-//
+/* Function: udi_gfx_buffer_write_req_op_t*/
+/* function pointer prototype for reading raw hardware buffers*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_buffer_cb_t>*/
+/**/
 typedef void udi_gfx_buffer_read_req_op_t (udi_gfx_buffer_cb_t *cb);
 udi_gfx_buffer_read_req_op_t udi_gfx_buffer_read_req;
 
-// Function: udi_gfx_buffer_write_ack_op_t
-// function pointer prototype for writing raw hardware buffers
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_buffer_cb_t>
-//
+/* Function: udi_gfx_buffer_write_ack_op_t*/
+/* function pointer prototype for writing raw hardware buffers*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_buffer_cb_t>*/
+/**/
 typedef void udi_gfx_buffer_write_ack_op_t (udi_gfx_buffer_cb_t *cb);
 udi_gfx_buffer_write_ack_op_t udi_gfx_buffer_write_ack;
 
-// Function: udi_gfx_buffer_write_ack_op_t
-// function pointer prototype for reading raw hardware buffers
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_buffer_cb_t>
-//
+/* Function: udi_gfx_buffer_write_ack_op_t*/
+/* function pointer prototype for reading raw hardware buffers*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_buffer_cb_t>*/
+/**/
 typedef void udi_gfx_buffer_read_ack_op_t (udi_gfx_buffer_cb_t *cb);
 udi_gfx_buffer_read_ack_op_t udi_gfx_buffer_read_ack;
 
-// Function: udi_gfx_buffer_write_nak_op_t
-// error handling for buffer writes
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_buffer_cb_t>
-//
-typedef void udi_gfx_buffer_write_nak_op_t (udi_gfx_buffer_cb_t *cb, udi_ubit32_t status);
+/* Function: udi_gfx_buffer_write_nak_op_t*/
+/* error handling for buffer writes*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_buffer_cb_t>*/
+/**/
+typedef void udi_gfx_buffer_write_nak_op_t (udi_gfx_buffer_cb_t *cb, udi_status_t status);
 udi_gfx_buffer_write_nak_op_t udi_gfx_buffer_write_nak;
 
-// Function: udi_gfx_buffer_write_nak_op_t
-// error handling for buffer reads
-// 
-// in:
-//     cb - A pointer to a <udi_gfx_buffer_cb_t>
-//
-typedef void udi_gfx_buffer_read_nak_op_t (udi_gfx_buffer_cb_t *cb, udi_ubit32_t status);
+/* Function: udi_gfx_buffer_write_nak_op_t*/
+/* error handling for buffer reads*/
+/* */
+/* in:*/
+/*     cb - A pointer to a <udi_gfx_buffer_cb_t>*/
+/**/
+typedef void udi_gfx_buffer_read_nak_op_t (udi_gfx_buffer_cb_t *cb, udi_status_t status);
 udi_gfx_buffer_read_nak_op_t udi_gfx_buffer_read_nak;
 
 /* Structure: udi_gfx_provider_ops_t
@@ -805,9 +802,9 @@ typedef const struct {
     udi_gfx_get_engine_req_op_t         *gfx_get_engine_req_op;
     udi_gfx_range_connector_req_op_t    *gfx_range_connector_req_op;
     udi_gfx_range_engine_req_op_t       *gfx_range_engine_req_op;
-    udi_gfx_get_engine_operator_req_op_t*gfx_get_engine_operator_req_op_t;
-    udi_gfx_connector_command_req_op_t  *gfx_connector_command_op;
-    udi_gfx_engine_command_req_op_t     *gfx_engine_command_op;
+    udi_gfx_get_engine_operator_req_op_t*gfx_get_engine_operator_req_op;
+    udi_gfx_connector_command_req_op_t  *gfx_connector_command_req_op;
+    udi_gfx_engine_command_req_op_t     *gfx_engine_command_req_op;
     udi_gfx_buffer_info_req_op_t        *gfx_buffer_info_req_op;
     udi_gfx_buffer_read_req_op_t        *gfx_buffer_read_req_op;
     udi_gfx_buffer_write_req_op_t       *gfx_buffer_write_req_op;
@@ -819,28 +816,28 @@ typedef const struct {
  */
 typedef const struct {
     udi_channel_event_ind_op_t          *channel_event_ind_op;
-    udi_gfx_bind_ack_op_t               *udi_gfx_bind_ack;
-    udi_gfx_unbind_ack_op_t             *udi_gfx_unbind_ack;
-    udi_gfx_set_connector_ack_op_t      *udi_gfx_set_connector_ack;
-    udi_gfx_set_engine_ack_op_t         *udi_gfx_set_engine_ack;
-    udi_gfx_set_connector_nak_op_t      *udi_gfx_set_connector_nak;
-    udi_gfx_set_engine_nak_op_t         *udi_gfx_set_engine_nak;
-    udi_gfx_get_connector_ack_op_t      *udi_gfx_get_connector_ack;
-    udi_gfx_get_engine_ack_op_t         *udi_gfx_get_engine_ack;
-    udi_gfx_range_connector_ack_op_t    *udi_gfx_range_connector_ack;
-    udi_gfx_range_engine_ack_op_t       *udi_gfx_range_engine_ack;
-    udi_gfx_get_engine_operator_req_op_t*udi_gfx_get_engine_operator_ack;
-    udi_gfx_connector_command_ack_op_t  *udi_gfx_connector_command_ack;
-    udi_gfx_engine_command_ack_op_t     *udi_gfx_engine_command_ack;
-    udi_gfx_buffer_info_ack_op_t        *gfx_buffer_info_ack;
-    udi_gfx_buffer_read_ack_op_t        *gfx_buffer_read_ack;
-    udi_gfx_buffer_write_ack_op_t       *gfx_buffer_write_ack;
-    udi_gfx_buffer_read_nak_op_t        *gfx_buffer_read_nak;
-    udi_gfx_buffer_write_nak_op_t       *gfx_buffer_write_nak;
+    udi_gfx_bind_ack_op_t               *gfx_bind_ack_op;
+    udi_gfx_unbind_ack_op_t             *gfx_unbind_ack_op;
+    udi_gfx_set_connector_ack_op_t      *gfx_set_connector_ack_op;
+    udi_gfx_set_engine_ack_op_t         *gfx_set_engine_ack_op;
+    udi_gfx_set_connector_nak_op_t      *gfx_set_connector_nak_op;
+    udi_gfx_set_engine_nak_op_t         *gfx_set_engine_nak_op;
+    udi_gfx_get_connector_ack_op_t      *gfx_get_connector_ack_op;
+    udi_gfx_get_engine_ack_op_t         *gfx_get_engine_ack_op;
+    udi_gfx_range_connector_ack_op_t    *gfx_range_connector_ack_op;
+    udi_gfx_range_engine_ack_op_t       *gfx_range_engine_ack_op;
+    udi_gfx_get_engine_operator_req_op_t*gfx_get_engine_operator_ack_op;
+    udi_gfx_connector_command_ack_op_t  *gfx_connector_command_ack_op;
+    udi_gfx_engine_command_ack_op_t     *gfx_engine_command_ack_op;
+    udi_gfx_buffer_info_ack_op_t        *gfx_buffer_info_ack_op;
+    udi_gfx_buffer_read_ack_op_t        *gfx_buffer_read_ack_op;
+    udi_gfx_buffer_write_ack_op_t       *gfx_buffer_write_ack_op;
+    udi_gfx_buffer_read_nak_op_t        *gfx_buffer_read_nak_op;
+    udi_gfx_buffer_write_nak_op_t       *gfx_buffer_write_nak_op;
 } udi_gfx_client_ops_t;
 
 
-// temporary
+/* temporary*/
 #ifndef UDI_ANNOY_ME
 void EngineReturnSimpleRange (int source, int index, int prop, int first, int last, int modulus);
 void ConnectorReturnSimpleRange (int source, int index, int prop, int first, int last, int modulus);
diff --git a/UDI/include/udi_gfx.h.ORIG b/UDI/include/udi_gfx.h.ORIG
new file mode 100644
index 0000000000000000000000000000000000000000..fcaa5b7423896241c08210765de46ff4bcdc5e45
--- /dev/null
+++ b/UDI/include/udi_gfx.h.ORIG
@@ -0,0 +1,848 @@
+/**
+ * Summary: udi_gfx.h
+ * Contains the graphics metalanguage interface details
+ *
+ * Author:
+ *     Marcel Sondaar
+ *
+ * License:
+ *     <Public Domain>
+ *
+ * Origin:
+ *     http://www.d-rift.nl/combuster/mos3/?p=viewsource&file=/include/common/udi_gfx.h
+ */
+
+// note that the specification, and thus, the contents of this file is not fixed.
+
+#ifndef __UDI_GFX_H__
+#define __UDI_GFX_H__
+
+#include <udi.h>
+
+#ifndef UDI_GFX_VERSION
+#error "UDI_GFX_VERSION not defined."
+#elif UDI_GFX_VERSION != 0x101
+#error "UDI_GFX_VERSION not supported."
+#endif
+
+/**
+ * Enumeration: UDI_GFX_PROP
+ * Lists the various UDI properties
+ */
+
+// General state properties
+/* Constant: UDI_GFX_PROP_ENABLE
+ *
+ * Valid values:
+ *     0 - disabled
+ *     1 - enabled
+ *     2 - reset
+ *
+ * Ranges:
+ *     Must include at least 1
+ *
+ * The primary state of the connector or engine. An enabled state indicates
+ * it is functioning and generating live output. A disabled state is one where
+ * it is not contributing to any output but is otherwise functional. Finally
+ * the reset state is where the driver is free to deallocate all resources 
+ * corresponding to this component and trash any state not referenced by other
+ * components.
+ *
+ * A disabled or reset engine forwards all data from the previous stage 
+ * unmodified. The disabled state indicates that the component might be 
+ * returned to its enabled state within short notice.
+ *
+ * A disabled connector will not send pixel data, but can perform other 
+ * initialisation communication such as DDC. A reset connector will not respond
+ * in any fashion and can not be used for other purposes. Hardware is expected
+ * to be powered down in such state.
+ *
+ * Users should expect significant delays when moving components in and out of
+ * the reset state. Moving engines between the enabled and disabled state should
+ * take effect within one frame, such transition should take effect on a frame 
+ * boundary when supported.
+ */
+#define UDI_GFX_PROP_ENABLE 0
+
+#define UDI_GFX_PROP_ENABLE_DISABLED 0
+#define UDI_GFX_PROP_ENABLE_ENABLED 1
+#define UDI_GFX_PROP_ENABLE_RESET 2
+/* Constant: UDI_GFX_PROP_INPUT
+ *
+ * Valid values:
+ *     Any valid engine ID, provided no dependency cycles are created, or -1
+ *
+ * Ranges:
+ *     Any non-empty set of valid values. Often hardwired.
+ *
+ * Points to the engine that is processed before this unit. In the case of a 
+ * connector, it points to the last engine in a pipeline, and each engine points 
+ * to the next engine in the sequence. A value of -1 indicates a source that 
+ * only yields black pixels. Implementations must not allow cyclic structures. 
+ * Changing this value may reallocate resources, and engines that are no longer 
+ * referenced may lose their data (but not their state) when it is not part of 
+ * any pipeline. If preservation is required, the ENABLE state should be used
+ * instead. Valid ranges includes one or more from the list of engines and -1 
+ * combined. In most cases, this property can not be modified.
+ */
+#define UDI_GFX_PROP_INPUT 1
+/* Constant: UDI_GFX_PROP_WIDTH
+ *
+ * Valid values:
+ *     Any non-zero positive number.
+ *
+ * Ranges:
+ *     Contains at least one valid value. Often only multiples of UNIT_WIDTH
+ *     or a power of two are allowed. May be hardwired.
+ *
+ * Contains the amount of pixels in the horizontal direction. For connectors, 
+ * this is the amount of data pixels rendered horizontally. For engines, this 
+ * is the width in pixels of the image. Pixels requested from an engine outside 
+ * the range (0..width-1) are defined according to the <UDI_GFX_PROP_CLIP> 
+ * property. In some cases, hardware may support only fixed combinations of 
+ * width and height. In such cases, changing the width will also change the 
+ * height to a corresponding valid number. Valid ranges include any values
+ * strictly above zero. For connectors, expect large continuous ranges, large
+ * ranges with a certain modulus, a limited number of fixed values, or a
+ * constant value.
+ */
+#define UDI_GFX_PROP_WIDTH 2
+/* Constant: UDI_GFX_PROP_HEIGHT
+ *
+ * Valid values:
+ *     Any non-zero positive number.
+ *
+ * Ranges:
+ *     Contains at least one valid value. Often only multiples of UNIT_HEIGHT
+ *     or a power of two are allowed. May be hardwired.
+ *
+ * Contains the amount of pixels in the vertical direction. Functions similar
+ * to the width property, but changing it will not alter the width property,
+ * and it's range at any time contains the valid range for the currently
+ * selected width.
+ */
+#define UDI_GFX_PROP_HEIGHT 3
+
+/* Constant: UDI_GFX_PROP_CUSTOM
+ * The first property index of the driver's custom range. These are not assigned
+ * directly assigned by the UDI specification, but may be specified in the
+ * operator tree.
+ */
+#define UDI_GFX_PROP_CUSTOM 1024
+
+// engine properties
+
+/* Constant: UDI_GFX_PROP_CLIP
+ *
+ * Valid values:
+ *     0 - points outside width x height are passed unmodified from input
+ *     1 - the engine's contents is tiled with size width x height
+ *     2 - points outside the width overflow into the y coordinate
+ *     3 - points outside the height overflow into the x coordinate
+ *
+ * Ranges:
+ *     Hardwired zero for connectors. Any non-empty subset for engines, usually
+ *     hardwired.
+ *
+ * For engines, contains the behaviour for pixels requested outside the width
+ * and height of the engine. Can be either 0 (pass from next stage), 1 (the
+ * coordinates are wrapped modulus the height and width), 2 (the coordinates
+ * overflow onto the next scanline horizontally, and wrap vertically), 3 (the
+ * coordinates overflow onto the next column vertically, and wrap horizontally).
+ * Valid ranges contain one or more of these options. For overlays and sprites,
+ * a value 0 is common. For framebuffers, 2 is the most common value. For
+ * connectors, this property is always 0 since they do not store pixel data
+ */
+#define UDI_GFX_PROP_CLIP 4
+
+/* Constant: UDI_GFX_PROP_UNIT_WIDTH
+ *
+ * Valid values:
+ *     Any non-zero positive value
+ *
+ * Ranges:
+ *     Any non-empty set of valid values. May be hardwired to 1 for
+ *     framebuffers, or a range of small values for hardware scaling, or any
+ *     larger hardwired number or set for tiling engines.
+ *
+ * Tiles are used to indicate that the hardware groups sets of pixels and have
+ * each group share certain properties, i.e. color or tile index, or share the
+ * same chroma subsample with only a different intensity. If the engine has no
+ * such grouping, or shares all properties over the entire contents, the value
+ * of this property should be 1. Some tile examples include rescaling, where a
+ * tile width of 2 indicates a pixel doubling in X direction, or in text mode
+ * where a tile width of 8 or 9 corresponds with the width of common bitmap
+ * fonts
+ */
+#define UDI_GFX_PROP_UNIT_WIDTH 5
+
+/* Constant: UDI_GFX_PROP_UNIT_HEIGHT
+ *
+ * Valid values:
+ *     Any non-zero positive value
+ *
+ * Ranges:
+ *     Any non-empty set of valid values. May be hardwired to 1 for
+ *     framebuffers, or a range of small values for hardware scaling, or any
+ *     larger hardwired number or set for tiling engines.
+ *
+ * See <UDI_GFX_PROP_UNIT_WIDTH>, but for the Y direction. Common values are
+ * 1-2 for framebuffers (doublescanning on or off), identical to the tile
+ * width, or mostly independent.
+ */
+#define UDI_GFX_PROP_UNIT_HEIGHT 6
+
+/* Constant: UDI_GFX_PROP_TRANSLATEX
+ * 
+ * Valid values:
+ *     Any, signed value.
+ *
+ * Ranges:
+ *     Any non-empty set. Typical values are hardwired zero, continuous
+ *     between -WIDTH and WIDTH, -WIDTH to zero inclusive, or all possible values
+ *
+ * The horizontal offset where drawing starts. A positive value means the top-left 
+ * corner moves towards the right end of the screen, a negative value moves the
+ * origin off the screen on the left side. Clipped areas moved off the screen do 
+ * not reappear on the opposite side.
+ *
+ * With clipping enabled, this field combined with <UDI_GFX_PROP_WIDTH> 
+ * determines the area where the image should be drawn, which is the horizontal 
+ * range from UDI_GFX_PROP_TRANSLATEX to UDI_GFX_PROP_WIDTH + 
+ * UDI_GFX_PROP_TRANSLATEX - 1
+ */
+#define UDI_GFX_PROP_TRANSLATEX 7
+
+/* Constant: UDI_GFX_PROP_TRANSLATEY
+ *
+ * Valid values:
+ *     Any signed value.
+ *
+ * Ranges:
+ *     Any non-empty set. Typical values are hardwired zero, continuous
+ *     between -WIDTH and WIDTH, or all possible values
+ *
+ * See <UDI_GFX_PROP_TRANSLATEX> but for the Y direction.
+ */
+#define UDI_GFX_PROP_TRANSLATEY 8
+
+#define UDI_GFX_PROP_GL_VERSION 14
+#define UDI_GFX_PROP_GLES_VERSION 15
+#define UDI_GFX_PROP_STATE_BLOCK 16
+#define UDI_GFX_PROP_COLOR_BITS 22
+#define UDI_GFX_PROP_GL_TARGET 23
+
+/* Constant: UDI_GFX_PROP_STOCK_FORMAT
+ *
+ * Value:
+ *     Zero, or any constant from <UDI_GFX_STOCK_FORMAT>
+ *
+ * Ranges:
+ *     Any non-empty set of valid values.
+ *
+ * This field indicates the storage format is one from a limited set of 
+ * typical configurations. If the field is zero, the engine is not knowingly
+ * configured as a common framebuffer. If nonzero, the operator chain and any
+ * dependent settings are defined to be functionally equivalent to that of a
+ * typical framebuffer device.
+ *
+ * The value zero does not imply that the device does not actually follow a
+ * set convention. This saves drivers from writing elaborate checking code
+ * to determine the condition in question.
+ *
+ * Writing this field potentially modifies other property fields within the
+ * same engine to establish the requested configuration. Manually writing such 
+ * properties after changing this setting may in turn revert this property to
+ * the zero state, even if there was no modification or the behaviour is still
+ * as previously advertised by this property.
+ */
+#define UDI_GFX_PROP_STOCK_FORMAT 27
+
+/* Constant: UDI_GFX_PROP_OPERATOR_COUNT
+ * 
+ * Valid values:
+ *     Any non-zero positive number
+ * 
+ * Ranges:
+ *     Most likely constant. Can be any set of valid values.
+ *
+ * The current value is the number of entries in the operator tree that can
+ * be requested for this engine using <udi_gfx_get_engine_operator_req> and
+ * <udi_gfx_get_engine_operator_ack>
+ */
+#define UDI_GFX_PROP_OPERATOR_COUNT 28
+
+// properties for removal:
+#define UDI_GFX_PROP_STORE_COUNT 24       // not generic
+#define UDI_GFX_PROP_STORE_WIDTH 9        // not generic
+#define UDI_GFX_PROP_STORE_HEIGHT 10      // not generic
+#define UDI_GFX_PROP_STORE_BITS 11        // not generic
+#define UDI_GFX_PROP_PALETTE 1024         // optional, can be derived from the operator tree
+#define UDI_GFX_PROP_BUFFER 1025          // optional, can be derived from the operator tree
+#define UDI_GFX_PROP_TILESHEET 1026       // optional, can be derived from the operator tree
+#define UDI_GFX_PROP_OPERATOR_INDEX 17    // deprecated for dedicated methods
+#define UDI_GFX_PROP_OPERATOR_OPCODE 18   // deprecated for dedicated methods
+#define UDI_GFX_PROP_OPERATOR_ARG_1 19    // deprecated for dedicated methods
+#define UDI_GFX_PROP_OPERATOR_ARG_2 20    // deprecated for dedicated methods
+#define UDI_GFX_PROP_OPERATOR_ARG_3 21    // deprecated for dedicated methods
+#define UDI_GFX_PROP_SOURCE_WIDTH 12      // should have been documented when I still knew what it did.
+#define UDI_GFX_PROP_SOURCE_HEIGHT 13     // should have been documented when I still knew what it did.
+#define UDI_GFX_PROP_INPUTX 25            // should have been documented when I still knew what it did.
+#define UDI_GFX_PROP_INPUTY 26            // should have been documented when I still knew what it did.
+
+// connector properties
+#define UDI_GFX_PROP_SIGNAL 23
+#define UDI_GFX_PROP_CONNECTOR_TYPE 24
+#define UDI_GFX_PROP_VGA_H_FRONT_PORCH 25
+#define UDI_GFX_PROP_VGA_H_BACK_PORCH 26
+#define UDI_GFX_PROP_VGA_H_SYNC 27
+#define UDI_GFX_PROP_VGA_V_FRONT_PORCH 28
+#define UDI_GFX_PROP_VGA_V_BACK_PORCH 29
+#define UDI_GFX_PROP_VGA_V_SYNC 30
+#define UDI_GFX_PROP_DOT_CLOCK 31
+#define UDI_GFX_PROP_VGA_H_SYNC_POL 32
+#define UDI_GFX_PROP_VGA_V_SYNC_POL 33
+
+/**
+ * Enumeration: UDI_GFX_SIGNAL
+ * Lists the various signal types
+ */
+#define UDI_GFX_SIGNAL_HIDDEN 0
+#define UDI_GFX_SIGNAL_INTEGRATED 0
+#define UDI_GFX_SIGNAL_RGBHV 1
+#define UDI_GFX_SIGNAL_RGBS 2
+#define UDI_GFX_SIGNAL_RGSB 3
+#define UDI_GFX_SIGNAL_YPBPR 4
+#define UDI_GFX_SIGNAL_DVID 5
+#define UDI_GFX_SIGNAL_YUV 6
+#define UDI_GFX_SIGNAL_YIQ 7
+#define UDI_GFX_SIGNAL_Y_UV 8
+#define UDI_GFX_SIGNAL_Y_IQ 9
+#define UDI_GFX_SIGNAL_HDMI 10
+#define UDI_GFX_SIGNAL_TEXT 11
+#define UDI_GFX_SIGNAL_CUSTOM 12
+
+/**
+ * Enumeration: UDI_GFX_CONNECTOR
+ * Lists the various external connectors
+ */
+#define UDI_GFX_CONNECTOR_HIDDEN 0
+#define UDI_GFX_CONNECTOR_VGA 1
+#define UDI_GFX_CONNECTOR_DVI 2
+#define UDI_GFX_CONNECTOR_SVIDEO 3
+#define UDI_GFX_CONNECTOR_COMPONENT 4
+#define UDI_GFX_CONNECTOR_HDMI 5
+#define UDI_GFX_CONNECTOR_RF 6
+#define UDI_GFX_CONNECTOR_SCART 7
+#define UDI_GFX_CONNECTOR_COMPOSITE 8
+#define UDI_GFX_CONNECTOR_MEMBUFFER 9
+
+/**
+ * Enumeration: UDI_GFX_OPERATOR
+ * Lists the display output operator
+ */
+#define UDI_GFX_OPERATOR_RGB     0 // output = (color) red(a1) + green(a2) + blue(a3) (each component is UDI_GFX_PROP_COLOR_BITS
+#define UDI_GFX_OPERATOR_YUV     1 // output = (color) Y(a1) + U(a2) + V(a3)
+#define UDI_GFX_OPERATOR_YIQ     2 // output = (color) Y(a1) + I(a2) + Q(a3)
+#define UDI_GFX_OPERATOR_I       3 // output = (color) intensity(a1)
+#define UDI_GFX_OPERATOR_ALPHA   4 // output = (color) a1 + alpha(a2)
+#define UDI_GFX_OPERATOR_ADD     5 // output = a1 + a2 + v3
+#define UDI_GFX_OPERATOR_SUB     6 // output = a1 - a2 - v3
+#define UDI_GFX_OPERATOR_MUL     7 // output = a1 * a2
+#define UDI_GFX_OPERATOR_DIV     8 // output = a1 / a2
+#define UDI_GFX_OPERATOR_MAD     9 // output = a1 * a2 + a3
+#define UDI_GFX_OPERATOR_FRC    10 // output = (a1 * a2) / a3
+#define UDI_GFX_OPERATOR_SHR    11 // output = a1 >> (a2 + v3)
+#define UDI_GFX_OPERATOR_SHL    12 // output = a1 << (a2 + v3)
+#define UDI_GFX_OPERATOR_ROR    13 // output = a1 >> a2 (over a3 bits)
+#define UDI_GFX_OPERATOR_ROL    14 // output = a1 << a2 (over a3 bits)
+#define UDI_GFX_OPERATOR_SAR    15 // output = a1 >> a2 (width is a3 bits, i.e. empties are filled with bit a3-1)
+#define UDI_GFX_OPERATOR_SAL    16 // output = a1 <<< (a2 + v3) (empties filled with bit 0)
+#define UDI_GFX_OPERATOR_AND    17 // output = a1 & a2
+#define UDI_GFX_OPERATOR_OR     18 // output = a1 | a2 | v3
+#define UDI_GFX_OPERATOR_NOT    19 // output = ~a1
+#define UDI_GFX_OPERATOR_XOR    20 // output = a1 ^ a2 ^ v3
+#define UDI_GFX_OPERATOR_NEG    21 // output = -a1
+#define UDI_GFX_OPERATOR_SEG    22 // output = (a1 >> v2) & (2**v3-1) (select v3 bits starting from bit v2)
+#define UDI_GFX_OPERATOR_RANGE  23 // output = (a1 > a2) ? a2 : ((a1 < a3) ? a3 : a1)
+#define UDI_GFX_OPERATOR_CONST  24 // output = v1
+#define UDI_GFX_OPERATOR_ATTR   25 // output = property[a1 + v2]
+#define UDI_GFX_OPERATOR_SWITCH 26 // output = output[(a1 % v3) + v2]
+#define UDI_GFX_OPERATOR_BUFFER 27 // output = buffer[a1][a2] (buffer is v3 bits per entry)
+#define UDI_GFX_OPERATOR_X      28 // output = output x pixel
+#define UDI_GFX_OPERATOR_Y      29 // output = output y pixel
+#define UDI_GFX_OPERATOR_TX     30 // output = horizontal tile index belonging to output pixel
+#define UDI_GFX_OPERATOR_TY     31 // output = vertical tile index belonging to output pixel
+#define UDI_GFX_OPERATOR_TXOFF  32 // output = horizontal offset from start of tile
+#define UDI_GFX_OPERATOR_TYOFF  33 // output = vertical offset from start of tile
+#define UDI_GFX_OPERATOR_INPUT  34 // output = input engine[x][y]   component v1
+#define UDI_GFX_OPERATOR_DINPUT 35 // output = input engine[a1][a2] component v3
+
+/* Enumeration: UDI_GFX_STOCK_FORMAT
+ * Lists stock configurations
+ *
+ * When a stock configuration is used, the device is set to behave as a 
+ * simple framebuffer device. The <UDI_GFX_PROP_WIDTH> and <UDI_GFX_PROP_HEIGHT>
+ * determine the virtual size of the framebuffer, and <UDI_GFX_PROP_TRANSLATEX>
+ * and <UDI_GFX_PROP_TRANSLATEY> indicate the offset into that framebuffer 
+ * that is visible (which are typically restricted to negative values)
+ */
+#define UDI_GFX_STOCK_FORMAT_UNKNOWN  0
+#define UDI_GFX_STOCK_FORMAT_R8G8B8X8 1
+#define UDI_GFX_STOCK_FORMAT_B8G8R8X8 2
+#define UDI_GFX_STOCK_FORMAT_R8G8B8   3
+#define UDI_GFX_STOCK_FORMAT_B8G8R8   4
+#define UDI_GFX_STOCK_FORMAT_R5G6B5   5
+#define UDI_GFX_STOCK_FORMAT_B5G6R5   6
+#define UDI_GFX_STOCK_FORMAT_R5G5B5X1 7
+#define UDI_GFX_STOCK_FORMAT_B5G5R5X1 8
+#define UDI_GFX_STOCK_FORMAT_N8 9
+
+// Enumeration: UDI_GFX_BUFFER_INFO_FLAG
+// Lists behavioural patterns for direct buffer accesses.
+//
+#define UDI_GFX_BUFFER_INFO_FLAG_R              0x0001  // buffer can be read
+#define UDI_GFX_BUFFER_INFO_FLAG_W              0x0002  // buffer can be written
+#define UDI_GFX_BUFFER_INFO_FLAG_BITALIGN_ENTRY 0x0004  // for non-multiple-of-eight buffer slot sizes, align on byte boundary every unit
+#define UDI_GFX_BUFFER_INFO_FLAG_BITALIGN_ROW   0x0008  // for non-multiple-of-eight buffer slot sizes, align only the start of the row
+
+
+// Constant: UDI_GFX_PROVIDER_OPS_NUM
+// the ops number used for the graphics driver
+#define UDI_GFX_PROVIDER_OPS_NUM 1
+
+// Constant: UDI_GFX_CLIENT_OPS_NUM
+// the ops number used for the graphics application
+#define UDI_GFX_CLIENT_OPS_NUM 2
+
+// Structure: udi_gfx_bind_cb_t
+// Contains the operations of a driver binding request
+typedef struct {
+    // Variable: gcb
+    // The main control block
+    udi_cb_t gcb;    
+} udi_gfx_bind_cb_t;
+#define UDI_GFX_BIND_CB_NUM 1
+
+// Function: udi_block_bind_req
+// function pointer prototype for connecting to a block device
+// 
+// in:
+//     cb - A pointer to a <udi_block_bind_cb_t>
+//
+typedef void udi_gfx_bind_req_op_t (udi_gfx_bind_cb_t *cb );
+udi_gfx_bind_req_op_t udi_gfx_bind_req;
+
+// Function: udi_gfx_bind_ack
+// function pointer prototype for acknowledging a connection request
+// 
+// in:
+//     cb      - A pointer to a <udi_gfx_bind_cb_t>
+//     sockets - The number of addressable socket components
+//     engines - The number of addressable engine components
+//     status  - The result of the bind operation
+//
+typedef void udi_gfx_bind_ack_op_t (udi_gfx_bind_cb_t *cb, udi_index_t sockets, udi_index_t engines, udi_status_t status );
+udi_gfx_bind_ack_op_t udi_gfx_bind_ack;
+
+// Function: udi_gfx_unbind_req
+// function pointer prototype for disconnecting a block device
+// 
+// in:
+//     cb - A pointer to a <udi_block_bind_cb_t>
+//
+typedef void udi_gfx_unbind_req_op_t (udi_gfx_bind_cb_t *cb );
+udi_gfx_unbind_req_op_t udi_gfx_unbind_req;
+
+// Function: udi_gfx_unbind_ack
+// function pointer prototype for connecting to a block device
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_bind_cb_t>
+//
+typedef void udi_gfx_unbind_ack_op_t (udi_gfx_bind_cb_t *cb );
+udi_gfx_unbind_ack_op_t udi_gfx_unbind_ack;
+
+// Structure: udi_gfx_state_cb_t
+// Contains the operations of a read/write transaction
+typedef struct {
+    // Variable: gcb
+    // The main control block
+    udi_cb_t gcb;    
+    udi_ubit32_t subsystem;
+    udi_ubit32_t attribute;
+} udi_gfx_state_cb_t;
+#define UDI_GFX_STATE_CB_NUM 2
+
+// Function: udi_gfx_set_engine_req
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_set_engine_req_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
+udi_gfx_set_engine_req_op_t udi_gfx_set_engine_req;
+
+// Function: udi_gfx_set_connector_req
+// function pointer prototype for setting an connector state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_set_connector_req_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
+udi_gfx_set_connector_req_op_t udi_gfx_set_connector_req;
+
+// Function: udi_gfx_set_engine_ack
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_set_engine_ack_op_t (udi_gfx_state_cb_t *cb );
+udi_gfx_set_engine_ack_op_t udi_gfx_set_engine_ack;
+
+// Function: udi_gfx_set_connector_ack
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_set_connector_ack_op_t (udi_gfx_state_cb_t *cb );
+udi_gfx_set_connector_ack_op_t udi_gfx_set_connector_ack;
+
+// Function: udi_gfx_get_engine_req
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_get_engine_req_op_t (udi_gfx_state_cb_t *cb );
+udi_gfx_get_engine_req_op_t udi_gfx_get_engine_req;
+
+// Function: udi_gfx_get_connector_req
+// function pointer prototype for setting an connector state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_get_connector_req_op_t (udi_gfx_state_cb_t *cb );
+udi_gfx_get_connector_req_op_t udi_gfx_get_connector_req;
+
+// Function: udi_gfx_get_engine_ack
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_get_engine_ack_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
+udi_gfx_get_engine_ack_op_t udi_gfx_get_engine_ack;
+
+// Function: udi_gfx_get_connector_ack
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_get_connector_ack_op_t (udi_gfx_state_cb_t *cb, udi_ubit32_t value);
+udi_gfx_get_connector_ack_op_t udi_gfx_get_connector_ack;
+
+// Function: udi_gfx_set_engine_nak
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb     - A pointer to a <udi_gfx_state_cb_t>
+//     status - An UDI status value indicative of the error
+//
+typedef void udi_gfx_set_engine_nak_op_t (udi_gfx_state_cb_t *cb, udi_status_t status);
+udi_gfx_set_engine_nak_op_t udi_gfx_set_engine_nak;
+
+// Function: udi_gfx_set_connector_nak
+// function pointer prototype for setting an engine state
+// 
+// in:
+//     cb     - A pointer to a <udi_gfx_state_cb_t>
+//     status - An UDI status value indicative of the error
+//
+typedef void udi_gfx_set_connector_nak_op_t (udi_gfx_state_cb_t *cb, udi_status_t status);
+udi_gfx_set_connector_nak_op_t udi_gfx_get_connector_nak;
+
+// Structure: udi_gfx_range_cb_t
+// Contains the operations of a range request transaction
+typedef struct {
+    // Variable: gcb
+    // The main control block
+    udi_cb_t gcb;    
+    udi_ubit32_t subsystem;
+    udi_ubit32_t attribute;
+    udi_buf_t * rangedata;  
+} udi_gfx_range_cb_t;
+#define UDI_GFX_RANGE_CB_NUM 3
+
+// Function: udi_gfx_range_engine_req
+// function pointer prototype for getting an engine property range
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_range_cb_t>
+//
+typedef void udi_gfx_range_engine_req_op_t (udi_gfx_range_cb_t *cb );
+udi_gfx_range_engine_req_op_t udi_gfx_range_engine_req;
+
+// Function: udi_gfx_range_connector_req
+// function pointer prototype for getting a connector property range
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_range_cb_t>
+//
+typedef void udi_gfx_range_connector_req_op_t (udi_gfx_range_cb_t *cb );
+udi_gfx_range_connector_req_op_t udi_gfx_range_connector_req;
+
+// Function: udi_gfx_range_engine_ack
+// function pointer prototype for replying an engine property range
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_range_cb_t>
+//
+typedef void udi_gfx_range_engine_ack_op_t (udi_gfx_range_cb_t *cb );
+udi_gfx_range_engine_ack_op_t udi_gfx_range_engine_ack;
+
+// Function: udi_gfx_range_connector_ack
+// function pointer prototype for replying a connector property range
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_range_cb_t>
+//
+typedef void udi_gfx_range_connector_ack_op_t (udi_gfx_range_cb_t *cb );
+udi_gfx_range_connector_ack_op_t udi_gfx_range_connector_ack;
+
+// Function: udi_gfx_get_engine_operator_req
+// function pointer prototype for requesting the engine operator layout
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_state_cb_t>
+//
+typedef void udi_gfx_get_engine_operator_req_op_t (udi_gfx_range_cb_t *cb );
+udi_gfx_get_engine_operator_req_op_t udi_gfx_get_engine_operator_req;
+
+// Function: udi_gfx_get_engine_operator_ack
+// function pointer prototype for replying the engine operator layout
+// 
+// in:
+//     cb   - A pointer to a <udi_gfx_state_cb_t>
+//     op   - The operator performed at this index
+//     arg1 - the first argument to this operator
+//     arg2 - the second argument to this operator
+//     arg3 - the third argument to this operator
+//
+typedef void udi_gfx_get_engine_operator_ack_op_t (udi_gfx_range_cb_t *cb, udi_ubit32_t op, udi_ubit32_t arg1, udi_ubit32_t arg2, udi_ubit32_t arg3 );
+udi_gfx_get_engine_operator_ack_op_t udi_gfx_get_engine_operator_ack;
+
+
+
+// Structure: udi_gfx_command_cb_t
+// Contains the operations of a command sequence
+typedef struct {
+    // Variable: gcb
+    // The main control block
+    udi_cb_t gcb;    
+    udi_buf_t * commanddata;
+} udi_gfx_command_cb_t;
+#define UDI_GFX_COMMAND_CB_NUM 4
+
+// Function: udi_gfx_connector_command_req
+// function pointer prototype for sending command data to the output connector
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_command_cb_t>
+//
+typedef void udi_gfx_connector_command_req_op_t (udi_gfx_command_cb_t *cb );
+udi_gfx_connector_command_req_op_t udi_gfx_connector_command_req;
+
+// Function: udi_gfx_engine_command_req
+// function pointer prototype for sending command data to the engine
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_command_cb_t>
+//
+typedef void udi_gfx_engine_command_req_op_t (udi_gfx_command_cb_t *cb );
+udi_gfx_engine_command_req_op_t udi_gfx_engine_command_req;
+
+// Function: udi_gfx_connector_command_ack
+// function pointer prototype for sending command data replies
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_command_cb_t>
+//
+typedef void udi_gfx_connector_command_ack_op_t (udi_gfx_command_cb_t *cb);
+udi_gfx_connector_command_ack_op_t udi_gfx_connector_command_ack;
+
+// Function: udi_gfx_engine_command_ack
+// function pointer prototype for sending engine data replies
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_command_cb_t>
+//
+typedef void udi_gfx_engine_command_ack_op_t (udi_gfx_command_cb_t *cb);
+udi_gfx_engine_command_ack_op_t udi_gfx_engine_command_ack;
+
+// Structure: udi_gfx_buffer_cb_t
+// Contains a description of a buffer, or area thereof
+typedef struct {
+    // Variable: gcb
+    // The main control block
+    udi_cb_t gcb;    
+    udi_ubit32_t buffer_index;
+} udi_gfx_buffer_info_cb_t;
+
+// Function: udi_gfx_buffer_info_req
+// function pointer prototype for getting buffer configuration information
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_command_cb_t>
+//
+typedef void udi_gfx_buffer_info_req_op_t (udi_gfx_buffer_info_cb_t *cb);
+udi_gfx_buffer_info_req_op_t udi_gfx_buffer_info_req;
+
+// Function: udi_gfx_buffer_info_ack
+// function pointer prototype for getting buffer configuration information
+// 
+// in:
+//     cb       - A pointer to a <udi_gfx_command_cb_t>
+//     width    - The width of the buffer
+//     height   - The height of the buffer
+//     bitsper  - The number of bits read from the buffer per pixel unit
+//     flags    - A bitfield of <UDI_GFX_BUFFER_FLAGS> indicating the exposed 
+//                capabilities of this buffer
+//
+// Note that bitsper might not be a multiple of eight.
+//
+typedef void udi_gfx_buffer_info_ack_op_t (udi_gfx_buffer_info_cb_t *cb, udi_ubit32_t width, udi_ubit32_t height, udi_ubit32_t bitsper, udi_ubit32_t flags);
+udi_gfx_buffer_info_ack_op_t udi_gfx_buffer_info_ack;
+
+// Structure: udi_gfx_buffer_cb_t
+// Contains a description of a buffer, or area thereof
+typedef struct {
+    // Variable: gcb
+    // The main control block
+    udi_cb_t gcb;    
+    udi_ubit32_t buffer_index;
+    udi_ubit32_t x;
+    udi_ubit32_t y;
+    udi_ubit32_t width;
+    udi_ubit32_t height;
+    udi_buf_t * buffer;
+} udi_gfx_buffer_cb_t;
+
+// Function: udi_gfx_buffer_write_req_op_t
+// function pointer prototype for writing raw hardware buffers
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_buffer_cb_t>
+//
+typedef void udi_gfx_buffer_write_req_op_t (udi_gfx_buffer_cb_t *cb);
+udi_gfx_buffer_write_req_op_t udi_gfx_buffer_write_req;
+
+// Function: udi_gfx_buffer_write_req_op_t
+// function pointer prototype for reading raw hardware buffers
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_buffer_cb_t>
+//
+typedef void udi_gfx_buffer_read_req_op_t (udi_gfx_buffer_cb_t *cb);
+udi_gfx_buffer_read_req_op_t udi_gfx_buffer_read_req;
+
+// Function: udi_gfx_buffer_write_ack_op_t
+// function pointer prototype for writing raw hardware buffers
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_buffer_cb_t>
+//
+typedef void udi_gfx_buffer_write_ack_op_t (udi_gfx_buffer_cb_t *cb);
+udi_gfx_buffer_write_ack_op_t udi_gfx_buffer_write_ack;
+
+// Function: udi_gfx_buffer_write_ack_op_t
+// function pointer prototype for reading raw hardware buffers
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_buffer_cb_t>
+//
+typedef void udi_gfx_buffer_read_ack_op_t (udi_gfx_buffer_cb_t *cb);
+udi_gfx_buffer_read_ack_op_t udi_gfx_buffer_read_ack;
+
+// Function: udi_gfx_buffer_write_nak_op_t
+// error handling for buffer writes
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_buffer_cb_t>
+//
+typedef void udi_gfx_buffer_write_nak_op_t (udi_gfx_buffer_cb_t *cb, udi_status_t status);
+udi_gfx_buffer_write_nak_op_t udi_gfx_buffer_write_nak;
+
+// Function: udi_gfx_buffer_write_nak_op_t
+// error handling for buffer reads
+// 
+// in:
+//     cb - A pointer to a <udi_gfx_buffer_cb_t>
+//
+typedef void udi_gfx_buffer_read_nak_op_t (udi_gfx_buffer_cb_t *cb, udi_status_t status);
+udi_gfx_buffer_read_nak_op_t udi_gfx_buffer_read_nak;
+
+/* Structure: udi_gfx_provider_ops_t
+ * 
+ * The graphics metalanguage entry points (provider side)
+ */
+typedef const struct {
+    udi_channel_event_ind_op_t          *channel_event_ind_op;
+    udi_gfx_bind_req_op_t               *gfx_bind_req_op;
+    udi_gfx_unbind_req_op_t             *gfx_unbind_req_op;
+    udi_gfx_set_connector_req_op_t      *gfx_set_connector_req_op;
+    udi_gfx_set_engine_req_op_t         *gfx_set_engine_req_op;
+    udi_gfx_get_connector_req_op_t      *gfx_get_connector_req_op;
+    udi_gfx_get_engine_req_op_t         *gfx_get_engine_req_op;
+    udi_gfx_range_connector_req_op_t    *gfx_range_connector_req_op;
+    udi_gfx_range_engine_req_op_t       *gfx_range_engine_req_op;
+    udi_gfx_get_engine_operator_req_op_t*gfx_get_engine_operator_req_op;
+    udi_gfx_connector_command_req_op_t  *gfx_connector_command_req_op;
+    udi_gfx_engine_command_req_op_t     *gfx_engine_command_req_op;
+    udi_gfx_buffer_info_req_op_t        *gfx_buffer_info_req_op;
+    udi_gfx_buffer_read_req_op_t        *gfx_buffer_read_req_op;
+    udi_gfx_buffer_write_req_op_t       *gfx_buffer_write_req_op;
+} udi_gfx_provider_ops_t;
+
+/* Structure: udi_gfx_client_ops_t
+ *
+ * The graphics metalanguage entry points (client side)
+ */
+typedef const struct {
+    udi_channel_event_ind_op_t          *channel_event_ind_op;
+    udi_gfx_bind_ack_op_t               *gfx_bind_ack_op;
+    udi_gfx_unbind_ack_op_t             *gfx_unbind_ack_op;
+    udi_gfx_set_connector_ack_op_t      *gfx_set_connector_ack_op;
+    udi_gfx_set_engine_ack_op_t         *gfx_set_engine_ack_op;
+    udi_gfx_set_connector_nak_op_t      *gfx_set_connector_nak_op;
+    udi_gfx_set_engine_nak_op_t         *gfx_set_engine_nak_op;
+    udi_gfx_get_connector_ack_op_t      *gfx_get_connector_ack_op;
+    udi_gfx_get_engine_ack_op_t         *gfx_get_engine_ack_op;
+    udi_gfx_range_connector_ack_op_t    *gfx_range_connector_ack_op;
+    udi_gfx_range_engine_ack_op_t       *gfx_range_engine_ack_op;
+    udi_gfx_get_engine_operator_req_op_t*gfx_get_engine_operator_ack_op;
+    udi_gfx_connector_command_ack_op_t  *gfx_connector_command_ack_op;
+    udi_gfx_engine_command_ack_op_t     *gfx_engine_command_ack_op;
+    udi_gfx_buffer_info_ack_op_t        *gfx_buffer_info_ack_op;
+    udi_gfx_buffer_read_ack_op_t        *gfx_buffer_read_ack_op;
+    udi_gfx_buffer_write_ack_op_t       *gfx_buffer_write_ack_op;
+    udi_gfx_buffer_read_nak_op_t        *gfx_buffer_read_nak_op;
+    udi_gfx_buffer_write_nak_op_t       *gfx_buffer_write_nak_op;
+} udi_gfx_client_ops_t;
+
+
+// temporary
+#ifndef UDI_ANNOY_ME
+void EngineReturnSimpleRange (int source, int index, int prop, int first, int last, int modulus);
+void ConnectorReturnSimpleRange (int source, int index, int prop, int first, int last, int modulus);
+void EngineReturnConstantRange (int source, int index, int prop, int value);
+void ConnectorReturnConstantRange (int source, int index, int prop, int value);
+void EngineReturnBooleanRange (int source, int index, int prop, int value1, int value2);
+void ConnectorReturnBooleanRange (int source, int index, int prop, int value1, int value2);
+#endif
+
+#endif
diff --git a/Usermode/Libraries/Makefile.tpl b/Usermode/Libraries/Makefile.tpl
index 5e241f23376d484f6fa54c42410913ad020b350f..8f548bfa99adc20171b738395a9a4fb5e8548e36 100644
--- a/Usermode/Libraries/Makefile.tpl
+++ b/Usermode/Libraries/Makefile.tpl
@@ -43,7 +43,7 @@ else
 V := @
 endif
 
-.PHONY: all clean install postbuild
+.PHONY: all clean install postbuild utest-build utest-run generate_exp
 
 all: _libs $(_BIN) $(_XBIN)
 
@@ -60,16 +60,13 @@ _libs: $(HEADERS)
 
 .PHONY: utest utest-build utest-run $(UTESTS:%=runtest-%)
 
-utest: utest-build utest-run
+utest: utest-build generate_exp utest-run
 
 generate_exp: $(UTESTS:%=EXP_%.txt)
-	@echo > /dev/null
 
 utest-build: $(UTESTS:%=TEST_%)
-	@echo > /dev/null
 
 utest-run: $(UTESTS:%=runtest-%)
-	@echo > /dev/null
 
 $(UTESTS:%=runtest-%): runtest-%: TEST_% EXP_%.txt
 	@echo --- [TEST] $*
diff --git a/Usermode/Libraries/crt0.o_src/armv7-crti.S b/Usermode/Libraries/crt0.o_src/armv7-crti.S
new file mode 100644
index 0000000000000000000000000000000000000000..310cd6abad9f81bc48a20c8d93491825c20f33f2
--- /dev/null
+++ b/Usermode/Libraries/crt0.o_src/armv7-crti.S
@@ -0,0 +1,31 @@
+.section .init
+.global _init
+.type _init, function
+_init:
+#ifdef __thumb__
+	.thumb
+	
+	push	{r3, r4, r5, r6, r7, lr}
+#else
+	.arm
+	mov	ip, sp
+	stmdb	sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+	sub	fp, ip, #4
+#endif
+	/* gcc will nicely put the contents of crtbegin.o's .init section here. */
+
+.section .fini
+.global _fini
+.type _fini, function
+_fini:
+#ifdef __thumb__
+	.thumb
+	
+	push	{r3, r4, r5, r6, r7, lr}
+#else
+	.arm
+	mov	ip, sp
+	stmdb	sp!, {r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
+	sub	fp, ip, #4
+#endif
+	/* gcc will nicely put the contents of crtbegin.o's .fini section here. */
diff --git a/Usermode/Libraries/crt0.o_src/armv7-crtn.S b/Usermode/Libraries/crt0.o_src/armv7-crtn.S
new file mode 100644
index 0000000000000000000000000000000000000000..1c3e1113e82be2b18a637484f8bda441e1a9e67f
--- /dev/null
+++ b/Usermode/Libraries/crt0.o_src/armv7-crtn.S
@@ -0,0 +1,41 @@
+.section .init
+	/* gcc will nicely put the contents of crtend.o's .init section here. */
+#ifdef __thumb__
+	.thumb
+	
+	pop	{r3, r4, r5, r6, r7}
+	pop	{r3}
+	mov	lr, r3
+#else
+	.arm
+	
+	sub	sp, fp, #40
+	ldmfd	sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
+#endif
+	
+#if defined __THUMB_INTERWORK__ || defined __thumb__
+	bx	lr
+#else
+	mov	pc, lr
+#endif
+
+.section .fini
+	/* gcc will nicely put the contents of crtend.o's .fini section here. */
+#ifdef __thumb__
+	.thumb
+	
+	pop	{r3, r4, r5, r6, r7}
+	pop	{r3}
+	mov	lr, r3
+#else
+	.arm
+	
+	sub	sp, fp, #40
+	ldmfd	sp, {r4, r5, r6, r7, r8, r9, sl, fp, sp, lr}
+#endif
+	
+#if defined __THUMB_INTERWORK__ || defined __thumb__
+	bx	lr
+#else
+	mov	pc, lr
+#endif
diff --git a/Usermode/Libraries/ld-acess.so_src/Makefile b/Usermode/Libraries/ld-acess.so_src/Makefile
index 78aac4bd7f7b548463a0c141719526357c3b374b..d6691e401c731185a9ba6803caa54582e7021689 100644
--- a/Usermode/Libraries/ld-acess.so_src/Makefile
+++ b/Usermode/Libraries/ld-acess.so_src/Makefile
@@ -33,15 +33,15 @@ include ../Makefile.tpl
 # create libld-acess.so
 $(_XBIN): $(_OBJPREFIX)_stublib.o
 	@echo [LD] -o -shared libld-acess.so
-	$(LD) -shared -o $@ $<
+	$V$(LD) -shared -o $@ $<
 #	@$(LD) $(LDFLAGS) -o $@ $(OBJ)
 
 
 # Override .ao to look in the object prefix for the source
-$(_OBJPREFIX)arch/$(ARCHDIR).ao_: $(_OBJPREFIX)arch/$(ARCHDIR).$(ASSUFFIX)
+$(_OBJPREFIX)arch/$(ARCHDIR).ao_: $(_OBJPREFIX)arch/$(ARCHDIR).$(ASSUFFIX) Makefile
 	@echo [AS] -o $@
 	@mkdir -p $(dir $@)
-	@$(AS) $(ASFLAGS) -o $@ $<
+	$V$(AS) $(ASFLAGS) -o $@ $<
 
 #.PRECIOUS: $(OBJ:%.ao=%.asm)
 
@@ -49,7 +49,7 @@ $(_OBJPREFIX)arch/$(ARCHDIR).ao_: $(_OBJPREFIX)arch/$(ARCHDIR).$(ASSUFFIX)
 $(_OBJPREFIX)arch/$(ARCHDIR).$(ASSUFFIX): arch/$(ARCHDIR).$(ASSUFFIX).h arch/syscalls.s.h
 	@echo [CPP] -o $@
 	@mkdir -p $(dir $@)
-	@$(CPP) $(CPPFLAGS) -P -D__ASSEMBLER__ $< -o $@
+	$V$(CPP) $(CPPFLAGS) -P -D__ASSEMBLER__ $< -o $@
 
 $(_OBJPREFIX)arch/$(ARCHDIR).$(ASSUFFIX): $(ACESSDIR)/KernelLand/Kernel/include/syscalls.h
 
diff --git a/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h b/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h
index 351c84147c43f2867c49b632548e5335b0557a13..7e604f1d85bd192374d8332ad56673b38e184e9b 100644
--- a/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h
+++ b/Usermode/Libraries/ld-acess.so_src/arch/armv7.S.h
@@ -16,7 +16,7 @@ _start:
 	
 	b _exit
 
-@ Stupid GCC
+// Stupid GCC
 .globl __ucmpdi2
 __ucmpdi2:
 	cmp r0, r2
@@ -32,8 +32,8 @@ __ucmpdi2:
 	mov r0, #1
 	mov pc, lr
 
-@ Well, can't blame it
-@ - Clear the instruction cache
+//@ Well, can't blame it
+// - Clear the instruction cache
 .globl __clear_cache
 __clear_cache:
 	svc #0x1001
diff --git a/Usermode/Libraries/libc++.so_src/include_exp/typeinfo b/Usermode/Libraries/libc++.so_src/include_exp/typeinfo
index fd823db19400c12957ba10e66ecb73854be48b83..c8b037ceab3ff39e5879b28938bd3539dec8d6d1 100644
--- a/Usermode/Libraries/libc++.so_src/include_exp/typeinfo
+++ b/Usermode/Libraries/libc++.so_src/include_exp/typeinfo
@@ -8,6 +8,8 @@
 #ifndef _LIBCXX__TYPEINFO_
 #define _LIBCXX__TYPEINFO_
 
+#include <cstddef>
+
 namespace std {
 
 // Type information class
@@ -21,7 +23,7 @@ public:
 	const char* name() const;
 	
 	// acess
-	bool __is_child(const type_info &, unsigned long&) const;
+	bool __is_child(const type_info &, size_t&) const;
 private:
 	type_info (const type_info& rhs);
 	type_info& operator= (const type_info& rhs);
diff --git a/Usermode/Libraries/libc++.so_src/typeinfo.cc b/Usermode/Libraries/libc++.so_src/typeinfo.cc
index 31907ee10c2eb36b592294941ee93b2dab00ad0a..99bfedc5de1ce40e459ac1de54e064da592aa34d 100644
--- a/Usermode/Libraries/libc++.so_src/typeinfo.cc
+++ b/Usermode/Libraries/libc++.so_src/typeinfo.cc
@@ -71,7 +71,7 @@ bool type_info::is_subclass() const
 }
 
 // Acess-defined
-bool type_info::__is_child(const type_info &poss_child, unsigned long &offset) const
+bool type_info::__is_child(const type_info &poss_child, size_t &offset) const
 {
 	_SysDebug("typeids = this:%s , poss_child:%s", typeid(*this).name(), typeid(poss_child).name());
 
diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile
index 40977e9c5e9a90de5772725c35d0b1bb60407be2..64749b3b8c03eb5af66bb364fc605fc290f047e4 100644
--- a/Usermode/Libraries/libc.so_src/Makefile
+++ b/Usermode/Libraries/libc.so_src/Makefile
@@ -29,8 +29,8 @@ endif
 include ../Makefile.tpl
 
 EXP_%.txt: TEST_%.native
-	./$< > $@
-	rm $<
+	@./$< > $@
+	@rm $<
 EXP_strtoi.txt:
 	echo -n "" > $@
 
diff --git a/Usermode/Libraries/libc.so_src/TEST_string.c b/Usermode/Libraries/libc.so_src/TEST_string.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ecca307d684819ece57ff7b12de56fe12834f64
--- /dev/null
+++ b/Usermode/Libraries/libc.so_src/TEST_string.c
@@ -0,0 +1,51 @@
+/*
+ */
+#include <stdio.h>
+#include <string.h>
+
+#define ASSERT(cnd)	printf("ASSERT: "#cnd" == %s\n", ((cnd) ? "pass" : "FAIL"))
+
+int main()
+{
+	ASSERT(strcmp("hello", "world") < 0);
+	ASSERT(strcmp("hello", "hello") == 0);
+	ASSERT(strcmp("wello", "hello") > 0);
+	ASSERT(strcmp("\xff", "\1") > 0);
+	ASSERT(strcmp("\1", "\xff") < 0);
+	ASSERT(strcmp("Hello", "hello") < 0);
+	
+	ASSERT(strncmp("hello world", "hello", 5) == 0);
+	
+	ASSERT(strcasecmp("hello", "world") < 0);
+	ASSERT(strcasecmp("hello", "hello") == 0);
+	ASSERT(strcasecmp("wello", "hello") > 0);
+	ASSERT(strcasecmp("\xff", "\1") > 0);
+	ASSERT(strcasecmp("\1", "\xff") < 0);
+	ASSERT(strcasecmp("Hello", "hello") == 0);
+	ASSERT(strcasecmp("Hello", "Hello") == 0);
+	ASSERT(strcasecmp("hellO", "Hello") == 0);
+	
+	char buf[13];
+	memset(buf, 127, sizeof(buf));
+	ASSERT(buf[0] == 127);	ASSERT(buf[4] == 127);
+	strncpy(buf, "hello", 4);
+	ASSERT(buf[3] == 'l');	ASSERT(buf[4] == 127);
+	strncpy(buf, "hello", 8);
+	ASSERT(buf[4] == 'o');	ASSERT(buf[5] == '\0'); ASSERT(buf[7] == '\0'); ASSERT(buf[8] == 127);
+	
+	memset(buf, 0, 13);
+	ASSERT(buf[0] == 0);	ASSERT(buf[12] == 0);
+	
+	ASSERT(memchr("\xffhello", 'x', 6) == NULL);
+	
+	const char *teststr_foo = "foo";
+	ASSERT(strchr(teststr_foo, 'f') == teststr_foo+0);
+	ASSERT(strchr(teststr_foo, 'o') == teststr_foo+1);
+	ASSERT(strchr(teststr_foo, '\0') == teststr_foo+3);
+	ASSERT(strchr(teststr_foo, 'X') == NULL);
+	ASSERT(strrchr(teststr_foo, 'f') == teststr_foo+0);
+	ASSERT(strrchr(teststr_foo, 'o') == teststr_foo+2);
+	ASSERT(strrchr(teststr_foo, '\0') == teststr_foo+3);
+	ASSERT(strrchr(teststr_foo, 'X') == NULL);
+}
+
diff --git a/Usermode/Libraries/libc.so_src/errno.c b/Usermode/Libraries/libc.so_src/errno.c
index f5a142a84ea9af96261327210fb352a154a54994..295183c4310c578594bc3809067432e7618d3f7f 100644
--- a/Usermode/Libraries/libc.so_src/errno.c
+++ b/Usermode/Libraries/libc.so_src/errno.c
@@ -56,6 +56,7 @@ EXPORT char *strerror(int errnum)
 	case EAFNOSUPPORT:	return "Address family not supported";
 	case EADDRINUSE:	return "Address already in use";
 	case ETIMEDOUT:	return "Operation timed out";
+	case EOPNOTSUPP:	return "Operation not supported on socket";
 
 	case EINTERNAL:	return "Internal error";
 	}
diff --git a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h
index be8c882a37df7ef550aa1b6f0c523d87caa5a829..d7b105365e14bccf3c0614f22ad7206872c3c1ae 100755
--- a/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h
+++ b/Usermode/Libraries/libc.so_src/include_exp/errno.enum.h
@@ -37,8 +37,9 @@ enum libc_eErrorNumbers {
 
 	// psockets
 	EAFNOSUPPORT,	
-	EADDRINUSE,	// Specified addres is already in use
+	EADDRINUSE,	// (POSIX.1) Specified addres is already in use
 	ETIMEDOUT,
+	EOPNOTSUPP,	// (POSIX.1) Operation not supported on socket
 	
 	EINTERNAL	// Internal Error
 };
diff --git a/Usermode/Libraries/libc.so_src/include_exp/stdlib.h b/Usermode/Libraries/libc.so_src/include_exp/stdlib.h
index 07fc81f4c8d7756e978ac8c3574da9fe9e9b29ee..fa923eef6e7244cc3fe896d50852165e76605e0c 100644
--- a/Usermode/Libraries/libc.so_src/include_exp/stdlib.h
+++ b/Usermode/Libraries/libc.so_src/include_exp/stdlib.h
@@ -112,6 +112,8 @@ extern int	rand_p(unsigned int *seedp);
 # define SEEK_END	(-1)
 #endif
 
+#define MB_CUR_MAX	5	// (C99) Max number of bytes in a single multibyte character (UTF8=5)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c
index cf2e733671e626bb684558758f318e39554d0adf..55fd52134750e57d62f5aeaa04d273a03f8fa54d 100644
--- a/Usermode/Libraries/libc.so_src/stdio.c
+++ b/Usermode/Libraries/libc.so_src/stdio.c
@@ -795,13 +795,12 @@ EXPORT char *fgets(char *s, int size, FILE *fp)
  */
 EXPORT int fputc(int c, FILE *fp)
 {
-	char	ch = c;
+	unsigned char	ch = c;
 	return fwrite(&ch, 1, 1, fp);
 }
 
 EXPORT int putchar(int c)
 {
-	c &= 0xFF;
 	return fputc(c, stdout);
 }
 
@@ -811,7 +810,7 @@ EXPORT int putchar(int c)
  */
 EXPORT int fgetc(FILE *fp)
 {
-	char	ret = 0;
+	unsigned char	ret = 0;
 	if( fread(&ret, 1, 1, fp) != 1 )
 		return -1;
 	return ret;
@@ -825,7 +824,6 @@ EXPORT int getchar(void)
 
 EXPORT int puts(const char *str)
 {
-	
 	if(!str)	return 0;
 	 int	len = strlen(str);
 	
diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c
index 0757c24ad3ee46432d3cc7f1232017dfe06cb968..d61d51dde0d2b742b69c06733c166d6e464b7150 100644
--- a/Usermode/Libraries/libc.so_src/string.c
+++ b/Usermode/Libraries/libc.so_src/string.c
@@ -2,7 +2,7 @@
  * AcessOS Basic C Library
  * string.c
  */
-#include <acess/sys.h>
+//#include <acess/sys.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <ctype.h>
@@ -13,20 +13,19 @@
  * \fn EXPORT int strcmp(const char *s1, const char *s2)
  * \brief Compare two strings
  */
-EXPORT int strcmp(const char *s1, const char *s2)
+EXPORT int strcmp(const char *_s1, const char *_s2)
 {
-	while(*s1 && *s1 == *s2) {
-		s1++; s2++;
-	}
-	return (int)*s1 - (int)*s2;
+	return strncmp(_s1, _s2, SIZE_MAX);
 }
 
 /**
- * \fn EXPORT int strncmp(const char *s1, const char *s2)
- * \brief Compare two strings
+ * \fn EXPORT int strncmp(const char *s1, const char *s2, size_t n)
+ * \brief Compare two strings, stopping after n characters
  */
-EXPORT int strncmp(const char *s1, const char *s2, size_t n)
+EXPORT int strncmp(const char *_s1, const char *_s2, size_t n)
 {
+	const unsigned char*	s1 = (const unsigned char*)_s1;
+	const unsigned char*	s2 = (const unsigned char*)_s2;
 	while(n && *s1 && *s1 == *s2)
 	{
 		s1++; s2++;
@@ -38,23 +37,31 @@ EXPORT int strncmp(const char *s1, const char *s2, size_t n)
 		return (int)*s1 - (int)*s2;
 }
 
-EXPORT int strcasecmp(const char *s1, const char *s2)
+EXPORT int strcasecmp(const char *_s1, const char *_s2)
 {
-	 int	rv;
-	while( (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0' ) {
-		s1++; s2++;
-	}
-	return rv;
+	return strncasecmp(_s1, _s2, SIZE_MAX);
 }
 
-EXPORT int strncasecmp(const char *s1, const char *s2, size_t n)
+EXPORT int strncasecmp(const char *_s1, const char *_s2, size_t n)
 {
-	 int	rv = 0;
-	if( n == 0 )	return 0;
-	while(n -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') {
-		s1++; s2++;
+	const unsigned char*	s1 = (const unsigned char*)_s1;
+	const unsigned char*	s2 = (const unsigned char*)_s2;
+	while( n-- && *s1 && *s2 )
+	{
+		if( *s1 != *s2 )
+		{
+			int rv;
+			rv = toupper(*s1) - toupper(*s2);
+			if(rv != 0)
+				return rv;
+			rv = tolower(*s1) - tolower(*s2);
+			if(rv != 0)
+				return rv;
+		}
+		s1 ++;
+		s2 ++;
 	}
-	return rv;
+	return 0;
 }
 
 /**
@@ -80,8 +87,13 @@ EXPORT char *strcpy(char *dst, const char *src)
 EXPORT char *strncpy(char *dst, const char *src, size_t num)
 {
 	char *to = dst;
-	while(*src && num--)	*to++ = *src++;
-	*to = '\0';
+	while(num --)
+	{
+		if(*src)
+			*to++ = *src++;
+		else
+			*to++ = '\0';
+	}
 	return dst;
 }
 
@@ -118,9 +130,10 @@ EXPORT char *strncat(char *dst, const char *src, size_t n)
  */
 EXPORT size_t strlen(const char *str)
 {
-	size_t	retval;
-	for(retval = 0; *str != '\0'; str++, retval++);
-	return retval;
+	size_t	len = 0;
+	while(str[len] != '\0')
+		len ++;
+	return len;
 }
 
 /**
@@ -130,8 +143,9 @@ EXPORT size_t strlen(const char *str)
  */
 EXPORT size_t strnlen(const char *str, size_t maxlen)
 {
-	size_t	len;
-	for( len = 0; maxlen -- && *str; str ++, len ++ );
+	size_t	len = 0;
+	while( len < maxlen && str[len] != '\0' )
+		len ++;
 	return len;
 }
 
@@ -171,11 +185,12 @@ EXPORT char *strndup(const char *str, size_t maxlen)
  * \fn EXPORT char *strchr(char *str, int character)
  * \brief Locate a character in a string
  */
-EXPORT char *strchr(const char *str, int character)
+EXPORT char *strchr(const char *_str, int character)
 {
+	const unsigned char* str = (const unsigned char*)_str;
 	for(;*str;str++)
 	{
-		if(*str == character)
+		if( *str == character )
 			return (char*)str;
 	}
 	return NULL;
@@ -185,11 +200,10 @@ EXPORT char *strchr(const char *str, int character)
  * \fn EXPORT char *strrchr(char *str, int character)
  * \brief Locate the last occurance of a character in a string
  */
-EXPORT char *strrchr(const char *str, int character)
+EXPORT char *strrchr(const char *_str, int character)
 {
-	 int	i;
-	i = strlen(str)-1;
-	while(i--)
+	const unsigned char* str = (const unsigned char*)_str;
+	for( size_t i = strlen(_str); i--; )
 	{
 		if(str[i] == character)
 			return (void*)&str[i];
@@ -277,6 +291,8 @@ EXPORT void *memcpy(void *__dest, const void *__src, size_t count)
 	return __dest;
 }
 
+// TODO: memccpy (POSIX defined)
+
 /**
  * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
  * \brief Copy data in memory, avoiding overlap problems
@@ -316,7 +332,7 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
 	while(count--)
 	{
 		if( *p1 != *p2 )
-			return *p1 - *p2;
+			return (int)*p1 - (int)*p2;
 		p1 ++;
 		p2 ++;
 	}
@@ -332,11 +348,12 @@ EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
  */
 EXPORT void *memchr(const void *ptr, int value, size_t num)
 {
+	const unsigned char* buf = ptr;
 	while(num--)
 	{
-		if( *(const unsigned char*)ptr == (unsigned char)value )
-			return (void*)ptr;
-		ptr ++;
+		if( *buf == (unsigned char)value )
+			return (void*)buf;
+		buf ++;
 	}
 	return NULL;
 }
@@ -344,12 +361,13 @@ EXPORT void *memchr(const void *ptr, int value, size_t num)
 EXPORT size_t strcspn(const char *haystack, const char *reject)
 {
 	size_t	ret = 0;
-	 int	i;
 	while( *haystack )
 	{
-		for( i = 0; reject[i] && reject[i] == *haystack; i ++ );
-
-		if( reject[i] ) return ret;
+		for( int i = 0; reject[i]; i ++ )
+		{
+			if( reject[i] == *haystack )
+				return ret;
+		}
 		ret ++;
 	}
 	return ret;
@@ -358,12 +376,13 @@ EXPORT size_t strcspn(const char *haystack, const char *reject)
 EXPORT size_t strspn(const char *haystack, const char *accept)
 {
 	size_t	ret = 0;
-	 int	i;
 	while( *haystack )
 	{
-		for( i = 0; accept[i] && accept[i] == *haystack; i ++ );
-
-		if( !accept[i] )	return ret;
+		for( int i = 0; accept[i]; i ++ )
+		{
+			if( accept[i] != *haystack )
+				return ret;
+		}
 		ret ++;
 	}
 	return ret;
@@ -378,6 +397,7 @@ EXPORT char *strpbrk(const char *haystack, const char *accept)
 			if( accept[i] == *haystack )
 				return (char*)haystack;
 		}
+		haystack ++;
 	}
 	return NULL;
 }
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/glob.h b/Usermode/Libraries/libposix.so_src/include_exp/glob.h
new file mode 100644
index 0000000000000000000000000000000000000000..ff96b8e600f755972074a0078681c9b9750a6270
--- /dev/null
+++ b/Usermode/Libraries/libposix.so_src/include_exp/glob.h
@@ -0,0 +1,13 @@
+/*
+ * Acess2 POSIX Emulation Library
+ * - By John Hodge (thePowersGang)
+ *
+ * glob.h
+ * - Globbing code
+ */
+#ifndef _LIBPOSIX__GLOB_H_
+#define _LIBPOSIX__GLOB_H_
+
+
+
+#endif
diff --git a/Usermode/Libraries/libposix.so_src/include_exp/regex.h b/Usermode/Libraries/libposix.so_src/include_exp/regex.h
index a830286c91c4fc28552b8919f8f88f98c51c81af..ebbe6b631e4b9d1a8a871f09958a6829b527e8dd 100644
--- a/Usermode/Libraries/libposix.so_src/include_exp/regex.h
+++ b/Usermode/Libraries/libposix.so_src/include_exp/regex.h
@@ -30,6 +30,11 @@ enum {
 	REG_BADRPT,
 };
 
+#define REG_EXTENDED	0x1
+#define REG_ICASE	0x2
+#define REG_NOSUB	0x4
+#define REG_NEWLINE	0x8
+
 
 #endif
 
diff --git a/Usermode/Libraries/libpthread.so_src/Makefile b/Usermode/Libraries/libpthread.so_src/Makefile
index fe3fc8c2bcbcb5ed23e42bf701b9a9a4912f5574..0870c0cfbefa24182ae15af3d268f7074c7ff110 100644
--- a/Usermode/Libraries/libpthread.so_src/Makefile
+++ b/Usermode/Libraries/libpthread.so_src/Makefile
@@ -6,7 +6,7 @@ CPPFLAGS +=
 CFLAGS   += -Wall
 LDFLAGS  += -lc -soname libpthread.so
 
-OBJ = main.o
+OBJ = main.o thread.o
 BIN = libpthread.so
 
 include ../Makefile.tpl
diff --git a/Usermode/Libraries/libpthread.so_src/include_exp/pthread.h b/Usermode/Libraries/libpthread.so_src/include_exp/pthread.h
index 8f4f779eb802193a95d35621230ab0fe00f7713b..376fb0e2b69c0cb35b28756a7bbba9042e0ce82a 100644
--- a/Usermode/Libraries/libpthread.so_src/include_exp/pthread.h
+++ b/Usermode/Libraries/libpthread.so_src/include_exp/pthread.h
@@ -60,7 +60,7 @@ struct pthread_mutex_s
 {
 	void*	futex;
 };
-#define PTHREAD_MUTEX_INITIALIZER	((struct pthread_mutex_s){NULL})
+#define PTHREAD_MUTEX_INITIALIZER	((struct pthread_mutex_s){0})
 typedef struct pthread_mutex_s	pthread_mutex_t;
 extern int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *attrs);
 extern int pthread_mutex_lock(pthread_mutex_t *lock);
diff --git a/Usermode/Libraries/libpthread.so_src/thread.c b/Usermode/Libraries/libpthread.so_src/thread.c
new file mode 100644
index 0000000000000000000000000000000000000000..4b5f51fee5388794c2da727186f4bc2e47bcfe58
--- /dev/null
+++ b/Usermode/Libraries/libpthread.so_src/thread.c
@@ -0,0 +1,44 @@
+/*
+ * Acess2 libpthread
+ * - By John Hodge (thePowersGang)
+ *
+ * thread.c
+ * - Thread management for pthreads
+ */
+#include <pthread.h>
+#include <assert.h>
+
+int pthread_create(pthread_t *threadptr, const pthread_attr_t * attrs, void* (*fcn)(void*), void* arg)
+{
+	assert(!"TODO: pthread_create");
+	return 0;
+}
+int pthread_detach(pthread_t thread)
+{
+	assert(!"TODO: pthread_detach");
+	return 0;
+}
+int pthread_join(pthread_t thread, void **retvalptr)
+{
+	assert(!"TODO: pthread_join");
+	return 0;
+}
+int pthread_cancel(pthread_t thread)
+{
+	assert(!"TODO: pthread_cancel");
+	return 0;
+}
+int pthread_equal(pthread_t t1, pthread_t t2)
+{
+	assert(!"TODO: pthread_equal");
+	return 0;
+}
+pthread_t pthread_self(void)
+{
+	assert(!"TODO: pthread_self");
+	return (pthread_t){0};
+}
+void pthread_exit(void* retval)
+{
+	assert(!"TODO: pthread_create");
+}
diff --git a/Usermode/Libraries/libresolv.so_src/Makefile b/Usermode/Libraries/libresolv.so_src/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..21eb942d6567d093d5a54d7d0739b44f0596e9d3
--- /dev/null
+++ b/Usermode/Libraries/libresolv.so_src/Makefile
@@ -0,0 +1,16 @@
+# Acess2 BSD "resolv" library
+# Makefile
+
+-include ../Makefile.cfg
+
+CPPFLAGS += 
+CFLAGS   += -Wextra
+ASFLAGS  +=
+LDFLAGS  += 
+LIBS     += -lnet -lpsocket
+
+OBJ  = resolv.o
+BIN = libresolv.so
+
+include ../Makefile.tpl
+
diff --git a/Usermode/Libraries/libresolv.so_src/include_exp/arpa/nameser.h b/Usermode/Libraries/libresolv.so_src/include_exp/arpa/nameser.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f2532b5b3553c7aea06cd72d28d326f42f29dd0
--- /dev/null
+++ b/Usermode/Libraries/libresolv.so_src/include_exp/arpa/nameser.h
@@ -0,0 +1,16 @@
+/*
+ * Acess2 POSIX Sockets Emulation
+ * - By John Hodge (thePowersGang)
+ *
+ * arpa/nameser.h
+ * - BSD name resolution (TODO: move to libresolv)
+ *
+ * NOTE: I have no fucking idea who/what defines this header, it's wanted by glib
+ */
+#ifndef _LIBPSOCKET__ARPA_NAMESER_H_
+#define _LIBPSOCKET__ARPA_NAMESER_H_
+
+#define C_IN	0x1
+
+#endif
+
diff --git a/Usermode/Libraries/libresolv.so_src/include_exp/resolv.h b/Usermode/Libraries/libresolv.so_src/include_exp/resolv.h
new file mode 100644
index 0000000000000000000000000000000000000000..66d965731b0aa085df97727b43f7fb897cb5d71b
--- /dev/null
+++ b/Usermode/Libraries/libresolv.so_src/include_exp/resolv.h
@@ -0,0 +1,20 @@
+/*
+ */
+#ifndef _LIBRESOLV__RESOLV_H_
+#define _LIBRESOLV__RESOLV_H_
+
+extern int res_init(void);
+
+extern int res_query(const char *dname, int class, int type, unsigned char *answer, int anslen);
+
+extern int res_search(const char *dname, int class, int type, unsigned char *answer, int anslen);
+
+extern int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *answer, int anslen);
+
+extern int res_mkquery(int op, const char *dname, int class, int type, char *data, int datalen, struct rrec *newrr, char *buf, int buflen);
+
+extern int res_send(const char *msg, int msglen, char *answer, int anslen);
+
+
+#endif
+
diff --git a/Usermode/Libraries/libresolv.so_src/resolv.c b/Usermode/Libraries/libresolv.so_src/resolv.c
new file mode 100644
index 0000000000000000000000000000000000000000..e8d121bea636a13f34c4bbdc38eef4abff18c137
--- /dev/null
+++ b/Usermode/Libraries/libresolv.so_src/resolv.c
@@ -0,0 +1,33 @@
+/*
+ */
+
+int res_init(void)
+{
+	return 1;
+}
+
+int res_query(const char *dname, int class, int type, unsigned char *answer, int anslen)
+{
+	return 1;
+}
+
+int res_search(const char *dname, int class, int type, unsigned char *answer, int anslen)
+{
+	return 1;
+}
+
+int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *answer, int anslen)
+{
+	return 1;
+}
+
+int res_mkquery(int op, const char *dname, int class, int type, char *data, int datalen, struct rrec *newrr, char *buf, int buflen)
+{
+	return 1;
+}
+
+int res_send(const char *msg, int msglen, char *answer, int anslen)
+{
+	return 1;
+}
+