diff --git a/Asuro.iso b/Asuro.iso
index 29b179df..6ac6356b 100644
Binary files a/Asuro.iso and b/Asuro.iso differ
diff --git a/bin/kernel.bin b/bin/kernel.bin
index dc8d7ecc..7a3dcc56 100755
Binary files a/bin/kernel.bin and b/bin/kernel.bin differ
diff --git a/compile.sh b/compile.sh
index 67911d9c..2d13d868 100755
--- a/compile.sh
+++ b/compile.sh
@@ -5,6 +5,10 @@ echo "======================="
 echo "== ASURO COMPILATION =="
 echo "======================="
 echo " "
+echo "Checking out latest VM Source..."
+echo " "
+./updatevm.sh
+echo " "
 echo "Compiling ASM Stub..."
 echo " "
 rm lib/*
diff --git a/iso/boot/asuro.bin b/iso/boot/asuro.bin
index dc8d7ecc..7a3dcc56 100755
Binary files a/iso/boot/asuro.bin and b/iso/boot/asuro.bin differ
diff --git a/lib/ACE.ppu b/lib/ACE.ppu
index b038e1d6..0c422133 100644
Binary files a/lib/ACE.ppu and b/lib/ACE.ppu differ
diff --git a/lib/BPE.ppu b/lib/BPE.ppu
index 944ea193..2a7d5f1e 100644
Binary files a/lib/BPE.ppu and b/lib/BPE.ppu differ
diff --git a/lib/BTSSE.ppu b/lib/BTSSE.ppu
index 0cb77a81..6e0f0900 100644
Binary files a/lib/BTSSE.ppu and b/lib/BTSSE.ppu differ
diff --git a/lib/CFE.ppu b/lib/CFE.ppu
index 1e0670bd..22ee2ce2 100644
Binary files a/lib/CFE.ppu and b/lib/CFE.ppu differ
diff --git a/lib/CSOE.ppu b/lib/CSOE.ppu
index e61e1beb..04f438d4 100644
Binary files a/lib/CSOE.ppu and b/lib/CSOE.ppu differ
diff --git a/lib/DBGE.ppu b/lib/DBGE.ppu
index e344e500..b0a100f2 100644
Binary files a/lib/DBGE.ppu and b/lib/DBGE.ppu differ
diff --git a/lib/DBZ.ppu b/lib/DBZ.ppu
index c0d53974..5c13322b 100644
Binary files a/lib/DBZ.ppu and b/lib/DBZ.ppu differ
diff --git a/lib/DFE.ppu b/lib/DFE.ppu
index de4061f4..a09bfd33 100644
Binary files a/lib/DFE.ppu and b/lib/DFE.ppu differ
diff --git a/lib/E1000.ppu b/lib/E1000.ppu
index 888562c0..368cb115 100644
Binary files a/lib/E1000.ppu and b/lib/E1000.ppu differ
diff --git a/lib/EHCI.ppu b/lib/EHCI.ppu
index 3050b1b4..7d3ed1e2 100644
Binary files a/lib/EHCI.ppu and b/lib/EHCI.ppu differ
diff --git a/lib/GPF.ppu b/lib/GPF.ppu
index cda5f150..1d020a94 100644
Binary files a/lib/GPF.ppu and b/lib/GPF.ppu differ
diff --git a/lib/IDE.ppu b/lib/IDE.ppu
index f804cdaf..0586cf75 100644
Binary files a/lib/IDE.ppu and b/lib/IDE.ppu differ
diff --git a/lib/IDOE.ppu b/lib/IDOE.ppu
index fbcd22ad..ea097f36 100644
Binary files a/lib/IDOE.ppu and b/lib/IDOE.ppu differ
diff --git a/lib/IOPE.ppu b/lib/IOPE.ppu
index f25f4f1e..c58dc75b 100644
Binary files a/lib/IOPE.ppu and b/lib/IOPE.ppu differ
diff --git a/lib/MCE.ppu b/lib/MCE.ppu
index 6a151f1e..111983f8 100644
Binary files a/lib/MCE.ppu and b/lib/MCE.ppu differ
diff --git a/lib/NCE.ppu b/lib/NCE.ppu
index 07d78d15..009e740a 100644
Binary files a/lib/NCE.ppu and b/lib/NCE.ppu differ
diff --git a/lib/NMIE.ppu b/lib/NMIE.ppu
index cf5101a3..7fa15e47 100644
Binary files a/lib/NMIE.ppu and b/lib/NMIE.ppu differ
diff --git a/lib/OHCI.ppu b/lib/OHCI.ppu
index bce9f75a..2e57c304 100644
Binary files a/lib/OHCI.ppu and b/lib/OHCI.ppu differ
diff --git a/lib/OOBE.ppu b/lib/OOBE.ppu
index bc30139b..1cf80873 100644
Binary files a/lib/OOBE.ppu and b/lib/OOBE.ppu differ
diff --git a/lib/PCI.ppu b/lib/PCI.ppu
index 61779621..92584185 100644
Binary files a/lib/PCI.ppu and b/lib/PCI.ppu differ
diff --git a/lib/PF.ppu b/lib/PF.ppu
index e241dd03..d699f846 100644
Binary files a/lib/PF.ppu and b/lib/PF.ppu differ
diff --git a/lib/PS2_KEYBOARD_ISR.ppu b/lib/PS2_KEYBOARD_ISR.ppu
index 7af4a014..d374dd53 100644
Binary files a/lib/PS2_KEYBOARD_ISR.ppu and b/lib/PS2_KEYBOARD_ISR.ppu differ
diff --git a/lib/RTC.ppu b/lib/RTC.ppu
index 717fc443..36fbe32a 100644
Binary files a/lib/RTC.ppu and b/lib/RTC.ppu differ
diff --git a/lib/SFE.ppu b/lib/SFE.ppu
index 5a25e037..111fa774 100644
Binary files a/lib/SFE.ppu and b/lib/SFE.ppu differ
diff --git a/lib/SNPE.ppu b/lib/SNPE.ppu
index 5b44d8a8..168046ff 100644
Binary files a/lib/SNPE.ppu and b/lib/SNPE.ppu differ
diff --git a/lib/TMR_0_ISR.ppu b/lib/TMR_0_ISR.ppu
index d7ec8ae1..a4dfbe90 100644
Binary files a/lib/TMR_0_ISR.ppu and b/lib/TMR_0_ISR.ppu differ
diff --git a/lib/UHCI.ppu b/lib/UHCI.ppu
index 23714b50..c49c19b3 100644
Binary files a/lib/UHCI.ppu and b/lib/UHCI.ppu differ
diff --git a/lib/UIE.ppu b/lib/UIE.ppu
index 692f639e..809a3cba 100644
Binary files a/lib/UIE.ppu and b/lib/UIE.ppu differ
diff --git a/lib/USB.ppu b/lib/USB.ppu
index 5caad8ff..b8316e57 100644
Binary files a/lib/USB.ppu and b/lib/USB.ppu differ
diff --git a/lib/XHCI.ppu b/lib/XHCI.ppu
index 897d5eb1..88be1722 100644
Binary files a/lib/XHCI.ppu and b/lib/XHCI.ppu differ
diff --git a/lib/arp.ppu b/lib/arp.ppu
index 735c1a08..78a5cd87 100644
Binary files a/lib/arp.ppu and b/lib/arp.ppu differ
diff --git a/lib/asuro.ppu b/lib/asuro.ppu
index 6d0c0205..1f2ab04f 100644
Binary files a/lib/asuro.ppu and b/lib/asuro.ppu differ
diff --git a/lib/bios_data_area.ppu b/lib/bios_data_area.ppu
index 6483926c..1f0ae174 100644
Binary files a/lib/bios_data_area.ppu and b/lib/bios_data_area.ppu differ
diff --git a/lib/console.o b/lib/console.o
index 6a86407f..611d4124 100644
Binary files a/lib/console.o and b/lib/console.o differ
diff --git a/lib/console.ppu b/lib/console.ppu
index dfe4656a..8b513940 100644
Binary files a/lib/console.ppu and b/lib/console.ppu differ
diff --git a/lib/cpu.ppu b/lib/cpu.ppu
index 44bd6d1e..903fb8e0 100644
Binary files a/lib/cpu.ppu and b/lib/cpu.ppu differ
diff --git a/lib/drivermanagement.ppu b/lib/drivermanagement.ppu
index 7ee21909..5c0b6457 100644
Binary files a/lib/drivermanagement.ppu and b/lib/drivermanagement.ppu differ
diff --git a/lib/eth2.ppu b/lib/eth2.ppu
index 51088ba6..333e5398 100644
Binary files a/lib/eth2.ppu and b/lib/eth2.ppu differ
diff --git a/lib/fat32.ppu b/lib/fat32.ppu
index c2aff9ba..ed423603 100644
Binary files a/lib/fat32.ppu and b/lib/fat32.ppu differ
diff --git a/lib/gdt.ppu b/lib/gdt.ppu
index b275a772..d7b740ae 100644
Binary files a/lib/gdt.ppu and b/lib/gdt.ppu differ
diff --git a/lib/icmp.ppu b/lib/icmp.ppu
new file mode 100644
index 00000000..81e0cc9e
Binary files /dev/null and b/lib/icmp.ppu differ
diff --git a/lib/idt.ppu b/lib/idt.ppu
index 5f865cbf..2a7a8f41 100644
Binary files a/lib/idt.ppu and b/lib/idt.ppu differ
diff --git a/lib/ipv4.ppu b/lib/ipv4.ppu
index e7debf7f..593bb802 100644
Binary files a/lib/ipv4.ppu and b/lib/ipv4.ppu differ
diff --git a/lib/irq.ppu b/lib/irq.ppu
index 8a0df563..f60136f2 100644
Binary files a/lib/irq.ppu and b/lib/irq.ppu differ
diff --git a/lib/isr.ppu b/lib/isr.ppu
index 1a62ff08..9d454c78 100644
Binary files a/lib/isr.ppu and b/lib/isr.ppu differ
diff --git a/lib/isrmanager.ppu b/lib/isrmanager.ppu
index f519a975..499b4829 100644
Binary files a/lib/isrmanager.ppu and b/lib/isrmanager.ppu differ
diff --git a/lib/kernel.ppu b/lib/kernel.ppu
index fce0c051..89e1ce57 100644
Binary files a/lib/kernel.ppu and b/lib/kernel.ppu differ
diff --git a/lib/keyboard.ppu b/lib/keyboard.ppu
index e261543e..870bfe46 100644
Binary files a/lib/keyboard.ppu and b/lib/keyboard.ppu differ
diff --git a/lib/libpconsole.a b/lib/libpconsole.a
index bc5f8294..094cc18b 100644
Binary files a/lib/libpconsole.a and b/lib/libpconsole.a differ
diff --git a/lib/libpmultiboot.a b/lib/libpmultiboot.a
index f50929f5..6d18368d 100644
Binary files a/lib/libpmultiboot.a and b/lib/libpmultiboot.a differ
diff --git a/lib/libpsystem.a b/lib/libpsystem.a
index 5bb4b056..48764804 100644
Binary files a/lib/libpsystem.a and b/lib/libpsystem.a differ
diff --git a/lib/lists.ppu b/lib/lists.ppu
index baba431b..621df644 100644
Binary files a/lib/lists.ppu and b/lib/lists.ppu differ
diff --git a/lib/lmemorymanager.ppu b/lib/lmemorymanager.ppu
index 21a401e4..3223d699 100644
Binary files a/lib/lmemorymanager.ppu and b/lib/lmemorymanager.ppu differ
diff --git a/lib/memview.ppu b/lib/memview.ppu
index 1a3d3637..26a1f39e 100644
Binary files a/lib/memview.ppu and b/lib/memview.ppu differ
diff --git a/lib/mouse.ppu b/lib/mouse.ppu
index 8ed11a8d..c91faa10 100644
Binary files a/lib/mouse.ppu and b/lib/mouse.ppu differ
diff --git a/lib/net.ppu b/lib/net.ppu
index f3471507..eb279554 100644
Binary files a/lib/net.ppu and b/lib/net.ppu differ
diff --git a/lib/netlog.ppu b/lib/netlog.ppu
index 320ef9e6..98983b02 100644
Binary files a/lib/netlog.ppu and b/lib/netlog.ppu differ
diff --git a/lib/netutils.ppu b/lib/netutils.ppu
index 16a1fd35..13b0d3ac 100644
Binary files a/lib/netutils.ppu and b/lib/netutils.ppu differ
diff --git a/lib/pmemorymanager.ppu b/lib/pmemorymanager.ppu
index 34326464..18af1702 100644
Binary files a/lib/pmemorymanager.ppu and b/lib/pmemorymanager.ppu differ
diff --git a/lib/scheduler.ppu b/lib/scheduler.ppu
index dbd20aca..5f3c3850 100644
Binary files a/lib/scheduler.ppu and b/lib/scheduler.ppu differ
diff --git a/lib/serial.ppu b/lib/serial.ppu
index 74daf61a..49660e32 100644
Binary files a/lib/serial.ppu and b/lib/serial.ppu differ
diff --git a/lib/shell.ppu b/lib/shell.ppu
index a3888b45..977c54d9 100644
Binary files a/lib/shell.ppu and b/lib/shell.ppu differ
diff --git a/lib/splash.ppu b/lib/splash.ppu
index 4c69bb5d..3349e30c 100644
Binary files a/lib/splash.ppu and b/lib/splash.ppu differ
diff --git a/lib/storagemanagement.ppu b/lib/storagemanagement.ppu
index 01234a00..0cd36286 100644
Binary files a/lib/storagemanagement.ppu and b/lib/storagemanagement.ppu differ
diff --git a/lib/strings.ppu b/lib/strings.ppu
index b2479cfa..67a16255 100644
Binary files a/lib/strings.ppu and b/lib/strings.ppu differ
diff --git a/lib/system.ppu b/lib/system.ppu
index a570d845..d602e62a 100644
Binary files a/lib/system.ppu and b/lib/system.ppu differ
diff --git a/lib/terminal.ppu b/lib/terminal.ppu
index 99bb49c5..6f71dfc7 100644
Binary files a/lib/terminal.ppu and b/lib/terminal.ppu differ
diff --git a/lib/testdriver.ppu b/lib/testdriver.ppu
index 52eb9177..38973aa3 100644
Binary files a/lib/testdriver.ppu and b/lib/testdriver.ppu differ
diff --git a/lib/themer.ppu b/lib/themer.ppu
index 10654440..f4072402 100644
Binary files a/lib/themer.ppu and b/lib/themer.ppu differ
diff --git a/lib/tracer.ppu b/lib/tracer.ppu
index 5167e8c2..93c32dde 100644
Binary files a/lib/tracer.ppu and b/lib/tracer.ppu differ
diff --git a/lib/tss.ppu b/lib/tss.ppu
index 548ed644..1df495b9 100644
Binary files a/lib/tss.ppu and b/lib/tss.ppu differ
diff --git a/lib/types.ppu b/lib/types.ppu
new file mode 100644
index 00000000..7426e123
Binary files /dev/null and b/lib/types.ppu differ
diff --git a/lib/util.ppu b/lib/util.ppu
index 043bc1ff..cd32b81c 100644
Binary files a/lib/util.ppu and b/lib/util.ppu differ
diff --git a/lib/vm.ppu b/lib/vm.ppu
new file mode 100644
index 00000000..03a97b89
Binary files /dev/null and b/lib/vm.ppu differ
diff --git a/lib/vm_instance.ppu b/lib/vm_instance.ppu
new file mode 100644
index 00000000..a718d60d
Binary files /dev/null and b/lib/vm_instance.ppu differ
diff --git a/lib/vm_scheduler.ppu b/lib/vm_scheduler.ppu
new file mode 100644
index 00000000..98a786f9
Binary files /dev/null and b/lib/vm_scheduler.ppu differ
diff --git a/lib/vmemorymanager.ppu b/lib/vmemorymanager.ppu
index eed426b3..6e720712 100644
Binary files a/lib/vmemorymanager.ppu and b/lib/vmemorymanager.ppu differ
diff --git a/lib/vmlog.ppu b/lib/vmlog.ppu
new file mode 100644
index 00000000..cb5b3970
Binary files /dev/null and b/lib/vmlog.ppu differ
diff --git a/src/console.pas b/src/console.pas
index f42daa9c..3203aa94 100644
--- a/src/console.pas
+++ b/src/console.pas
@@ -71,11 +71,6 @@ procedure writeintln(i: Integer);
 procedure writeintex(i: Integer; attributes: uint32);
 procedure writeintlnex(i: Integer; attributes: uint32);
 
-procedure writeword(i: DWORD);
-procedure writewordln(i: DWORD);
-procedure writewordex(i: DWORD; attributes: uint32);
-procedure writewordlnex(i: DWORD; attributes: uint32);
-
 procedure writehexpair(b : uint8);
 procedure writehex(i: DWORD);
 procedure writehexln(i: DWORD);
@@ -130,11 +125,6 @@ procedure writeintlnWND(i: Integer; WND : uint32);
 procedure writeintexWND(i: Integer; attributes: uint32; WND : uint32);
 procedure writeintlnexWND(i: Integer; attributes: uint32; WND : uint32);
 
-procedure writewordWND(i: DWORD; WND : uint32);
-procedure writewordlnWND(i: DWORD; WND : uint32);
-procedure writewordexWND(i: DWORD; attributes: uint32; WND : uint32);
-procedure writewordlnexWND(i: DWORD; attributes: uint32; WND : uint32);
-
 procedure writehexpairWND(b : uint8; WND : uint32);
 procedure writehexpairExWND(b : uint8; Attributes : uint32; WND : uint32);
 procedure writehexWND(i: DWORD; WND : uint32);
@@ -283,12 +273,16 @@ type
     end;
     PWindow = ^TWindow;
 
-    TWindows = Array[0..MAX_WINDOWS-1] of PWindow;
-    TZOrder  = Array[0..MAX_WINDOWS-1] of uint32;
+    TWindows    = Array[0..MAX_WINDOWS-1] of PWindow;
+    TZOrder     = Array[0..MAX_WINDOWS-1] of uint32;
+    TBackOrder  = Array[0..MAX_WINDOWS-1] of uint32;
+    TFrontOrder = Array[0..MAX_WINDOWS-1] of uint32;
 
     TWindowManager = record
         Windows     : TWindows;
         Z_Order     : TZOrder;
+        Back_Order  : TBackOrder;
+        Front_Order : TFrontOrder;
         MousePos    : TMouseCoord;
         MousePrev   : TMouseCoord;
     end;
@@ -544,6 +538,7 @@ var
     WND : PWindow;
 
 begin
+    tracer.push_trace('console.newWindow');
     newWindow:= 0;
     for idx:=1 to MAX_WINDOWS-1 do begin
         if WindowManager.Windows[idx] = nil then begin
@@ -927,6 +922,16 @@ begin
     WND^.Closed:= false;
     WND^.Border:= false;
     WND^.ShellWND:= false;
+    WND^.Hooks.OnDraw:= nil;
+    WND^.Hooks.OnMouseClick:= nil;
+    WND^.Hooks.OnMouseMove:= nil;
+    WND^.Hooks.OnMouseDown:= nil;
+    WND^.Hooks.OnMouseUp:= nil;
+    WND^.Hooks.OnKeyPressed:= nil;
+    WND^.Hooks.OnClose:= nil;
+    WND^.Hooks.OnMinimize:= nil;
+    WND^.Hooks.OnFocus:= nil;
+    WND^.Hooks.OnLoseFocus:= nil;
     WindowManager.Windows[0]:= WND;
     AddToZOrder(0);
     FocusZOrder(0);
@@ -1252,11 +1257,6 @@ begin
      console.writeintex(i, Console_Properties.Default_Attribute);
 end;
 
-procedure writeword(i: DWORD); [public, alias: 'console_writeword'];
-begin
-     console.writewordex(i, Console_Properties.Default_Attribute);
-end;
-
 procedure writecharln(character: char); [public, alias: 'console_writecharln'];
 begin
      console.writecharlnex(character, Console_Properties.Default_Attribute);
@@ -1272,13 +1272,9 @@ begin
      console.writeintlnex(i, Console_Properties.Default_Attribute);
 end;
 
-procedure writewordln(i: DWORD); [public, alias: 'console_writewordln'];
-begin
-     console.writewordlnex(i, Console_Properties.Default_Attribute);
-end;
-
 procedure writecharex(character: char; attributes: uint32); [public, alias: 'console_writecharex'];
 begin
+    serial.send(COM1, uint8(character), 10000);
     if WindowManager.Windows[DefaultWND] <> nil then begin
         WindowManager.Windows[DefaultWND]^.Buffer[WindowManager.Windows[DefaultWND]^.Cursor.Y][WindowManager.Windows[DefaultWND]^.Cursor.X].Character:= character;
         WindowManager.Windows[DefaultWND]^.Buffer[WindowManager.Windows[DefaultWND]^.Cursor.Y][WindowManager.Windows[DefaultWND]^.Cursor.X].Attributes:= attributes;
@@ -1435,24 +1431,6 @@ begin
         end;
         console.writestringex(str, attributes);
 end;
- 
-procedure writewordex(i: DWORD; attributes: uint32); [public, alias: 'console_writedwordex'];
-var
-        buffer: array [0..11] of Char;
-        str: PChar;
-        digit: DWORD;
-begin
-        for digit := 0 to 10 do buffer[digit] := '0';
-        str := @buffer[11];
-        str^ := #0;
-        digit := i;
-        repeat
-                Dec(str);
-                str^ := Char((digit mod 10) + Byte('0'));
-                digit := digit div 10;
-        until (digit = 0);
-        console.writestringex(@Buffer[0], attributes);
-end;
 
 procedure writecharlnex(character: char; attributes: uint32); [public, alias: 'console_writecharlnex'];
 begin
@@ -1472,12 +1450,6 @@ begin
      console._safeincrement_y();
 end;
 
-procedure writewordlnex(i: DWORD; attributes: uint32); [public, alias: 'console_writewordlnex'];
-begin
-     console.writewordex(i, attributes);
-     console._safeincrement_y();
-end;
-
 function combinecolors(Foreground, Background: uint16): uint32; 
 begin
      combinecolors:= (uint32(Foreground) SHL 16) OR Background;
@@ -1558,6 +1530,8 @@ end;
 
 procedure _safeincrement_y(); [public, alias: '_console_safeincrement_y'];
 begin
+     serial.send(COM1, uint8(13), 10000);
+     serial.send(COM1, uint8(10), 10000);
      if WindowManager.Windows[DefaultWND] <> nil then begin
         WindowManager.Windows[DefaultWND]^.Cursor.Y:= WindowManager.Windows[DefaultWND]^.Cursor.Y+1;
         if WindowManager.Windows[DefaultWND]^.Cursor.Y > WindowManager.Windows[DefaultWND]^.WND_H-1 then begin
@@ -1758,11 +1732,6 @@ begin
      console.writeintexWND(i, Console_Properties.Default_Attribute, WND);
 end;
 
-procedure writewordWND(i: DWORD; WND : uint32);
-begin
-     console.writewordexWND(i, Console_Properties.Default_Attribute, WND);
-end;
-
 procedure writecharlnWND(character: char; WND : uint32);
 begin
      console.writecharlnexWND(character, Console_Properties.Default_Attribute, WND);
@@ -1778,11 +1747,6 @@ begin
      console.writeintlnexWND(i, Console_Properties.Default_Attribute, WND);
 end;
 
-procedure writewordlnWND(i: DWORD; WND : uint32);
-begin
-     console.writewordlnexWND(i, Console_Properties.Default_Attribute, WND);
-end;
-
 procedure writecharexWND(character: char; attributes: uint32; WND : uint32); 
 begin
     if WindowManager.Windows[WND] <> nil then begin
@@ -1946,24 +1910,6 @@ begin
         end;
         console.writestringexWND(str, attributes, WND);
 end;
- 
-procedure writewordexWND(i: DWORD; attributes: uint32; WND : uint32);
-var
-        buffer: array [0..11] of Char;
-        str: PChar;
-        digit: DWORD;
-begin
-        for digit := 0 to 10 do buffer[digit] := '0';
-        str := @buffer[11];
-        str^ := #0;
-        digit := i;
-        repeat
-                Dec(str);
-                str^ := Char((digit mod 10) + Byte('0'));
-                digit := digit div 10;
-        until (digit = 0);
-        console.writestringexWND(@Buffer[0], attributes, WND);
-end;
 
 procedure writecharlnexWND(character: char; attributes: uint32; WND : uint32);
 begin
@@ -1983,12 +1929,6 @@ begin
      console._safeincrement_y_WND(WND);
 end;
 
-procedure writewordlnexWND(i: DWORD; attributes: uint32; WND : uint32);
-begin
-     console.writewordexWND(i, attributes, WND);
-     console._safeincrement_y_WND(WND);
-end;
-
 procedure backspaceWND(WND : uint32);
 begin
      if WindowManager.Windows[WND] <> nil then begin
diff --git a/src/driver/interface/serial.pas b/src/driver/interface/serial.pas
index 4978e5cf..e479340d 100644
--- a/src/driver/interface/serial.pas
+++ b/src/driver/interface/serial.pas
@@ -3,7 +3,7 @@ unit serial;
 interface
 
 uses
-    util, isrmanager;
+    util, isrmanager, strings;
 
 const
     COM1 = $3F8;
@@ -14,6 +14,7 @@ const
 procedure init();
 function receive(PORT : uint16; timeout : uint32) : uint8;
 function send(PORT : uint16; data : uint8; timeout : uint32) : boolean;
+function sendString(str : pchar) : boolean;
 
 implementation
 
@@ -85,4 +86,17 @@ begin
     end;
 end;
 
+function sendString(str : pchar) : boolean;
+var
+    i : uint32;
+
+begin
+    sendString:= true;
+    for i:=0 to StringSize(str)-1 do begin
+        sendString:= sendString AND send(COM1, uint8(str[i]), 10000);
+    end;
+    sendString:= sendString AND send(COM1, uint8(13), 10000);
+    sendString:= sendString AND send(COM1, uint8(10), 10000);
+end;
+
 end.
\ No newline at end of file
diff --git a/src/driver/net/l3/arp.pas b/src/driver/net/l3/arp.pas
index 6ebd4145..9900bc2e 100644
--- a/src/driver/net/l3/arp.pas
+++ b/src/driver/net/l3/arp.pas
@@ -22,6 +22,7 @@ function  MACToIIPv4(mac : puint8) : puint8;
 procedure sendGratuitous;
 procedure sendRequest(ip : puint8);
 procedure send(hType : uint16; pType : uint16; op : uint16; p_context : PPacketContext);
+function resolveIP(ip : puint8) : puint8;
 
 implementation
 
@@ -67,18 +68,6 @@ begin
     end;
 end;
 
-function findCacheRecord(ip : puint8) : PARPCacheRecord;
-var
-    CacheRecord : PARPCacheRecord;
-
-begin
-    CacheRecord:= findCacheRecordByIP(ip);
-    if CacheRecord = nil then begin
-        
-    end;
-    findCacheRecord:= CacheRecord;
-end;
-
 procedure send(hType : uint16; pType : uint16; op : uint16; p_context : PPacketContext);
 var
     buf : void;
@@ -171,6 +160,21 @@ begin
      sendRequestGateway(ip);
 end;
 
+function resolveIP(ip : puint8) : puint8;
+var
+    CacheRecord : PARPCacheRecord;
+
+begin
+    CacheRecord:= findCacheRecordByIP(ip);
+    resolveIP:= nil;
+    if CacheRecord = nil then begin
+        sendRequest(ip);
+        sendRequestGateway(ip);
+    end else begin
+        resolveIP:= @CacheRecord^.MAC[0];
+    end;
+end;
+
 procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
 var
     Header       : PARPHeader;
diff --git a/src/driver/net/l4/icmp.pas b/src/driver/net/l4/icmp.pas
index ba537958..aec3baa5 100644
--- a/src/driver/net/l4/icmp.pas
+++ b/src/driver/net/l4/icmp.pas
@@ -3,26 +3,114 @@ unit icmp;
 interface
 
 uses
-    net, nettypes, netutils, ipv4, console, terminal;
+    bios_data_area,
+    lmemorymanager,
+    net, nettypes, netutils, ipv4, console, terminal, arp, util;
+
+type
+    TARPErrorCode     = (aecFailedToResolveHost, aecNoRouteToHost, aecTimeout, aecTTLExpired);
+    TARPReplyCallback = procedure(hdr : PICMPHeader);
+    TARPErrorCallback = procedure(hdr : PICMPHeader; Reason : TARPErrorCode);
+    TARPHandler = record
+        Active  : Boolean;
+        OnReply : TARPReplyCallback;
+        OnError : TARPErrorCallback;
+    end;
 
 procedure register;
+procedure sendICMPRequest(ip : puint8; Sequence : uint16; TTL : uint8; OnRep : TARPReplyCallback; OnErr : TARPErrorCallback);
+
+procedure ping_err(hdr : PICMPHeader; Reason : TARPErrorCode);
+procedure ping_rep(hdr : PICMPHeader);
 
 implementation
 
+var
+    Handlers : Array[0..255] of TARPHandler;
+
+function nextInactiveHandler : uint8;
+var
+    i : uint8;
+
+begin
+    nextInactiveHandler:= 0;
+    for i:=1 to 255 do begin
+        if not Handlers[i].Active then begin
+            nextInactiveHandler:= i;
+            break;
+        end;
+    end;
+end;
+
 procedure sendResponse(p_context : PPacketContext);
 begin
 
 end;
 
-procedure sendRequest(ip : puint8);
+procedure sendICMPRequest(ip : puint8; Sequence : uint16; TTL : uint8; OnRep : TARPReplyCallback; OnErr : TARPErrorCallback);
+var
+    handle   : uint8;
+    dest_mac : puint8;
+    context  : PPacketContext;
+    Header   : PICMPHeader;
+    Buffer   : void;
+    CHK      : uint16;
+    Size     : uint32;
+
+begin
+    handle:= nextInactiveHandler;
+    Handlers[handle].Active:= true;
+    Handlers[handle].OnReply:= OnRep;
+    Handlers[handle].OnError:= OnErr;
+    if SameSubnetIPv4(ip, @getIPv4Config^.Address[0], @getIPv4Config^.Netmask[0]) then begin
+        dest_mac:= arp.resolveIP(ip);
+    end else begin
+        dest_mac:= arp.resolveIP(@getIPv4Config^.Gateway[0]);
+    end;
+    if dest_mac = nil then begin
+        if Handlers[handle].OnError <> nil then Handlers[handle].OnError(nil, aecFailedToResolveHost);
+        Handlers[handle].Active:= false;
+    end else begin
+        context:= newPacketContext;
+        copyMAC(getMAC, @context^.MAC.Source[0]);
+        copyIPv4(@getIPv4Config^.Address[0], @context^.IP.Source[0]);
+        copyMAC(dest_mac, @context^.MAC.Destination[0]);
+        copyIPv4(ip, @context^.IP.Destination[0]);
+        context^.TTL:= TTL;
+        context^.Protocol.L4:= $01;
+
+        Size:= sizeof(TICMPHeader) + sizeof(ICMP_DATA_GENERIC);
+        Buffer:= kalloc(Size);
+        Header:= PICMPHeader(Buffer);
+        Header^.ICMP_Type:= $08;
+        Header^.ICMP_CHK_Hi:= 0;
+        Header^.ICMP_CHK_Lo:= 0;
+        Header^.Identifier:= handle;
+        Header^.Sequence:= Sequence;
+
+        memcpy(uint32(@ICMP_DATA_GENERIC[0]), uint32(Buffer) + sizeof(TICMPHeader), sizeof(ICMP_DATA_GENERIC));
+
+        CHK:= calculateChecksum(puint16(Buffer), Size);
+
+        Header^.ICMP_CHK_Hi:= CHK AND $FF;
+        Header^.ICMP_CHK_Lo:= CHK SHR 8;
+
+        ipv4.send(Buffer, size, context);
+        
+        freePacketContext(context);
+    end;
+end;
+
+{procedure sendRequest(ip : puint8);
 begin
 
-end;
+end;}
 
 procedure recv(p_data : void; p_len : uint16; p_context : PPacketContext);
 var
     Header : PICMPHeader;
     CHK    : uint16;
+    Handle : uint8;
 
 begin
     writeToLogLn('            L4: icmp.recv');
@@ -45,13 +133,100 @@ begin
         end;
         $00:begin //Reply
             writeToLogLn('            L4: icmp.reply');
+            Handle:= Header^.Identifier;
+            if (Handle > 0) and (Handle < 256) then begin
+                If Handlers[Handle].Active then begin
+                    If Handlers[Handle].OnReply <> nil then Handlers[Handle].OnReply(Header);
+                    Handlers[Handle].Active:= false;
+                    Handlers[Handle].OnError:= nil;
+                    Handlers[Handle].OnReply:= nil;
+                end;
+            end;
         end;
     end; 
 end;
 
-procedure register;
+var
+    PING_T1 : uint64;
+    PING_N  : uint16;
+    PING_C  : uint16;
+    PING_L  : uint32;
+    PING_IP : puint8;
+
+procedure ping_err(hdr : PICMPHeader; Reason : TARPErrorCode);
 begin
+    writestringWND('Ping Error: ', getTerminalHWND);
+    case Reason of
+        aecFailedToResolveHost:writestringlnWND('Failed to resolve host.', getTerminalHWND);
+        aecNoRouteToHost:writestringlnWND('No route to host.', getTerminalHWND);
+        aecTimeout:writestringlnWND('Timeout expired.', getTerminalHWND);
+        aecTTLExpired:writestringlnWND('TTL Expired.', getTerminalHWND);
+    end;
+    PING_T1:= Counters.c64;
+    INC(PING_C);
+    if PING_C < PING_N then begin
+        sendICMPRequest(PING_IP, PING_C, 128, @ping_rep, @ping_err);
+    end else begin
+        terminal.done(PING_L);
+    end;
+end;
+
+procedure ping_rep(hdr : PICMPHeader);
+var
+    PING_T2 : uint64;
+
+begin
+    PING_T2:= Counters.c64;
+    writestringWND('Ping Reply: ', getTerminalHWND);
+    writeIntWND(PING_T2-PING_T1, getTerminalHWND);
+    writeStringlnWND('ms.', getTerminalHWND);
+    PING_T1:= PING_T2;
+    INC(PING_C);
+    if PING_C < PING_N then begin
+        sendICMPRequest(PING_IP, PING_C, 128, @ping_rep, @ping_err);
+    end else begin
+        terminal.done(PING_L);
+    end;
+end;
+
+procedure ping_terminate();
+begin
+    PING_N:= 0;
+end;
+
+procedure terminal_command_ping(Params : PParamList);
+var
+    ip_str : pchar;
+    ip : puint8;
+
+begin
+    if ParamCount(Params) > 0 then begin
+        ip_str:= getParam(0, Params);
+        ip:= stringToIPv4(ip_str);
+        if ip <> nil then begin
+            terminal.halt(PING_L, @ping_terminate);
+            PING_L:= Counters.c32;
+            PING_N:= 10;
+            PING_C:= 0;
+            PING_T1:= Counters.c64;
+            PING_IP:= ip;
+            sendICMPRequest(PING_IP, PING_C, 128, @ping_rep, @ping_err); 
+        end;
+    end;
+end;
+
+procedure register;
+var
+    i : uint32;
+
+begin
+    for i:=0 to 255 do begin
+        Handlers[i].Active:= false;
+        Handlers[i].OnError:= nil;
+        Handlers[i].OnReply:= nil;
+    end;
     ipv4.registerProtocol($01, @recv);
+    terminal.registerCommand('PING', @terminal_command_ping, 'Ping a host.');
 end;
 
 end.
\ No newline at end of file
diff --git a/src/driver/timers/TMR_0_ISR.pas b/src/driver/timers/TMR_0_ISR.pas
index eb9252ab..d23a1789 100644
--- a/src/driver/timers/TMR_0_ISR.pas
+++ b/src/driver/timers/TMR_0_ISR.pas
@@ -45,9 +45,7 @@ procedure register();
 begin
     if not registered then begin
         asm
-            mov al, $36
-            out $46, al
-            mov ax, 1165
+            mov ax, 1193
             out $40, al
             mov al, ah
             out $40, al
diff --git a/src/include/asuro.pas b/src/include/asuro.pas
index e7707962..6cfd8b63 100644
--- a/src/include/asuro.pas
+++ b/src/include/asuro.pas
@@ -3,20 +3,20 @@ unit asuro;
 interface
  
 const
-     VERSION       = '1.0.1-728ia';
+     VERSION       = '1.0.1-745ia';
      VERSION_MAJOR = '1';
      VERSION_MINOR = '0';
      VERSION_SUB   = '1';
-     REVISION      = '728';
+     REVISION      = '745';
      RELEASE       = 'ia';
-     LINE_COUNT    = 28522;
-     FILE_COUNT    = 90;
+     LINE_COUNT    = 29372;
+     FILE_COUNT    = 110;
      DRIVER_COUNT  = 32;
      FPC_VERSION   = '2.6.4';
      NASM_VERSION  = '2.10.09';
      MAKE_VERSION  = '3.81';
-     COMPILE_DATE  = '13/05/18';
-     COMPILE_TIME  = '16:34:39';
+     COMPILE_DATE  = '22/05/18';
+     COMPILE_TIME  = '04:31:53';
  
 implementation
  
diff --git a/src/include/types.pas b/src/include/types.pas
new file mode 100644
index 00000000..a6c9ea8e
--- /dev/null
+++ b/src/include/types.pas
@@ -0,0 +1,9 @@
+unit types;
+
+interface
+
+{ THIS IS JUST HERE SO THAT VM PLAYS NICE WITHOUT CHANGES }
+
+implementation
+
+end.
\ No newline at end of file
diff --git a/src/include/util.pas b/src/include/util.pas
index 702ef0cd..97bf2f9b 100644
--- a/src/include/util.pas
+++ b/src/include/util.pas
@@ -53,6 +53,8 @@ function get32bitcounter : uint32;
 function get64bitcounter : uint64;
 function getTSC : uint64;
 
+function div6432(dividend : uint64; divisor : uint32) : uint64;
+
 function BCDToUint8(bcd : uint8) : uint8;
 
 function HexCharToDecimal(hex : char) : uint8;
@@ -61,6 +63,8 @@ procedure resetSystem();
 
 function getESP : uint32;
 
+function MsSinceSystemBoot : uint64;
+
 var
     endptr : uint32; external name '__end';
     stack  : uint32; external name 'KERNEL_STACK';
@@ -70,6 +74,33 @@ implementation
 uses
     console, RTC, cpu;
 
+function MsSinceSystemBoot : uint64;
+begin
+    MsSinceSystemBoot:= div6432(getTSC, (CPUID.ClockSpeed.Hz div 1000));
+end;
+
+function div6432(dividend : uint64; divisor : uint32) : uint64;
+var
+    d0, d4 : uint32;
+    r0, r4 : uint32;
+
+begin
+    d4:= dividend SHR 32;
+    d0:= dividend AND $FFFFFFFF;
+    asm
+        PUSHAD
+        xor edx, edx
+        mov eax, d4
+        div divisor
+        mov r4, eax
+        mov eax, d0
+        div divisor
+        mov r0, eax
+        POPAD
+    end;
+    div6432:= (r0 SHL 32) OR r4;
+end;
+
 function switchendian32(b : uint32) : uint32;
 begin
     switchendian32:= ((b AND $FF000000) SHR 24) OR 
@@ -254,6 +285,7 @@ begin
           POP EDX
           POP EAX
      end;
+     io_wait;
 end;
 
 procedure outw(port : uint16; val : uint16); [public, alias: 'util_outw'];
@@ -267,6 +299,7 @@ begin
           POP EDX
           POP EAX
      end;
+     io_wait;
 end;
 
 procedure outb(port : uint16; val : uint8); [public, alias: 'util_outb'];
@@ -280,6 +313,7 @@ begin
           POP EDX
           POP EAX
      end;
+     io_wait;
 end;
 
 procedure halt_and_catch_fire(); [public, alias: 'util_halt_and_catch_fire'];
@@ -307,6 +341,7 @@ begin
           POP EDX
           POP EAX
      end;
+     io_wait;
 end;
 
 function inw(port : uint16) : uint16; [public, alias: 'util_inw'];
@@ -320,6 +355,7 @@ begin
           POP EDX
           POP EAX
      end;
+     io_wait;
 end;
 
 function inb(port : uint16) : uint8; [public, alias: 'util_inb'];
@@ -333,6 +369,7 @@ begin
           POP EDX
           POP EAX
      end;
+     io_wait;
 end;
 
 procedure memset(location : uint32; value : uint8; size : uint32);
diff --git a/src/kernel.pas b/src/kernel.pas
index d79c0868..90a70a23 100644
--- a/src/kernel.pas
+++ b/src/kernel.pas
@@ -43,7 +43,9 @@ uses
      splash,
      cpu,
      themer,
-     netlog;
+     netlog,
+     vmlog,
+     vm;
  
 procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
  
@@ -97,6 +99,9 @@ var
    l               : PLinkedListBase;
    
 begin
+     { Serial Init }
+     serial.init();
+
      { Store Multiboot info }
      multibootinfo:= mbinfo;
      multibootmagic:= mbmagic;
@@ -133,6 +138,15 @@ begin
         BSOD('GDT', 'Failed to load the GDT correctly.');
      end;
 
+     console.output('MULTIBOOT', 'Assigned Framebuffer: ');
+     console.writehexln(multibootinfo^.framebuffer_addr);
+     console.output('MULTIBOOT', 'Assigned Framebuffer Metrics: ');
+     console.writeint(multibootinfo^.framebuffer_width);
+     console.writestring('x');
+     console.writeint(multibootinfo^.framebuffer_height);
+     console.writestring('x');
+     console.writeintln(multibootinfo^.framebuffer_bpp);
+
      { Memory/CPU Init }
      idt.init();
      irq.init();
@@ -151,9 +165,6 @@ begin
      { CPUID }
      cpu.init();
 
-     { Serial Init }
-     serial.init();
-
      { Call Tracer }
      tracer.init();
 
@@ -184,7 +195,7 @@ begin
      { Bus Drivers }
      tracer.push_trace('kmain.BUSDRV');
      console.outputln('KERNEL', 'BUS DRIVERS: INIT BEGIN.');
-     USB.init();
+     //USB.init();
      pci.init();
      console.outputln('KERNEL', 'BUS DRIVERS: INIT END.');
 
@@ -192,26 +203,43 @@ begin
      tracer.push_trace('kmain.NETDRV');
      net.init;
 
+     tracer.push_trace('kmain.VMINIT');
+     vm.init();
+
+     { Init Progs }
+     tracer.push_trace('kmain.SHELLINIT');
+     shell.init();
+     tracer.push_trace('kmain.MEMVIEWINIT');
+     memview.init();
+     tracer.push_trace('kmain.THEMERINIT');
+     themer.init();
+     tracer.push_trace('kmain.NETLOGINIT');
+     netlog.init();
+     tracer.push_trace('kmain.VMLOGINIT');
+     vmlog.init();
+
+     terminal.run();
+
+     { Init Splash }
+     tracer.push_trace('kmain.SPLASHINIT');
+     splash.init();
+
      { End of Boot }
      tracer.push_trace('kmain.EOB');
+
      console.writestringln('');
      console.setdefaultattribute(console.combinecolors($17E0, $0000));
      console.writestringln('Asuro Booted Correctly!');
      console.setdefaultattribute(console.combinecolors($FFFF, $0000));
 
-     { Init Progs }
-     shell.init();
-     memview.init();
-     themer.init();
-     netlog.init();
-
-     { Init Splash }
-     splash.init();
-
      tracer.push_trace('kmain.END');
 
+     tracer.push_trace('kmain.TICK');
      while true do begin
+        tracer.push_trace('kmain.RedrawWindows');
         console.redrawWindows;
+        tracer.push_trace('kmain.VMTick');
+        vm.tick();
      end;
 end;
  
diff --git a/src/pmemorymanager.pas b/src/pmemorymanager.pas
index 2ca3a50a..0bb99eb2 100644
--- a/src/pmemorymanager.pas
+++ b/src/pmemorymanager.pas
@@ -125,7 +125,7 @@ begin
     force_alloc_block(2, 0); //First 12MiB reserved for Kernel/BIOS.
     force_alloc_block(3, 0);
     console.output('PMM',' ');
-    console.writeword(nPresent);
+    console.writeint(nPresent);
     console.writestringln('/1024 Block Available for Allocation.');
     console.outputln('PMM','INIT END.');
     pop_trace;
diff --git a/src/prog/netlog.pas b/src/prog/netlog.pas
index f27f5ba4..5c360e6f 100644
--- a/src/prog/netlog.pas
+++ b/src/prog/netlog.pas
@@ -27,6 +27,8 @@ procedure run(Params : PParamList);
 begin
     if Handle = 0 then begin
         Handle:= newWindow(20, 40, 63, 14, 'NETLOG');
+        clearWND(Handle);
+        registerEventHandler(Handle, EVENT_CLOSE, void(@OnClose));
     end;
 end;
 
diff --git a/src/prog/shell.pas b/src/prog/shell.pas
index c100b9f8..83bbf275 100644
--- a/src/prog/shell.pas
+++ b/src/prog/shell.pas
@@ -3,7 +3,7 @@ unit shell;
 interface
 
 uses
-    Console, RTC, terminal, strings, asuro;
+    Console, RTC, terminal, strings, asuro, tracer;
 
 procedure init();
 function getTaskbarColorsPtr : puint32;
@@ -197,24 +197,38 @@ end;
 
 procedure init();
 begin
+    tracer.push_trace('shell.init.1');
     Takbar_Colors:= console.combinecolors($0000, $FFFF);
+    tracer.push_trace('shell.init.2');
     Explore_Colors:= console.combinecolors($01C3, $07EE);
+    tracer.push_trace('shell.init.3');
     Desktop_Colors:= console.combinecolors($FFFF, $34DB);
 
+    tracer.push_trace('shell.init.4');
     DesktopHandle:= Console.newWindow(0, 0, 159, 63, 'DESKTOP');
+    tracer.push_trace('shell.init.5');
     TaskBarHandle:= Console.newWindow(0, 63, 159, 1, 'SHELL');
 
+    tracer.push_trace('shell.init.6');
     console.bordersEnabled(TaskBarHandle, false);
+    tracer.push_trace('shell.init.7');
     console.setShellWindow(TaskBarHandle, false);
 
+    tracer.push_trace('shell.init.8');
     console.bordersEnabled(DesktopHandle, false);
+    tracer.push_trace('shell.init.9');
     console.setShellWindow(DesktopHandle, false);
     
+    tracer.push_trace('shell.init.10');
     console.registerEventHandler(TaskBarHandle, EVENT_DRAW, void(@Draw));
+    tracer.push_trace('shell.init.11');
     console.registerEventHandler(TaskBarHandle, EVENT_MOUSE_CLICK, void(@OnMouseClick));
+    tracer.push_trace('shell.init.12');
     console.registerEventHandler(DesktopHandle, EVENT_DRAW, void(@onBaseDraw));
 
+    tracer.push_trace('shell.init.13');
     terminal.registerCommand('BACKGROUND', @Command_Background, 'Hide/Show background - usage: BACKGROUND <hide/show>');
+    tracer.push_trace('shell.init.14');
     terminal.registerCommand('COLORS', @Command_Colors, 'Set the desktop colors');
 end;
 
diff --git a/src/prog/terminal.pas b/src/prog/terminal.pas
index 9425c8ed..011ce3af 100644
--- a/src/prog/terminal.pas
+++ b/src/prog/terminal.pas
@@ -71,7 +71,7 @@ function done(id : uint32) : boolean;
 implementation
 
 uses
-    RTC;
+    RTC, cpu;
 
 var
     TERMINAL_HWND : HWND = 0;
@@ -520,6 +520,27 @@ begin
     terminal.halt(555, @teapot_halt);
 end;
 
+var
+    c1, c2 : uint64;
+    first : boolean = true;
+
+procedure testt(Params : PParamList);
+var
+    diff : uint32;
+
+begin
+    if first then begin
+        c1:= Counters.c64;
+        first:= false;
+    end else begin
+        c2:= Counters.c64;
+        diff:= c2 - c1;
+        writeIntWND(diff, getTerminalHWND);
+        writeStringlnWND('ms', getTerminalHWND);
+        c1:= c2;
+    end;
+end;
+
 procedure init;
 begin
     console.writestringln('TERMINAL: INIT BEGIN.');
@@ -533,6 +554,7 @@ begin
     registerCommandEx('SERIAL', @SendSerial, 'Send ''helloworld'' through COM1.', true);
     registerCommand('REBOOT', @Reboot, 'Reboot the system.');
     registerCommandEx('LOLWUT', @teapot, '?', true);
+    registerCommandEx('TEST', @testt, '?', true);
     console.writestringln('TERMINAL: INIT END.');
 end;
 
diff --git a/src/prog/vmlog.pas b/src/prog/vmlog.pas
new file mode 100644
index 00000000..198d34d4
--- /dev/null
+++ b/src/prog/vmlog.pas
@@ -0,0 +1,41 @@
+unit vmlog;
+
+interface
+
+uses
+    console, terminal, keyboard, util, strings, tracer;
+
+procedure init();
+function  getVMLogHWND : HWND;
+
+implementation
+
+var
+    Handle  : HWND = 0;
+
+function getVMLogHWND : HWND;
+begin
+    getVMLogHWND:= Handle;
+end;
+
+procedure OnClose();
+begin
+    Handle:= 0;
+end;
+
+procedure run(Params : PParamList);
+begin
+    if Handle = 0 then begin
+        Handle:= newWindow(20, 40, 63, 14, 'VMLOG');
+        clearWND(Handle);
+        registerEventHandler(Handle, EVENT_CLOSE, void(@OnClose));
+    end;
+end;
+
+procedure init();
+begin
+    tracer.push_trace('vmlog.init');
+    terminal.registerCommand('VMLOG', @Run, 'View virtual-machine event log.');
+end;
+
+end.
\ No newline at end of file
diff --git a/updatevm.sh b/updatevm.sh
new file mode 100755
index 00000000..2b54ef96
--- /dev/null
+++ b/updatevm.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+DIRECTORY="src/vm"
+if [ -d "$DIRECTORY" ]; then
+	cd "src/vm"
+	svn update
+	cd ".."
+	cd ".."
+else
+	cd src
+	svn checkout http://ovh.spexeah.com:81/svn/MINJ/src/vm
+fi