Index: Kernel/Core/ADC/X86/APM.cs
===================================================================
--- Kernel/Core/ADC/X86/APM.cs	(revision 0)
+++ Kernel/Core/ADC/X86/APM.cs	(revision 0)
@@ -0,0 +1,131 @@
+﻿//
+// (C) 2006-2008 The SharpOS Project Team (http://www.sharpos.org)
+//
+// Authors:
+//	Shevchenko Taras aka airstep <back.neomind@gmail.com>
+//
+// Licensed under the terms of the GNU GPL v3,
+//  with Classpath Linking Exception for Libraries
+//
+
+using System;
+using SharpOS.AOT;
+using AOTAttr = SharpOS.AOT.Attributes;
+using SharpOS.AOT.X86;
+
+namespace SharpOS.Kernel.ADC.X86
+{
+	public unsafe class APM
+	{
+		public static bool IsInstalled ()
+		{
+			//UInt32 PMStack = SwitchToRealMode ();
+
+			//Asm.MOV (R16.AX, 0x5300);
+			//Asm.XOR (R16.BX, R16.BX);
+			//Asm.XOR (R16.CX, R16.CX);
+			//Asm.INT (0x15);
+
+			//SwitchToProtectedMode (PMStack);
+
+			return true;
+		}
+
+		public static void Test ()
+		{
+			UInt32 PMStack = SwitchToRealMode ();
+
+			//SwitchToProtectedMode (PMStack);
+		}
+
+		private static uint SwitchToRealMode ()
+		{
+			UInt32 CR0_PE_OFF = 0xfffffffe;
+			UInt32 STACKOFF = 0x1FF0; //(0x2000 - 0x10)
+			//UInt16 PSEUDO_RM_DSEG = 0x20;
+			//ushort PSEUDO_RM_CSEG = 0x18;
+			UInt32 PMStack = 0;
+
+			Asm.LGDT (new SharpOS.AOT.X86.Memory ("GDTPointer"));
+
+			Asm.MOV (R32.EAX, R32.ESP);
+			Asm.MOV (&PMStack, R32.EAX);
+
+			Asm.MOV (R32.EAX, R32.ESP);
+			Asm.MOV (&STACKOFF, R32.EAX);
+
+			Asm.MOV (R32.EAX, STACKOFF);
+			Asm.MOV (R32.ESP, R32.EAX);
+			Asm.MOV (R32.EBP, R32.EAX);
+
+			//Asm.MOV(R16.AX, PSEUDO_RM_DSEG);
+			//Asm.MOV(Seg.DS, R16.AX);
+			//Asm.MOV(Seg.ES, R16.AX);
+			//Asm.MOV(Seg.FS, R16.AX);
+			//Asm.MOV(Seg.GS, R16.AX);
+			//Asm.MOV(Seg.SS, R16.AX);
+
+			//Asm.JMP(0x18, "tmpcseg");
+
+			//Asm.LABEL("tmpcseg");
+
+			Asm.MOV (R32.EAX, CR.CR0);
+			Asm.AND (R32.EAX, CR0_PE_OFF);
+			Asm.MOV (CR.CR0, R32.EAX);
+
+			Asm.JMP (0, "realcseg");
+
+			Asm.LABEL ("realcseg");
+			Asm.XOR (R32.EAX, R32.EAX);
+			Asm.MOV (Seg.DS, R16.AX);
+			Asm.MOV (Seg.ES, R16.AX);
+			Asm.MOV (Seg.FS, R16.AX);
+			Asm.MOV (Seg.GS, R16.AX);
+			Asm.MOV (Seg.SS, R16.AX);
+
+			Asm.STI ();
+
+			Asm.RET ();
+
+			return PMStack;
+		}
+
+		private static void SwitchToProtectedMode (uint PMStack)
+		{
+			UInt32 CR0_PE_ON = 0x1;
+			//ushort PROT_MODE_CSEG = 0x8; 
+			UInt16 PROT_MODE_DSEG = 0x10;
+			UInt32 STACKOFF = 0x1FF0; //(0x2000 - 0x10)
+
+			Asm.LGDT (new SharpOS.AOT.X86.Memory ("GDTPointer"));
+
+			Asm.MOV (R32.EAX, CR.CR0);
+			Asm.OR (R32.EAX, CR0_PE_ON);
+			Asm.MOV (CR.CR0, R32.EAX);
+
+			Asm.JMP (0x8, "protcseg");
+
+			Asm.LABEL ("protcseg");
+			Asm.MOV (R16.AX, PROT_MODE_DSEG);
+			Asm.MOV (Seg.DS, R16.AX);
+			Asm.MOV (Seg.ES, R16.AX);
+			Asm.MOV (Seg.FS, R16.AX);
+			Asm.MOV (Seg.GS, R16.AX);
+			Asm.MOV (Seg.SS, R16.AX);
+
+			Asm.MOV (R32.EAX, R32.ESP);
+			Asm.MOV (&STACKOFF, R32.EAX);
+
+			Asm.MOV (R32.EAX, PMStack);
+			Asm.MOV (R32.ESP, R32.EAX);
+			Asm.MOV (R32.EBP, R32.EAX);
+
+			Asm.MOV (R32.EAX, STACKOFF);
+			Asm.MOV (R32.ESP, R32.EAX);
+			Asm.XOR (R32.EAX, R32.EAX);
+
+			Asm.RET ();
+		}
+
+	}
+}
Index: Kernel/Core/ADC/X86/BootControl.cs
===================================================================
--- Kernel/Core/ADC/X86/BootControl.cs	(revision 1018)
+++ Kernel/Core/ADC/X86/BootControl.cs	(working copy)
@@ -30,13 +30,13 @@
 		/// </summary>
 		public static void PowerOff ()
 		{
-			// TODO: turn off system here..
-
 			// Disable interrupts
-			Asm.CLI ();
+			Asm.CLI();
 
-			// Halt the system
-			Asm.HLT ();
+			APM.Test ();
+
+ 			// Halt the system
+			//Asm.HLT ();
 		}
 
 		/// <summary>
Index: Kernel/Core/EntryModule.cs
===================================================================
--- Kernel/Core/EntryModule.cs	(revision 1018)
+++ Kernel/Core/EntryModule.cs	(working copy)
@@ -311,6 +311,15 @@
 			BootControl.Reboot ();
 		}
 
+		/// <summary>
+		/// Performs poweroff
+		/// function.
+		/// </summary>
+		public unsafe static void PowerOff()
+		{
+			SetKernelStage(KernelStage.Stop);
+			BootControl.PowerOff();
+		}
 		#endregion
 	}
 }
Index: Kernel/Core/SharpOS.Kernel.Core.csproj
===================================================================
--- Kernel/Core/SharpOS.Kernel.Core.csproj	(revision 1018)
+++ Kernel/Core/SharpOS.Kernel.Core.csproj	(working copy)
@@ -78,6 +78,7 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ADC\X86\APM.cs" />
     <Compile Include="ADC\X86\IOPortStream8bit.cs" />
     <Compile Include="DriverSystem\DeviceManager.cs" />
     <Compile Include="DriverSystem\DriverFlags.cs" />
@@ -183,6 +184,7 @@
     <Compile Include="Korlib\System\NullReferenceException.cs" />
     <Compile Include="Shell\Commands\BuiltIn\Cls.cs" />
     <Compile Include="Shell\Commands\BuiltIn\Egg.cs" />
+    <Compile Include="Shell\Commands\BuiltIn\PowerOff.cs" />
     <Compile Include="Shell\Commands\BuiltIn\Stage.cs" />
     <Compile Include="Shell\Commands\BuiltIn\MemDump.cs" />
     <Compile Include="Shell\Commands\BuiltIn\Version.cs" />
@@ -288,7 +290,7 @@
 ..\build\key-compiler.exe -D:.\..\Data\KeyMaps\ "$(SolutionDir)\Data\KeyMaps\US-Dvorak-ANSI.skm" -o:"$(SolutionDir)\build\KeyMaps\US-Dvorak-ANSI.bin"
 ..\build\key-compiler.exe -D:.\..\Data\KeyMaps\ "$(SolutionDir)\Data\KeyMaps\US-Dvorak-Classic.skm" -o:"$(SolutionDir)\build\KeyMaps\US-Dvorak-Classic.bin"
 ..\build\key-compiler.exe -D:.\..\Data\KeyMaps\ -ar -o:"$(TargetDir)\Temp\BuiltinKeymaps.ska" "@$(ProjectDir)\Config\BuiltinKeymaps.cfg"</PreBuildEvent>
-    <PostBuildEvent>..\build\SharpOS-AOT.exe -d:tests.dump -text-dump -v -o ..\build\SharpOS.Kernel.bin ..\build\SharpOS.Kernel.dll ..\build\SharpOS.Kernel.Tests.CS.dll ..\build\SharpOS.Kernel.Tests.IL.dll
+    <PostBuildEvent>..\build\SharpOS-AOT.exe -d:- -v -o ..\build\SharpOS.Kernel.bin ..\build\SharpOS.Kernel.dll ..\build\SharpOS.Kernel.Tests.CS.dll ..\build\SharpOS.Kernel.Tests.IL.dll
 copy ..\build\..\Data\DiskImages\TemplateDisk.img ..\build\distro\common\SharpOS.img
 ..\build\disk-image-updater.exe -m -i ..\build\SharpOS.Kernel.bin -o ..\build\distro\common\SharpOS.img -vhd ..\build\distro\VirtualPC\hd1.vhd</PostBuildEvent>
   </PropertyGroup>
Index: Kernel/Core/Shell/Commands/BuiltIn/PowerOff.cs
===================================================================
--- Kernel/Core/Shell/Commands/BuiltIn/PowerOff.cs	(revision 0)
+++ Kernel/Core/Shell/Commands/BuiltIn/PowerOff.cs	(revision 0)
@@ -0,0 +1,55 @@
+﻿// 
+// (C) 2007 The SharpOS Project Team (http://www.sharpos.org)
+//
+// Authors:
+//	airstep <back.neomind@gmail.com>
+//
+// Licensed under the terms of the GNU GPL v3,
+//  with Classpath Linking Exception for Libraries
+//
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SharpOS.AOT.Attributes;
+using SharpOS.Kernel.Foundation;
+using SharpOS.Kernel.ADC;
+
+namespace SharpOS.Kernel.Shell.Commands.BuiltIn
+{
+    public unsafe static class PowerOff
+    {
+        public const string name = "poweroff";
+        public const string shortDescription = "Turn off the machine";
+        public const string lblExecute = "COMMANDS.poweroff.Execute";
+        public const string lblGetHelp = "COMMANDS.poweroff.GetHelp";
+
+        [Label(lblExecute)]
+        public static void Execute(CommandExecutionContext* context)
+        {
+            EntryModule.PowerOff();
+        }
+
+        [Label(lblGetHelp)]
+        public static void GetHelp(CommandExecutionContext* context)
+        {
+            TextMode.WriteLine("Syntax: ");
+            TextMode.WriteLine("     poweroff");
+            TextMode.WriteLine("");
+            TextMode.WriteLine("Turn off the machine.");
+        }
+
+        public static CommandTableEntry* CREATE()
+        {
+            CommandTableEntry* entry = (CommandTableEntry*)SharpOS.Kernel.ADC.MemoryManager.Allocate((uint)sizeof(CommandTableEntry));
+
+            entry->name = (CString8*)SharpOS.Kernel.Stubs.CString(name);
+            entry->shortDescription = (CString8*)SharpOS.Kernel.Stubs.CString(shortDescription);
+            entry->func_Execute = (void*)SharpOS.Kernel.Stubs.GetLabelAddress(lblExecute);
+            entry->func_GetHelp = (void*)SharpOS.Kernel.Stubs.GetLabelAddress(lblGetHelp);
+            entry->nextEntry = null;
+
+            return entry;
+        }
+    }
+}
\ No newline at end of file
Index: Kernel/Core/Shell/Commands/CommandTableHeader.cs
===================================================================
--- Kernel/Core/Shell/Commands/CommandTableHeader.cs	(revision 1018)
+++ Kernel/Core/Shell/Commands/CommandTableHeader.cs	(working copy)
@@ -270,6 +270,7 @@
 			header->AddEntry (BuiltIn.MemView.CREATE ());
 			header->AddEntry (BuiltIn.Panic.CREATE ());
 			header->AddEntry (BuiltIn.Reboot.CREATE ());
+            header->AddEntry (BuiltIn.PowerOff.CREATE());
 			header->AddEntry (BuiltIn.Show.CREATE ());
 			header->AddEntry (BuiltIn.Snake.CREATE ());
 			header->AddEntry (BuiltIn.Stage.CREATE ());
Index: Tools/DiagnosticTool/MainWindow.cs
===================================================================
--- Tools/DiagnosticTool/MainWindow.cs	(revision 1018)
+++ Tools/DiagnosticTool/MainWindow.cs	(working copy)
@@ -110,17 +110,20 @@
 			this.Invoke (this.dMessage, "OK. Pipe opened.");
 			this.Invoke (this.dUpdateGUI);
 
-			while (true)
+			while (!vm.HasExited)
 			{
 				string status = string.Format ("R: {0} / W: {1}", Client.BytesRead, Client.BytesWritten);
 				this.Invoke (this.dSetStatus, status);
 
 				string log = System.Text.Encoding.ASCII.GetString (Client.LogQueue.ToArray ());
 				Client.LogQueue.Clear ();
-				this.Invoke (this.dAddLogger, log.Replace ("\n", "\r\n")); 
+				this.Invoke (this.dAddLogger, log.Replace ("\n", "\r\n"));
 
-				Thread.Sleep (100);
+				Thread.Sleep(100);
 			}
+
+			this.Invoke (this.dMessage, "VM is turned off...");
+			this.BeginInvoke ((MethodInvoker)delegate { this.Close (); });
 		}
 
 		private Thread waitForVMThread;
@@ -128,17 +131,17 @@
 
 		private void MainWindow_Shown (object sender, EventArgs e)
 		{
-      waitForVMThread = new Thread(new ThreadStart(WaitForVM));
+			waitForVMThread = new Thread(new ThreadStart(WaitForVM));
 			waitForVMThread.Start ();
 			waitForVMThread.Name = "WaitForVM";
 
-      string basePath = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
+			string basePath = Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);
 			string distroPath = Path.Combine (basePath, "distro");
-      string qemuPath = Path.Combine (distroPath , "qemu");
-      string commonPath = Path.Combine (distroPath, "common");
+			string qemuPath = Path.Combine (distroPath , "qemu");
+			string commonPath = Path.Combine (distroPath, "common");
 
-      vm.StartInfo.FileName = Path.Combine (qemuPath , "qemu.exe");
-      vm.StartInfo.Arguments = "-L " + qemuPath + " -hda " + Path.Combine (commonPath , "SharpOS.img") + " -serial pipe:SharpOS-Log -serial pipe:SharpOS-Control";
+			vm.StartInfo.FileName = Path.Combine (qemuPath , "qemu.exe");
+			vm.StartInfo.Arguments = "-L " + qemuPath + " -hda " + Path.Combine (commonPath , "SharpOS.img") + " -serial pipe:SharpOS-Log -serial pipe:SharpOS-Control";
 			vm.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
 			vm.Start ();
 		}
@@ -146,7 +149,7 @@
 		private void MainWindow_FormClosing (object sender, FormClosingEventArgs e)
 		{
 			if (waitForVMThread!=null && waitForVMThread.IsAlive)
-        waitForVMThread.Abort ();
+				waitForVMThread.Abort ();
 
 			if (!vm.HasExited)
 				vm.Kill ();
