diff --git a/Zenith-latest-2021-05-26-21_25_20.iso b/Zenith-latest-2021-06-01-16_25_31.iso
old mode 100644
new mode 100755
similarity index 99%
rename from Zenith-latest-2021-05-26-21_25_20.iso
rename to Zenith-latest-2021-06-01-16_25_31.iso
index 1bcf2733..857ce298
Binary files a/Zenith-latest-2021-05-26-21_25_20.iso and b/Zenith-latest-2021-06-01-16_25_31.iso differ
diff --git a/src/Doc/ChangeLog.DD b/src/Doc/ChangeLog.DD
index 77ae6ccf..3d284db5 100755
--- a/src/Doc/ChangeLog.DD
+++ b/src/Doc/ChangeLog.DD
@@ -1,4 +1,8 @@
 $WW,1$$FG,5$$TX+CX,"ChangeLog"$$FG$
+$IV,1$----06/01/21 16:02:38----$IV,0$
+* Overhauled entire OS to use AHCI routines instead of IDE.
+$BK,1$* Raised version number to ZenithOS 2.0.$BK,0$
+
 $IV,1$----05/24/21 05:08:09----$IV,0$
 * Fixed $LK+PU,"Chess",A="FF:::/Demo/Games/Chess.CC,JobQueue"$ crashing when only one CPU core available.
 
diff --git a/src/Doc/Demands.DD b/src/Doc/Demands.DD
index 7a1b8528..2836725c 100755
--- a/src/Doc/Demands.DD
+++ b/src/Doc/Demands.DD
@@ -29,7 +29,7 @@ $LK,"/Kernel/PCIBIOS.CC",A="FI:::/Kernel/PCIBIOS.CC"$ 					:290 could be elimina
 
 * Until super-simple serial ports are available, PS/2 emulated keyboard and mouse must work.	The BIOS must enable these.  The plan is to transition the industry off of USB.  Interum solution is to make virtual RS232 Octart for USB devices in the same way PS/2 mouse is emulated.  All mice will be two button, one wheel.	No more HID insanity, no more multi-end point, just simple tx rx fifos with soft/hard flowcontrol that can jump the queue.	People with special needs can buy PCI cards.	Our kids deserve code this simple $LK,"::/Doc/Comm.CC"$.	The right to do your own port banging is what the C64 being our God given ancestral land means.
 
-* The x86 IN/OUT port instructions, normally have a delay.	Perhaps, VMware & Intel can enable faster x86 IN/OUT instruction timing for ATA/ATAPI PIO, so bandwidth isn't as bad when doing port I/O.  See $LK,"ATAGetRes",A="MN:ATAGetRes"$().  We don't want to do DMA.  Perhaps, x86 CPU chips need a new ZenithOS mode for fast IN/OUT instructions?	I think VMware already does something to speed disk I/O to faster than native speed.
+* The x86 IN/OUT port instructions, normally have a delay.	Perhaps, VMware & Intel can enable faster x86 IN/OUT instruction timing for ATA/ATAPI PIO, so bandwidth isn't as bad when doing port I/O.  See $LK,"IDEATAGetRes",A="MN:IDEATAGetRes"$().  We don't want to do DMA.  Perhaps, x86 CPU chips need a new ZenithOS mode for fast IN/OUT instructions?	I think VMware already does something to speed disk I/O to faster than native speed.
 
 * Perhaps, a new interrupt descriptor table entry type or a new x86 CPU mode can be made that cause fast software interrupts, doing exactly what the CALL REL32 does, but with IDT as indirection.	We don't need to change privilege levels or stacks.
 
diff --git a/src/Home/AHCI/ahcifunctions.CC b/src/Home/AHCI/ahcifunctions.CC
old mode 100644
new mode 100755
index f7baba04..f4d8f76e
--- a/src/Home/AHCI/ahcifunctions.CC
+++ b/src/Home/AHCI/ahcifunctions.CC
@@ -2,10 +2,14 @@
 
 U0 Test()
 {
-	CBlkDev *ata_bd = CAlloc(sizeof(CBlkDev));
+//	CBlkDev *ata_bd = CAlloc(sizeof(CBlkDev));
 	CBlkDev *atapi_bd = CAlloc(sizeof(CBlkDev));
-	AHCIPortInit(ata_bd, &blkdev.ahci_hba->ports[0], 0);
-	AHCIPortInit(atapi_bd, &blkdev.ahci_hba->ports[1], 1);
+//	AHCIPortInit(ata_bd, &blkdev.ahci_hba->ports[0], 0);
+//	AHCIPortInit(atapi_bd, &blkdev.ahci_hba->ports[1], 1);
+	AHCIPortInit(atapi_bd, &blkdev.ahci_hba->ports[0], 0);
+
+
+
 }
 
 Test;
\ No newline at end of file
diff --git a/src/Home/AHCI/notes.DD b/src/Home/AHCI/notes.DD
index 0575d4aa..176b96aa 100755
--- a/src/Home/AHCI/notes.DD
+++ b/src/Home/AHCI/notes.DD
@@ -5,6 +5,7 @@ $WW$
 
 - Remove Buffer alignment check and just do it on every call
 
+- AHCIATAPISetMaxSpeed?
 
 $FG,7$ZenithOS IDE DVD Boot function order list and summary$FG$ 
 
@@ -18,35 +19,35 @@ KMain														// $LK+PU,"Kernel/KMain.CC",A="FF:::/Kernel/KMain.CC,KMain"$
 				BlkDevNextFreeSlot							// $LK+PU,"Kernel/BlkDev/DiskBlkDev.CC",A="FF:::/Kernel/BlkDev/DiskBlkDev.CC,BlkDevNextFreeSlot"$
 				...
 				GetBaseUnit									// $LK+PU,"Kernel/BlkDev/DiskAddDev.CC",A="FF:::/Kernel/BlkDev/DiskAddDev.CC,GetBaseUnit"$
-					BootDVDProbeAll							// $LK+PU,"Kernel/BlkDev/DiskATAId.CC",A="FF:::/Kernel/BlkDev/DiskATAId.CC,BootDVDProbeAll"$
+					IDEBootDVDProbeAll							// $LK+PU,"Kernel/BlkDev/DiskATAId.CC",A="FF:::/Kernel/BlkDev/DiskATAId.CC,IDEBootDVDProbeAll"$
 						j = PCIClassFind(0x010100 + k, ++i);
 						...
-						BootDVDProbe						// $LK+PU,"Kernel/BlkDev/DiskATAId.CC",A="FF:::/Kernel/BlkDev/DiskATAId.CC,BootDVDProbe"$
-							ATAProbe						// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAProbe"$
-								ATAGetDevId					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAGetDevId"$
+						IDEBootDVDProbe						// $LK+PU,"Kernel/BlkDev/DiskATAId.CC",A="FF:::/Kernel/BlkDev/DiskATAId.CC,IDEBootDVDProbe"$
+							IDEATAProbe						// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAProbe"$
+								IDEATAGetDevId					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAGetDevId"$
 
-							ATAPIStartStop					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIStartStop"$
-								ATAPIWritePacketWord		// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIWritePacketWord"$
+							IDEATAPIStartStop					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIStartStop"$
+								IDEATAPIWritePacketWord		// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIWritePacketWord"$
 
-							ATAPIReadBlks2					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIReadBlks2"$
-								ATAInit						// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAInit"$
-									ATAReadNativeMax		// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAReadNativeMax"$
-										ATAGetDevId			// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAGetDevId"$
-									ATABlkSel				// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATABlkSel"$
-									ATAPIStartStop			// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIStartStop"$
-										ATAPIWritePacketWord// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIWritePacketWord"$
+							IDEATAPIReadBlks2					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIReadBlks2"$
+								IDEATAInit						// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAInit"$
+									IDEATAReadNativeMax		// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAReadNativeMax"$
+										IDEATAGetDevId			// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAGetDevId"$
+									IDEATABlkSel				// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATABlkSel"$
+									IDEATAPIStartStop			// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIStartStop"$
+										IDEATAPIWritePacketWord// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIWritePacketWord"$
 
 				BlkDevAdd									// $LK+PU,"Kernel/BlkDev/DiskAddDev.CC",A="FF:::/Kernel/BlkDev/DiskAddDev.CC,BlkDevAdd"$
 					DriveMakeFreeSlot						// $LK+PU,"Kernel/BlkDev/DiskDrive.CC",A="FF:::/Kernel/BlkDev/DiskDrive.CC,DriveMakeFreeSlot"$
 
 	DiskChange												// $LK+PU,"Kernel/BlkDev/DiskDrive.CC",A="FF:::/Kernel/BlkDev/DiskDrive.CC,U0 DiskChange"$
 		BlkDevInit											// $LK+PU,"Kernel/BlkDev/DiskBlkDev.CC",A="FF:::/Kernel/BlkDev/DiskBlkDev.CC,BlkDevInit"$
-			ATAInit											// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAInit"$
-				ATAReadNativeMax							// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAReadNativeMax"$
-					ATAGetDevId								// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAGetDevId"$
-				ATABlkSel									// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATABlkSel"$
-				ATAPIStartStop								// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIStartStop"$
-					ATAPIWritePacketWord					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIWritePacketWord"$
+			IDEATAInit											// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAInit"$
+				IDEATAReadNativeMax							// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAReadNativeMax"$
+					IDEATAGetDevId								// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAGetDevId"$
+				IDEATABlkSel									// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATABlkSel"$
+				IDEATAPIStartStop								// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIStartStop"$
+					IDEATAPIWritePacketWord					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIWritePacketWord"$
 
 		DiskCacheInvalidate									// $LK+PU,"Kernel/BlkDev/DiskDrive.CC",A="FF:::/Kernel/BlkDev/DiskDrive.CC,U0 DiskCacheInvalidate"$
 			DiskCheck										// $LK+PU,"Zenith/ZBlkDev/DiskCheck.CC",A="FF:::/Zenith/ZBlkDev/DiskCheck.CC,DiskCheck"$
@@ -54,9 +55,9 @@ KMain														// $LK+PU,"Kernel/KMain.CC",A="FF:::/Kernel/KMain.CC,KMain"$
 				...
 			ISOInit											// $LK+PU,"Kernel/BlkDev/DiskCDDVD.CC",A="FF:::/Kernel/BlkDev/DiskCDDVD.CC,ISOInit"$
 				BlkRead										// $LK+PU,"Kernel/BlkDev/DiskBlk.CC",A="FF:::/Kernel/BlkDev/DiskBlk.CC,BlkRead"$
-					ATARBlks								// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATARBlks"$
-						ATAPIReadBlks						// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIReadBlks:2"$
-							ATAPIReadBlks2					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,ATAPIReadBlks2"$
+					IDEATARBlks								// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATARBlks"$
+						IDEATAPIReadBlks						// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIReadBlks:2"$
+							IDEATAPIReadBlks2					// $LK+PU,"Kernel/BlkDev/DiskATA.CC",A="FF:::/Kernel/BlkDev/DiskATA.CC,IDEATAPIReadBlks2"$
 								...
 
 		Drive												// $LK+PU,"Kernel/BlkDev/DiskDrive.CC",A="FF:::/Kernel/BlkDev/DiskDrive.CC,Bool Drive("$
diff --git a/src/Home/DoDistro.CC b/src/Home/DoDistro.CC
index a863927a..85ff0117 100755
--- a/src/Home/DoDistro.CC
+++ b/src/Home/DoDistro.CC
@@ -1,6 +1,7 @@
 //Make Your own Distro by #include-ing this file.
 
-#define STD_DISTRO_DVD_CONFIG 	"TB\nScale2Mem(2048,0x40000)\nT \n\n1024\n768\n\n\n"
+//#define STD_DISTRO_DVD_CONFIG 	"TB\nScale2Mem(2048,0x40000)\nT \n\n1024\n768\n\n\n"
+#define STD_DISTRO_DVD_CONFIG 	"TB\nScale2Mem(2048,0x40000)\nT0\n\n5\n\n\n"
 
 U0 MakeMyISO(U8 *_out_iso_filename)
 {//Does everything with current drive.
diff --git a/src/Home/K.CC b/src/Home/K.CC
index e5979e91..684a5062 100755
--- a/src/Home/K.CC
+++ b/src/Home/K.CC
@@ -1,6 +1,6 @@
 //Ed("/Doc/ChangeLog.DD");
 
-In("CC\n\n1\n\n5\n\n\n");
+//In("CC\n\n1\n\n5\n\n\n");
 BootHDIns;
 
 "\n\nSuccessful? ";
diff --git a/src/Home/satarep.CC b/src/Home/satarep.CC
deleted file mode 100644
index 9555ebb4..00000000
--- a/src/Home/satarep.CC
+++ /dev/null
@@ -1,24 +0,0 @@
-I64 SATARep()
-{
-	I64 bdf;
-	CAHCIPort *port;
-	CPCIDev *pci;
-	"AHCI version %X.%1X%1X\n", blkdev.ahci_hba->version >> 16, (blkdev.ahci_hba->version & 0xFF00) >> 8, blkdev.ahci_hba->version & 0xFF;
-	if (dev.pci_head)
-	{
-		pci = PCIDevFind(PCIC_STORAGE, PCISC_AHCI);
-		ClassRep(pci);
-		"Bus:0x%02X, Dev:0x%02X, Fun:0x%02X\n\n", pci->bus, pci->dev, pci->fun;
-		"$$PURPLE$$Vendor$$FG$$: $$BLACK$$%s$$FG$$\n", pci->vendor_str;
-		"$$PURPLE$$Device$$FG$$: $$BLACK$$%s$$FG$$\n", pci->dev_id_str;
-	}	
-	else
-	{
-		bdf = PCIClassFind(PCIC_STORAGE << 16 | PCISC_AHCI << 8 + 1, 0);
-		"Bus:%02X, Dev:%02X, Fun:%02X", bdf.u8[2], bdf.u8[1], bdf.u8[0];
-		"HBA Base Address: 0x%X", PCIReadU32(bdf.u8[2], bdf.u8[1], bdf.u8[0], PCIR_BASE5) & ~0x1F;
-	}
-	return 0;
-}
-
-SATARep;
\ No newline at end of file
diff --git a/src/Kernel/BlkDev/DiskAHCI.CC b/src/Kernel/BlkDev/DiskAHCI.CC
old mode 100644
new mode 100755
index fcae9a02..f1deaf9e
--- a/src/Kernel/BlkDev/DiskAHCI.CC
+++ b/src/Kernel/BlkDev/DiskAHCI.CC
@@ -243,16 +243,16 @@ I64 AHCIAtaBlksRW(CBlkDev *bd, U8 *buf, I64 blk, I64 count, Bool write)
 	buf_size = buf_size_tmp = count * BLK_SIZE;
 	prdt_len = (buf_size - 1) / AHCI_PRD_MAX_BYTES + 1;
 
-	"PRDT Length:\t%d\n", prdt_len;
-	"Count:\t\t\t%d\n", count;
-	"Buffer size:\t%X\n", buf_size;
+//	"PRDT Length:\t%d\n", prdt_len;
+//	"Count:\t\t\t%d\n", count;
+//	"Buffer size:\t%X\n", buf_size;
 
 	cmd_header->prdt_len = prdt_len; //Set PRD table length in cmd header.
 	//Set 'write' bit depending on 'write' argument.
 	BEqual(&cmd_header->desc, AHCI_CH_DESCf_W, write);
 
 	internal_buf = internal_buf_tmp = AHCIBufferAlign(bd, buf, buf_size, write);
-	"Buffer:\t\t\t0x%X\n", internal_buf;
+//	"Buffer:\t\t\t0x%X\n", internal_buf;
 
 	if (!internal_buf) throw('AHCI'); //Will probably never happen.
 
@@ -268,8 +268,8 @@ I64 AHCIAtaBlksRW(CBlkDev *bd, U8 *buf, I64 blk, I64 count, Bool write)
 		else
 			byte_count = buf_size_tmp;
 
-		"prdt[%d].data_base_addr  = 0x%X\n"  , i, internal_buf_tmp;
-		"prdt[%d].data_byte_count = 0x%X\n\n", i, byte_count;
+//		"prdt[%d].data_base_addr  = 0x%X\n"  , i, internal_buf_tmp;
+//		"prdt[%d].data_byte_count = 0x%X\n\n", i, byte_count;
 
 		cmd_table->prdt[i].data_base = internal_buf_tmp;
 		cmd_table->prdt[i].data_byte_count = byte_count - 1; //Zero-based value
@@ -306,7 +306,7 @@ I64 AHCIAtaBlksRW(CBlkDev *bd, U8 *buf, I64 blk, I64 count, Bool write)
 	if (!write) //If internal_buf was created it back to argument buf.
 		if (bd->flags & BDF_INTERNAL_BUF)
 		{
-			"Writing back internal buffer\n";
+//			"Writing back internal buffer\n";
 			MemCopy(buf, internal_buf, buf_size);
 		}
 	return cmd_header->prd_byte_count;
@@ -319,23 +319,26 @@ I64 AHCIAtaBlksRead(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 		return 0;
 	if (count <= AHCI_PRDT_MAX_BLOCKS)
 	{
-		"$$GREEN$$READ less than MAX_BLOCKS$$FG$$\n";
+//		"$$GREEN$$READ less than MAX_BLOCKS$$FG$$\n";
 		return AHCIAtaBlksRW(bd, buf, blk, count, FALSE);
 	}
 	else
 	{
-		"$$GREEN$$READ greater than MAX_BLOCKS\n";
-		"read count: %d\n$$FG$$", count;
+//		"$$GREEN$$READ greater than MAX_BLOCKS\n";
+//		"read count: %d\n$$FG$$", count;
 		while (count > AHCI_PRDT_MAX_BLOCKS)
 		{
 			byte_count += AHCIAtaBlksRW(bd, buf, blk, AHCI_PRDT_MAX_BLOCKS, FALSE);
 			count -= AHCI_PRDT_MAX_BLOCKS;
 			blk += AHCI_PRDT_MAX_BLOCKS;
 			buf += AHCI_PRDT_MAX_BLOCKS * BLK_SIZE;
-			"$$GREEN$$read count: %d\n$$FG$$", count;
+//			"$$GREEN$$read count: %d\n$$FG$$", count;
 		}$ER$
 		byte_count += AHCIAtaBlksRW(bd, buf, blk, count, FALSE);
 	}
+
+	blkdev.read_count += (count * bd->blk_size) >> BLK_SIZE_BITS;
+
 	return byte_count;
 }
 
@@ -346,20 +349,20 @@ I64 AHCIAtaBlksWrite(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 		return 0;
 	if (count <= AHCI_PRDT_MAX_BLOCKS)
 	{
-		"$$GREEN$$WRITE less than MAX_BLOCKS$$FG$$\n";
+//		"$$GREEN$$WRITE less than MAX_BLOCKS$$FG$$\n";
 		return AHCIAtaBlksRW(bd, buf, blk, count, TRUE);
 	}
 	else
 	{
-		"$$GREEN$$WRITE greater than MAX_BLOCKS\n";
-		"write count: %d$$FG$$\n", count;
+//		"$$GREEN$$WRITE greater than MAX_BLOCKS\n";
+//		"write count: %d$$FG$$\n", count;
 		while (count > AHCI_PRDT_MAX_BLOCKS)
 		{
 			byte_count += AHCIAtaBlksRW(bd, buf, blk, AHCI_PRDT_MAX_BLOCKS, TRUE);
 			count -= AHCI_PRDT_MAX_BLOCKS;
 			blk += AHCI_PRDT_MAX_BLOCKS;
 			buf += AHCI_PRDT_MAX_BLOCKS * BLK_SIZE;
-			"$$GREEN$$write count: %d\n$$FG$$\n", count;
+//			"$$GREEN$$write count: %d\n$$FG$$\n", count;
 		}
 		byte_count += AHCIAtaBlksRW(bd, buf, blk, count, TRUE);
 	}
@@ -386,14 +389,14 @@ I64 AHCIAtapiBlksRead(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 	buf_size = buf_size_tmp = count * DVD_BLK_SIZE;
 	prdt_len = (buf_size - 1) / AHCI_PRD_MAX_BYTES + 1;
 
-	"PRDT Length:\t%d\n", prdt_len;
-	"Count:\t\t\t%d\n", count;
-	"Buffer size:\t%X\n", buf_size;
+//	"PRDT Length:\t%d\n", prdt_len;
+//	"Count:\t\t\t%d\n", count;
+//	"Buffer size:\t%X\n", buf_size;
 
 	cmd_header->prdt_len = prdt_len;
 
 	internal_buf = internal_buf_tmp = AHCIBufferAlign(bd, buf, buf_size, FALSE);
-	"Buffer:\t\t\t0x%X\n", internal_buf;
+//	"Buffer:\t\t\t0x%X\n", internal_buf;
 
 	if (!internal_buf) throw('AHCI');
 
@@ -408,8 +411,8 @@ I64 AHCIAtapiBlksRead(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 		else
 			byte_count = buf_size_tmp;
 
-		"prdt[%d].data_base_addr  = 0x%X\n"  , i, internal_buf_tmp;
-		"prdt[%d].data_byte_count = 0x%X\n\n", i, byte_count;
+//		"prdt[%d].data_base_addr  = 0x%X\n"  , i, internal_buf_tmp;
+//		"prdt[%d].data_byte_count = 0x%X\n\n", i, byte_count;
 		cmd_table->prdt[i].data_base = internal_buf_tmp;
 		cmd_table->prdt[i].data_byte_count = byte_count - 1; //Zero-based value
 		buf_size_tmp -= byte_count;
@@ -441,7 +444,7 @@ I64 AHCIAtapiBlksRead(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 	
 	if (bd->flags & BDF_INTERNAL_BUF)
 	{
-		"Writing back internal buffer\n";
+//		"Writing back internal buffer\n";
 		MemCopy(buf, internal_buf, buf_size);
 	}
 	return cmd_header->prd_byte_count;
@@ -544,6 +547,138 @@ U0 AHCIInit()
 	}
 }
 
+Bool AHCIBootDVDProbeAll(CBlkDev *bd)
+{
+	I64			 i;
+	CAHCIPort	*port;
+	U8			*buf = CAlloc(DVD_BLK_SIZE);
+	CKernel 	*kernel;
+
+	for (i = 0; i < AHCI_MAX_PORTS; i++)
+	{
+		if (Bt(&blkdev.ahci_hba->ports_implemented, i))
+		{
+			port = &blkdev.ahci_hba->ports[i];
+			if (port->signature == AHCI_PxSIG_ATAPI)
+			{
+				AHCIPortInit(bd, port, i);
+
+				AHCIAtapiBlksRead(bd, buf, sys_boot_blk, 1);
+
+				kernel = buf + sys_boot_src.u16[1] << BLK_SIZE_BITS;
+
+				if (kernel->compile_time == sys_compile_time)
+				{
+					"Found sys_compile_time at BLK %d on Port %d\n", sys_boot_blk, i;
+					return TRUE;
+				}
+				else
+					"Did not find matching sys_compile_time on Port %d\n", i;
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+Bool AHCIAtapiRBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
+{
+	CBlkDev	*bd			= drive->bd;
+	I64		 nn, spc	= bd->blk_size >> BLK_SIZE_BITS, n, blk2, l2;
+	U8		*dvd_buf;//	= MAlloc(l2 << BLK_SIZE_BITS);
+
+	while (count > 0)
+	{
+		nn = count;
+		if (nn > bd->max_reads)
+			nn = bd->max_reads;
+
+		if (bd->type == BDT_ATAPI)
+		{
+//			"AHCIAtapiBlksRead(bd, buf, %d, %d);\n", blk, nn;
+//			AHCIAtapiBlksRead(bd, buf, blk, nn);
+
+
+			l2 = bd->max_reads << 1 + spc << 1;
+			dvd_buf	= MAlloc(l2 << BLK_SIZE_BITS);
+
+			if (blk <= bd->max_reads)
+				blk2 = 0;
+			else
+				blk2 = FloorU64(blk - bd->max_reads, spc);
+
+			if (blk2 + l2 > drive->size + drive->drv_offset)
+				l2 = drive->size + drive->drv_offset - blk2;
+
+			n = (l2 + spc - 1) / spc;
+
+			"AHCIAtapiBlksRead(bd, dvd_buf, %d, %d);", blk2 / spc, n;
+			AHCIAtapiBlksRead(bd, dvd_buf, blk2 / spc, n);
+
+			if (bd->flags & BDF_READ_CACHE)
+				DiskCacheAdd(drive, dvd_buf, blk2, n * spc);
+
+			MemCopy(buf, dvd_buf + (blk - blk2) << BLK_SIZE_BITS, nn << BLK_SIZE_BITS);
+			Free(dvd_buf);
+
+		}
+		else
+			return FALSE;
+
+		buf += nn << BLK_SIZE_BITS;
+		blk += nn;
+		count -= nn;
+	}
+
+	return TRUE;
+}
+//IDEATARBlks
+
+Bool AHCIAtaRBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
+{
+	I64		 n;
+	CBlkDev	*bd = drive->bd;
+
+	while (count > 0)
+	{
+		n = count;
+		if (n > bd->max_reads)
+			n = bd->max_reads;
+
+		if (bd->type == BDT_ATA)
+			AHCIAtaBlksRead(bd, buf, blk, n);
+		else
+			return FALSE;
+
+		buf += n << BLK_SIZE_BITS;
+		blk += n;
+		count -= n;
+	}
+	return TRUE;
+}
+
+Bool AHCIAtaWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
+{
+	I64		 n;
+	CBlkDev	*bd = drive->bd;
+//	Bool	 unlock;
+
+	while (count > 0)
+	{
+		n = count;
+		if (n > bd->max_writes)
+			n = bd->max_writes;
+			AHCIAtaBlksWrite(bd, buf, blk, n);
+
+		buf += n << BLK_SIZE_BITS;
+		blk += n;
+		count -= n;
+		blkdev.write_count += n;
+	}
+
+	return TRUE;
+}
+
 /*
 AHCIInit;
 
diff --git a/src/Kernel/BlkDev/DiskATA.CC b/src/Kernel/BlkDev/DiskATA.CC
index a521db81..a8727a5a 100755
--- a/src/Kernel/BlkDev/DiskATA.CC
+++ b/src/Kernel/BlkDev/DiskATA.CC
@@ -1,5 +1,5 @@
 
-U0 ATABlkSel(CBlkDev *bd, I64 blk, I64 count)
+U0 IDEATABlkSel(CBlkDev *bd, I64 blk, I64 count)
 {
 	if (bd->type != BDT_ATAPI && bd->base1)
 		OutU8(bd->base1 + ATAR1_CTRL, 0x8);
@@ -25,7 +25,7 @@ U0 ATABlkSel(CBlkDev *bd, I64 blk, I64 count)
 	}
 }
 
-Bool ATAWaitNotBUSY(CBlkDev *bd, F64 timeout)
+Bool IDEATAWaitNotBUSY(CBlkDev *bd, F64 timeout)
 {
 	I64 i;
 
@@ -41,7 +41,7 @@ Bool ATAWaitNotBUSY(CBlkDev *bd, F64 timeout)
 	return FALSE;
 }
 
-Bool ATAWaitDRQ(CBlkDev *bd, F64 timeout)
+Bool IDEATAWaitDRQ(CBlkDev *bd, F64 timeout)
 {
 	I64 i;
 
@@ -57,7 +57,7 @@ Bool ATAWaitDRQ(CBlkDev *bd, F64 timeout)
 	return FALSE;
 }
 
-Bool ATANop(CBlkDev *bd, F64 timeout)
+Bool IDEATANop(CBlkDev *bd, F64 timeout)
 {
 	if (bd->flags & BDF_EXT_SIZE)
 		OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -66,10 +66,10 @@ Bool ATANop(CBlkDev *bd, F64 timeout)
 
 	OutU8(bd->base0 + ATAR0_FEAT,	0);
 	OutU8(bd->base0 + ATAR0_CMD,	ATA_NOP);
-	return ATAWaitNotBUSY(bd, timeout);
+	return IDEATAWaitNotBUSY(bd, timeout);
 }
 
-U0 ATACmd(CBlkDev *bd, U8 cmd)
+U0 IDEATACmd(CBlkDev *bd, U8 cmd)
 {
 	OutU8(bd->base0 + ATAR0_FEAT,	0);
 	OutU8(bd->base0 + ATAR0_CMD,	cmd);
@@ -77,7 +77,7 @@ U0 ATACmd(CBlkDev *bd, U8 cmd)
 	PortNop;
 }
 
-Bool ATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 count, I64 _avail, Bool one_read)
+Bool IDEATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 count, I64 _avail, Bool one_read)
 {
 	I64 avail, overflow;
 
@@ -85,7 +85,7 @@ Bool ATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 count, I64 _avail, Bool on
 	MemSet(buf, 0, count);
 	while (count > 0)
 	{
-		if (!ATAWaitDRQ(bd, timeout))
+		if (!IDEATAWaitDRQ(bd, timeout))
 			return FALSE;
 		if (_avail)
 			avail = _avail;
@@ -121,16 +121,16 @@ Bool ATAGetRes(CBlkDev *bd, F64 timeout, U8 *buf, I64 count, I64 _avail, Bool on
 		else
 			Yield;
 	}
-	return ATAWaitNotBUSY(bd, timeout);
+	return IDEATAWaitNotBUSY(bd, timeout);
 }
 
-Bool ATAPIWritePacketWord(CBlkDev *bd, F64 timeout, ...)
+Bool IDEATAPIWritePacketWord(CBlkDev *bd, F64 timeout, ...)
 {
 	I64 i;
 
 	for (i = 0; i < argc; i++)
 	{
-		if (!ATAWaitDRQ(bd, timeout))
+		if (!IDEATAWaitDRQ(bd, timeout))
 			return FALSE;
 
 		OutU16(bd->base0 + ATAR0_DATA, EndianU16(argv[i]));
@@ -140,7 +140,7 @@ Bool ATAPIWritePacketWord(CBlkDev *bd, F64 timeout, ...)
 	return TRUE;
 }
 
-Bool ATAPISetMaxSpeed(CBlkDev *bd)
+Bool IDEATAPISetMaxSpeed(CBlkDev *bd)
 {
 	if (bd->flags & BDF_EXT_SIZE)
 		OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -149,13 +149,13 @@ Bool ATAPISetMaxSpeed(CBlkDev *bd)
 
 	OutU8(bd->base0 + ATAR0_LCYL, 0);
 	OutU8(bd->base0 + ATAR0_HCYL, 0);
-	ATACmd(bd, ATA_PACKET);
-	ATAPIWritePacketWord(bd, 0, ATAPI_SET_CD_SPEED, 0xFFFF, 0xFFFF, 0, 0, 0);
+	IDEATACmd(bd, ATA_PACKET);
+	IDEATAPIWritePacketWord(bd, 0, ATAPI_SET_CD_SPEED, 0xFFFF, 0xFFFF, 0, 0, 0);
 
-	return ATAWaitNotBUSY(bd, 0);
+	return IDEATAWaitNotBUSY(bd, 0);
 }
 
-Bool ATAPISeek(CBlkDev *bd, I64 native_blk)
+Bool IDEATAPISeek(CBlkDev *bd, I64 native_blk)
 {
 	if (bd->flags & BDF_EXT_SIZE)
 		OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -164,13 +164,13 @@ Bool ATAPISeek(CBlkDev *bd, I64 native_blk)
 
 	OutU8(bd->base0 + ATAR0_LCYL, 0);
 	OutU8(bd->base0 + ATAR0_HCYL, 0);
-	ATACmd(bd, ATA_PACKET);
-	ATAPIWritePacketWord(bd, 0, ATAPI_SEEK, native_blk >> 16, native_blk, 0, 0, 0);
+	IDEATACmd(bd, ATA_PACKET);
+	IDEATAPIWritePacketWord(bd, 0, ATAPI_SEEK, native_blk >> 16, native_blk, 0, 0, 0);
 
-	return ATAWaitNotBUSY(bd, 0);
+	return IDEATAWaitNotBUSY(bd, 0);
 }
 
-Bool ATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start)
+Bool IDEATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start)
 {
 	I64 i;
 
@@ -183,15 +183,15 @@ Bool ATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start)
 	else
 		OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
 
-	ATACmd(bd, ATA_PACKET);
+	IDEATACmd(bd, ATA_PACKET);
 //Start/Stop
-	if (ATAPIWritePacketWord(bd, timeout, ATAPI_START_STOP_UNIT, 0, i, 0, 0, 0))
-		return ATAWaitNotBUSY(bd, timeout);
+	if (IDEATAPIWritePacketWord(bd, timeout, ATAPI_START_STOP_UNIT, 0, i, 0, 0, 0))
+		return IDEATAWaitNotBUSY(bd, timeout);
 	else
 		return FALSE;
 }
 
-I64 ATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record)
+I64 IDEATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record)
 {
 	I64  res		= BDT_NULL;
 	U16 *id_record	= NULL;
@@ -203,15 +203,15 @@ I64 ATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record)
 	else
 		OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
 
-	ATACmd(bd, ATA_IDENTIFY);
-	if (ATAWaitNotBUSY(bd, timeout))
+	IDEATACmd(bd, ATA_IDENTIFY);
+	if (IDEATAWaitNotBUSY(bd, timeout))
 	{
 		if (InU8(bd->base0 + ATAR0_STAT) & ATAS_ERR)
 			res = BDT_ATAPI;
 		else
 		{
 			id_record = ZCAlloc(512);
-			if (ATAGetRes(bd, timeout, id_record, 512, 512, FALSE))
+			if (IDEATAGetRes(bd, timeout, id_record, 512, 512, FALSE))
 				res = BDT_ATA;
 			else
 			{
@@ -229,7 +229,7 @@ I64 ATAGetDevId(CBlkDev *bd, F64 timeout, Bool keep_id_record)
 	return res;
 }
 
-I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
+I64 IDEATAReadNativeMax(CBlkDev *bd, F64 timeout)
 {//Returns zero on error
 	I64  res  = 0;
 	Bool okay = TRUE;
@@ -241,8 +241,8 @@ I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
 		else
 			OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
 
-		ATACmd(bd, ATA_DEV_RST);
-		if (!ATAWaitNotBUSY(bd, 0))
+		IDEATACmd(bd, ATA_DEV_RST);
+		if (!IDEATAWaitNotBUSY(bd, 0))
 			okay = FALSE;
 	}
 	else
@@ -257,7 +257,7 @@ I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
 			if (0 < timeout < tS)
 				return FALSE;
 		}
-		if (ATAGetDevId(bd, timeout, TRUE) == BDT_NULL)
+		if (IDEATAGetDevId(bd, timeout, TRUE) == BDT_NULL)
 			okay = FALSE;
 		else
 			BEqual(&bd->flags, BDf_EXT_SIZE, Bt(&bd->dev_id_record[86], 10));
@@ -269,8 +269,8 @@ I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
 			OutU8(bd->base1 + ATAR1_CTRL,	0x8);
 			OutU8(bd->base0 + ATAR0_SEL,	0xEF | bd->unit << 4);
 
-			ATACmd(bd, ATA_READ_NATIVE_MAX_EXT);
-			if (ATAWaitNotBUSY(bd, timeout))
+			IDEATACmd(bd, ATA_READ_NATIVE_MAX_EXT);
+			if (IDEATAWaitNotBUSY(bd, timeout))
 			{
 				res.u8[0] = InU8(bd->base0 + ATAR0_SECT);
 				res.u8[1] = InU8(bd->base0 + ATAR0_LCYL);
@@ -293,8 +293,8 @@ I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
 			if (bd->type != BDT_ATAPI && bd->base1)
 				OutU8(bd->base1 + ATAR1_CTRL, 0x8);
 			OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
-			ATACmd(bd, ATA_READ_NATIVE_MAX);
-			if (ATAWaitNotBUSY(bd, timeout))
+			IDEATACmd(bd, ATA_READ_NATIVE_MAX);
+			if (IDEATAWaitNotBUSY(bd, timeout))
 			{
 				res.u8[0] = InU8(bd->base0 + ATAR0_SECT);
 				res.u8[1] = InU8(bd->base0 + ATAR0_LCYL);
@@ -306,13 +306,13 @@ I64 ATAReadNativeMax(CBlkDev *bd, F64 timeout)
 	return bd->max_blk = res;
 }
 
-I64 ATAPIReadCapacity(CBlkDev *bd, I64 *_blk_size=NULL)
+I64 IDEATAPIReadCapacity(CBlkDev *bd, I64 *_blk_size=NULL)
 {//Supposedly this can return a res +/- 75 sects.
 //Error might just be for music.
 	Bool unlock = BlkDevLock(bd);
 	U32  buf[2];
 
-	if (ATAWaitNotBUSY(bd, 0))
+	if (IDEATAWaitNotBUSY(bd, 0))
 	{
 		if (bd->flags & BDF_EXT_SIZE)
 			OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -321,10 +321,10 @@ I64 ATAPIReadCapacity(CBlkDev *bd, I64 *_blk_size=NULL)
 
 		OutU8(bd->base0 + ATAR0_LCYL, 8);
 		OutU8(bd->base0 + ATAR0_HCYL, 0);
-		ATACmd(bd, ATA_PACKET);
-		ATAPIWritePacketWord(bd, 0, ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0);
+		IDEATACmd(bd, ATA_PACKET);
+		IDEATAPIWritePacketWord(bd, 0, ATAPI_READ_CAPACITY, 0, 0, 0, 0, 0);
 
-		if (!ATAGetRes(bd, 0, buf, 8, 0, TRUE))
+		if (!IDEATAGetRes(bd, 0, buf, 8, 0, TRUE))
 			buf[0] = buf[1] = 0;
 	}
 	else
@@ -338,12 +338,12 @@ I64 ATAPIReadCapacity(CBlkDev *bd, I64 *_blk_size=NULL)
 	return EndianU32(buf[0]);
 }
 
-CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd, I64 blk)
+CATAPITrack *IDEATAPIReadTrackInfo(CBlkDev *bd, I64 blk)
 {
 	CATAPITrack	*res	= CAlloc(sizeof(CATAPITrack));
 	Bool		 unlock	= BlkDevLock(bd);
 
-	if (ATAWaitNotBUSY(bd, 0))
+	if (IDEATAWaitNotBUSY(bd, 0))
 	{
 		if (bd->flags & BDF_EXT_SIZE)
 			OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -353,8 +353,8 @@ CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd, I64 blk)
 		OutU8(bd->base0 + ATAR0_LCYL, sizeof(CATAPITrack) & 0xFF);
 		OutU8(bd->base0 + ATAR0_HCYL, sizeof(CATAPITrack) >> 8);
 
-		ATACmd(bd, ATA_PACKET);
-		ATAPIWritePacketWord(bd,
+		IDEATACmd(bd, ATA_PACKET);
+		IDEATAPIWritePacketWord(bd,
 							 0,
 							 ATAPI_READ_TRACK_INFO,
 							 blk.u16[1],
@@ -363,7 +363,7 @@ CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd, I64 blk)
 							 (sizeof(CATAPITrack) & 0x00FF) << 8,
 							 0);
 
-		if (!ATAGetRes(bd, 0, res, sizeof(CATAPITrack), 0, TRUE))
+		if (!IDEATAGetRes(bd, 0, res, sizeof(CATAPITrack), 0, TRUE))
 		{
 			Free(res);
 			res = NULL;
@@ -379,7 +379,7 @@ CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd, I64 blk)
 	return res;
 }
 
-Bool ATAInit(CBlkDev *bd)
+Bool IDEATAInit(CBlkDev *bd)
 {
 	Bool unlock = BlkDevLock(bd), okay = FALSE;
 
@@ -388,22 +388,22 @@ Bool ATAInit(CBlkDev *bd)
 	else
 		bd->flags |= BDF_EXT_SIZE;
 
-	if (ATAReadNativeMax(bd, tS + 0.1))
+	if (IDEATAReadNativeMax(bd, tS + 0.1))
 	{
-		ATABlkSel(bd, bd->max_blk, 0);
+		IDEATABlkSel(bd, bd->max_blk, 0);
 		if (bd->flags & BDF_EXT_SIZE)
-			ATACmd(bd, ATA_SET_MAX_EXT);
+			IDEATACmd(bd, ATA_SET_MAX_EXT);
 		else
-			ATACmd(bd, ATA_SET_MAX);
+			IDEATACmd(bd, ATA_SET_MAX);
 
-		if (ATAWaitNotBUSY(bd, 0))
+		if (IDEATAWaitNotBUSY(bd, 0))
 		{
 			okay = TRUE;
 			if (bd->type == BDT_ATAPI)
 			{
-				if (ATAPIStartStop(bd, 0, TRUE))
+				if (IDEATAPIStartStop(bd, 0, TRUE))
 				{
-					if (!ATAPISetMaxSpeed(bd))
+					if (!IDEATAPISetMaxSpeed(bd))
 						okay = FALSE;
 				}
 				else
@@ -417,16 +417,16 @@ Bool ATAInit(CBlkDev *bd)
 	return okay;
 }
 
-Bool ATAPIWaitReady(CBlkDev *bd, F64 timeout)
+Bool IDEATAPIWaitReady(CBlkDev *bd, F64 timeout)
 {
 	do
 	{
-		if (!ATAWaitNotBUSY(bd, timeout) || !ATANop(bd, timeout) || !ATAPIStartStop(bd, timeout, TRUE))
+		if (!IDEATAWaitNotBUSY(bd, timeout) || !IDEATANop(bd, timeout) || !IDEATAPIStartStop(bd, timeout, TRUE))
 			return FALSE;
 		if (InU8(bd->base0 + ATAR0_STAT) & ATAS_DRDY && !InU8(bd->base0 + ATAR0_FEAT));
 			return TRUE;
 
-		ATAInit(bd);
+		IDEATAInit(bd);
 		Yield;
 	}
 	while (!(0 < timeout < tS));
@@ -434,23 +434,23 @@ Bool ATAPIWaitReady(CBlkDev *bd, F64 timeout)
 	return FALSE;
 }
 
-U0 ATAReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
+U0 IDEATAReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 {
 	I64  retries = 3;
 	Bool unlock  = BlkDevLock(bd);
 
 	retry:
-	ATABlkSel(bd, blk, count);
+	IDEATABlkSel(bd, blk, count);
 	if (bd->flags & BDF_EXT_SIZE)
-		ATACmd(bd, ATA_READ_MULTI_EXT);
+		IDEATACmd(bd, ATA_READ_MULTI_EXT);
 	else
-		ATACmd(bd, ATA_READ_MULTI);
+		IDEATACmd(bd, ATA_READ_MULTI);
 
-	if (!ATAGetRes(bd, tS + 1.0, buf, count * bd->blk_size, BLK_SIZE, FALSE))
+	if (!IDEATAGetRes(bd, tS + 1.0, buf, count * bd->blk_size, BLK_SIZE, FALSE))
 	{
 		if (retries--)
 		{
-			ATAWaitNotBUSY(bd, 0);
+			IDEATAWaitNotBUSY(bd, 0);
 			goto retry;
 		}
 		else
@@ -463,7 +463,7 @@ U0 ATAReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 		BlkDevUnlock(bd);
 }
 
-I64 ATAProbe(I64 base0, I64 base1, I64 unit)
+I64 IDEATAProbe(I64 base0, I64 base1, I64 unit)
 {
 	CBlkDev bd;
 
@@ -474,10 +474,10 @@ I64 ATAProbe(I64 base0, I64 base1, I64 unit)
 	bd.unit = unit;
 	bd.blk_size = DVD_BLK_SIZE;
 
-	return ATAGetDevId(&bd, tS + 0.1, FALSE);
+	return IDEATAGetDevId(&bd, tS + 0.1, FALSE);
 }
 
-Bool ATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 count, Bool lock)
+Bool IDEATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 count, Bool lock)
 {
 	Bool res = FALSE, unlock;
 
@@ -485,7 +485,7 @@ Bool ATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 count
 		return FALSE;
 	if (lock)
 		unlock = BlkDevLock(bd);
-	if (ATAPIWaitReady(bd, timeout))
+	if (IDEATAPIWaitReady(bd, timeout))
 	{
 		if (bd->flags & BDF_EXT_SIZE)
 			OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -494,23 +494,23 @@ Bool ATAPIReadBlks2(CBlkDev *bd, F64 timeout, U8 *buf, I64 native_blk, I64 count
 
 		OutU8(bd->base0 + ATAR0_LCYL, bd->blk_size);
 		OutU8(bd->base0 + ATAR0_HCYL, bd->blk_size.u8[1]);
-		ATACmd(bd, ATA_PACKET);
+		IDEATACmd(bd, ATA_PACKET);
 
-		if (ATAPIWritePacketWord(bd, timeout, ATAPI_READ, native_blk.u16[1], native_blk, count.u16[1], count, 0) &&
-			ATAGetRes(bd, timeout, buf, count * bd->blk_size, 0, FALSE))
+		if (IDEATAPIWritePacketWord(bd, timeout, ATAPI_READ, native_blk.u16[1], native_blk, count.u16[1], count, 0) &&
+			IDEATAGetRes(bd, timeout, buf, count * bd->blk_size, 0, FALSE))
 		{
 			blkdev.read_count += (count * bd->blk_size) >> BLK_SIZE_BITS;
 			res = TRUE;
 		}
 	}
-//	ATAPIStartStop(bd, 0, FALSE);
+//	IDEATAPIStartStop(bd, 0, FALSE);
 	if (lock && unlock)
 		BlkDevUnlock(bd);
 
 	return res;
 }
 
-U0 ATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
+U0 IDEATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 {
 	CDrive	*drive		= Letter2Drive(bd->first_drive_let);
 	I64		 retry, spc = bd->blk_size >> BLK_SIZE_BITS, n, blk2, l2 = bd->max_reads << 1 + spc << 1;
@@ -530,11 +530,11 @@ U0 ATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 
 		retry = 4;
 		while (--retry)
-			if (ATAPIReadBlks2(bd, tS + 7.0 + 0.004 * n, dvd_buf, blk2 / spc, n, TRUE))
+			if (IDEATAPIReadBlks2(bd, tS + 7.0 + 0.004 * n, dvd_buf, blk2 / spc, n, TRUE))
 //n is 0x800 if max_reads.	Up to 8 additional seconds
 				break;
 		if (!retry)
-			ATAPIReadBlks2(bd, 0, dvd_buf, blk2 / spc, n, TRUE);
+			IDEATAPIReadBlks2(bd, 0, dvd_buf, blk2 / spc, n, TRUE);
 		if (bd->flags & BDF_READ_CACHE)
 			DiskCacheAdd(drive, dvd_buf, blk2, n * spc);
 
@@ -543,7 +543,7 @@ U0 ATAPIReadBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 	Free(dvd_buf);
 }
 
-Bool ATARBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
+Bool IDEATARBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 {
 	I64		 n;
 	CBlkDev	*bd = drive->bd;
@@ -555,9 +555,9 @@ Bool ATARBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 			n = bd->max_reads;
 
 		if (bd->type == BDT_ATAPI)
-			ATAPIReadBlks(bd, buf, blk, n);
+			IDEATAPIReadBlks(bd, buf, blk, n);
 		else
-			ATAReadBlks(bd, buf, blk, n);
+			IDEATAReadBlks(bd, buf, blk, n);
 
 		buf += n << BLK_SIZE_BITS;
 		blk += n;
@@ -566,7 +566,7 @@ Bool ATARBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 	return TRUE;
 }
 
-U0 ATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
+U0 IDEATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 {//For low level disk access.
 //Use BlkWrite() instead.
 	I64  i, U32s_avail, sects_avail, retries = 3;
@@ -574,11 +574,11 @@ U0 ATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count)
 	Bool unlock = BlkDevLock(bd);
 
 retry:
-	ATABlkSel(bd, blk, count);
+	IDEATABlkSel(bd, blk, count);
 	if (bd->flags & BDF_EXT_SIZE)
-		ATACmd(bd, ATA_WRITE_MULTI_EXT);
+		IDEATACmd(bd, ATA_WRITE_MULTI_EXT);
 	else
-		ATACmd(bd, ATA_WRITE_MULTI);
+		IDEATACmd(bd, ATA_WRITE_MULTI);
 
 	bd->flags |= BDF_LAST_WAS_WRITE;
 	while (count > 0)
@@ -597,7 +597,7 @@ retry:
 			{
 				if (retries--)
 				{
-					ATAWaitNotBUSY(bd, 0);
+					IDEATAWaitNotBUSY(bd, 0);
 					goto retry;
 				}
 				else
@@ -611,16 +611,16 @@ retry:
 		count -= sects_avail;
 		retries = 3;
 	}
-	ATAWaitNotBUSY(bd, 0);
+	IDEATAWaitNotBUSY(bd, 0);
 	if (unlock)
 		BlkDevUnlock(bd);
 }
 
-Bool ATAPISync(CBlkDev *bd)
+Bool IDEATAPISync(CBlkDev *bd)
 {
 	Bool okay = TRUE;
 
-	if (!ATAWaitNotBUSY(bd, 0))
+	if (!IDEATAWaitNotBUSY(bd, 0))
 		okay = FALSE;
 	else
 	{
@@ -631,17 +631,17 @@ Bool ATAPISync(CBlkDev *bd)
 
 		OutU8(bd->base0 + ATAR0_LCYL, 0);
 		OutU8(bd->base0 + ATAR0_HCYL, 0);
-		ATACmd(bd, ATA_PACKET);
-		ATAPIWritePacketWord(bd, 0, ATAPI_SYNC_CACHE, 0, 0, 0, 0, 0);
+		IDEATACmd(bd, ATA_PACKET);
+		IDEATAPIWritePacketWord(bd, 0, ATAPI_SYNC_CACHE, 0, 0, 0, 0, 0);
 
-		if (!ATAWaitNotBUSY(bd, 0))
+		if (!IDEATAWaitNotBUSY(bd, 0))
 			okay = FALSE;
 	}
 
 	return okay;
 }
 
-U0 ATAPIClose(CBlkDev *bd, I64 close_field=0x200, I64 track=0)
+U0 IDEATAPIClose(CBlkDev *bd, I64 close_field=0x200, I64 track=0)
 {//0x200 CD/DVD part 1
 // 0x300		DVD part 2
 	if (bd->flags & BDF_EXT_SIZE)
@@ -651,19 +651,19 @@ U0 ATAPIClose(CBlkDev *bd, I64 close_field=0x200, I64 track=0)
 
 	OutU8(bd->base0 + ATAR0_LCYL, 0);
 	OutU8(bd->base0 + ATAR0_HCYL, 0);
-	ATACmd(bd, ATA_PACKET);
-	ATAPIWritePacketWord(bd, 0, ATAPI_CLOSE_TRACK_SESSION, close_field, track, 0, 0, 0);
+	IDEATACmd(bd, ATA_PACKET);
+	IDEATAPIWritePacketWord(bd, 0, ATAPI_CLOSE_TRACK_SESSION, close_field, track, 0, 0, 0);
 
-	ATAWaitNotBUSY(bd, 0);
+	IDEATAWaitNotBUSY(bd, 0);
 }
 
-U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
+U0 IDEATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
 {
 	I64 U32s_avail;
 	U8 *buf2;
 
-	ATAWaitNotBUSY(bd, 0);
-	ATAPISeek(bd, native_blk);
+	IDEATAWaitNotBUSY(bd, 0);
+	IDEATAPISeek(bd, native_blk);
 
 	OutU8(bd->base0 + ATAR0_FEAT, 0);
 	OutU8(bd->base0 + ATAR0_LCYL, bd->blk_size);
@@ -675,12 +675,12 @@ U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
 		OutU8(bd->base0 + ATAR0_SEL, 0xE0 | bd->unit << 4);
 
 	OutU8(bd->base0 + ATAR0_CMD, ATA_PACKET);
-	ATAPIWritePacketWord(bd, 0, ATAPI_FORMAT_UNIT, native_blk.u16[1], native_blk, count.u16[1], count, 0);
+	IDEATAPIWritePacketWord(bd, 0, ATAPI_FORMAT_UNIT, native_blk.u16[1], native_blk, count.u16[1], count, 0);
 
 	bd->flags |= BDF_LAST_WAS_WRITE;
 
-	ATAWaitNotBUSY(bd, 0);
-	ATAPISeek(bd, native_blk);
+	IDEATAWaitNotBUSY(bd, 0);
+	IDEATAPISeek(bd, native_blk);
 
 	if (bd->flags & BDF_EXT_SIZE)
 		OutU8(bd->base0 + ATAR0_SEL, 0xEF | bd->unit << 4);
@@ -689,13 +689,13 @@ U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
 
 	OutU8(bd->base0 + ATAR0_LCYL, bd->blk_size);
 	OutU8(bd->base0 + ATAR0_HCYL, bd->blk_size.u8[1]);
-	ATACmd(bd, ATA_PACKET);
-	ATAPIWritePacketWord(bd, 0, ATAPI_WRITE, native_blk.u16[1], native_blk, count.u16[1], count, 0);
+	IDEATACmd(bd, ATA_PACKET);
+	IDEATAPIWritePacketWord(bd, 0, ATAPI_WRITE, native_blk.u16[1], native_blk, count.u16[1], count, 0);
 
 	buf2 = buf + bd->blk_size * count;
 	while (buf < buf2)
 	{
-		ATAWaitDRQ(bd, 0);
+		IDEATAWaitDRQ(bd, 0);
 		U32s_avail = (InU8(bd->base0 + ATAR0_HCYL) << 8 + InU8(bd->base0 + ATAR0_LCYL)) >> 2;
 		if (buf + U32s_avail << 2 > buf2)
 			U32s_avail = (buf2-buf) >> 2;
@@ -706,10 +706,10 @@ U0 ATAPIWriteBlks(CBlkDev *bd, U8 *buf, I64 native_blk, I64 count)
 			blkdev.write_count += U32s_avail >> (BLK_SIZE_BITS - 2);
 		}
 	}
-	ATAWaitNotBUSY(bd, 0);
+	IDEATAWaitNotBUSY(bd, 0);
 }
 
-Bool ATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
+Bool IDEATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 {
 	I64		 n, spc;
 	CBlkDev	*bd = drive->bd;
@@ -720,7 +720,7 @@ Bool ATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 	if (bd->type == BDT_ATAPI)
 	{
 		unlock = BlkDevLock(bd);
-		ATAPIWaitReady(bd, 0);
+		IDEATAPIWaitReady(bd, 0);
 	}
 	while (count > 0)
 	{
@@ -729,9 +729,9 @@ Bool ATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 			n = bd->max_writes;
 
 		if (bd->type == BDT_ATAPI)
-			ATAPIWriteBlks(bd, buf, blk / spc, (n + spc - 1) / spc);
+			IDEATAPIWriteBlks(bd, buf, blk / spc, (n + spc - 1) / spc);
 		else
-			ATAWriteBlks(bd, buf, blk, n);
+			IDEATAWriteBlks(bd, buf, blk, n);
 
 		buf += n << BLK_SIZE_BITS;
 		blk += n;
@@ -740,8 +740,8 @@ Bool ATAWBlks(CDrive *drive, U8 *buf, I64 blk, I64 count)
 	}
 	if (bd->type == BDT_ATAPI)
 	{
-		ATAPISync(bd);
-//		ATAPIStartStop(bd,0,FALSE);
+		IDEATAPISync(bd);
+//		IDEATAPIStartStop(bd,0,FALSE);
 		if (unlock)
 			BlkDevUnlock(bd);
 	}
diff --git a/src/Kernel/BlkDev/DiskATAId.CC b/src/Kernel/BlkDev/DiskATAId.CC
index c2beda6c..a99bae54 100755
--- a/src/Kernel/BlkDev/DiskATAId.CC
+++ b/src/Kernel/BlkDev/DiskATAId.CC
@@ -1,19 +1,19 @@
-Bool BootDVDProbe(CBlkDev *bd)
+Bool IDEBootDVDProbe(CBlkDev *bd)
 {
 	U8		*img = CAlloc(DVD_BLK_SIZE);
 	I64		 i;
 	Bool	 res = FALSE;
 
 	"Port: %04X,%04X Unit: %02X  ", bd->base0, bd->base1, bd->unit;
-	if (ATAProbe(bd->base0, bd->base1, bd->unit) == BDT_ATAPI)
+	if (IDEATAProbe(bd->base0, bd->base1, bd->unit) == BDT_ATAPI)
 	{
 		" ATAPI";
-		if (ATAPIStartStop(bd, tS + 5.0, TRUE))
+		if (IDEATAPIStartStop(bd, tS + 5.0, TRUE))
 		{
 			" Started";
 			for (i = 0; i < 2; i++)
 			{//Retry
-				if (ATAPIReadBlks2(bd, tS + 7.0, img, sys_boot_blk, 1, FALSE))
+				if (IDEATAPIReadBlks2(bd, tS + 7.0, img, sys_boot_blk, 1, FALSE))
 				{
 					if ((img + sys_boot_src.u16[1] << BLK_SIZE_BITS)(CKernel *)->compile_time == sys_compile_time)
 					{
@@ -34,7 +34,7 @@ Bool BootDVDProbe(CBlkDev *bd)
 	return res;
 }
 
-Bool BootDVDProbeAll(CBlkDev *bd)
+Bool IDEBootDVDProbeAll(CBlkDev *bd)
 {
 	I64 d1, d2, i, j, k;
 
@@ -55,10 +55,10 @@ Bool BootDVDProbeAll(CBlkDev *bd)
 				if (bd->base0 = d1 & ~7)
 				{
 					bd->unit = 0;
-					if (BootDVDProbe(bd))
+					if (IDEBootDVDProbe(bd))
 						return TRUE;
 					bd->unit = 1;
-					if (BootDVDProbe(bd))
+					if (IDEBootDVDProbe(bd))
 						return TRUE;
 				}
 			}
@@ -69,10 +69,10 @@ Bool BootDVDProbeAll(CBlkDev *bd)
 				if (bd->base0 = d1 & ~7)
 				{
 					bd->unit = 0;
-					if (BootDVDProbe(bd))
+					if (IDEBootDVDProbe(bd))
 						return TRUE;
 					bd->unit = 1;
-					if (BootDVDProbe(bd))
+					if (IDEBootDVDProbe(bd))
 						return TRUE;
 				}
 			}
@@ -84,10 +84,10 @@ Bool BootDVDProbeAll(CBlkDev *bd)
 	if (bd->base0 = d1 & ~7)
 	{
 		bd->unit = 0;
-		if (BootDVDProbe(bd))
+		if (IDEBootDVDProbe(bd))
 			return TRUE;
 		bd->unit = 1;
-		if (BootDVDProbe(bd))
+		if (IDEBootDVDProbe(bd))
 			return TRUE;
 	}
 
@@ -96,10 +96,10 @@ Bool BootDVDProbeAll(CBlkDev *bd)
 	if (bd->base0 = d1 & ~7)
 	{
 		bd->unit = 0;
-		if (BootDVDProbe(bd))
+		if (IDEBootDVDProbe(bd))
 			return TRUE;
 		bd->unit = 1;
-		if (BootDVDProbe(bd))
+		if (IDEBootDVDProbe(bd))
 			return TRUE;
 	}
 }
@@ -111,7 +111,7 @@ U0 ATARepEntry(I64 base0, I64 base1, I64 unit, U8 *message, CATARep **_head, I64
 	base1 &= -4;
 	CATARep	*tmpha;
 
-	if (type = ATAProbe(base0,base1,unit))
+	if (type = IDEATAProbe(base0,base1,unit))
 	{
 		*num_hints += 1;
 		"\n$$PURPLE$$ $$BT+X,\"%d\",LM=\"%d\\n\"$$$$FG$$$$LM,4$$", *num_hints, *num_hints;
diff --git a/src/Kernel/BlkDev/DiskAddDev.CC b/src/Kernel/BlkDev/DiskAddDev.CC
index 442152b9..26263abe 100755
--- a/src/Kernel/BlkDev/DiskAddDev.CC
+++ b/src/Kernel/BlkDev/DiskAddDev.CC
@@ -83,14 +83,16 @@ I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free
 					drive->size = bd->max_blk + 1 - bd->drv_offset;
 //The following read is a test read.
 					//if it hangs, the drive is not supported.
-					ATAReadBlks(bd, &mbr, 0, 1);
+//					IDEATAReadBlks(bd, &mbr, 0, 1);
+					AHCIAtaBlksRead(bd, &mbr, 0, 1); // ahci
 					break;
 				}
 				offset = 0;
 				ext_base = INVALID_CLUS;
 				while (prt_num < 0 || num <= prt_num)
 				{
-					ATAReadBlks(bd, &mbr, offset, 1);
+//					IDEATAReadBlks(bd, &mbr, offset, 1);
+					AHCIAtaBlksRead(bd, &mbr, offset, 1); // ahci
 					if (mbr.signature != 0xAA55)
 						break;
 					j = -1;
@@ -121,7 +123,9 @@ I64 BlkDevAdd(CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free
 								case MBR_PT_FAT32d:
 								case MBR_PT_FAT32e:
 								case MBR_PT_FAT32f:
-									ATAReadBlks(bd, &br, drive->drv_offset, 1);
+//									IDEATAReadBlks(bd, &br, drive->drv_offset, 1);
+									AHCIAtaBlksRead(bd, &br, drive->drv_offset, 1); // ahci
+
 									drive->drive_signature = DRIVE_SIGNATURE_VAL;
 									drive->prt_num = num;
 									res++;
@@ -222,7 +226,7 @@ Bool GetBaseUnit(CBlkDev *bd)
 			StreamPrint("probe = TRUE;");
 	};
 
-	if (!probe || !BootDVDProbeAll(bd))
+	if (!probe || !IDEBootDVDProbeAll(bd))
 	{
 		"\nDon't worry.  This is not a product\n"
 		"registration.				ZenithOS just needs the\n"
@@ -244,7 +248,7 @@ Bool GetBaseUnit(CBlkDev *bd)
 			while (!('0' <= ch <= '1'));
 			'' ch;
 			bd->unit = ch - '0';
-			blkdev.dvd_boot_is_good = BootDVDProbe(bd);
+			blkdev.dvd_boot_is_good = IDEBootDVDProbe(bd);
 			return TRUE;
 		}
 		else
@@ -268,6 +272,22 @@ U0 BlkDevsInitAll()
 
 	AHCIInit;
 
+	if (!blkdev.ahci_hba)
+	{
+		"\nZenithOS requires AHCI.\n\n"
+		"If in IDE compatibility mode, switch to SATA mode.\n"
+		"If running in a VM, ensure disks are organized under a SATA controller.\n\n"
+		"Rebooting in 10 seconds...\n";
+		Sleep(10*1000);
+//		Reboot; // illegal forward ref compiler error?
+		*0x472(U16 *) = 0; // Manual reboot
+		OutU8(0x70, 0x8F);
+		OutU8(0x71, 0x00);
+		OutU8(0x70, 0x00);
+		OutU8(0x92, InU8(0x92) | 1);
+		SysHlt;
+	}
+
 	#exe {
 		if (kernel_config->opts[CONFIG_MOUNT_IDE_AUTO])
 			StreamPrint("MountIDEAuto;");
diff --git a/src/Kernel/BlkDev/DiskBlk.CC b/src/Kernel/BlkDev/DiskBlk.CC
index 861e55a1..212e7975 100755
--- a/src/Kernel/BlkDev/DiskBlk.CC
+++ b/src/Kernel/BlkDev/DiskBlk.CC
@@ -46,7 +46,7 @@ Bool BlkRead(CDrive *drive, U8 *buf, I64 blk, I64 count)
 	{
 		unlock = DriveLock(drive);
 		BlkDevInit(bd);
-		if (drive->drv_offset && blk<drive->drv_offset || blk + count>drive->drv_offset + drive->size)
+		if (drive->drv_offset && blk < drive->drv_offset || blk + count > drive->drv_offset + drive->size)
 			throw('Drive');
 		if (bd->flags & BDF_READ_CACHE)
 			RCache(drive, &buf, &blk, &count);
@@ -64,8 +64,13 @@ Bool BlkRead(CDrive *drive, U8 *buf, I64 blk, I64 count)
 					break;
 
 				case BDT_ATA:
-				case BDT_ATAPI:
-					res = ATARBlks(drive, buf, blk, count);
+//				case BDT_ATAPI:
+//					res = IDEATARBlks(drive, buf, blk, count);
+					res = AHCIAtaRBlks(drive, buf, blk, count); // ahci
+					break;
+				case BDT_ATAPI: // ahci
+					res = AHCIAtapiRBlks(drive, buf, blk, count);
+					D(buf, count);
 					break;
 			}
 			bd->last_time = tS;
@@ -113,7 +118,8 @@ Bool BlkWrite(CDrive *drive, U8 *buf, I64 blk, I64 count)
 
 				case BDT_ATA:
 				case BDT_ATAPI:
-					res = ATAWBlks(drive, buf, blk, count);
+//					res = IDEATAWBlks(drive, buf, blk, count);
+					res = AHCIAtaWBlks(drive, buf, blk, count); // ahci
 					break;
 			}
 			bd->last_time = tS;
diff --git a/src/Kernel/BlkDev/DiskBlkDev.CC b/src/Kernel/BlkDev/DiskBlkDev.CC
index e2a84f4f..d91127ec 100755
--- a/src/Kernel/BlkDev/DiskBlkDev.CC
+++ b/src/Kernel/BlkDev/DiskBlkDev.CC
@@ -110,7 +110,8 @@ Bool BlkDevInit(CBlkDev *bd)
 			case BDT_ATA:
 				bd->max_reads = 128;
 				bd->max_writes = 1;
-				res = ATAInit(bd);
+//				res = IDEATAInit(bd);
+				res = TRUE; // ahci
 				break;
 
 			case BDT_ATAPI:
@@ -122,7 +123,8 @@ Bool BlkDevInit(CBlkDev *bd)
 				if (bd->max_reads < 128)
 					bd->max_reads = 128;
 				bd->max_writes = 0xFFFF * 4;
-				if (res = ATAInit(bd))
+//				if (res = IDEATAInit(bd))
+				if (res = TRUE) // ahci
 					drive->size = bd->max_blk + 1;
 				break;
 		}
diff --git a/src/Kernel/BlkDev/DiskCDDVD.CC b/src/Kernel/BlkDev/DiskCDDVD.CC
index 0528e46e..b9b0227c 100755
--- a/src/Kernel/BlkDev/DiskCDDVD.CC
+++ b/src/Kernel/BlkDev/DiskCDDVD.CC
@@ -16,7 +16,10 @@ Bool ISOInit(CDrive *drive, I64 blk)
 		while (TRUE)
 		{
 			drive->size = MaxI64(drive->size, (i + 1) * spc);
+			"BlkRead(drive, iso, %d, %d);", i * spc, spc;
 			BlkRead(drive, iso, i * spc, spc);
+			D(iso);
+//			Sleep(3000);
 			buf[0](U32) = iso->id[0](U32);
 			buf[4](U16) = iso->id[4](U8);
 			switch (ListMatch(buf, "CD001\0CDW02\0BEA01\0BOOT2\0NSR02\0NSR03\0TEA01\0", LMF_EXACT))
@@ -98,12 +101,12 @@ U0 DVDImageRead(U8 dvd_drive_let, U8 *out_name)
 
 		retry = 4;
 		while (--retry)
-			if (ATAPIReadBlks2(bd, tS + 7.0 + 0.004 * n / spc, buf, blk / spc, n / spc, TRUE))
+			if (IDEATAPIReadBlks2(bd, tS + 7.0 + 0.004 * n / spc, buf, blk / spc, n / spc, TRUE))
 //n is 0x800 if max_reads.	Up to 8 additional seconds
 				break;
 
 		if (!retry)
-			ATAPIReadBlks2(bd, 0, buf, blk / spc, n / spc, TRUE);
+			IDEATAPIReadBlks2(bd, 0, buf, blk / spc, n / spc, TRUE);
 
 		FBlkWrite(f, buf, blk, n);
 		count -= n;
@@ -204,7 +207,7 @@ U0 DVDImageWrite(U8 dvd_drive_let, U8 *in_name=NULL, I64 media_type=MT_DVD)
 		Yield;
 
 	BlkDevLock(bd);
-	ATAPIWaitReady(bd, 0);
+	IDEATAPIWaitReady(bd, 0);
 
 	progress1 = 0;
 	progress1_max = count;
@@ -223,31 +226,31 @@ U0 DVDImageWrite(U8 dvd_drive_let, U8 *in_name=NULL, I64 media_type=MT_DVD)
 			buf = d->buf0;
 		while (d->in_buf <= d->out_buf)
 			Yield;
-		ATAPIWriteBlks(bd, buf, blk / spc, (n + spc - 1) / spc);
+		IDEATAPIWriteBlks(bd, buf, blk / spc, (n + spc - 1) / spc);
 		d->out_buf++;
 		count -= n;
 		blk += n;
 		progress1 += n;
 	}
-	ATAPISync(bd);
+	IDEATAPISync(bd);
 
 	progress1 = 0;
 	progress1_max = 2;
 	StrCopy(progress1_desc, "Closing");
 	for (i = 0; i < 2; i++)
 	{
-		ATAPIClose(bd, 0x100, i); //Close tracks
+		IDEATAPIClose(bd, 0x100, i); //Close tracks
 		progress1++;
 	}
 
-	ATAPISync(bd);
+	IDEATAPISync(bd);
 
-	ATAPIClose(bd, 0x200); //close disk
-	ATAPISync(bd);
+	IDEATAPIClose(bd, 0x200); //close disk
+	IDEATAPISync(bd);
 	if (media_type == MT_DVD)
 	{
-		ATAPIClose(bd, 0x300);
-		ATAPISync(bd);
+		IDEATAPIClose(bd, 0x300);
+		IDEATAPISync(bd);
 	}
 
 	*progress1_desc = 0;
diff --git a/src/Kernel/BlkDev/DiskDrive.CC b/src/Kernel/BlkDev/DiskDrive.CC
index 7c336ab9..73cfb89a 100755
--- a/src/Kernel/BlkDev/DiskDrive.CC
+++ b/src/Kernel/BlkDev/DiskDrive.CC
@@ -276,7 +276,7 @@ U0 DiskChange(U8 drv_let=0)
 	else if (bd->flags & BDF_REMOVABLE)
 	{
 		if (bd->type == BDT_ATAPI)
-			ATAInit(bd); //TODO: This is a kludge for QEMU?
+			//IDEATAInit(bd); //TODO: This is a kludge for QEMU?
 		DiskCacheInvalidate(drive);
 	}
 	Drive(drv_let);
diff --git a/src/Kernel/BlkDev/DiskFormat.CC b/src/Kernel/BlkDev/DiskFormat.CC
index 20dcb1d6..a7d64faa 100755
--- a/src/Kernel/BlkDev/DiskFormat.CC
+++ b/src/Kernel/BlkDev/DiskFormat.CC
@@ -14,7 +14,8 @@ Bool DriveTypeSet(U8 drv_let, I64 type=FSt_REDSEA)
 			ext_base = INVALID_CLUS;
 			while (TRUE)
 			{
-				ATAReadBlks(bd, &mbr, offset, 1);
+//				IDEATAReadBlks(bd, &mbr, offset, 1);
+				AHCIAtaBlksRead(bd, &mbr, offset, 1); // ahci
 				j =- 1;
 				for (i = 0; i < 4; i++)
 				{
@@ -41,7 +42,8 @@ Bool DriveTypeSet(U8 drv_let, I64 type=FSt_REDSEA)
 										throw('Drive');
 								}
 								mbr.p[i].active = 0x80;
-								ATAWriteBlks(bd, &mbr, offset, 1);
+//								IDEATAWriteBlks(bd, &mbr, offset, 1);
+								AHCIAtaBlksWrite(bd, &mbr, offset, 1); // ahci
 								return TRUE;
 							}
 							drv_num++;
diff --git a/src/Kernel/KGlobals.CC b/src/Kernel/KGlobals.CC
index a898f16e..8863ab2d 100755
--- a/src/Kernel/KGlobals.CC
+++ b/src/Kernel/KGlobals.CC
@@ -13,7 +13,7 @@ CTask	*sys_winmgr_task,
 U8		*rev_bits_table; //Table with U8 bits reversed
 CDate	 local_time_offset;
 F64		*pow10_I64,
-		 sys_os_version = 1.14;
+		 sys_os_version = 2.0;
 
 CAutoCompleteDictGlobals acd;
 CAutoCompleteGlobals	 ac;
diff --git a/src/Kernel/KStart16.CC b/src/Kernel/KStart16.CC
index b496b660..cb6bf061 100755
--- a/src/Kernel/KStart16.CC
+++ b/src/Kernel/KStart16.CC
@@ -22,7 +22,7 @@ SYS_RUN_LEVEL::				DU32	0;
 
 #exe
 {
-	StreamPrint("SYS_COMPILE_TIME:: DU64 0x%X;", Now); //See $LK,"BootDVDProbe",A="MN:BootDVDProbe"$
+	StreamPrint("SYS_COMPILE_TIME:: DU64 0x%X;", Now); //See $LK,"IDEBootDVDProbe",A="MN:IDEBootDVDProbe"$
 };
 
 #assert SYS_COMPILE_TIME + sizeof(CDate) + sizeof(CBinFile) < DVD_BLK_SIZE
diff --git a/src/Kernel/KernelC.HH b/src/Kernel/KernelC.HH
index eca10da1..cc273d30 100755
--- a/src/Kernel/KernelC.HH
+++ b/src/Kernel/KernelC.HH
@@ -351,10 +351,10 @@ public extern CDirEntry *FilesFind(U8 *files_find_mask, I64 fuf_flags=0);
 #help_index "File/System"
 public extern	CATARep			*ATAIDDrives(CATARep *head, CATARep **_ata_drive, CATARep **_atapi_drive);
 extern			CBlkDev			*ATAMount(U8 first_drive_let, I64 type, I64 base0, I64 base1, I64 unit);
-extern			Bool			 ATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start);
-extern			I64				 ATAProbe(I64 base0, I64 base1, I64 unit);
-extern			U0				 ATAReadBlks( CBlkDev *bd, U8 *buf, I64 blk, I64 count);
-extern			U0				 ATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count);
+extern			Bool			 IDEATAPIStartStop(CBlkDev *bd, F64 timeout, Bool start);
+extern			I64				 IDEATAProbe(I64 base0, I64 base1, I64 unit);
+extern			U0				 IDEATAReadBlks( CBlkDev *bd, U8 *buf, I64 blk, I64 count);
+extern			U0				 IDEATAWriteBlks(CBlkDev *bd, U8 *buf, I64 blk, I64 count);
 extern			I64				 BlkDevAdd(   CBlkDev *bd, I64 prt_num=I64_MIN, Bool whole_drive, Bool make_free);
 extern			U0				 DiskCacheInit(I64 size_in_U8s);
 public extern	U0				 DiskCacheInvalidate(CDrive *drive);
diff --git a/src/Misc/AHCIOSInstall.CC b/src/Misc/AHCIOSInstall.CC
new file mode 100755
index 00000000..f1405dbc
--- /dev/null
+++ b/src/Misc/AHCIOSInstall.CC
@@ -0,0 +1,161 @@
+U0 InstallDrive(U8 drv_let)
+{
+	U8 *st;
+
+	Sleep(3000);
+
+	ExePrint("CopyTree(\"::/\",\"%C:/\");",			drv_let);
+	ExePrint("DirMake(\"%C:/Tmp\");",				drv_let);
+	ExePrint("DirMake(\"%C:/Tmp/ScreenShots\");",	drv_let);
+	ExePrint("DirMake(\"%C:/Home\");",				drv_let);
+
+	st = MStrPrint("%C:/Home/DoDistro.CC", drv_let);
+	if (!FileFind(st))
+		Copy("::/Misc/DoDistro.CC", st);
+	Free(st);
+
+	st = MStrPrint("%C:/Home/MakeHome.CC", drv_let);
+	if (!FileFind(st))
+		Copy("::/MakeHome.CC", st);
+	Free(st);
+}
+
+Bool VMPartDisk(CTask *task, I64 ata_port)
+{
+	if (ata_port > -1)
+	{
+		XTalkWait(task, "DiskPart(,0.5,0.5);\nC\n%d\nY", ata_port); // DOUBLE CHECK INFILE
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
+
+U0 VMInstallDrive(CTask *task, U8 drv_let, I64 ata_port, I64 atapi_port)
+{// DOUBLE CHECK INFILE
+	InstallDrive(drv_let);
+	XTalkWait(task, "BootHDIns('%C');\n\nB\n0x20000\n", drv_let);
+	if (ata_port > -1)
+		XTalkWait(task, "C\n%d\n", ata_port);
+	if (atapi_port > -1)
+		XTalkWait(task, "T%d\n", atapi_port);
+	XTalkWait(task, "\n1024\n768\n\n\n"); //Exit Drives,  set Screen Resolution, skip Disk Cache and Options
+}
+
+U0 VMInstallWiz()
+{
+	CTask		*task;
+	I64			 i, atapi_port = -1, ata_port = -1;
+	CAHCIPort	*port;
+
+	task = User;
+	TaskWait(task);
+	task->border_src	= BDS_CONST;
+	task->border_attr	= LTGRAY << 4 + DriveTextAttrGet(':') & 15;
+	task->text_attr		= LTGRAY << 4 + BLUE;
+	task->win_inhibit	= WIG_TASK_DEFAULT - WIF_SELF_BORDER;
+	WinHorz(Fs->win_left, Fs->win_right, task);
+	WinVert(Fs->win_top,  (Fs->win_top + Fs->win_bottom) >> 2 - 1, task);
+	WinVert(task->win_bottom + 3, Fs->win_bottom);
+	WinToTop(Fs);
+
+
+	////////////////////////////////////
+	SATARep;
+	for (i = 0; i < AHCI_MAX_PORTS; i++)
+	{
+		if (Bt(&blkdev.ahci_hba->ports_implemented, i))
+		{
+			port = &blkdev.ahci_hba->ports[i];
+			if (port->signature == AHCI_PxSIG_ATA)
+			{
+				ata_port = i;
+				break;
+			}
+		}
+	}
+	for (i = 0; i < AHCI_MAX_PORTS; i++)
+	{
+		if (Bt(&blkdev.ahci_hba->ports_implemented, i))
+		{
+			port = &blkdev.ahci_hba->ports[i];
+			if (port->signature == AHCI_PxSIG_ATAPI)
+			{
+				atapi_port = i;
+				break;
+			}
+		}
+	}
+
+	if (VMPartDisk(task, ata_port))
+	{
+		VMInstallDrive(task, 'C', ata_port, atapi_port);
+		VMInstallDrive(task, 'D', ata_port, atapi_port);
+		BootMHDIns('C');
+	}
+
+	////////////////////////////////////
+
+	WinVert(task->win_top, Fs->win_bottom);
+	Kill(task);
+}
+
+U0 DoInstructions()
+{
+	CTask *task = User;
+
+	AutoComplete;
+	WinToTop(Fs);
+	WinTileVert;
+	XTalk(task, "Ed(\"::/Doc/Install.DD\");\n");
+}
+
+Bool DoInstall(Bool prompt_reboot)
+{
+	I64					 res = FALSE, vm_install = TRUE;
+	CSMBIOSSystemInfo	*sys_info = SMBIOSStructGet(SMBIOSt_SYSTEM);
+	U8					*company = SMBIOSStr(sys_info, sys_info->manufacturer);
+	
+	if (StrCompare(company, "VMware, Inc.") && StrCompare(company, "innotek GmbH") && StrCompare(company, "QEMU"))
+	{
+		"\n\n\n\n\nAre you installing inside VMware, QEMU, VirtualBox or a similar virtual machine? ";
+		vm_install = YorN;
+	}
+	DocBottom;
+	if (vm_install)
+	{
+		VMInstallWiz();
+		res = TRUE;
+	}
+	else
+	{
+		"\n\nThis wizard works if you have a partition ready. You can partition the drive or BootHDIns() "
+				"with more options if you do it by hand, not using this wizard.\n\n"
+				"Continue Install Wizard ";
+		if (YorN)
+		{
+			//RegularInstallWiz(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+			res = TRUE;
+		}
+		else
+			prompt_reboot = FALSE;
+	}
+	if (prompt_reboot)
+	{
+		"Reboot Now ";
+		if (YorN)
+			Reboot;
+	}
+	return res;
+}
+
+Bool OSInstall(Bool prompt_reboot=TRUE)
+{
+	DoInstructions;
+
+	return DoInstall(prompt_reboot);
+}
+
+#if __CMD_LINE__
+OSInstall(TRUE);
+#endif
diff --git a/src/Once.CC b/src/Once.CC
index 9cc299b4..5ae27e6a 100755
--- a/src/Once.CC
+++ b/src/Once.CC
@@ -27,7 +27,8 @@ U0 Tmp()
 			if (YorN)
 			{
 				DocBottom;
-				RunFile("::/Misc/OSInstall",, TRUE);
+//				RunFile("::/Misc/OSInstall",, TRUE);
+				RunFile("::/Misc/AHCIOSInstall",, TRUE);
 			}
 			if (FileFind("::/Misc/Tour"))
 			{
diff --git a/src/Zenith/Boot/BootDVD.CC b/src/Zenith/Boot/BootDVD.CC
index 272fcc3d..8882a9ea 100755
--- a/src/Zenith/Boot/BootDVD.CC
+++ b/src/Zenith/Boot/BootDVD.CC
@@ -168,7 +168,7 @@ BDVD_MAIN::
 				LOOP		@@35
 				POP 		DS
 
-//See $LK,"BootDVDProbe",A="MN:BootDVDProbe"$().
+//See $LK,"IDEBootDVDProbe",A="MN:IDEBootDVDProbe"$().
 				MOV 		EBX, U32 [BDVD_BLK_LO     - BDVD_START]
 				MOV 		AX,  U16 [BDVD_SHIFT_BLKS - BDVD_START]
 				SHL 		EAX, 16
diff --git a/src/Zenith/Boot/BootHDIns.CC b/src/Zenith/Boot/BootHDIns.CC
index da440d11..8215e0a3 100755
--- a/src/Zenith/Boot/BootHDIns.CC
+++ b/src/Zenith/Boot/BootHDIns.CC
@@ -48,7 +48,7 @@ public U0 BootHDIns(U8 drv_let=0)
 				{
 					Free(de.full_name);
 					"Modifying partition boot record.\n";
-					BlkRead(drive, &br,drive->drv_offset, 1);
+					BlkRead(drive, &br, drive->drv_offset, 1);
 
 					br.jump_and_nop[0] = OC_JMP_REL8;
 					br.jump_and_nop[1] = offset(CFAT32Boot.code) - 2;
diff --git a/src/Zenith/Boot/BootMHDIns.CC b/src/Zenith/Boot/BootMHDIns.CC
index 81d891f0..b352334b 100755
--- a/src/Zenith/Boot/BootMHDIns.CC
+++ b/src/Zenith/Boot/BootMHDIns.CC
@@ -28,7 +28,8 @@ public U0 BootMHDOldRead(U8 src_drive, U8 dst_drive)
 	{
 //Bypass partition bounds-checking
 		BlkDevLock(bd);
-		ATAReadBlks(bd, &mbr, 0, 1);
+//		IDEATAReadBlks(bd, &mbr, 0, 1);
+		AHCIAtaBlksRead(bd, &mbr, 0, 1); // ahci
 		BlkDevUnlock(bd);
 
 		Drive(dst_drive);
@@ -49,7 +50,8 @@ public U0 BootMHDOldWrite(U8 src_drive, U8 dst_drive)
 	{
 //Bypass partition bounds-checking
 		BlkDevLock(bd);
-		ATAWriteBlks(bd, mbr, 0, 1);
+//		IDEATAWriteBlks(bd, mbr, 0, 1);
+		AHCIAtaBlksWrite(bd, mbr, 0, 1); // ahci
 		BlkDevUnlock(bd);
 	}
 	Free(mbr);
@@ -69,7 +71,8 @@ public U0 BootMHDZero(U8 dst_drive)
 	MemSet(&mbr, 0, BLK_SIZE);
 //Bypass partition bounds-checking
 	BlkDevLock(bd);
-	ATAWriteBlks(bd, &mbr, 0, 1);
+//	IDEATAWriteBlks(bd, &mbr, 0, 1);
+	AHCIAtaBlksWrite(bd, &mbr, 0, 1); // ahci
 	BlkDevUnlock(bd);
 }
 
@@ -151,7 +154,8 @@ public Bool BootMHDIns(U8 drv_let, U8 *drv_list=NULL)
 				*BMHD_DAP_BLK(I64 *) = Clus2Blk(drive, de.clus);
 //Bypass partition bounds-checking
 				BlkDevLock(bd);
-				ATAReadBlks(bd, &mbr, 0, 1);
+//				IDEATAReadBlks(bd, &mbr, 0, 1);
+				AHCIAtaBlksRead(bd, &mbr, 0, 1); // ahci
 
 				for (i = 0; i < BMHD_END - BMHD_CODE; i++)
 					mbr.code[i] = BMHD_CODE(U8 *)[i];
@@ -167,7 +171,9 @@ public Bool BootMHDIns(U8 drv_let, U8 *drv_list=NULL)
 				mbr.zero = 0;
 				mbr.signature = 0xAA55;
 
-				ATAWriteBlks(bd, &mbr, 0, 1);
+//				IDEATAWriteBlks(bd, &mbr, 0, 1);
+				AHCIAtaBlksWrite(bd, &mbr, 0, 1); // ahci
+
 				BlkDevUnlock(bd);
 				res = TRUE;
 			}
diff --git a/src/Zenith/ZBlkDev/DiskPart.CC b/src/Zenith/ZBlkDev/DiskPart.CC
index b84d376f..24f1b78f 100755
--- a/src/Zenith/ZBlkDev/DiskPart.CC
+++ b/src/Zenith/ZBlkDev/DiskPart.CC
@@ -130,7 +130,8 @@ drv_let=0 means add new drive that is not already mounted.
 		mbr.p[i].size		= remaining;
 		ext_base = offset;
 	}
-	ATAWriteBlks(bd, &mbr, 0, 1);
+//	IDEATAWriteBlks(bd, &mbr, 0, 1);
+	AHCIAtaBlksWrite(bd, &mbr, 0, 1); // ahci
 
 	while (tmppp != &head)
 	{
@@ -159,7 +160,8 @@ drv_let=0 means add new drive that is not already mounted.
 			mbr.p[1].offset		= offset - ext_base;
 			mbr.p[1].size		= tmppp->size;
 		}
-		ATAWriteBlks(bd, &mbr, start_offset, 1);
+//		IDEATAWriteBlks(bd, &mbr, start_offset, 1);
+		AHCIAtaBlksWrite(bd, &mbr, start_offset, 1); // ahci
 	}
 
 	bd->flags &= ~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
diff --git a/src/Zenith/ZBlkDev/Mount.CC b/src/Zenith/ZBlkDev/Mount.CC
index b41f479a..0f703020 100755
--- a/src/Zenith/ZBlkDev/Mount.CC
+++ b/src/Zenith/ZBlkDev/Mount.CC
@@ -1,7 +1,60 @@
+I64 SATARep()
+{
+	I64			 /*bdf, */i, num = 0;
+	CAHCIPort	*port;
+//	CPCIDev		*pci;
+
+	"\nAHCI version %X.%1X%1X\n",
+		blkdev.ahci_hba->version >> 16, (blkdev.ahci_hba->version & 0xFF00) >> 8, blkdev.ahci_hba->version & 0xFF;
+/*
+	if (dev.pci_head)
+	{
+		pci = PCIDevFind(PCIC_STORAGE, PCISC_AHCI);
+//		ClassRep(pci);
+		"$$PURPLE$$$$HL,1$$Bus: 0x%02X, Dev: 0x%02X, Fun: 0x%02X$$HL,0$$$$FG$$\n\n", pci->bus, pci->dev, pci->fun;
+		"$$PURPLE$$Vendor$$FG$$: $$BLACK$$%s$$FG$$\n", pci->vendor_str;
+		"$$PURPLE$$Device$$FG$$: $$BLACK$$%s$$FG$$\n", pci->dev_id_str;
+	}	
+	else
+	{
+		bdf = PCIClassFind(PCIC_STORAGE << 16 | PCISC_AHCI << 8 + 1, 0);
+		"Bus:%02X, Dev:%02X, Fun:%02X", bdf.u8[2], bdf.u8[1], bdf.u8[0];
+		"HBA Base Address: 0x%X", PCIReadU32(bdf.u8[2], bdf.u8[1], bdf.u8[0], PCIR_BASE5) & ~0x1F;
+	}
+*/
+	if (blkdev.ahci_hba)
+	{
+		"\nImplemented Ports:\n\n";
+		for (i = 0; i < AHCI_MAX_PORTS; i++)
+		{
+			if (Bt(&blkdev.ahci_hba->ports_implemented, i))
+			{
+				port = &blkdev.ahci_hba->ports[i];
+				"$$PURPLE$$ $$BT,\"%d\",LM=\"%d\n\"$$$$FG$$", i, i;
+
+				if (port->signature == AHCI_PxSIG_ATA)
+					"$$LM,4$$$$RED$$Hard Drive   $$LTBLUE$$ATA$$FG$$\n";
+				else if (port->signature == AHCI_PxSIG_ATAPI)
+					"$$LM,4$$$$RED$$CD/DVD Drive $$LTBLUE$$ATAPI$$FG$$\n";
+				else
+					"$$LM,4$$$$RED$$Unknown      $$LTBLUE$$0x%0X$$FG$$\n", port->signature;
+
+				"$$LM,0$$\n\n";
+				num++;
+			}
+		}
+	}
+	else
+		"$$HL,1$$blkdev.ahci_hba$$HL,0$$ is NULL !\n";
+	"\n";
+
+	return num;
+}
+
 #help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
 U8 Mount2(U8 boot_drive_let, CDoc *_doc, Bool _caller_is_prtdisk)
 {//If _doc, called by $LK,"::/Kernel/KConfig.CC"$ else called by $LK,"Mount",A="MN:Mount"$().
-	I64		 count, total = 0, num_hints, drv_let, type, unit, prt_num;
+	I64		 count, total = 0, num_hints, drv_let, type, unit, prt_num, port = -1; // ahci
 	U8		 blks_buf[STR_LEN], addr_buf[STR_LEN], base0_buf[STR_LEN], base1_buf[STR_LEN],
 			*filename = NULL, *filename2 = NULL, res = 0;
 	CATARep	*head = NULL, *tmpha;
@@ -58,21 +111,26 @@ U8 Mount2(U8 boot_drive_let, CDoc *_doc, Bool _caller_is_prtdisk)
 				case BDT_ATA:
 					prt_num = I64Get("Partition Num (Default=All):", prt_num);
 				case BDT_ATAPI:
-					num_hints = ATARep(,, &head);
+//					num_hints = ATARep(,, &head);
+					num_hints = SATARep; // ahci
 					if (type == BDT_ATAPI && boot_drive_let)
 						"<ENTER> to use booted CD/DVD\n"; //Only $LK,"::/Kernel/KConfig.CC"$
 					do
 					{
 						if (num_hints)
-							"Enter dev number or\nport with $$PURPLE$$0x$$FG$$ prefix.\n"
-							"I/O Port Base0:\n";
-						else
-							"Include $$PURPLE$$0x$$FG$$ prefix.\nI/O Port Base0:\n";
+							"Enter port number: \n"; // ahci (!! using base0_buf for port num !!)
+//							"Enter dev number or\nport with $$PURPLE$$0x$$FG$$ prefix.\n"
+//							"I/O Port Base0:\n";
+//						else
+//							"Include $$PURPLE$$0x$$FG$$ prefix.\nI/O Port Base0:\n";
 						StrNGet(base0_buf, STR_LEN);
 					}
-					while (!Str2I64(base0_buf) && (type != BDT_ATAPI || !boot_drive_let));
-
-					if (1 <= Str2I64(base0_buf) <= num_hints)
+//					while (!Str2I64(base0_buf) && (type != BDT_ATAPI || !boot_drive_let));
+					while ((0 > Str2I64(base0_buf) || Str2I64(base0_buf) > num_hints - 1) &&
+							(type != BDT_ATAPI || !boot_drive_let)); // ahci
+					port = Str2I64(base0_buf);
+					
+/*					if (1 <= Str2I64(base0_buf) <= num_hints)
 					{
 						tmpha = ATARepFind(head, Str2I64(base0_buf));
 						StrPrint(base0_buf, "0x%X", tmpha->base0);
@@ -98,11 +156,18 @@ U8 Mount2(U8 boot_drive_let, CDoc *_doc, Bool _caller_is_prtdisk)
 						while (!(0 <= unit <= 1));
 						'\n';
 					}
-					LinkedListDel(head);
+					LinkedListDel(head);*/
 					break;
 			}
 			DocPrint(doc, "\"bd = BlkDevNextFreeSlot('%C', %d); bd->unit = %d;\n\";\n", drv_let, type, unit);
 			DocPrint(doc, "bd = BlkDevNextFreeSlot(\'%C\', %d); bd->unit = %d;\n", drv_let, type, unit);
+			if (port != -1) // ahci
+			{
+				DocPrint(doc, "\"AHCIPortInit(bd, &blkdev.ahci_hba->ports[%d], %d);\n\";\n", port, port);
+				DocPrint(doc, "AHCIPortInit(bd, &blkdev.ahci_hba->ports[%d], %d);\n", port, port);
+
+			}
+
 			switch (type)
 			{
 				case BDT_RAM:
@@ -124,13 +189,16 @@ U8 Mount2(U8 boot_drive_let, CDoc *_doc, Bool _caller_is_prtdisk)
 				case BDT_ATAPI:
 					if (type == BDT_ATAPI && !*base0_buf)
 					{
-						DocPrint(doc, "\"GetBaseUnit(bd);\n\";\n");
-						DocPrint(doc, "GetBaseUnit(bd);\n"); //Only $LK,"::/Kernel/KConfig.CC"$
+//						DocPrint(doc, "\"GetBaseUnit(bd);\n\";\n");
+//						DocPrint(doc, "GetBaseUnit(bd);\n"); //Only $LK,"::/Kernel/KConfig.CC"$
+						DocPrint(doc, "\"AHCIBootDVDProbeAll(bd);\n\";\n");
+						DocPrint(doc, "AHCIBootDVDProbeAll(bd);\n"); //Only $LK,"::/Kernel/KConfig.CC"$
+
 						if (drv_let == boot_drive_let)
 							make_free = TRUE;
 					}
-					else
-						DocPrint(doc, "bd->base0 = %s; bd->base1 = %s;\n", base0_buf, base1_buf);
+//					else
+//						DocPrint(doc, "bd->base0 = %s; bd->base1 = %s;\n", base0_buf, base1_buf);
 					if (type == BDT_ATA && _caller_is_prtdisk)
 					{
 						"\nReformat WHOLE drive!";