Esempio n. 1
0
        /// <summary>
        /// Read sectors into the output buffer and return size in bytes
        /// </summary>
        /// <param name="num">The disk number</param>
        /// <param name="lba">Input LBA</param>
        /// <param name="size">Size in sectors</param>
        /// <param name="buffer">Output buffer</param>
        /// <returns>The amount of bytes read</returns>
        public static int ReadSector(int num, uint lba, byte size, byte[] buffer)
        {
            // The driver only supports up to 4 drives
            if (num >= 4)
            {
                return(0);
            }

            // Get IDE device from array
            IDE_Device device = Devices[num];

            if (!device.Exists)
            {
                return(0);
            }

            uint port  = device.BasePort;
            int  drive = device.Drive;

            int cmd = (drive == ATA_MASTER) ? 0xE0 : 0xF0;

            // Set Drive
            PortIO.Out8((ushort)(port + ATA_REG_DRIVE), (byte)(cmd | (byte)((lba >> 24) & 0x0F)));

            // Set PIO MODE
            PortIO.Out8((ushort)(port + ATA_REG_FEATURE), ATA_FEATURE_PIO);

            // Set size
            PortIO.Out8((ushort)(port + ATA_REG_SECCNT), size);

            // Set LBA
            PortIO.Out8((ushort)(port + ATA_REG_LBALO), (byte)lba);
            PortIO.Out8((ushort)(port + ATA_REG_LBAMID), (byte)(lba >> 8));
            PortIO.Out8((ushort)(port + ATA_REG_LBAHI), (byte)(lba >> 16));

            // Issue command
            PortIO.Out8((ushort)(port + ATA_REG_CMD), ATA_CMD_PIO_READ);

            // Wait till done
            poll(port);

            // Read data
            int offset = 0;

            for (int i = 0; i < size * 256; i++)
            {
                ushort data = PortIO.In16((ushort)(port + ATA_REG_DATA));
                buffer[offset + 0] = (byte)(data);
                buffer[offset + 1] = (byte)(data >> 8);
                offset            += 2;
            }

            return(size * 512);
        }
Esempio n. 2
0
        /// <summary>
        /// IDE Prope
        /// </summary>
        private static unsafe void probe()
        {
            int num = 0;

            // Let's prope 4 devices!
            while (num < 4)
            {
                ushort port;
                byte   channel;
                byte   drive;

                if (num <= 1)
                {
                    port    = ATA_PRIMARY_IO;
                    channel = ATA_PRIMARY;
                }
                else
                {
                    port    = ATA_SECONDARY_IO;
                    channel = ATA_SECONDARY;
                }

                if ((num % 2) != 0)
                {
                    drive = ATA_SLAVE;
                }
                else
                {
                    drive = ATA_PRIMARY;
                }

                Devices[num] = new IDE_Device();

                Devices[num].BasePort = port;
                Devices[num].Channel  = channel;
                Devices[num].Drive    = drive;

                byte[] result = identify(channel, drive);
                if (result == null)
                {
                    Devices[num].Exists = false;
                    num++;
                    continue;
                }

                Devices[num].Exists = true;

                int pos = ATA_IDENT_COMMANDSETS;
                Devices[num].CmdSet = (uint)((result[pos] << 24) | (result[pos + 1] << 16) | (result[pos + 2] << 8) | result[pos + 3]);

                pos = ATA_IDENT_DEVICETYPE;
                Devices[num].Type = (ushort)((result[pos + 1] << 8) | result[pos]);

                pos = ATA_IDENT_CAPABILITIES;
                Devices[num].Capabilities = (ushort)((result[pos + 1] << 8) | result[pos]);

                pos = ATA_IDENT_CYLINDERS;
                Devices[num].Cylinders = (ushort)((result[pos + 1] << 8) | result[pos]);

                pos = ATA_IDENT_HEADS;
                Devices[num].Heads = (ushort)((result[pos + 1] << 8) | result[pos]);

                pos = ATA_IDENT_SECTORSPT;
                Devices[num].Sectorspt = (ushort)((result[pos + 1] << 8) | result[pos]);

                pos = ATA_IDENT_MAX_LBA;
                Devices[num].Size = (uint)(((result[pos] << 24) | (result[pos + 1] << 16) | (result[pos + 2] << 8) | result[pos + 3]));

                // Model name
                pos = ATA_IDENT_MODEL;

                // NULL-terminated string
                char *name = (char *)Heap.Alloc(40 + 1);
                fixed(void *source = &result[pos])
                {
                    Memory.Memcpy(name, source, 40);
                }

                name[40]          = '\0';
                Devices[num].Name = Util.CharPtrToString(name);

                num++;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Write sector to drive and return size in bytes
        /// </summary>
        /// <param name="num">The disk number</param>
        /// <param name="lba">Input LBA</param>
        /// <param name="size">Output size in sectors</param>
        /// <param name="buffer">Input buffer</param>
        /// <returns>The amount of bytes written</returns>
        public static int WriteSector(int num, uint lba, byte size, byte[] buffer)
        {
            // The driver only supports up to 4 drivers
            if (num >= 4)
            {
                return(0);
            }

            // Get IDE device from array
            IDE_Device device = Devices[num];

            if (!device.Exists)
            {
                return(0);
            }

            uint port  = device.BasePort;
            int  drive = device.Drive;

            int cmd = (drive == ATA_MASTER) ? 0xE0 : 0xF0;

            // Set Drive
            PortIO.Out8((ushort)(port + ATA_REG_DRIVE), (byte)(cmd | (byte)((lba >> 24) & 0x0F)));

            // Set PIO MODE
            PortIO.Out8((ushort)(port + ATA_REG_FEATURE), ATA_FEATURE_PIO);

            // Set size
            PortIO.Out8((ushort)(port + ATA_REG_SECCNT), size);

            // Set LBA
            PortIO.Out8((ushort)(port + ATA_REG_LBALO), (byte)lba);
            PortIO.Out8((ushort)(port + ATA_REG_LBAMID), (byte)(lba >> 8));
            PortIO.Out8((ushort)(port + ATA_REG_LBAHI), (byte)(lba >> 16));

            // Issue command
            PortIO.Out8((ushort)(port + ATA_REG_CMD), ATA_CMD_PIO_WRITE);

            // Wait till done
            poll(port);

            // Wait for 400ns
            wait400ns(port);

            // Write data
            for (int i = 0; i < size * 256; i++)
            {
                int    pos  = i * 2;
                ushort shrt = (ushort)((buffer[pos + 1] << 8) | buffer[pos]);

                PortIO.Out16((ushort)(port + ATA_REG_DATA), shrt);
            }

            // Flush data
            PortIO.Out8((ushort)(port + ATA_REG_CMD), ATA_CMD_FLUSH);

            // Wait till done
            byte status;

            do
            {
                status = PortIO.In8((ushort)(port + ATA_REG_STATUS));
            }while ((status & ATA_STATUS_BSY) > 0);

            return(size * 512);
        }