diff --git a/Kernel/arch/x86_64/desctab.asm b/Kernel/arch/x86_64/desctab.asm
index 7ad93eb7d14bb0293b08cfedd7f236806f814ca7..8212773b5b81468a9dbe35614ab9ac5bc9371b1f 100644
--- a/Kernel/arch/x86_64/desctab.asm
+++ b/Kernel/arch/x86_64/desctab.asm
@@ -154,6 +154,7 @@ IRQ_AddHandler:
 	; RDI - IRQ Number
 	; RSI - Callback
 	
+	; Check for RDI >= 16
 	cmp rdi, 16
 	jb .numOK
 	xor rax, rax
@@ -161,10 +162,10 @@ IRQ_AddHandler:
 	jmp .ret
 .numOK:
 
-	mov rax, rdi
-	shr rax, 3+2
+	; Get handler base into RAX
+	lea rax, [rdi*4]
 	mov rcx, gaIRQ_Handlers
-	add rax, rcx
+	lea rax, [rcx+rax*8]
 	
 	; Find a free callback slot
 	%rep NUM_IRQ_CALLBACKS
@@ -196,6 +197,7 @@ IRQ_AddHandler:
 	pop rsi
 	pop rdi
 
+	; Assign and return
 	mov [rax], rsi
 	xor rax, rax
 
@@ -292,12 +294,14 @@ IrqCommon:
 	push gs
 	push fs
 	
-	mov rbx, [rsp+(16+2)*8]	; Calculate address
-	shr rbx, 3+2	; *8*4
+	mov rbx, [rsp+(16+2)*8]	; Get interrupt number (16 GPRS + 2 SRs)
+;	xchg bx, bx	; Bochs Magic break (NOTE: will clear the high-bits of RBX)
+	shl rbx, 2	; *8*4
 	mov rax, gaIRQ_Handlers
-	add rbx, rax
+	lea rbx, [rax+rbx*8]
 	
 	; Check all callbacks
+	sub rsp, 8	; Shadow of argument
 	%assign i 0
 	%rep NUM_IRQ_CALLBACKS
 	; Get callback address
@@ -305,17 +309,18 @@ IrqCommon:
 	test rax, rax	; Check if it exists
 	jz .skip.%[i]
 	; Set RDI to IRQ number
-	mov rdi, [rsp+16*8]	; Get IRQ number
+	mov rdi, [rsp+(16+2+1)*8]	; Get IRQ number
 	call rax	; Call
 .skip.%[i]:
 	add rbx, 8	; Next!
 	%assign i i+1
 	%endrep
+	add rsp, 8
 	
 	; ACK
+	mov al, 0x20
 	mov rdi, [rsp+16*8]	; Get IRQ number
 	cmp rdi, 8
-	mov al, 0x20
 	jb .skipAckSecondary
 	mov dx, 0x00A0
 	out dx, al
diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c
index f2abb289e206a23e3c491c847a8ad4d8aee3c35c..8691100c6a16659217a0b7cdeaef83cf6e80f4de 100644
--- a/Kernel/arch/x86_64/proc.c
+++ b/Kernel/arch/x86_64/proc.c
@@ -12,14 +12,13 @@
 #if USE_MP
 # include <mp.h>
 #endif
+#include <arch_config.h>
 
 // === FLAGS ===
 #define DEBUG_TRACE_SWITCH	0
 
 // === CONSTANTS ===
 #define	SWITCH_MAGIC	0x55ECAFFF##FFFACE55	// There is no code in this area
-// Base is 1193182
-#define TIMER_DIVISOR	11931	//~100Hz
 
 // === TYPES ===
 typedef struct sCPU
@@ -46,6 +45,7 @@ extern tThread	gThreadZero;
 extern void	Threads_Dump(void);
 extern void	Proc_ReturnToUser(void);
 extern int	GetCPUNum(void);
+extern void	Time_UpdateTimestamp(void);
 
 // === PROTOTYPES ===
 void	ArchThreads_Init(void);
@@ -304,8 +304,8 @@ void ArchThreads_Init(void)
 	
 	// Set timer frequency
 	outb(0x43, 0x34);	// Set Channel 0, Low/High, Rate Generator
-	outb(0x40, TIMER_DIVISOR&0xFF);	// Low Byte of Divisor
-	outb(0x40, (TIMER_DIVISOR>>8)&0xFF);	// High Byte
+	outb(0x40, PIT_TIMER_DIVISOR&0xFF);	// Low Byte of Divisor
+	outb(0x40, (PIT_TIMER_DIVISOR>>8)&0xFF);	// High Byte
 	
 	// Create Per-Process Data Block
 	if( !MM_Allocate(MM_PPD_CFG) )
@@ -541,6 +541,7 @@ int Proc_Clone(Uint *Err, Uint Flags)
 	rip = GetRIP();
 	if(rip == SWITCH_MAGIC) {
 		outb(0x20, 0x20);	// ACK Timer and return as child
+		__asm__ __volatile__ ("sti");
 		return 0;
 	}
 	
@@ -589,6 +590,7 @@ int Proc_SpawnWorker(void)
 	rip = GetRIP();
 	if(rip == SWITCH_MAGIC) {
 		outb(0x20, 0x20);	// ACK Timer and return as child
+		__asm__ __volatile__ ("sti");
 		return 0;
 	}
 	
@@ -753,6 +755,9 @@ void Proc_Scheduler(int CPU)
 {
 	Uint	rsp, rbp, rip;
 	tThread	*thread;
+
+	if( CPU == 0 )
+		Time_UpdateTimestamp();
 	
 	// If the spinlock is set, let it complete
 	if(IS_LOCKED(&glThreadListLock))	return;
diff --git a/Kernel/arch/x86_64/time.c b/Kernel/arch/x86_64/time.c
index 6153db23e127e5c51e684f02105c15eb0066917e..03c889fecc4faf6c4b207c78db0663c1d1d393c3 100644
--- a/Kernel/arch/x86_64/time.c
+++ b/Kernel/arch/x86_64/time.c
@@ -4,18 +4,13 @@
  * arch/x86_64/time.c
  */
 #include <acess.h>
+#include <arch_config.h>
 
 // === MACROS ===
 #define	TIMER_QUANTUM	100
-// 2^(15-rate), 15: 1HZ, 5: 1024Hz, 2: 8192Hz
-// (Max: 15, Min: 2) - 15 = 1Hz, 13 = 4Hz, 12 = 8Hz, 11 = 16Hz 10 = 32Hz, 2 = 8192Hz
-//#define TIMER_RATE	10	// 32 Hz
-//#define TIMER_RATE	12	// 8 Hz
-#define TIMER_RATE	14	// 2Hz
-//#define TIMER_RATE	15	// 1HZ
-#define TIMER_FREQ	(0x8000>>TIMER_RATE)	//Hz
-#define MS_PER_TICK_WHOLE	(1000/(TIMER_FREQ))
-#define MS_PER_TICK_FRACT	((0x80000000*(1000%TIMER_FREQ))/TIMER_FREQ)
+#define TIMER_FREQ	PIT_TIMER_BASE_N/(PIT_TIMER_BASE_D*PIT_TIMER_DIVISOR)
+#define MS_PER_TICK_WHOLE	(1000*(PIT_TIMER_BASE_D*PIT_TIMER_DIVISOR)/PIT_TIMER_BASE_N)
+#define MS_PER_TICK_FRACT	((0x80000000ULL*1000ULL*PIT_TIMER_BASE_D*PIT_TIMER_DIVISOR/PIT_TIMER_BASE_N)&0x7FFFFFFF)
 
 // === IMPORTS ===
 extern volatile Sint64	giTimestamp;
@@ -30,7 +25,7 @@ volatile Uint64	giTime_TSCPerTick = 0;
 // === PROTOTYPES ===
 //Sint64	now(void);
  int	Time_Setup(void);
-void	Time_Interrupt(int);
+void	Time_UpdateTimestamp(void);
 Uint64	Time_ReadTSC(void);
 
 // === CODE ===
@@ -57,48 +52,19 @@ Sint64 now(void)
  */
 int Time_Setup(void)
 {
-	Uint8	val;
-	
-	Log_Log("Timer", "RTC Timer firing at %iHz (%i divisor), %i.0x%08x",
-		TIMER_FREQ, TIMER_RATE, MS_PER_TICK_WHOLE, MS_PER_TICK_FRACT);
-	
-	outb(0x70, inb(0x70)&0x7F);	// Disable NMIs
-	__asm__ __volatile__ ("cli");	// Disable normal interrupts
-	
-	// Set IRQ8 firing rate
-	outb(0x70, 0x0A);	// Set the index to register A
-	val = inb(0x71); // Get the current value of register A
-	outb(0x70, 0x0A); // Reset index to A
-	val &= 0xF0;
-	val |= TIMER_RATE;
-	outb(0x71, val);	// Update the timer rate
-		
-	// Enable IRQ8
-	outb(0x70, 0x0B);	// Set the index to register B
-	val = inb(0x71);	// Read the current value of register B
-	outb(0x70, 0x0B);	// Set the index again (a read will reset the index to register D)
-	outb(0x71, val | 0x40);	// Write the previous value or'd with 0x40. This turns on bit 6 of register D
-	
-	__asm__ __volatile__ ("sti");	// Re-enable normal interrupts
-	outb(0x70, inb(0x70)|0x80);	// Re-enable NMIs
-	
-	// Install IRQ Handler
-	IRQ_AddHandler(8, Time_Interrupt);
-	
-	// Make sure the RTC actually fires
-	outb(0x70, 0x0C); // Select register C
-	inb(0x71);	// Just throw away contents.
+	Log_Log("Timer", "PIT Timer firing at %iHz, %i.0x%08x miliseconds per tick",
+		TIMER_FREQ, MS_PER_TICK_WHOLE, MS_PER_TICK_FRACT);
+
+	// TODO: Read time from RTC
 	
 	return 0;
 }
 
 /**
  * \brief Called on the timekeeping IRQ
- * \param irq	IRQ number (unused)
  */
-void Time_Interrupt(int irq)
+void Time_UpdateTimestamp(void)
 {
-	//Log("RTC Tick");
 	Uint64	curTSC = Time_ReadTSC();
 	
 	if( giTime_TSCAtLastTick )
@@ -116,10 +82,6 @@ void Time_Interrupt(int irq)
 	}
 	
 	Timer_CallTimers();
-
-	// Make sure the RTC Fires again
-	outb(0x70, 0x0C); // Select register C
-	inb(0x71);	// Just throw away contents.
 }
 
 #if 0
diff --git a/Kernel/debug.c b/Kernel/debug.c
index 3e5ac0a9682a83320206e2037ea2b21634a67a6f..76ed7cfbcda0f00ec399df3a865d9cece6a3cd3f 100644
--- a/Kernel/debug.c
+++ b/Kernel/debug.c
@@ -12,7 +12,7 @@
 #define	LOCK_DEBUG_OUTPUT	1
 
 // === IMPORTS ===
-extern void Threads_Dump(void);
+extern void	Threads_Dump(void);
 extern void	KernelPanic_SetMode(void);
 extern void	KernelPanic_PutChar(char Ch);
 
diff --git a/Kernel/time.c b/Kernel/time.c
index 1180cad979fabc0d7133382ed0a51751e13a5ab1..3d06b0e733143c1d1c0570d62e9accc129227a0b 100644
--- a/Kernel/time.c
+++ b/Kernel/time.c
@@ -84,9 +84,9 @@ void Time_RemoveTimer(int ID)
  */
 void Time_Delay(int Delay)
 {
-	Sint64	dest = giTimestamp + Delay;
+	Sint64	dest = now() + Delay;
 	//Log("Time_Delay: dest = %lli", dest);
-	while(dest > giTimestamp)	Threads_Yield();
+	while(dest > now())	Threads_Yield();
 	//Log("Time_Delay: giTimestamp = %lli", giTimestamp);
 }
 
diff --git a/Modules/Storage/ATA/io.c b/Modules/Storage/ATA/io.c
index 368c310bf7d6bfad9eef35434599b94cb2bc2634..de6bf96b48dee67a1600b9528e46310526f3fb4f 100644
--- a/Modules/Storage/ATA/io.c
+++ b/Modules/Storage/ATA/io.c
@@ -353,7 +353,8 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer)
 	
 	// HACK: Ensure the PRDT is reset
 	ATA_int_BusMasterWriteDWord(cont*8+4, gaATA_PRDT_PAddrs[cont]);
-		
+	ATA_int_BusMasterWriteByte(cont*8, 4);	// Reset IRQ
+	
 	LOG("gATA_PRDTs[%i].Bytes = %i", cont, gATA_PRDTs[cont].Bytes);
 	if( Address > 0x0FFFFFFF )
 		outb(base+0x07, HDD_DMA_R48);	// Read Command (LBA48)
diff --git a/Modules/Storage/FDD/fdd.c b/Modules/Storage/FDD/fdd.c
index f83a0063a15ead83fcb0c12f72f5dd028830bc82..801f2eb7d0b12da1c00f3457e5432cf5595d94f3 100644
--- a/Modules/Storage/FDD/fdd.c
+++ b/Modules/Storage/FDD/fdd.c
@@ -114,6 +114,7 @@ void	FDD_SensInt(int base, Uint8 *sr0, Uint8 *cyl);
  int	FDD_int_GetByte(int base, Uint8 *Byte);
  int	FDD_Reset(int id);
 void	FDD_Recalibrate(int disk);
+ int	FDD_Reconfigure(int ID);
  int	FDD_int_SeekTrack(int disk, int head, int track);
 void	FDD_int_TimerCallback(void *Arg);
 void	FDD_int_StopMotor(void *Arg);
@@ -172,6 +173,21 @@ int FDD_Install(char **Arguments)
 	
 	// Install IRQ6 Handler
 	IRQ_AddHandler(6, FDD_IRQHandler);
+
+	// Ensure the FDD version is 0x90
+	{
+		Uint8	tmp;
+		FDD_int_SendByte(cPORTBASE[0], CMD_VERSION);
+		FDD_int_GetByte(cPORTBASE[0], &tmp);
+		if( tmp != 0x90 ) {
+			Log_Error("FDD", "Version(0x%2x) != 0x90", tmp);
+			return MODULE_ERR_NOTNEEDED;
+		}
+	}
+
+	// Configure
+	FDD_Reconfigure(0);
+
 	// Reset Primary FDD Controller
 	if( FDD_Reset(0) != 0 ) {
 		return MODULE_ERR_MISC;
@@ -591,7 +607,8 @@ int FDD_int_SeekTrack(int disk, int head, int track)
 	
 	// Set Track in structure
 	gFDD_Devices[disk].track[head] = track;
-	
+
+	LOG("Time_Delay(100)");	
 	// Wait for Head to settle
 	Time_Delay(100);
 	
@@ -793,38 +810,42 @@ int FDD_Reset(int id)
 	outb(base + PORT_DIGOUTPUT, 0);	// Disable FDC
 	// Wait 4 microseconds - or use 1 thread delay
 	Threads_Yield();
-	outb(base + PORT_DIGOUTPUT, 0x0C);	// Re-enable FDC (DMA and Enable)
+	Threads_Yield();
+	outb(base + PORT_DIGOUTPUT, 8|4);	// Re-enable FDC (DMA and Enable)
 	
+	// Set the data rate
+	outb(base + PORT_DATARATE, 0);	// Set data rate to 500K/s
+
+	// Wait for IRQ
 	LOG("Awaiting IRQ");
 	
 	FDD_WaitIRQ();
+	LOG("4x SenseInterrupt");
 	FDD_SensInt(base, NULL, NULL);
 	FDD_SensInt(base, NULL, NULL);
 	FDD_SensInt(base, NULL, NULL);
 	FDD_SensInt(base, NULL, NULL);
 	
-	// Set the data rate
-	outb(base + PORT_DATARATE, 0);	// Set data rate to 500K/s
-
-	// Configure
+	// Specify
 	FDD_int_SendByte(base, CMD_SPECIFY);	// Step and Head Load Times
 	FDD_int_SendByte(base, 0xDF);	// Step Rate Time, Head Unload Time (Nibble each)
 	FDD_int_SendByte(base, 0x02);	// Head Load Time >> 1
 
+	// Recalibrate disks
+	LOG("Recalibrate disks (16x seek)");
 	retries = 16;
 	while(FDD_int_SeekTrack(0, 0, 1) == 0 && retries --);	// set track
-	if(retries < 0)	return -1;
+	if(retries < 0)	LEAVE_RET('i', -1);
 
 	retries = 16;
-	while(FDD_int_SeekTrack(0, 1, 1) == 0);	// set track
-	if(retries < 0)	return -1;
+	while(FDD_int_SeekTrack(0, 1, 1) == 0 && retries --);	// set track
+	if(retries < 0)	LEAVE_RET('i', -1);
 	
 	LOG("Recalibrating Disk");
 	FDD_Recalibrate((id<<1)|0);
 	FDD_Recalibrate((id<<1)|1);
 
-	LEAVE('i',0);
-	return 0;
+	LEAVE_RET('i', 0);
 }
 
 /**
diff --git a/Modules/x86/VGAText/vga.c b/Modules/x86/VGAText/vga.c
index 9fa9fd21019f941614e5c8f762858e30616ad1b2..e926313002ec659039156fdcee35bb2a2bd28429 100644
--- a/Modules/x86/VGAText/vga.c
+++ b/Modules/x86/VGAText/vga.c
@@ -246,18 +246,20 @@ void VGA_2D_Fill(void *Ent, Uint16 X, Uint16 Y, Uint16 W, Uint16 H, Uint32 Colou
 	Y /= giVT_CharHeight;
 	H /= giVT_CharHeight;
 
-	if( X > VGA_WIDTH || Y > VGA_HEIGHT )	return ;
-	if( X + W > VGA_WIDTH )	W = VGA_WIDTH - X;
-	if( Y + H > VGA_HEIGHT )	H = VGA_HEIGHT - Y;
-
 	ch.Ch = 0x20;
 	ch.BGCol  = (Colour & 0x0F0000) >> (16-8);
 	ch.BGCol |= (Colour & 0x000F00) >> (8-4);
 	ch.BGCol |= (Colour & 0x00000F);
+	word = VGA_int_GetWord(&ch);
+
+	Log("Fill (%i,%i) %ix%i with 0x%x", X, Y, W, H, word);
+
+	if( X > VGA_WIDTH || Y > VGA_HEIGHT )	return ;
+	if( X + W > VGA_WIDTH )	W = VGA_WIDTH - X;
+	if( Y + H > VGA_HEIGHT )	H = VGA_HEIGHT - Y;
 
 	buf = gVGA_Framebuffer + Y*VGA_WIDTH + X;
 
-	word = VGA_int_GetWord(&ch);
 	
 	while( H -- ) {
 		 int	i;
@@ -281,6 +283,14 @@ void VGA_2D_Blit(void *Ent, Uint16 DstX, Uint16 DstY, Uint16 SrcX, Uint16 SrcY,
 
 //	Log("(%i,%i) from (%i,%i) %ix%i", DstX, DstY, SrcX, SrcY, W, H);
 
+	if( SrcX > VGA_WIDTH || SrcY > VGA_HEIGHT )	return ;
+	if( SrcX + W > VGA_WIDTH )	W = VGA_WIDTH - SrcX;
+	if( SrcY + H > VGA_HEIGHT )	H = VGA_HEIGHT - SrcY;
+	if( DstX > VGA_WIDTH || DstY > VGA_HEIGHT )	return ;
+	if( DstX + W > VGA_WIDTH )	W = VGA_WIDTH - DstX;
+	if( DstY + H > VGA_HEIGHT )	H = VGA_HEIGHT - DstY;
+
+
 	src = gVGA_Framebuffer + SrcY*VGA_WIDTH + SrcX;
 	dst = gVGA_Framebuffer + DstY*VGA_WIDTH + DstX;