diff --git a/source/Boot/KudzuTest/Program.cs b/source/Boot/KudzuTest/Program.cs
index 98055142c..4ab7d1a7a 100644
--- a/source/Boot/KudzuTest/Program.cs
+++ b/source/Boot/KudzuTest/Program.cs
@@ -26,8 +26,8 @@ namespace KudzuTest {
- Cosmos.Hardware.PC.Bus.PCIBus.Init();
- Console.ReadLine();
+ //Cosmos.Hardware.PC.Bus.PCIBus.Init();
+ //Console.ReadLine();
Tests.DoAll();
//Cosmos.Kernel.Temp.Kudzu.PCI.Test();
diff --git a/source/Boot/KudzuTest/Tests.cs b/source/Boot/KudzuTest/Tests.cs
index 875355b53..ac79ded01 100644
--- a/source/Boot/KudzuTest/Tests.cs
+++ b/source/Boot/KudzuTest/Tests.cs
@@ -10,22 +10,22 @@ namespace KudzuTest {
public delegate object TestDelegate();
static public void DoAll() {
- Tests.Do("String Concatenation", Tests.StringConcat);
- Console.WriteLine("String test");
- Console.WriteLine(" " + Tests.StringConcat());
- Console.WriteLine();
+ Tests.Do("String Concatenation", Tests.StringConcat);
+ Console.WriteLine("String test");
+ Console.WriteLine(" " + Tests.StringConcat());
+ Console.WriteLine();
- Console.WriteLine("StringBuilder test");
- Console.WriteLine(Tests.StringBuilder());
- Console.WriteLine();
+ Console.WriteLine("StringBuilder test");
+ Console.WriteLine(Tests.StringBuilder());
+ Console.WriteLine();
- Console.WriteLine("IntToStr 16 test");
- Console.WriteLine(" " + Tests.IntToStr16());
- Console.WriteLine();
+ Console.WriteLine("IntToStr 16 test");
+ Console.WriteLine(" " + Tests.IntToStr16());
+ Console.WriteLine();
- Console.WriteLine("IntToStr 32 test");
- Console.WriteLine(" " + Tests.IntToStr32());
- Console.WriteLine();
+ Console.WriteLine("IntToStr 32 test");
+ Console.WriteLine(" " + Tests.IntToStr32());
+ Console.WriteLine();
Console.WriteLine("WriteLnUInt32 test");
Console.WriteLine(" " + Tests.WriteLnUInt32());
diff --git a/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs b/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs
index c819a0365..58b511339 100644
--- a/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs
+++ b/source/Cosmos.Hardware.PC/Bus/CPU/Keyboard.cs
@@ -13,5 +13,10 @@ namespace Cosmos.Hardware.PC.Bus.CPU {
byte xByte = PC.Bus.CPUBus.Read8(0x60);
ByteReceived(xByte);
}
+ public override string Name {
+ get {
+ return "Keyboard";
+ }
+ }
}
}
diff --git a/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs b/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs
index 988d9d520..ef6b3b5d6 100644
--- a/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs
+++ b/source/Cosmos.Hardware.PC/Bus/CPU/PIC.cs
@@ -5,7 +5,7 @@ using System.Text;
namespace Cosmos.Hardware.PC.Bus.CPU {
//TODO: Change this to be an instance like other drivers
- public class PIC : Cosmos.Hardware.Device {
+ public abstract class PIC : Cosmos.Hardware.Device {
///
/// Remaps the IRQ's to INT20-INT2F
///
diff --git a/source/Cosmos.Hardware.PC/Global.cs b/source/Cosmos.Hardware.PC/Global.cs
index 51ebc8343..1e205fc4b 100644
--- a/source/Cosmos.Hardware.PC/Global.cs
+++ b/source/Cosmos.Hardware.PC/Global.cs
@@ -27,6 +27,10 @@ namespace Cosmos.Hardware.PC {
HW.CPU.CreateIDT();
// end old -----------------
+ // MTW new
+ HW.New.Storage.ATA.Initialize(Sleep);
+ // MTW new end
+
HW.Device.Add(new Bus.CPU.Keyboard());
}
diff --git a/source/Cosmos.Hardware.PC/Interrupts.cs b/source/Cosmos.Hardware.PC/Interrupts.cs
index 46252d75f..af086c043 100644
--- a/source/Cosmos.Hardware.PC/Interrupts.cs
+++ b/source/Cosmos.Hardware.PC/Interrupts.cs
@@ -105,7 +105,9 @@ namespace Cosmos.Hardware.PC {
//IRQ 14 - Primary IDE. If no Primary IDE this can be changed
public static unsafe void HandleInterrupt_2E(InterruptContext* aContext) {
- Storage.ATAOld.HandleInterruptPrimary();
+ Cosmos.Hardware.DebugUtil.SendMessage("IRQ", "Primary IDE");
+ //Storage.ATAOld.HandleInterruptPrimary();
+ New.Storage.ATA.HandleInterruptPrimary();
Bus.CPU.PIC.SignalSecondary();
}
@@ -120,7 +122,8 @@ namespace Cosmos.Hardware.PC {
//IRQ 15 - Secondary IDE
public static unsafe void HandleInterrupt_2F(InterruptContext* aContext) {
- Storage.ATAOld.HandleInterruptSecondary();
+ New.Storage.ATA.HandleInterruptSecondary();
+ Cosmos.Hardware.DebugUtil.SendMessage("IRQ", "Secondary IDE");
Bus.CPU.PIC.SignalSecondary();
}
diff --git a/source/Cosmos/Cosmos.Hardware/BlockDevice.cs b/source/Cosmos/Cosmos.Hardware/BlockDevice.cs
index c25fda325..28b0e03f5 100644
--- a/source/Cosmos/Cosmos.Hardware/BlockDevice.cs
+++ b/source/Cosmos/Cosmos.Hardware/BlockDevice.cs
@@ -3,6 +3,16 @@ using System.Collections.Generic;
using System.Text;
namespace Cosmos.Hardware {
- public abstract class BlockDevice : Device {
- }
+ public abstract class BlockDevice: Device {
+ public abstract uint BlockSize {
+ get;
+ }
+
+ public abstract ulong BlockCount {
+ get;
+ }
+
+ public abstract byte[] ReadBlock(ulong aBlock);
+ public abstract void WriteBlock(ulong aBlock, byte[] aContents);
+ }
}
diff --git a/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj b/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj
index 54745461d..327afa292 100644
--- a/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj
+++ b/source/Cosmos/Cosmos.Hardware/Cosmos.Hardware.csproj
@@ -48,6 +48,8 @@
+
+
diff --git a/source/Cosmos/Cosmos.Hardware/Device.cs b/source/Cosmos/Cosmos.Hardware/Device.cs
index 254d490b2..536b175ab 100644
--- a/source/Cosmos/Cosmos.Hardware/Device.cs
+++ b/source/Cosmos/Cosmos.Hardware/Device.cs
@@ -3,37 +3,65 @@ using System.Collections.Generic;
using System.Text;
namespace Cosmos.Hardware {
- // This is the base class for all hardware devices. Hardware devices
- // are defined here as abstracts and overridden in specific implementations
- // later
- public abstract class Device {
- public enum DeviceType { Unknown, Other, Keyboard, Mouse, Storage };
+ // This is the base class for all hardware devices. Hardware devices
+ // are defined here as abstracts and overridden in specific implementations
+ // later
+ public abstract class Device:Hardware {
+ public enum DeviceType {
+ Unknown,
+ Other,
+ Keyboard,
+ Mouse,
+ Storage
+ };
- public Device() {
- }
+ public Device() {
+ }
- static protected List mDevices = new List();
- static public List Devices {
- get { return mDevices; }
- }
+ static protected List mDevices = new List();
+ static public List Devices {
+ get {
+ return mDevices;
+ }
+ }
- static public void Add(Device aDevice) {
+ static public void Add(Device aDevice) {
+ if (aDevice == null) {
+ throw new ArgumentNullException("aDevice");
+ }
mDevices.Add(aDevice);
- }
+ }
- static public List Find(DeviceType aType) {
- var xResult = new List();
- foreach (var xDevice in mDevices) {
- if (xDevice.Type == aType) {
- xResult.Add(xDevice);
- }
- }
- return xResult;
- }
+ public static Device FindFirst(DeviceType aType) {
+ for (int i = 0; i < mDevices.Count; i++) {
+ var xDevice = mDevices[i];
+ if (xDevice.Type == aType) {
+ return xDevice;
+ }
+ }
+ return null;
+ }
- protected DeviceType mType = DeviceType.Unknown;
- public DeviceType Type {
- get { return mType; }
- }
- }
+ static public List Find(DeviceType aType) {
+ var xResult = new List();
+ for (int i = 0; i < mDevices.Count;i++){
+ var xDevice = mDevices[i];
+ if (xDevice.Type == aType) {
+ xResult.Add(xDevice);
+ }
+ }
+ return xResult;
+ }
+
+ protected DeviceType mType = DeviceType.Unknown;
+ public DeviceType Type {
+ get {
+ return mType;
+ }
+ }
+
+ public abstract string Name {
+ get;
+ }
+ }
}
diff --git a/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs
new file mode 100644
index 000000000..495965aa5
--- /dev/null
+++ b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.Constants.cs
@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+
+namespace Cosmos.Hardware.New.Storage {
+ partial class ATA {
+ private static ushort[] mControllerAddresses1 = new ushort[] {
+ 0x1F0,
+ 0x170
+ };
+ private static ushort[] mControllerAddresses2 = new ushort[] {
+ 0x3F0,
+ 0x370
+ };
+ private static string[] mControllerNumbers = new string[] { "First", "Second", "Third", "Fourth" };
+ private static string[] mControllerChannels = new string[] { "Primary", "Secondary" };
+ private static string[] mDriveNames = new string[] { "Master", "Slave" };
+ private const byte ATA_DELAY_DEFAULT = 5;
+ private const byte ATA_DATA = 0;
+ private const byte ATA_ERROR = 1;
+ private const byte ATA_SECTORCOUNT = 2;
+ private const byte ATA_SECTORNUMBER = 3;
+ private const byte ATA_CYLINDERLOW = 4;
+ private const byte ATA_CYLINDERHIGH = 5;
+ private const byte ATA_DRIVEHEAD = 6;
+ private const byte ATA_STATUS = 7;
+ private const byte ATA_COMMAND = 8;
+
+ private const byte IDE_STATUSREG_ERR = 0x00000001;
+ private const byte IDE_STATUSREG_IDX = 0x00000002;
+ private const byte IDE_STATUSREG_CORR = 0x00000004;
+ private const byte IDE_STATUSREG_DRQ = 0x00000008;
+ private const byte IDE_STATUSREG_DSC = 0x00000010;
+ private const byte IDE_STATUSREG_DWF = 0x00000020;
+ private const byte IDE_STATUSREG_DRDY = 0x00000040;
+ private const byte IDE_STATUSREG_BSY = 0x00000080;
+ private const byte IDE_ERRORREG_ABRT = 0x00000004;
+
+ private const uint Timeout = 60;
+
+ private enum ATA_Commands: byte {
+ Nop = 0x00,
+ CfaRequestExtErrCode = 0x03,
+ DeviceReset = 0x08,
+ Recalibrate = 0x10,
+ ReadSectors = 0x20,
+ ReadSectorsExt = 0x24,
+ ReadDmaExt = 0x25,
+ ReadDmaQueuedExt = 0x26,
+ ReadMultipleExt = 0x29,
+ WriteSectors = 0x30,
+ WriteSectorsExt = 0x34,
+ WriteDmaExt = 0x35,
+ WriteDmaQueuedExt = 0x36,
+ CfaWriteSectorsWoErase = 0x38,
+ WriteMultipleExt = 0x39,
+ WriteVerify = 0x3C,
+ ReadVerifySectors = 0x40,
+ ReadVerifySectorsExt = 0x42,
+ FormatTrack = 0x50,
+ Seek = 0x70,
+ CfaTranslateSector = 0x87,
+ ExecuteDeviceDiagnostic = 0x90,
+ InitializeDriveParameters = 0x91,
+ InitializeDeviceParameters = 0x91,
+ StandbyImmediate2 = 0x94,
+ IdleImmediate2 = 0x95,
+ Standby2 = 0x96,
+ Idle2 = 0x97,
+ CheckPowerMode2 = 0x98,
+ Sleep2 = 0x99,
+ Packet = 0xA0,
+ IdentifyDevicePacket = 0xA1,
+ IdentifyPacketDevice = 0xA1,
+ Smart = 0xB0,
+ CfaEraseSectors = 0xC0,
+ ReadMultiple = 0xC4,
+ WriteMultiple = 0xC5,
+ SetMultipleMode = 0xC6,
+ ReadDmaQueued = 0xC7,
+ ReadDma = 0xC8,
+ WriteDma = 0xCA,
+ WriteDmaQueued = 0xCC,
+ CfaWriteMultipleWoErase = 0xCD,
+ StandbyImmediate1 = 0xE0,
+ IdleImmediate1 = 0xE1,
+ Standby1 = 0xE2,
+ Idle1 = 0xE3,
+ ReadBuffer = 0xE4,
+ CheckPowerMode1 = 0xE5,
+ Sleep1 = 0xE6,
+ FlushCache = 0xE7,
+ WriteBuffer = 0xE8,
+ FlushCacheExt = 0xEA,
+ IdentifyDevice = 0xEC,
+ SetFeatures = 0xEF,
+ }
+ private enum DeviceControlBits: byte {
+ ///
+ /// High Order Byte (48-bit LBA)
+ ///
+ HighOrderByte = 0x80,
+ ///
+ /// Soft reset
+ ///
+ CB_DC_SRST = 0x04,// soft reset
+ ///
+ /// Disable interrupts
+ ///
+ CB_DC_NIEN = 0x02 // disable interrupts
+
+ }
+ }
+}
diff --git a/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs
new file mode 100644
index 000000000..bf1d7d646
--- /dev/null
+++ b/source/Cosmos/Cosmos.Hardware/New/Storage/ATA.cs
@@ -0,0 +1,234 @@
+using System;
+using System.Collections.Generic;
+
+namespace Cosmos.Hardware.New.Storage {
+ public partial class ATA: BlockDevice {
+ private static Action mSleep;
+ private readonly string mName;
+ private readonly byte mControllerIndex;
+ private readonly ushort mController;
+ private readonly ushort mController2;
+ private readonly ushort mController_Data;
+ private readonly ushort mController_Error;
+ private readonly ushort mController_FeatureReg;
+ private readonly ushort mController_SectorCount;
+ private readonly ushort mController_SectorNumber;
+ private readonly ushort mController_CylinderLow;
+ private readonly ushort mController_CylinderHigh;
+ private readonly ushort mController_DeviceHead;
+ private readonly ushort mController_PrimaryStatus;
+ private readonly ushort mController_Command;
+ private readonly ushort mController_AlternateStatus;
+ private readonly ushort mController_DeviceControl;
+ private readonly ushort mController_DeviceAddress;
+ private readonly bool mIsPrimary;
+ /*
+#define CB_DATA 0 // data reg in/out pio_base_addr1+0
+#define CB_ERR 1 // error in pio_base_addr1+1
+#define CB_FR 1 // feature reg out pio_base_addr1+1
+#define CB_SC 2 // sector count in/out pio_base_addr1+2
+#define CB_SN 3 // sector number in/out pio_base_addr1+3
+#define CB_CL 4 // cylinder low in/out pio_base_addr1+4
+#define CB_CH 5 // cylinder high in/out pio_base_addr1+5
+#define CB_DH 6 // device head in/out pio_base_addr1+6
+#define CB_STAT 7 // primary status in pio_base_addr1+7
+#define CB_CMD 7 // command out pio_base_addr1+7
+#define CB_ASTAT 8 // alternate status in pio_base_addr2+6
+#define CB_DC 8 // device control out pio_base_addr2+6
+#define CB_DA 9 // device address in pio_base_addr2+7*/
+ private readonly byte mDrive;
+ private ATA(string aName, byte aController, byte aDrive) {
+ DebugUtil.SendMessage("ATA", aName);
+ mName = aName;
+ mControllerIndex = aController;
+ mController = mControllerAddresses1[aController];
+ mController2 = mControllerAddresses2[aController];
+ DebugUtil.SendNumber("ATA", "Primary address", mController, 16);
+ DebugUtil.SendNumber("ATA", "Secondary address", mController2, 16);
+ mType = DeviceType.Storage;
+ mDrive = aDrive;
+ mController_Data = mController;
+ mIsPrimary = aController == 0;
+ mController_Error = mController;
+ //mController_Error += 1;
+ DebugUtil.SendNumber("ATA", "mController_Error", mController_Error, 16);
+ mController_FeatureReg = (ushort)(mController + 1);
+ DebugUtil.SendNumber("ATA", "mController_FeatureReg", mController_FeatureReg, 16);
+ mController_SectorCount = (ushort)(mController + 2);
+ DebugUtil.SendNumber("ATA", "mController_SectorCount", mController_SectorCount, 16);
+ mController_SectorNumber = (ushort)(mController + 3);
+ DebugUtil.SendNumber("ATA", "mController_SectorNumber", mController_SectorNumber, 16);
+ mController_CylinderLow = (ushort)(mController + 4);
+ DebugUtil.SendNumber("ATA", "mController_CylinderLow", mController_CylinderLow, 16);
+ mController_CylinderHigh = (ushort)(mController + 5);
+ DebugUtil.SendNumber("ATA", "mController_CylinderHigh", mController_CylinderHigh, 16);
+ mController_DeviceHead = (ushort)(mController + 6);
+ DebugUtil.SendNumber("ATA", "mController_DeviceHead", mController_DeviceHead, 16);
+ mController_PrimaryStatus = (ushort)(mController + 7);
+ DebugUtil.SendNumber("ATA", "mController_PrimaryStatus", mController_PrimaryStatus, 16);
+ mController_Command = (ushort)(mController + 7);
+ DebugUtil.SendNumber("ATA", "mController_Command", mController_Command, 16);
+ mController_AlternateStatus = (ushort)(mController2 + 8);
+ DebugUtil.SendNumber("ATA", "mController_AlternateStatus", mController_AlternateStatus, 16);
+ mController_DeviceControl = (ushort)(mController2 + 8);
+ DebugUtil.SendNumber("ATA", "mController_DeviceControl", mController_DeviceControl, 16);
+ mController_DeviceAddress = (ushort)(mController2 + 9);
+ DebugUtil.SendNumber("ATA", "mController_DeviceAddress", mController_DeviceAddress, 16);
+ DebugUtil.SendNumber("ATA", "Primary address", mController, 16);
+ DebugUtil.SendNumber("ATA", "Secondary address", mController2, 16);
+ IOWriteByte(mController_DeviceControl, 0);
+ }
+
+ private void Initialize() {
+ }
+
+ public static void HandleInterruptSecondary() {
+ mSecondaryInterruptCount++;
+ IOReadByte((ushort)(mControllerAddresses1[0] + 7));
+ }
+
+ private static uint mSecondaryInterruptCount;
+
+ public static void HandleInterruptPrimary() {
+ mPrimaryInterruptCount++;
+ IOReadByte((ushort)(mControllerAddresses1[1] + 7));
+ }
+
+ private static uint mPrimaryInterruptCount;
+
+ private uint mBlockCount;
+
+ public static void Initialize(Action aSleep) {
+ if (aSleep == null) {
+ throw new ArgumentNullException("aSleep");
+ }
+ mSleep = aSleep;
+ DebugUtil.SendMessage("ATA", "Start Device Detection");
+ for (byte xControllerBaseAIdx = 0; xControllerBaseAIdx < mControllerAddresses1.Length; xControllerBaseAIdx++) {
+ for (byte xDrive = 0; xDrive < 2; xDrive++) {
+ IOWriteByte((ushort)(mControllerAddresses1[xControllerBaseAIdx] + ATA_DRIVEHEAD), (byte)((xControllerBaseAIdx << 4) | 0xA0 | (xDrive << 4)));
+ mSleep(1);
+ if (IOReadByte((ushort)(mControllerAddresses1[xControllerBaseAIdx] + ATA_STATUS)) == 0x50) {
+ Device.Add(new ATA(String.Concat(mControllerNumbers[xControllerBaseAIdx], " ", mDriveNames[xDrive]), xControllerBaseAIdx, xDrive));
+ }
+ }
+ }
+ }
+ public override uint BlockSize {
+ get {
+ return 512;
+ }
+ }
+
+ public override ulong BlockCount {
+ get {
+ throw new NotImplementedException();
+ }
+ }
+ /*
+#define CB_DATA 0 // data reg in/out pio_base_addr1+0
+#define CB_ERR 1 // error in pio_base_addr1+1
+#define CB_FR 1 // feature reg out pio_base_addr1+1
+#define CB_SC 2 // sector count in/out pio_base_addr1+2
+#define CB_SN 3 // sector number in/out pio_base_addr1+3
+#define CB_CL 4 // cylinder low in/out pio_base_addr1+4
+#define CB_CH 5 // cylinder high in/out pio_base_addr1+5
+#define CB_DH 6 // device head in/out pio_base_addr1+6
+#define CB_STAT 7 // primary status in pio_base_addr1+7
+#define CB_CMD 7 // command out pio_base_addr1+7
+#define CB_ASTAT 8 // alternate status in pio_base_addr2+6
+#define CB_DC 8 // device control out pio_base_addr2+6
+#define CB_DA 9 // device address in pio_base_addr2+7*/
+ public override byte[] ReadBlock(ulong aBlock) {
+ // 1) Read the status register of the primary or the secondary IDE controller.
+ // 2) The BSY and DRQ bits must be zero if the controller is ready.
+ DebugUtil.SendNumber("ATA", "ReadBlock", (ushort)aBlock, 32);
+ uint xSleepCount = Timeout;
+ while (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
+ mSleep(1);
+ xSleepCount--;
+ }
+ if (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
+ throw new Exception("[ATA#2] Read failed");
+ }
+ //3) Set the DEV bit to 0 for Drive0 and to 1 for Drive1 on the selected IDE controller using
+ // the Device/Head register and wait for approximately 400 nanoseconds using some NOP perhaps.
+ IOWriteByte(mController_DeviceHead, (byte)(mDrive << 4));
+ //4) Read the status register again.
+ //5) The BSY and DRQ bits must be 0 again for you to know that the IDE controller and the selected IDE drive are ready.
+ xSleepCount = Timeout;
+ while (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
+ mSleep(1);
+ xSleepCount--;
+ }
+ if (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != 0) && xSleepCount > 0) {
+ throw new Exception("[ATA#5] Read failed");
+ }
+ // 6) Write the LBA28 address to the designated IDE registers.
+ IOWriteByte(mController_SectorNumber, (byte)aBlock);
+ IOWriteByte(mController_CylinderLow, (byte)(aBlock >> 8));
+ IOWriteByte(mController_CylinderHigh, (byte)(aBlock >> 16));
+ IOWriteByte(mController_DeviceHead, (byte)(0xE0 | (mDrive << 4) | ((byte)((aBlock >> 24) & 0x0F))));
+ // 7) Set the Sector count using the Sector Count register.
+ IOWriteByte(mController_SectorCount, 1);
+ //8) Issue the Read Sector(s) command.
+ IOWriteByte(mController_Command, 0x20);
+ // 9) Read the Error register. If the ABRT bit is set then the Read Sector(s) command
+ // is not supported for that IDE drive. If the ABRT bit is not set, continue to the next step.
+ if ((IOReadByte(mController_Error) & IDE_ERRORREG_ABRT) == IDE_ERRORREG_ABRT) {
+ throw new Exception("[ATA#9] Read failed");
+ }
+ // 10) If you want to receive interrupts after reading each sector, clear the nIEN bit in the
+ // Device Control register. If you do not clear this bit then interrupts will not be generated
+ // after the reading of each sector which might cause an infinite loop if you are waiting for them.
+ // The Primary IDE Controller will generate IRQ14 and the secondary IDE controller generates IRQ 15.
+ IOWriteByte(mController_DeviceControl, 0); // receive interrupts...
+ // 11) Read the Alternate Status Register (you may even ignore the value that is read)
+ IOReadByte(mController_AlternateStatus);
+ // 12) Read the Status register for the selected IDE Controller.
+ IOReadByte(mController_Command);
+ //13) Whenever a sector of data is ready to be read from the Data Register, the BSY bit
+ // in the status register will be set to 0 and DRQ to 1 so you might want to wait until
+ // those bits are set to the mentioned values before attempting to read from the drive.
+ xSleepCount = Timeout;
+ while (((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) && xSleepCount != 0) {
+ xSleepCount--;
+ mSleep(1);
+ }
+ if ((IOReadByte(mController_Command) & (IDE_STATUSREG_BSY | IDE_STATUSREG_DRQ)) != IDE_STATUSREG_DRQ) {
+ throw new Exception("[ATA#13] Read failed");
+ }
+ //14) Read one sector from the IDE Controller 16-bits at a time using the IN or the INSW instructions.
+ byte[] xResult = new byte[512];
+ for (uint i = 0; i < 256; i++) {
+ ushort xValue = IOReadWord(mController);
+ if (xValue > 0) {
+ Console.Write("Block ");
+ Console.Write(aBlock.ToString());
+ Console.WriteLine(" Contains nonzero information!");
+ }
+ xResult[i * 2] = (byte)xValue;
+ xResult[(i * 2) + 1] = (byte)(xValue >> 8);
+ }
+ // 15) See if you have to read one more sector. If yes, repeat from step 11 again.
+ //16) If you don't need to read any more sectors, read the Alternate Status Register and ignore the byte that you read.
+ IOReadByte(mController_AlternateStatus);
+ //17) Read the status register. When the status register is read, the IDE Controller will negate
+ // the INTRQ and you will not have pending IRQs waiting to be detected. This is a MUST to read
+ // the status register when you are done reading from IDE ports.
+ IOReadByte(mController_Command);
+ DebugUtil.SendATA_BlockReceived(mControllerIndex, mDrive, (uint)aBlock, xResult);
+ return xResult;
+ }
+
+ public override void WriteBlock(ulong aBlock, byte[] aContents) {
+ throw new NotImplementedException();
+ }
+
+ public override string Name {
+ get {
+ return mName;
+ }
+ }
+ }
+}
diff --git a/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs b/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs
index 0033fb759..96995fef1 100644
--- a/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs
+++ b/source/Cosmos/Cosmos.Hardware/Old/DebugUtil.cs
@@ -36,9 +36,8 @@ namespace Cosmos.Hardware {
EndLogging();
}
- public static unsafe void SendATA_BlockReceived(byte aController, byte aDrive, uint aBlock, ushort* aValue) {
+ public static unsafe void SendATA_BlockReceived(byte aController, byte aDrive, uint aBlock, byte[] aValue) {
StartLogging();
- byte* xValueBytes = (byte*)aValue;
for (int i = 0; i < 4; i++) {
WriteSerialString("\r\n");
}
diff --git a/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj b/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj
index fa08d7d51..4c7bb8a5a 100644
--- a/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj
+++ b/source/Cosmos/Cosmos.Kernel/Cosmos.Kernel.csproj
@@ -90,6 +90,9 @@
+
+
+