示例#1
0
        /// <summary>
        /// Performs the LBA28.
        /// </summary>
        /// <param name="operation">The operation.</param>
        /// <param name="drive">The drive NBR.</param>
        /// <param name="lba">The lba.</param>
        /// <param name="data">The data.</param>
        /// <param name="offset">The offset.</param>
        /// <returns></returns>
        protected bool PerformLBA28(SectorOperation operation, uint drive, uint lba, byte[] data, uint offset)
        {
            if (drive > MaximunDriveCount)
            {
                return(false);
            }

            FeaturePort.Write8(0);
            SectorCountPort.Write8(1);

            LBALowPort.Write8((byte)(lba & 0xFF));
            LBAMidPort.Write8((byte)((lba >> 8) & 0xFF));
            LBAHighPort.Write8((byte)((lba >> 16) & 0xFF));

            DeviceHeadPort.Write8((byte)(0xE0 | (drive << 4) | ((lba >> 24) & 0x0F)));

            if (operation == SectorOperation.Write)
            {
                CommandPort.Write8(IDECommands.WriteSectorsWithRetry);
            }
            else
            {
                CommandPort.Write8(IDECommands.ReadSectorsWithRetry);
            }

            if (!WaitForRegisterReady())
            {
                return(false);
            }

            DataBlock sector = new DataBlock(data);

            //TODO: Don't use PIO
            if (operation == SectorOperation.Read)
            {
                for (uint index = 0; index < 256; index++)
                {
                    sector.SetUShort(offset + (index * 2), DataPort.Read16());
                }
            }
            else
            {
                for (uint index = 0; index < 256; index++)
                {
                    DataPort.Write16(sector.GetUShort(offset + (index * 2)));
                }
            }

            return(true);
        }
示例#2
0
        private void DoIdentifyDrive(byte index)
        {
            //HAL.DebugWriteLine("Device " + index.ToString() + " ID...");

            driveInfo[index].Present = false;

            //Send the identify command to the selected drive
            DeviceHeadPort.Write8((byte)((index == 0) ? 0xA0 : 0xB0));
            SectorCountPort.Write8(0);
            LBALowPort.Write8(0);
            LBAMidPort.Write8(0);
            LBAHighPort.Write8(0);
            CommandPort.Write8(IDECommand.IdentifyDrive);

            if (StatusPort.Read8() == 0)
            {
                //HAL.DebugWriteLine("Device " + index.ToString() + " doesnt exist...");

                //Drive doesn't exist
                return;
            }

            //Wait until a ready status is present
            if (!WaitForReadyStatus())
            {
                return;                                              //There's no ready status, this drive doesn't exist
            }
            if (LBAMidPort.Read8() != 0 && LBAHighPort.Read8() != 0) //Check if the drive is ATA
            {
                //In this case the drive is ATAPI, which is not supported
                //HAL.DebugWriteLine("Device " + index.ToString() + " not ATA");

                return;
            }

            //Wait until the identify data is present (256x16 bits)
            if (!WaitForIdentifyData())
            {
                //HAL.DebugWriteLine("Device " + index.ToString() + " ID error");
                return;
            }

            //Read the identification info
            var info = new DataBlock(512);

            for (uint ix = 0; ix < 256; ix++)
            {
                info.SetUShort(ix * 2, DataPort.Read16());
            }

            //Find the addressing mode
            bool lba48Supported = ((info.GetUShort(IdentifyDrive.CommandSetSupported83) & 0x200) == 0x200);

            driveInfo[index].AddressingMode = (lba48Supported ? AddressingMode.LBA48 : AddressingMode.LBA28);

            //Find the max LBA count
            uint  lba28SectorCount = info.GetUInt(IdentifyDrive.MaxLBA28);
            ulong lba48SectorCount = info.GetULong(IdentifyDrive.MaxLBA48);

            //HAL.DebugWriteLine("LBA48BIT=" + lba48Supported.ToString());
            //HAL.DebugWriteLine("LBA28   =" + lba28SectorCount.ToString("X2"));

            if (!lba48Supported)            //No LBA48
            {
                driveInfo[index].MaxLBA = lba28SectorCount;
            }
            else                                    //LBA48 supported
            {
                if (lba28SectorCount == 0x0FFFFFFF) //Check the limit according to the d1699r3f-ata8-acs.pdf (4.10.4 IDENTIFY DEVICE data)
                {
                    driveInfo[index].MaxLBA = (uint)lba48SectorCount;
                }
                else
                {
                    driveInfo[index].MaxLBA = lba28SectorCount;
                }
            }

            //An ATA drive is present and ready to use
            driveInfo[index].Present = true;

            //HAL.DebugWriteLine("Device " + index.ToString() + " present - MaxLBA=" + driveInfo[index].MaxLBA.ToString());
        }
示例#3
0
        private void DoIdentifyDrive(byte index)
        {
            driveInfo[index].Present = false;

            //Send the identify command to the selected drive
            DeviceHeadPort.Write8((byte)((index == 0) ? 0xA0 : 0xB0));
            SectorCountPort.Write8(0);
            LBALowPort.Write8(0);
            LBAMidPort.Write8(0);
            LBAHighPort.Write8(0);
            CommandPort.Write8(IDECommand.IdentifyDrive);

            if (StatusPort.Read8() == 0)
            {
                //Drive doesn't exist
                return;
            }

            //Wait until a ready status is present
            if (!WaitForReadyStatus())
            {
                return;                 //There's no ready status, this drive doesn't exist
            }

            if (LBAMidPort.Read8() != 0 && LBAHighPort.Read8() != 0)             //Check if the drive is ATA
            {
                //In this case the drive is ATAPI
                //HAL.DebugWriteLine("Device " + index.ToString() + " not ATA");
                return;
            }

            //Wait until the identify data is present (256x16 bits)
            if (!WaitForIdentifyData())
            {
                //HAL.DebugWriteLine("Device " + index.ToString() + " ID error");
                return;
            }

            //An ATA drive is present
            driveInfo[index].Present = true;

            //Read the identification info
            var info = new DataBlock(512);

            for (uint ix = 0; ix < 256; ix++)
            {
                info.SetUShort(ix * 2, DataPort.Read16());
            }

            //Find the addressing mode
            var lba28SectorCount = info.GetUInt(IdentifyDrive.MaxLBA28);

            AddressingMode aMode = AddressingMode.NotSupported;

            if ((info.GetUShort(IdentifyDrive.CommandSetSupported83) & 0x200) == 0x200)             //Check the LBA48 support bit
            {
                aMode = AddressingMode.LBA48;
                driveInfo[index].MaxLBA = info.GetUInt(IdentifyDrive.MaxLBA48);
            }
            else if (lba28SectorCount > 0)             //LBA48 not supported, check LBA28
            {
                aMode = AddressingMode.LBA28;
                driveInfo[index].MaxLBA = lba28SectorCount;
            }

            driveInfo[index].AddressingMode = aMode;

            //HAL.DebugWriteLine("Device " + index.ToString() + " present - MaxLBA=" + driveInfo[index].MaxLBA.ToString());
        }