diff --git a/BuildConf/armv7/tegra2.mk b/BuildConf/armv7/tegra2.mk
index ad787821311a745484180efa54508b6913864a13..ece6ccf57aafd8a7364dab69ffe32d89b2e1e3a9 100644
--- a/BuildConf/armv7/tegra2.mk
+++ b/BuildConf/armv7/tegra2.mk
@@ -1,4 +1,4 @@
 
 include $(ACESSDIR)/BuildConf/armv7/default.mk
 
-#MODULES += Display/Tegra2
+MODULES += Display/Tegra2
diff --git a/Kernel/Makefile b/Kernel/Makefile
index 9c65db88f3c89812768a16335539969fb725355c..48a2c9f44ede30a2154be30dc527bc8aafcb1dbd 100644
--- a/Kernel/Makefile
+++ b/Kernel/Makefile
@@ -23,7 +23,7 @@ endif
 
 ASFLAGS         += -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
 CPPFLAGS	+= -I./include -I./arch/$(ARCHDIR)/include -D_MODULE_NAME_=\"Kernel\"
-CPPFLAGS	+= -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
+CPPFLAGS	+= -D ARCH=$(ARCH) -D ARCHDIR=$(ARCHDIR) -D PLATFORM=\"$(PLATFORM)\" -D ARCHDIR_IS_$(ARCHDIR)=1 -D PLATFORM_is_$(PLATFORM)=1
 CPPFLAGS	+= -D KERNEL_VERSION=$(KERNEL_VERSION)
 CFLAGS  	+= -Wall -fno-stack-protector -Wstrict-prototypes -g
 CFLAGS  	+= -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wuninitialized
diff --git a/Kernel/arch/x86/desctab.asm b/Kernel/arch/x86/desctab.asm
index 0c19fc0a013a740bb5326ca25334b4b9f3682f6c..8c7d320eba90201412fb483ab031b82a5741816e 100644
--- a/Kernel/arch/x86/desctab.asm
+++ b/Kernel/arch/x86/desctab.asm
@@ -3,30 +3,8 @@
 ; desctab.asm
 [BITS 32]
 
-%if USE_MP
-MAX_CPUS	equ	8
-%else
-MAX_CPUS	equ	1
-%endif
-GDT_SIZE	equ	(1+2*2+1+MAX_CPUS)*8
 
 [section .data]
-; GDT
-[global gGDT]
-gGDT:
-	; PL0 - Kernel
-	; PL3 - User
-	dd 0x00000000, 0x00000000	; 00 NULL Entry
-	dd 0x0000FFFF, 0x00CF9A00	; 08 PL0 Code
-	dd 0x0000FFFF, 0x00CF9200	; 10 PL0 Data
-	dd 0x0000FFFF, 0x00CFFA00	; 18 PL3 Code
-	dd 0x0000FFFF, 0x00CFF200	; 20 PL3 Data
-	dd 26*4-1, 0x00408900	; 28 Double Fault TSS
-	times MAX_CPUS	dd 26*4-1, 0x00408900	; 30+ TSSes
-[global gGDTPtr]
-gGDTPtr:
-	dw	GDT_SIZE-1
-	dd	gGDT
 ; IDT
 ALIGN 8
 [global gIDT]
@@ -42,17 +20,6 @@ gIDTPtr:
 
 [global Desctab_Install]
 Desctab_Install:
-	; Set GDT
-	lgdt [gGDTPtr]
-	mov ax, 0x10	; PL0 Data
-	mov ss, ax
-	mov ds, ax
-	mov es, ax
-	mov gs, ax
-	mov fs, ax
-	jmp 0x08:.pl0code
-.pl0code:
-
 	; Set up IDT
 	; Helper Macros
 	; - Set an IDT entry to an ISR
diff --git a/Kernel/arch/x86/kpanic.c b/Kernel/arch/x86/kpanic.c
index 6a7b9b0fac943877d52db6e1650ba72785d8e390..9300c69ef20e36932526cadfb41a7957eba36a59 100644
--- a/Kernel/arch/x86/kpanic.c
+++ b/Kernel/arch/x86/kpanic.c
@@ -105,7 +105,7 @@ void KernelPanic_SetMode(void)
 	for( i = 0; i < giNumCPUs; i ++ )
 	{
 		if(i == GetCPUNum())	continue ;
-		FB[i] = BGC|'A'+i;
+		FB[i] = BGC|('A'+i);
 		MP_SendIPIVector(i, 0xED);
 	}
 	#endif
diff --git a/Kernel/arch/x86/lib.c b/Kernel/arch/x86/lib.c
index 3858eff3eee7ccf75abfcc235e2a338c48221f50..ecc575c1ad240b3c57693025ad1c73437d076430 100644
--- a/Kernel/arch/x86/lib.c
+++ b/Kernel/arch/x86/lib.c
@@ -22,6 +22,7 @@ extern struct sShortSpinlock	glThreadListLock;
 extern int	GetCPUNum(void);
 
 // === PROTOTYPES ==
+Uint64	__divmod64(Uint64 Num, Uint64 Den, Uint64 *Rem);
 Uint64	__udivdi3(Uint64 Num, Uint64 Den);
 Uint64	__umoddi3(Uint64 Num, Uint64 Den);
 
@@ -330,9 +331,12 @@ void *memcpyd(void *Dest, const void *Src, size_t Num)
 	return Dest;
 }
 
+#include "../helpers.h"
+
+DEF_DIVMOD(64);
+
 Uint64 DivMod64U(Uint64 Num, Uint64 Div, Uint64 *Rem)
 {
-	Uint64	ret;
 	if( Div < 0x100000000ULL && Num < 0xFFFFFFFF * Div ) {
 		Uint32	rem, ret_32;
 		__asm__ __volatile__(
@@ -344,9 +348,7 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Div, Uint64 *Rem)
 		return ret_32;
 	}
 
-	ret = __udivdi3(Num, Div);
-	if(Rem)	*Rem = __umoddi3(Num, Div);
-	return ret;
+	return __divmod64(Num, Div, Rem);
 }
 
 /**
@@ -355,11 +357,10 @@ Uint64 DivMod64U(Uint64 Num, Uint64 Div, Uint64 *Rem)
  */
 Uint64 __udivdi3(Uint64 Num, Uint64 Den)
 {
-	Uint64	P[2];
-	Uint64	q = 0;
-	 int	i;
-	
-	if(Den == 0)	__asm__ __volatile__ ("int $0x0");
+	if(Den == 0) {
+		__asm__ __volatile__ ("int $0x0");
+		return -1;
+	}
 	// Common speedups
 	if(Num <= 0xFFFFFFFF && Den <= 0xFFFFFFFF)
 		return (Uint32)Num / (Uint32)Den;
@@ -375,46 +376,8 @@ Uint64 __udivdi3(Uint64 Num, Uint64 Den)
 	if(Num < Den)	return 0;
 	if(Num < Den*2)	return 1;
 	if(Num == Den*2)	return 2;
-	
-	#if 1
-	i = 0;	// Shut up
-	P[0] = Num;
-	P[1] = Den;
-	__asm__ __volatile__ (
-		"fildq %2\n\t"	// Num
-		"fildq %1\n\t"	// Den
-		"fdivp\n\t"
-		"fistpq %0"
-		: "=m" (q)
-		: "m" (P[0]), "m" (P[1])
-		);
-		
-	//Log("%llx / %llx = %llx\n", Num, Den, q);
-	#else
-	// Restoring division, from wikipedia
-	// http://en.wikipedia.org/wiki/Division_(digital)
-	P[0] = Num;	P[1] = 0;
-	for( i = 64; i--; )
-	{
-		// P <<= 1;
-		P[1] = (P[1] << 1) | (P[0] >> 63);
-		P[0] = P[0] << 1;
-		
-		// P -= Den << 64
-		P[1] -= Den;
-		
-		// P >= 0
-		if( !(P[1] & (1ULL<<63)) ) {
-			q |= (Uint64)1 << (63-i);
-		}
-		else {
-			//q |= 0 << (63-i);
-			P[1] += Den;
-		}
-	}
-	#endif
-	
-	return q;
+
+	return __divmod64(Num, Den, NULL);
 }
 
 /**
@@ -423,7 +386,11 @@ Uint64 __udivdi3(Uint64 Num, Uint64 Den)
  */
 Uint64 __umoddi3(Uint64 Num, Uint64 Den)
 {
-	if(Den == 0)	__asm__ __volatile__ ("int $0x0");	// Call Div by Zero Error
+	Uint64	ret = 0;
+	if(Den == 0) {
+		__asm__ __volatile__ ("int $0x0");	// Call Div by Zero Error
+		return -1;
+	}
 	if(Den == 1)	return 0;	// Speed Hacks
 	if(Den == 2)	return Num & 1;	// Speed Hacks
 	if(Den == 4)	return Num & 3;	// Speed Hacks
@@ -437,7 +404,8 @@ Uint64 __umoddi3(Uint64 Num, Uint64 Den)
 	if(Num >> 32 == 0 && Den >> 32 == 0)
 		return (Uint32)Num % (Uint32)Den;
 	
-	return Num - __udivdi3(Num, Den) * Den;
+	__divmod64(Num, Den, &ret);
+	return ret;
 }
 
 
diff --git a/Kernel/arch/x86/main.c b/Kernel/arch/x86/main.c
index d7c06e7952122e8dd3ec991cff5813262b742fb6..2106b6afe2b47e2ef960c1ed1e43701e4cded5ac 100644
--- a/Kernel/arch/x86/main.c
+++ b/Kernel/arch/x86/main.c
@@ -45,7 +45,7 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
 	tMBoot_Module	*mods;
 	tMBoot_Info	*mbInfo;
 
-	LogF("Acess2 x86 v"EXPAND_STR(KERNEL_VERSION)"\n");
+	LogF("Acess2 x86-"PLATFORM" v"EXPAND_STR(KERNEL_VERSION)"\n");
 	LogF(" Build %i, Git Hash %s\n", BUILD_NUM, gsGitHash);
 	
 	Log("MbMagic = %08x, MbInfoPtr = %p", MbMagic, MbInfoPtr);
@@ -81,7 +81,6 @@ int kmain(Uint MbMagic, void *MbInfoPtr)
 	MM_InstallVirtual();	// Clean up virtual address space
 	Heap_Install();		// Create initial heap
 	
-	//Log_Log("Arch", "Starting Multitasking...");
 	// Start Multitasking
 	Threads_Init();
 	
diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c
index 73e19d3bbe835e9e4a7b843e0b9b8e2e43234015..137240c9cf214c84778ee7f00c9240f62f1a5d13 100644
--- a/Kernel/arch/x86/mm_virt.c
+++ b/Kernel/arch/x86/mm_virt.c
@@ -212,14 +212,15 @@ void MM_PageFault(tVAddr Addr, Uint ErrorCode, tRegs *Regs)
 			);
 	}
 	
-	Log("Code at %p accessed %p", Regs->eip, Addr);
+	Log("CPU %i - Code at %p accessed %p", GetCPUNum(), Regs->eip, Addr);
 	// Print Stack Backtrace
 	Error_Backtrace(Regs->eip, Regs->ebp);
-	
+
+	#if 0	
 	Log("gaPageDir[0x%x] = 0x%x", Addr>>22, gaPageDir[Addr>>22]);
 	if( gaPageDir[Addr>>22] & PF_PRESENT )
 		Log("gaPageTable[0x%x] = 0x%x", Addr>>12, gaPageTable[Addr>>12]);
-	
+	#endif
 	//MM_DumpTables(0, -1);	
 	
 	// Register Dump
diff --git a/Kernel/arch/x86/proc.asm b/Kernel/arch/x86/proc.asm
index 74a25d46b18618c93a903a5d67c913d85fcef8b7..014cfed1cac482bce97c168e1c976cf7211cdf3f 100644
--- a/Kernel/arch/x86/proc.asm
+++ b/Kernel/arch/x86/proc.asm
@@ -55,11 +55,14 @@ SwitchTasks:
 	
 	; Old IP
 	mov eax, [esp+0x20+16]
+	test eax, eax
+	jz .nosave
 	mov DWORD [eax], .restore
 	; Old SP
 	mov eax, [esp+0x20+8]
 	mov [eax], esp
 
+.nosave:
 	mov ecx, [esp+0x20+12]	; New IP
 	mov eax, [esp+0x20+20]	; New CR3
 	mov esp, [esp+0x20+ 4]	; New SP
@@ -376,4 +379,4 @@ User_Syscall_Exit:
 	mov ebx, [esp+4]
 	int 0xAC
 
-; vim: ft=nasm, ts=8
+; vim: ft=nasm ts=8
diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c
index 1cd11067256f2af745f32076d9d7a3704854b5c8..7d54d0c2ea1004121fe48b859f88d5a3bc6e53dd 100644
--- a/Kernel/arch/x86/proc.c
+++ b/Kernel/arch/x86/proc.c
@@ -14,9 +14,9 @@
 #include <hal_proc.h>
 
 // === FLAGS ===
-#define DEBUG_TRACE_SWITCH	1
+#define DEBUG_TRACE_SWITCH	0
 #define DEBUG_DISABLE_DOUBLEFAULT	1
-#define DEBUG_VERY_SLOW_SWITCH	0
+#define DEBUG_VERY_SLOW_PERIOD	0
 
 // === CONSTANTS ===
 // Base is 1193182
@@ -165,6 +165,7 @@ void ArchThreads_Init(void)
 	{
 		 int	i;
 	 	tMPTable_Ent	*ents;
+		#if DUMP_MP_TABLE
 		Log("gMPFloatPtr = %p", gMPFloatPtr);
 		Log("*gMPFloatPtr = {");
 		Log("\t.Sig = 0x%08x", gMPFloatPtr->Sig);
@@ -178,8 +179,10 @@ void ArchThreads_Init(void)
 			gMPFloatPtr->Features[4]
 			);
 		Log("}");
-		
+		#endif		
+
 		mptable = (void*)( KERNEL_BASE|gMPFloatPtr->MPConfig );
+		#if DUMP_MP_TABLE
 		Log("mptable = %p", mptable);
 		Log("*mptable = {");
 		Log("\t.Sig = 0x%08x", mptable->Sig);
@@ -195,6 +198,7 @@ void ArchThreads_Init(void)
 		Log("\t.ExtendedTableLen = 0x%04x", mptable->ExtendedTableLen);
 		Log("\t.ExtendedTableChecksum = 0x%02x", mptable->ExtendedTableChecksum);
 		Log("}");
+		#endif
 		
 		gpMP_LocalAPIC = (void*)MM_MapHWPages(mptable->LocalAPICMemMap, 1);
 		
@@ -208,13 +212,14 @@ void ArchThreads_Init(void)
 			{
 			case 0:	// Processor
 				entSize = 20;
+				#if DUMP_MP_TABLE
 				Log("%i: Processor", i);
 				Log("\t.APICID = %i", ents->Proc.APICID);
 				Log("\t.APICVer = 0x%02x", ents->Proc.APICVer);
 				Log("\t.CPUFlags = 0x%02x", ents->Proc.CPUFlags);
 				Log("\t.CPUSignature = 0x%08x", ents->Proc.CPUSignature);
 				Log("\t.FeatureFlags = 0x%08x", ents->Proc.FeatureFlags);
-				
+				#endif
 				
 				if( !(ents->Proc.CPUFlags & 1) ) {
 					Log("DISABLED");
@@ -240,7 +245,7 @@ void ArchThreads_Init(void)
 				
 				break;
 			
-			#if DUMP_MP_TABLES
+			#if DUMP_MP_TABLE >= 2
 			case 1:	// Bus
 				entSize = 8;
 				Log("%i: Bus", i);
@@ -942,11 +947,22 @@ void Proc_Reschedule(void)
 		Proc_DisableSSE();
 	}
 
-	SwitchTasks(
-		nextthread->SavedState.ESP, &curthread->SavedState.ESP,
-		nextthread->SavedState.EIP, &curthread->SavedState.EIP,
-		nextthread->MemState.CR3
-		);
+	if( curthread )
+	{
+		SwitchTasks(
+			nextthread->SavedState.ESP, &curthread->SavedState.ESP,
+			nextthread->SavedState.EIP, &curthread->SavedState.EIP,
+			nextthread->MemState.CR3
+			);
+	}
+	else
+	{
+		SwitchTasks(
+			nextthread->SavedState.ESP, 0,
+			nextthread->SavedState.EIP, 0,
+			nextthread->MemState.CR3
+			);
+	}
 
 	return ;
 }
diff --git a/Kernel/arch/x86/start.asm b/Kernel/arch/x86/start.asm
index 68bdc55d74979fbb3e445452cd82efc50ea1c7b3..b6026de6b936ccbe97ba75dd6d8c53066b83ba91 100644
--- a/Kernel/arch/x86/start.asm
+++ b/Kernel/arch/x86/start.asm
@@ -68,17 +68,23 @@ start:
 	; Start Paging
 	mov ecx, gaInitPageDir - KERNEL_BASE
 	mov cr3, ecx
-	
 	mov ecx, cr0
 	or ecx, 0x80010000	; PG and WP
 	mov cr0, ecx
 	
 	mov WORD [0xB8002], 0x0763	; 'c'
-	mov WORD [0xB8004], 0x0765	; 'e'
 	
-	lea ecx, [.higherHalf]
-	jmp ecx
-.higherHalf:
+	; Set GDT
+	lgdt [gGDTPtr]
+	mov cx, 0x10	; PL0 Data
+	mov ss, cx
+	mov ds, cx
+	mov es, cx
+	mov gs, cx
+	mov fs, cx
+	mov WORD [0xB8004], 0x0765	; 'e'
+	jmp 0x08:.higher_half
+.higher_half:
 	
 	mov WORD [0xB8006], 0x0773	; 's'
 	mov WORD [0xB8008], 0x0773	; 's'
@@ -99,8 +105,6 @@ start:
 ; Multiprocessing AP Startup Code (Must be within 0 - 0x10FFF0)
 ;
 %if USE_MP
-[extern gGDT]
-[extern gGDTPtr]
 [extern gIDTPtr]
 [extern gpMP_LocalAPIC]
 [extern giMP_TimerCount]
@@ -108,6 +112,7 @@ start:
 [extern gaCPUs]
 [extern giNumInitingCPUs]
 [extern MM_NewKStack]
+[extern Proc_InitialiseSSE]
 
 lGDTPtr:	; Local GDT Pointer
 	dw	3*8-1
@@ -195,6 +200,9 @@ APStartup:
 	mov DWORD [ebp+0x360], 0x000100D2	; ##Enable LINT1 on IVT#0xD2
 	mov DWORD [ebp+0x370], 0x000100E1	; ##Enable Error on IVT#0xE1
 	mov DWORD [ebp+0x0B0], 0	; Send an EOI (just in case)
+
+	; Initialise SSE support
+	call Proc_InitialiseSSE
 	
 	; CPU is now marked as initialised
 
@@ -230,6 +238,25 @@ CallWithArgArray:
 	pop ebp
 	ret
 
+[section .data]
+; GDT
+GDT_SIZE	equ	(1+2*2+1+MAX_CPUS)*8
+[global gGDT]
+gGDT:
+	; PL0 - Kernel
+	; PL3 - User
+	dd 0x00000000, 0x00000000	; 00 NULL Entry
+	dd 0x0000FFFF, 0x00CF9A00	; 08 PL0 Code
+	dd 0x0000FFFF, 0x00CF9200	; 10 PL0 Data
+	dd 0x0000FFFF, 0x00CFFA00	; 18 PL3 Code
+	dd 0x0000FFFF, 0x00CFF200	; 20 PL3 Data
+	dd 26*4-1, 0x00408900	; 28 Double Fault TSS
+	times MAX_CPUS	dd 26*4-1, 0x00408900	; 30+ TSSes
+[global gGDTPtr]
+gGDTPtr:
+	dw	GDT_SIZE-1
+	dd	gGDT
+
 [section .initpd]
 [global gaInitPageDir]
 [global gaInitPageTable]
diff --git a/Kernel/arch/x86/vm8086.c b/Kernel/arch/x86/vm8086.c
index 879cec64dfe966e8dbcd134522b19227ea39f1b9..839a640bef450c06f85f439440a54b31a93f9c96 100644
--- a/Kernel/arch/x86/vm8086.c
+++ b/Kernel/arch/x86/vm8086.c
@@ -59,12 +59,15 @@ Uint32	gaVM8086_MemBitmap[VM8086_BLOCKCOUNT/32];
 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);
 	if(pid == -1)
 	{
 		Log_Error("VM8086", "Unable to clone kernel into VM8086 worker");
@@ -75,17 +78,16 @@ int VM8086_Install(char **Arguments)
 		Uint	* volatile stacksetup;	// Initialising Stack
 		Uint16	* volatile rmstack;	// Real Mode Stack
 		 int	i;
-		
+
+		Log_Debug("VM8086", "Initialising worker");	
+	
 		// Set Image Name
 		Threads_SetName("VM8086");
 
-//		Log_Debug("VM8086", "Mapping memory");	
-	
 		// Map ROM Area
 		for(i=0xA0;i<0x100;i++) {
 			MM_Map( i * 0x1000, i * 0x1000 );
 		}
-//		Log_Debug("VM8086", "ROM area mapped");
 		MM_Map( 0, 0 );	// IVT / BDA
 		// Map (but allow allocation) of 0x1000 - 0x9F000
 		// - So much hack, it isn't funny
@@ -102,7 +104,6 @@ int VM8086_Install(char **Arguments)
 			gVM8086_WorkerPID = 0;
 			Threads_Exit(0, 1);
 		}
-//		Log_Debug("VM8086", "Mapped low memory");
 		
 		*(Uint8*)(0x100000) = VM8086_OP_IRET;
 		*(Uint8*)(0x100001) = 0x07;	// POP ES
@@ -148,9 +149,10 @@ int VM8086_Install(char **Arguments)
 	}
 	
 	gVM8086_WorkerPID = pid;
-//	Log_Log("VM8086", "gVM8086_WorkerPID = %i", pid);
-	while( gpVM8086_State != NULL )
-		Threads_Yield();	// Yield to allow the child to initialise
+
+	// It's released when the GPF fires
+	Mutex_Acquire( &glVM8086_Process );
+	Mutex_Release( &glVM8086_Process );
 	
 	// Worker killed itself
 	if( gVM8086_WorkerPID != pid ) {
@@ -164,7 +166,7 @@ void VM8086_GPF(tRegs *Regs)
 {
 	Uint8	opcode;
 	
-	//Log_Log("VM8086", "GPF - %04x:%04x", Regs->cs, Regs->eip);
+//	Log_Log("VM8086", "GPF - %04x:%04x", Regs->cs, Regs->eip);
 	
 	if(Regs->eip == VM8086_MAGIC_IP && Regs->cs == VM8086_MAGIC_CS
 	&& Threads_GetPID() == gVM8086_WorkerPID)
@@ -174,8 +176,8 @@ void VM8086_GPF(tRegs *Regs)
 			gpVM8086_State = NULL;
 			Mutex_Release( &glVM8086_Process );	// Release lock obtained in VM8086_Install
 		}
-		//Log_Log("VM8086", "gpVM8086_State = %p, gVM8086_CallingThread = %i",
-		//	gpVM8086_State, gVM8086_CallingThread);
+//		Log_Log("VM8086", "gpVM8086_State = %p, gVM8086_CallingThread = %i",
+//			gpVM8086_State, gVM8086_CallingThread);
 		if( gpVM8086_State ) {
 			gpVM8086_State->AX = Regs->eax;	gpVM8086_State->CX = Regs->ecx;
 			gpVM8086_State->DX = Regs->edx;	gpVM8086_State->BX = Regs->ebx;
@@ -192,12 +194,12 @@ void VM8086_GPF(tRegs *Regs)
 		Semaphore_Wait(&gVM8086_TasksToDo, 1);
 		
 		//Log_Log("VM8086", "We have a task (%p)", gpVM8086_State);
-		Regs->esp -= 2;	*(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_CS;
-		Regs->esp -= 2;	*(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_IP;
-		Regs->esp -= 2;	*(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->CS;
-		Regs->esp -= 2;	*(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->IP;
-		Regs->esp -= 2;	*(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->DS;
-		Regs->esp -= 2;	*(Uint16*volatile)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->ES;
+		Regs->esp -= 2;	*(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_CS;
+		Regs->esp -= 2;	*(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = VM8086_MAGIC_IP;
+		Regs->esp -= 2;	*(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->CS;
+		Regs->esp -= 2;	*(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->IP;
+		Regs->esp -= 2;	*(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->DS;
+		Regs->esp -= 2;	*(Uint16*)( (Regs->ss<<4) + (Regs->esp&0xFFFF) ) = gpVM8086_State->ES;
 		
 		// Set Registers
 		Regs->eip = 0x11;	Regs->cs = 0xFFFF;
@@ -222,8 +224,9 @@ void VM8086_GPF(tRegs *Regs)
 		#endif
 		break;
 	case VM8086_OP_POPF:	//POPF
-		Regs->eflags &= 0xFFFF0002;
-		Regs->eflags |= *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) & 0xFFFD;	// Changing IF is not allowed
+		// Changing IF is not allowed
+		Regs->eflags &= 0xFFFF0202;
+		Regs->eflags |= *(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) );
 		Regs->esp += 2;
 		#if TRACE_EMU
 		Log_Debug("VM8086", "Emulated POPF");
@@ -236,8 +239,8 @@ void VM8086_GPF(tRegs *Regs)
 		id = *(Uint8*)( Regs->cs*16 +(Regs->eip&0xFFFF));
 		Regs->eip ++;
 		
-		Regs->esp -= 2;	*(Uint16*volatile)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->cs;
-		Regs->esp -= 2;	*(Uint16*volatile)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eip;
+		Regs->esp -= 2;	*(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->cs;
+		Regs->esp -= 2;	*(Uint16*)( Regs->ss*16 + (Regs->esp&0xFFFF) ) = Regs->eip;
 		
 		Regs->cs = *(Uint16*)(4*id + 2);
 		Regs->eip = *(Uint16*)(4*id);
diff --git a/Kernel/debug.c b/Kernel/debug.c
index 25ffda1912e37d09958953308b8490d674d316d1..355624d5c483769fafc237442a7ad64aaff4767f 100644
--- a/Kernel/debug.c
+++ b/Kernel/debug.c
@@ -9,7 +9,7 @@
 
 #define	DEBUG_MAX_LINE_LEN	256
 
-#define	LOCK_DEBUG_OUTPUT	0
+#define	LOCK_DEBUG_OUTPUT	1
 
 #define TRACE_TO_KTERM	0
 
diff --git a/Kernel/heap.c b/Kernel/heap.c
index 5593c68f70f91b14fa61e6eb6f434818e8ebb09c..921cc6b95d58893392b67a31df711baa3ac7a576 100644
--- a/Kernel/heap.c
+++ b/Kernel/heap.c
@@ -700,6 +700,7 @@ void Heap_Stats(void)
 	
 	// Scan and get distribution
 	#if 1
+	if(nBlocks > 0)
 	{
 		struct {
 			Uint	Size;
diff --git a/Kernel/lib.c b/Kernel/lib.c
index 953264b79eb6e2664a006ad4b7986955076685b7..76cc4286268fa0a84f4d2cae83656226fc1ccb91 100644
--- a/Kernel/lib.c
+++ b/Kernel/lib.c
@@ -210,8 +210,10 @@ int vsnprintf(char *__s, size_t __maxlen, const char *__format, va_list args)
 	size_t	pos = 0;
 	// Flags
 	 int	bPadLeft = 0;
+	
+	auto void _putch(char ch);
 
-	inline void _putch(char ch)
+	void _putch(char ch)
 	{
 		if(pos < __maxlen)
 		{
diff --git a/Modules/Display/Tegra2/Makefile b/Modules/Display/Tegra2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3155db3ce4149d5add29549eff5eb516f1cbbd92
--- /dev/null
+++ b/Modules/Display/Tegra2/Makefile
@@ -0,0 +1,7 @@
+#
+#
+
+OBJ = main.o
+NAME = Tegra2
+
+-include ../Makefile.tpl
diff --git a/Modules/Display/Tegra2/main.c b/Modules/Display/Tegra2/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..dfafb2a2d40b2314814a7b4193fd8ea648d19811
--- /dev/null
+++ b/Modules/Display/Tegra2/main.c
@@ -0,0 +1,281 @@
+/**
+ * main.c
+ * - Driver core
+ */
+#define DEBUG	0
+#define VERSION	((0<<8)|10)
+#include <acess.h>
+#include <errno.h>
+#include <modules.h>
+#include <vfs.h>
+#include <fs_devfs.h>
+#include <drv_pci.h>
+#include <api_drv_video.h>
+#include <lib/keyvalue.h>
+#include <options.h>	// ARM Arch
+#include "tegra2.h"
+
+#define ABS(a)	((a)>0?(a):-(a))
+
+// === PROTOTYPES ===
+// Driver
+ int	Tegra2Vid_Install(char **Arguments);
+void	Tegra2Vid_Uninstall();
+// Internal
+// Filesystem
+Uint64	Tegra2Vid_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);
+Uint64	Tegra2Vid_Write(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer);
+ int	Tegra2Vid_IOCtl(tVFS_Node *node, int id, void *data);
+// -- Internals
+ int	Tegra2Vid_int_SetMode(int Mode);
+
+// === GLOBALS ===
+MODULE_DEFINE(0, VERSION, Video_Tegra2, Tegra2Vid_Install, NULL, NULL);
+tDevFS_Driver	gTegra2Vid_DriverStruct = {
+	NULL, "PL110",
+	{
+	.Read = Tegra2Vid_Read,
+	.Write = Tegra2Vid_Write,
+	.IOCtl = Tegra2Vid_IOCtl
+	}
+};
+// -- Options
+tPAddr	gTegra2Vid_PhysBase = TEGRA2VID_BASE;
+ int	gbTegra2Vid_IsVersatile = 1;
+// -- KeyVal parse rules
+const tKeyVal_ParseRules	gTegra2Vid_KeyValueParser = {
+	NULL,
+	{
+		{"Base", "P", &gTegra2Vid_PhysBase},
+		{NULL, NULL, NULL}
+	}
+};
+// -- Driver state
+ int	giTegra2Vid_CurrentMode = 0;
+ int	giTegra2Vid_BufferMode;
+size_t	giTegra2Vid_FramebufferSize;
+Uint8	*gpTegra2Vid_IOMem;
+tPAddr	gTegra2Vid_FramebufferPhys;
+void	*gpTegra2Vid_Framebuffer;
+// -- Misc
+tDrvUtil_Video_BufInfo	gTegra2Vid_DrvUtil_BufInfo;
+tVideo_IOCtl_Pos	gTegra2Vid_CursorPos;
+
+// === CODE ===
+/**
+ */
+int Tegra2Vid_Install(char **Arguments)
+{
+//	KeyVal_Parse(&gTegra2Vid_KeyValueParser, Arguments);
+	
+	gpTegra2Vid_IOMem = (void*)MM_MapHWPages(gTegra2Vid_PhysBase, 256/4);
+
+	Tegra2Vid_int_SetMode(4);
+
+	DevFS_AddDevice( &gTegra2Vid_DriverStruct );
+
+	return 0;
+}
+
+/**
+ * \brief Clean up resources for driver unloading
+ */
+void Tegra2Vid_Uninstall()
+{
+}
+
+/**
+ * \brief Read from the framebuffer
+ */
+Uint64 Tegra2Vid_Read(tVFS_Node *node, Uint64 off, Uint64 len, void *buffer)
+{
+	return 0;
+}
+
+/**
+ * \brief Write to the framebuffer
+ */
+Uint64 Tegra2Vid_Write(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+{
+	gTegra2Vid_DrvUtil_BufInfo.BufferFormat = giTegra2Vid_BufferMode;
+	return DrvUtil_Video_WriteLFB(&gTegra2Vid_DrvUtil_BufInfo, Offset, Length, Buffer);
+}
+
+const char *csaTegra2Vid_IOCtls[] = {DRV_IOCTLNAMES, DRV_VIDEO_IOCTLNAMES, NULL};
+
+/**
+ * \brief Handle messages to the device
+ */
+int Tegra2Vid_IOCtl(tVFS_Node *Node, int ID, void *Data)
+{
+	 int	ret = -2;
+	ENTER("pNode iID pData", Node, ID, Data);
+	
+	switch(ID)
+	{
+	BASE_IOCTLS(DRV_TYPE_VIDEO, "PL110", VERSION, csaTegra2Vid_IOCtls);
+
+	case VIDEO_IOCTL_SETBUFFORMAT:
+		DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
+		ret = giTegra2Vid_BufferMode;
+		if(Data)	giTegra2Vid_BufferMode = *(int*)Data;
+		if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)
+			DrvUtil_Video_SetCursor( &gTegra2Vid_DrvUtil_BufInfo, &gDrvUtil_TextModeCursor );
+		break;
+	
+	case VIDEO_IOCTL_GETSETMODE:
+		if(Data)
+		{
+			 int	newMode;
+			
+			if( !CheckMem(Data, sizeof(int)) )
+				LEAVE_RET('i', -1);
+			
+			newMode = *(int*)Data;
+			
+			if(newMode < 0 || newMode >= ciTegra2Vid_ModeCount)
+				LEAVE_RET('i', -1);
+
+			if(newMode != giTegra2Vid_CurrentMode)
+			{
+				giTegra2Vid_CurrentMode = newMode;
+				Tegra2Vid_int_SetMode( newMode );
+			}
+		}
+		ret = giTegra2Vid_CurrentMode;
+		break;
+	
+	case VIDEO_IOCTL_FINDMODE:
+		{
+		tVideo_IOCtl_Mode *mode = Data;
+		 int	closest, closestArea, reqArea = 0;
+		if(!Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Mode)))
+			LEAVE_RET('i', -1);
+		if( mode->bpp != 32 )
+			LEAVE_RET('i', 0);
+		if( mode->flags	!= 0 )
+			LEAVE_RET('i', 0);
+
+		ret = 0;
+
+		for( int i = 0; i < ciTegra2Vid_ModeCount; i ++ )
+		{
+			 int	area;
+			if(mode->width == caTegra2Vid_Modes[i].W && mode->height == caTegra2Vid_Modes[i].H) {
+				mode->id = i;
+				ret = 1;
+				break;
+			}
+			
+			area = caTegra2Vid_Modes[i].W * caTegra2Vid_Modes[i].H;
+			if(!reqArea) {
+				reqArea = mode->width * mode->height;
+				closest = i;
+				closestArea = area;
+			}
+			else if( ABS(area - reqArea) < ABS(closestArea - reqArea) ) {
+				closest = i;
+				closestArea = area;
+			}
+		}
+		
+		if( ret == 0 )
+		{
+			mode->id = closest;
+			ret = 1;
+		}
+		mode->width = caTegra2Vid_Modes[mode->id].W;
+		mode->height = caTegra2Vid_Modes[mode->id].H;
+		break;
+		}
+	
+	case VIDEO_IOCTL_MODEINFO:
+		{
+		tVideo_IOCtl_Mode *mode = Data;
+		if(!Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Mode)))
+			LEAVE_RET('i', -1);
+		if(mode->id < 0 || mode->id >= ciTegra2Vid_ModeCount)
+			LEAVE_RET('i', 0);
+		
+
+		mode->bpp = 32;
+		mode->flags = 0;
+		mode->width = caTegra2Vid_Modes[mode->id].W;
+		mode->height = caTegra2Vid_Modes[mode->id].H;
+
+		ret = 1;
+		break;
+		}
+	
+	case VIDEO_IOCTL_SETCURSOR:
+		if( !Data || !CheckMem(Data, sizeof(tVideo_IOCtl_Pos)) )
+			LEAVE_RET('i', -1);
+
+		DrvUtil_Video_RemoveCursor( &gTegra2Vid_DrvUtil_BufInfo );
+		
+		gTegra2Vid_CursorPos = *(tVideo_IOCtl_Pos*)Data;
+		if(gTegra2Vid_DrvUtil_BufInfo.BufferFormat == VIDEO_BUFFMT_TEXT)
+			DrvUtil_Video_DrawCursor(
+				&gTegra2Vid_DrvUtil_BufInfo,
+				gTegra2Vid_CursorPos.x*giVT_CharWidth,
+				gTegra2Vid_CursorPos.y*giVT_CharHeight
+				);
+		else
+			DrvUtil_Video_DrawCursor(
+				&gTegra2Vid_DrvUtil_BufInfo,
+				gTegra2Vid_CursorPos.x,
+				gTegra2Vid_CursorPos.y
+				);
+		break;
+	
+	default:
+		LEAVE('i', -2);
+		return -2;
+	}
+	
+	LEAVE('i', ret);
+	return ret;
+}
+
+//
+//
+//
+
+int Tegra2Vid_int_SetMode(int Mode)
+{
+	const struct sTegra2_Disp_Mode	*mode = &caTegra2Vid_Modes[Mode];
+	 int	w = mode->W, h = mode->H;	// Horizontal/Vertical Active
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_FRONT_PORCH_0) = (mode->VFP << 16) | mode->HFP; 
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_SYNC_WIDTH_0)  = (mode->HS << 16)  | mode->HS;
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_BACK_PORCH_0)  = (mode->VBP << 16) | mode->HBP;
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_DISP_DISP_ACTIVE_0) = (mode->H << 16)   | mode->W;
+
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_POSITION_0) = 0;
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_SIZE_0) = (mode->H << 16) | mode->W;
+	*(Uint8*)(gpTegra2Vid_IOMem + DC_WIN_A_COLOR_DEPTH_0) = 12;	// Could be 13 (BGR/RGB)
+	*(Uint32*)(gpTegra2Vid_IOMem + DC_WIN_A_PRESCALED_SIZE_0) = (mode->H << 16) | mode->W;
+
+	if( !gpTegra2Vid_Framebuffer || w*h*4 != giTegra2Vid_FramebufferSize )
+	{
+		if( gpTegra2Vid_Framebuffer )
+		{
+			// TODO: Free framebuffer for reallocation
+		}
+
+		giTegra2Vid_FramebufferSize = w*h*4;		
+
+		gpTegra2Vid_Framebuffer = (void*)MM_AllocDMA(
+			(giTegra2Vid_FramebufferSize + PAGE_SIZE-1) / PAGE_SIZE,
+			32,
+			&gTegra2Vid_FramebufferPhys
+			);
+		// TODO: Catch allocation failures
+		
+		// Tell hardware
+		*(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_START_ADDR_0) = gTegra2Vid_FramebufferPhys;
+		*(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_V_OFFSET_0) = 0;	// Y offset
+		*(Uint32*)(gpTegra2Vid_IOMem + DC_WINBUF_A_ADDR_H_OFFSET_0) = 0;	// X offset
+	}
+
+	return 0;
+}
diff --git a/Modules/Display/Tegra2/tegra2.h b/Modules/Display/Tegra2/tegra2.h
new file mode 100644
index 0000000000000000000000000000000000000000..b05ca8c135d1d551165e23ad96e58170a8c8cc00
--- /dev/null
+++ b/Modules/Display/Tegra2/tegra2.h
@@ -0,0 +1,73 @@
+/*
+ * Acess2 NVidia Tegra2 Display Driver
+ * - By John Hodge (thePowersGang)
+ *
+ * tegra2.h
+ * - Driver definitions
+ */
+#ifndef _TEGRA2_DISP_H_
+#define _TEGRA2_DISP_H_
+
+#define TEGRA2VID_BASE	0x54200000	// 0x40000 Large (256 KB)
+
+const struct sTegra2_Disp_Mode
+{
+	Uint16	W,   H;
+	Uint16	HFP, VFP;
+	Uint16	HS,  VS;
+	Uint16	HBP, VBP;
+}	caTegra2Vid_Modes[] = {
+	// TODO: VESA timings
+	{720,  487,  16,33,   63, 33,   59, 133},	// NTSC 2
+	{720,  576,  12,33,   63, 33,   69, 193},	// PAL 2 (VFP shown as 2/33, used 33)
+	{720,  483,  16, 6,   63,  6,   59,  30},	// 480p
+	{1280, 720,  70, 5,  804,  6,  220,  20},	// 720p
+	{1920,1080,  44, 4,  884,  5,  148,  36},	// 1080p
+	// TODO: Can all but HA/VA be constant and those select the resolution?
+};
+const int ciTegra2Vid_ModeCount = sizeof(caTegra2Vid_Modes)/sizeof(caTegra2Vid_Modes[0]);
+
+enum eTegra2_Disp_Regs
+{
+	DC_DISP_DISP_SIGNAL_OPTIONS0_0 = 0x400,
+	DC_DISP_DISP_SIGNAL_OPTIONS1_0,
+	DC_DISP_DISP_WIN_OPTIONS_0,
+	DC_DISP_MEM_HIGH_PRIORITY_0,
+	DC_DISP_MEM_HIGH_PRIORITY_TIMER_0,
+	DC_DISP_DISP_TIMING_OPTIONS_0,
+	DC_DISP_REF_TO_SYNC_0,
+	DC_DISP_SYNC_WIDTH_0,
+	DC_DISP_BACK_PORCH_0,
+	DC_DISP_DISP_ACTIVE_0,
+	DC_DISP_FRONT_PORCH_0,
+
+	DC_DISP_H_PULSE0_CONTROL_0,
+	
+	DC_WINC_A_COLOR_PALETTE_0 = 0x500,
+	DC_WINC_A_PALETTE_COLOR_EXT_0 = 0x600,
+	DC_WIN_A_WIN_OPTIONS_0 = 0x700,
+	DC_WIN_A_BYTE_SWAP_0,
+	DC_WIN_A_BUFFER_CONTROL_0,
+	DC_WIN_A_COLOR_DEPTH_0,
+	DC_WIN_A_POSITION_0,
+	DC_WIN_A_SIZE_0,
+	DC_WIN_A_PRESCALED_SIZE_0,
+	DC_WIN_A_H_INITIAL_DDA_0,
+	DC_WIN_A_V_INITIAL_DDA_0,
+	DC_WIN_A_DDA_INCREMENT_0,
+	DC_WIN_A_LINE_STRIDE_0,
+	DC_WIN_A_BUF_STRIDE_0,
+	DC_WIN_A_BUFFER_ADDR_MODE_0,
+	DC_WIN_A_DV_CONTROL_0,
+	DC_WIN_A_BLEND_NOKEY_0,
+	
+	DC_WINBUF_A_START_ADDR_0 = 0x800,
+	DC_WINBUF_A_START_ADDR_NS_0,
+	DC_WINBUF_A_ADDR_H_OFFSET_0,
+	DC_WINBUF_A_ADDR_H_OFFSET_NS_0,
+	DC_WINBUF_A_ADDR_V_OFFSET_0,
+	DC_WINBUF_A_ADDR_V_OFFSET_NS_0,
+};
+
+#endif
+
diff --git a/Modules/Display/VESA/main.c b/Modules/Display/VESA/main.c
index 6f056f33fb752107b1c92fc005db6e295300c3ba..55083b043a808ed16f07775536beb6f6ffc12143 100644
--- a/Modules/Display/VESA/main.c
+++ b/Modules/Display/VESA/main.c
@@ -51,6 +51,7 @@ tVM8086	*gpVesa_BiosState;
 tVesa_Mode	*gVesa_Modes;
 tVesa_Mode	*gpVesaCurMode;
  int	giVesaModeCount = 0;
+ int	gbVesaModesChecked;
 // --- Framebuffer ---
 char	*gpVesa_Framebuffer = (void*)VESA_DEFAULT_FRAMEBUFFER;
  int	giVesaPageCount = 0;	//!< Framebuffer size in pages
@@ -67,15 +68,12 @@ int Vesa_Install(char **Arguments)
 {
 	tVesa_CallInfo	*info;
 	tFarPtr	infoPtr;
-	tVesa_CallModeInfo	*modeinfo;
-	tFarPtr	modeinfoPtr;
 	Uint16	*modes;
 	int	i;
 	
 	// Allocate Info Block
 	gpVesa_BiosState = VM8086_Init();
 	info = VM8086_Allocate(gpVesa_BiosState, 512, &infoPtr.seg, &infoPtr.ofs);
-	modeinfo = VM8086_Allocate(gpVesa_BiosState, 512, &modeinfoPtr.seg, &modeinfoPtr.ofs);
 	// Set Requested Version
 	memcpy(info->signature, "VBE2", 4);
 	// Set Registers
@@ -109,36 +107,9 @@ int Vesa_Install(char **Arguments)
 	for( i = 1; i < giVesaModeCount; i++ )
 	{
 		gVesa_Modes[i].code = modes[i];
-		// Get Mode info
-		gpVesa_BiosState->AX = 0x4F01;
-		gpVesa_BiosState->CX = gVesa_Modes[i].code;
-		gpVesa_BiosState->ES = modeinfoPtr.seg;
-		gpVesa_BiosState->DI = modeinfoPtr.ofs;
-		VM8086_Int(gpVesa_BiosState, 0x10);
-		
-		// Parse Info
-		gVesa_Modes[i].flags = 0;
-		if ( (modeinfo->attributes & 0x90) == 0x90 )
-		{
-			gVesa_Modes[i].flags |= FLAG_LFB;
-			gVesa_Modes[i].framebuffer = modeinfo->physbase;
-			gVesa_Modes[i].fbSize = modeinfo->Yres*modeinfo->pitch;
-		} else {
-			gVesa_Modes[i].framebuffer = 0;
-			gVesa_Modes[i].fbSize = 0;
-		}
-		
-		gVesa_Modes[i].pitch = modeinfo->pitch;
-		gVesa_Modes[i].width = modeinfo->Xres;
-		gVesa_Modes[i].height = modeinfo->Yres;
-		gVesa_Modes[i].bpp = modeinfo->bpp;
-		
-		#if DEBUG
-		Log_Log("VESA", "0x%x - %ix%ix%i",
-			gVesa_Modes[i].code, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);
-		#endif
 	}
-	
+
+//	VM8086_Deallocate( info );
 	
 	// Install Device
 	giVesaDriverId = DevFS_AddDevice( &gVesa_DriverStruct );
@@ -147,6 +118,53 @@ int Vesa_Install(char **Arguments)
 	return MODULE_ERR_OK;
 }
 
+void Vesa_int_FillModeList(void)
+{
+	if( !gbVesaModesChecked )
+	{
+		 int	i;
+		tVesa_CallModeInfo	*modeinfo;
+		tFarPtr	modeinfoPtr;
+		
+		modeinfo = VM8086_Allocate(gpVesa_BiosState, 512, &modeinfoPtr.seg, &modeinfoPtr.ofs);
+		for( i = 1; i < giVesaModeCount; i ++ )
+		{
+			// Get Mode info
+			gpVesa_BiosState->AX = 0x4F01;
+			gpVesa_BiosState->CX = gVesa_Modes[i].code;
+			gpVesa_BiosState->ES = modeinfoPtr.seg;
+			gpVesa_BiosState->DI = modeinfoPtr.ofs;
+			VM8086_Int(gpVesa_BiosState, 0x10);
+			
+			// Parse Info
+			gVesa_Modes[i].flags = 0;
+			if ( (modeinfo->attributes & 0x90) == 0x90 )
+			{
+				gVesa_Modes[i].flags |= FLAG_LFB;
+				gVesa_Modes[i].framebuffer = modeinfo->physbase;
+				gVesa_Modes[i].fbSize = modeinfo->Yres*modeinfo->pitch;
+			} else {
+				gVesa_Modes[i].framebuffer = 0;
+				gVesa_Modes[i].fbSize = 0;
+			}
+			
+			gVesa_Modes[i].pitch = modeinfo->pitch;
+			gVesa_Modes[i].width = modeinfo->Xres;
+			gVesa_Modes[i].height = modeinfo->Yres;
+			gVesa_Modes[i].bpp = modeinfo->bpp;
+			
+			#if DEBUG
+			Log_Log("VESA", "0x%x - %ix%ix%i",
+				gVesa_Modes[i].code, gVesa_Modes[i].width, gVesa_Modes[i].height, gVesa_Modes[i].bpp);
+			#endif
+		}
+	
+//		VM8086_Deallocate( modeinfo );
+		
+		gbVesaModesChecked = 1;
+	}
+}
+
 /* Read from the framebuffer
  */
 Uint64 Vesa_Read(tVFS_Node *Node, Uint64 off, Uint64 len, void *buffer)
@@ -225,6 +243,8 @@ int Vesa_Int_SetMode(int mode)
 	// Check for fast return
 	if(mode == giVesaCurrentMode)	return 1;
 	
+	Vesa_int_FillModeList();
+
 	Time_RemoveTimer(giVesaCursorTimer);
 	giVesaCursorTimer = -1;
 	
@@ -274,6 +294,8 @@ int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)
 	 int	factor, tmp;
 	
 	ENTER("idata->width idata->height idata->bpp", data->width, data->height, data->bpp);
+
+	Vesa_int_FillModeList();
 	
 	for(i=0;i<giVesaModeCount;i++)
 	{
@@ -329,6 +351,9 @@ int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)
 int Vesa_Int_ModeInfo(tVideo_IOCtl_Mode *data)
 {
 	if(data->id < 0 || data->id > giVesaModeCount)	return -1;
+
+	Vesa_int_FillModeList();
+
 	data->width = gVesa_Modes[data->id].width;
 	data->height = gVesa_Modes[data->id].height;
 	data->bpp = gVesa_Modes[data->id].bpp;
diff --git a/Modules/USB/Core/usb_io.c b/Modules/USB/Core/usb_io.c
index cd8fbcd3b91a9c916a54785237a866ff06b6dabe..25ff59d260dcb3f8d19cb20de1c79341c62d3145 100644
--- a/Modules/USB/Core/usb_io.c
+++ b/Modules/USB/Core/usb_io.c
@@ -103,6 +103,7 @@ void USB_AsyncCallback(void *Ptr, void *Buf, int Length)
 
 void USB_AsyncThread(void *Unused)
 {
+	Threads_SetName("USB Async IO Thread");
 	for(;;)
 	{
 		tAsyncOp *op = Workqueue_GetWork(&gUSB_AsyncQueue);
diff --git a/Modules/USB/Core/usb_poll.c b/Modules/USB/Core/usb_poll.c
index ec03036f16ca6a8164edfac8d7f1564dfa9f56e5..b6927fed2bb31afda01f28afcf932347cef552aa 100644
--- a/Modules/USB/Core/usb_poll.c
+++ b/Modules/USB/Core/usb_poll.c
@@ -70,6 +70,8 @@ int USB_PollThread(void *unused)
 			}
 		}
 
+//		Log_Debug("USBPoll", "giUSB_PollPosition = %i", giUSB_PollPosition);
+
 		// A little evil for neater code
 		prev = (void*)( (tVAddr)&gUSB_PollQueues[giUSB_PollPosition] - offsetof(tUSBEndpoint, Next) );