Huge amount of fixes

This commit is contained in:
mterwoord_cp 2008-03-08 08:26:25 +00:00
parent d72cf359e1
commit e628377ddc
24 changed files with 598 additions and 100 deletions

View file

@ -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();

View file

@ -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());

View file

@ -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";
}
}
}
}

View file

@ -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 {
/// <summary>
/// Remaps the IRQ's to INT20-INT2F
/// </summary>

View file

@ -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());
}

View file

@ -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();
}

View file

@ -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);
}
}

View file

@ -48,6 +48,8 @@
<Compile Include="Bus\Bus.cs" />
<Compile Include="Bus\CPUBus.cs" />
<Compile Include="Device.cs" />
<Compile Include="New\Storage\ATA.Constants.cs" />
<Compile Include="New\Storage\ATA.cs" />
<Compile Include="TempDictionary.cs" />
<Compile Include="Global.cs" />
<Compile Include="Old\CPU.cs" />

View file

@ -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<Device> mDevices = new List<Device>();
static public List<Device> Devices {
get { return mDevices; }
}
static protected List<Device> mDevices = new List<Device>();
static public List<Device> 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<Device> Find(DeviceType aType) {
var xResult = new List<Device>();
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<Device> Find(DeviceType aType) {
var xResult = new List<Device>();
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;
}
}
}

View file

@ -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 {
/// <summary>
/// High Order Byte (48-bit LBA)
/// </summary>
HighOrderByte = 0x80,
/// <summary>
/// Soft reset
/// </summary>
CB_DC_SRST = 0x04,// soft reset
/// <summary>
/// Disable interrupts
/// </summary>
CB_DC_NIEN = 0x02 // disable interrupts
}
}
}

View file

@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
namespace Cosmos.Hardware.New.Storage {
public partial class ATA: BlockDevice {
private static Action<uint> 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<uint> 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;
}
}
}
}

View file

@ -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("<ATA_BlockPartReceived");
WriteNumber((uint)i, 8, false);
@ -50,7 +49,7 @@ namespace Cosmos.Hardware {
WriteNumber(aBlock, 24);
WriteSerialString("\" Contents=\"0x");
for (int j = 0; j < 128; j++) {
WriteNumber(xValueBytes[(i * 128) + j], 8, false);
WriteNumber(aValue[(i * 128) + j], 8, false);
}
WriteSerialString("\"/>\r\n");
}

View file

@ -90,6 +90,9 @@
<ItemGroup>
<None Include="Cosmos.snk" />
</ItemGroup>
<ItemGroup>
<Folder Include="New\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Cosmos.Hardware;
namespace Cosmos.Shell.Console.Commands {
public class DeviceCommand: CommandBase {
public override string Name {
get {
return "device";
}
}
public override string Summary {
get {
return "Returns device information";
}
}
public override void Execute(string param) {
string xCommand = param;
int xIndex = param.IndexOf(' ');
if (xIndex != -1) {
xCommand = param.Substring(0, xIndex);
}
if (String.IsNullOrEmpty(xCommand)) {
System.Console.Write("Number of Storage devices: ");
System.Console.WriteLine(Device.Find(Device.DeviceType.Storage).Count.ToString());
System.Console.Write("Number of Keyboard devices: ");
System.Console.WriteLine(Device.Find(Device.DeviceType.Keyboard).Count.ToString());
System.Console.Write("Number of Mouse devices: ");
System.Console.WriteLine(Device.Find(Device.DeviceType.Mouse).Count.ToString());
System.Console.Write("Number of Other devices: ");
System.Console.WriteLine(Device.Find(Device.DeviceType.Other).Count.ToString());
System.Console.Write("Number of Unknown devices: ");
System.Console.WriteLine(Device.Find(Device.DeviceType.Unknown).Count.ToString());
return;
}
if (xCommand.CompareTo("test") == 0) {
DebugUtil.SendMessage("test", "Starting Test");
var xDevice = Hardware.Device.FindFirst(Cosmos.Hardware.Device.DeviceType.Storage);
if (xDevice == null) {
System.Console.WriteLine("No StorageDevicefound!");
DebugUtil.SendMessage("test", "No storage devices");
} else {
DebugUtil.SendMessage("test", "Storage devices found!");
BlockDevice xBD = (BlockDevice)xDevice;
if (xBD == null) {
DebugUtil.SendError("test", "Storage device is null!");
System.Console.WriteLine("Storage device is null!");
return;
}
for (uint i = 1; i <= 50; i++) {
var xBytes = xBD.ReadBlock(i);
for (int j = 0; j < xBytes.Length; j++) {
if (xBytes[j] != 0) {
System.Console.Write("Block ");
System.Console.Write(i.ToString());
System.Console.WriteLine(" contains data");
}
}
}
}
}
}
public override void Help() {
System.Console.WriteLine("device [command]");
System.Console.WriteLine(" Shows information regarding devices");
System.Console.WriteLine(" [command]: The command to execute");
}
}
}

View file

@ -48,6 +48,7 @@
<ItemGroup>
<Compile Include="Commands\BreakCommand.cs" />
<Compile Include="Commands\ClsCommand.cs" />
<Compile Include="Commands\DeviceCommand.cs" />
<Compile Include="Commands\DirCommand.cs" />
<Compile Include="Commands\EchoCommand.cs" />
<Compile Include="Commands\ExitCommand.cs" />

View file

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Text;
using Cosmos.Build.Windows;
using Cosmos.Hardware;
namespace Cosmos.Shell.Console {
public class MyClass {
@ -38,7 +39,6 @@ namespace Cosmos.Shell.Console {
System.Console.Write(" ");
System.Console.WriteLine(E.Message);
}
System.Console.WriteLine("Halting system now..");
// Halt system.

View file

@ -28,11 +28,12 @@ namespace Cosmos.Shell.Console {
_commands.Add(new Commands.ClsCommand());
_commands.Add(new Commands.DirCommand());
_commands.Add(new Commands.EchoCommand());
_commands.Add(new Commands.ExitCommand(Stop)); // TODO: Fix this.
_commands.Add(new Commands.ExitCommand(Stop));
_commands.Add(new Commands.FailCommand());
_commands.Add(new Commands.HelpCommand(_commands));
_commands.Add(new Commands.TypeCommand());
_commands.Add(new Commands.VersionCommand());
_commands.Add(new Commands.DeviceCommand());
while (running) {
System.Console.Write("Running = ");

View file

@ -33,13 +33,14 @@ namespace Indy.IL2CPU.IL.X86 {
MethodBase xMethodDef = xMethod;
mMethodDescription = CPU.Label.GenerateLabelName(xMethodDef);
mTargetMethodInfo = Engine.GetMethodInfo(xMethodDef, xMethodDef, mMethodDescription, null);
if (xMethodDef.IsStatic || !xMethodDef.IsVirtual) {
if (xMethodDef.IsStatic || !xMethodDef.IsVirtual || xMethod.IsFinal) {
Engine.QueueMethod(xMethodDef);
mNormalAddress = CPU.Label.GenerateLabelName(xMethodDef);
mReturnSize = mTargetMethodInfo.ReturnSize;
return;
}
mMethodIdentifier = Engine.GetMethodIdentifier(xMethodDef);
Engine.QueueMethod(VTablesImplRefs.GetMethodAddressForTypeRef);
mArgumentCount = mTargetMethodInfo.Arguments.Length;
mReturnSize = mTargetMethodInfo.ReturnSize;

View file

@ -15,6 +15,7 @@ namespace Indy.IL2CPU.IL.X86 {
private string mNextOpLabel;
private Type mCastAsType;
private int mCurrentILOffset;
private MethodInformation mMethodInfo;
public Castclass(ILReader aReader, MethodInformation aMethodInfo)
: base(aReader, aMethodInfo) {
Type xType = aReader.OperandValueType;
@ -26,33 +27,32 @@ namespace Indy.IL2CPU.IL.X86 {
mThisLabel = GetInstructionLabel(aReader);
mNextOpLabel = GetInstructionLabel(aReader.NextPosition);
mCurrentILOffset = (int)aReader.Position;
mMethodInfo = aMethodInfo;
}
public override void DoAssemble() {
// todo: throw an exception when the class does not support the cast!
string mReturnNullLabel = mThisLabel + "_ReturnNull";
new CPUx86.Pop(CPUx86.Registers.ECX);
Assembler.StackContents.Pop();
new CPUx86.Compare(CPUx86.Registers.ECX, "0");
new CPUx86.Move(CPUx86.Registers.EAX, CPUx86.Registers.AtESP);
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfZero(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.AtECX);
Assembler.StackContents.Push(new StackContent(4, true, false, false));
new CPUx86.Pushd("0" + mTypeId + "h");
Assembler.StackContents.Push(new StackContent(4, true, false, false));
MethodBase xMethodIsInstance = Engine.GetMethodBase(Engine.GetType("", "Indy.IL2CPU.VTablesImpl"), "IsInstance", "System.Int32", "System.Int32");
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
new CPUx86.Pushd("0x" + mTypeId.ToString("X") );
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32");
Engine.QueueMethod(xMethodIsInstance);
Op xOp = new Call(xMethodIsInstance, mCurrentILOffset);
xOp.Assembler = Assembler;
xOp.Assemble();
new CPUx86.Pop(CPUx86.Registers.EAX);
Assembler.StackContents.Pop();
new CPUx86.Pop(CPUx86.Registers.EAX);
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfEquals(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.ECX);
new CPUx86.JumpAlways(mNextOpLabel);
new CPUx86.JumpIfNotEquals(mNextOpLabel);
new CPU.Label(mReturnNullLabel);
new CPUx86.Pushd("0");
Assembler.StackContents.Push(new StackContent(4, mCastAsType));
new CPUx86.Add("esp", "4");
Newobj.Assemble(Assembler, typeof(InvalidCastException).GetConstructor(new Type[0]), Engine.RegisterType(typeof(InvalidCastException)), mThisLabel, mMethodInfo, mCurrentILOffset);
Call.EmitExceptionLogic(Assembler, mCurrentILOffset, mMethodInfo, mNextOpLabel, false);
}
}
}

View file

@ -33,7 +33,7 @@ namespace Indy.IL2CPU.IL.X86 {
new CPUx86.Compare(CPUx86.Registers.EAX, "0");
new CPUx86.JumpIfZero(mReturnNullLabel);
new CPUx86.Pushd(CPUx86.Registers.AtEAX);
new CPUx86.Pushd("0" + mTypeId + "h");
new CPUx86.Pushd("0" + mTypeId );
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
Assembler.StackContents.Push(new StackContent(4, typeof(object)));
MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32");

View file

@ -25,15 +25,16 @@ namespace Indy.IL2CPU.IL.X86 {
}
public override void DoAssemble() {
Assemble(Assembler, ObjectUtilities.GetObjectStorageSize(CtorDef.DeclaringType), CtorDef, Engine.RegisterType(CtorDef.DeclaringType), CurrentLabel, MethodInformation, ILOffset);
Assemble(Assembler, CtorDef, Engine.RegisterType(CtorDef.DeclaringType), CurrentLabel, MethodInformation, ILOffset);
}
public static void Assemble(Assembler.Assembler aAssembler, int aObjectSize, MethodBase aCtorDef, int aTypeId, string aCurrentLabel, MethodInformation aCurrentMethodInformation, int aCurrentILOffset) {
public static void Assemble(Assembler.Assembler aAssembler, MethodBase aCtorDef, int aTypeId, string aCurrentLabel, MethodInformation aCurrentMethodInformation, int aCurrentILOffset) {
if (aCtorDef != null) {
Engine.QueueMethod(aCtorDef);
} else {
throw new ArgumentNullException("aCtorDef");
}
int xObjectSize = ObjectUtilities.GetObjectStorageSize(aCtorDef.DeclaringType);
MethodInformation xCtorInfo = Engine.GetMethodInfo(aCtorDef, aCtorDef, Label.GenerateLabelName(aCtorDef), Engine.GetTypeInfo(aCtorDef.DeclaringType));
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
aAssembler.StackContents.Pop();
@ -44,7 +45,7 @@ namespace Indy.IL2CPU.IL.X86 {
if (!aAssembler.InMetalMode) {
xExtraSize += 4;
}
new CPUx86.Pushd("0" + (aObjectSize + xExtraSize).ToString("X").ToUpper() + "h");
new CPUx86.Pushd("0" + (xObjectSize + xExtraSize).ToString("X").ToUpper() + "h");
new CPUx86.Call(CPU.Label.GenerateLabelName(GCImplementationRefs.AllocNewObjectRef));
Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef);
new CPUx86.Pushd("eax");
@ -86,29 +87,29 @@ namespace Indy.IL2CPU.IL.X86 {
new Move("dword", CPUx86.Registers.AtEAX, "0" + aTypeId.ToString("X") + "h");
new Move("dword", "[eax + 4]", "0" + InstanceTypeEnum.NormalObject.ToString("X") + "h");
new Move("dword", "[eax + 8]", "0x" + xGCFieldCount.ToString("X"));
int xSize = (from item in xCtorInfo.Arguments
select item.Size + (item.Size % 4 == 0 ? 0 : (4 - (item.Size % 4)))).Take(xCtorInfo.Arguments.Length - 1).Sum();
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
new CPUx86.Pushd("[esp + 0x" + (xSize + 4).ToString("X") + "]");
}
new CPUx86.Call(CPU.Label.GenerateLabelName(aCtorDef));
new CPUx86.Test("ecx", "2");
new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_4");
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString());
}
new CPUx86.Add("esp", "4");
foreach (var xStackInt in aAssembler.StackContents) {
new CPUx86.Add("esp", xStackInt.Size.ToString());
}
Call.EmitExceptionLogic(aAssembler, aCurrentILOffset, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_4", false);
new CPU.Label(aCurrentLabel + "_NO_ERROR_4");
new CPUx86.Pop(CPUx86.Registers.EAX);
// aAssembler.StackSizes.Pop();
int xSize = (from item in xCtorInfo.Arguments
select item.Size + (item.Size % 4 == 0 ? 0 : (4 - (item.Size % 4)))).Take(xCtorInfo.Arguments.Length - 1).Sum();
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
new CPUx86.Pushd("[esp + 0x" + (xSize + 4).ToString("X") + "]");
}
new CPUx86.Call(CPU.Label.GenerateLabelName(aCtorDef));
new CPUx86.Test("ecx", "2");
new CPUx86.JumpIfEquals(aCurrentLabel + "_NO_ERROR_4");
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString());
}
new CPUx86.Add("esp", "4");
foreach (var xStackInt in aAssembler.StackContents) {
new CPUx86.Add("esp", xStackInt.Size.ToString());
}
Call.EmitExceptionLogic(aAssembler, aCurrentILOffset, aCurrentMethodInformation, aCurrentLabel + "_NO_ERROR_4", false);
new CPU.Label(aCurrentLabel + "_NO_ERROR_4");
new CPUx86.Pop(CPUx86.Registers.EAX);
// aAssembler.StackSizes.Pop();
// new CPUx86.Add(CPUx86.Registers.ESP, "4");
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size/4)*4)+1).ToString());
}
for (int i = 1; i < xCtorInfo.Arguments.Length; i++) {
new CPUx86.Add(CPUx86.Registers.ESP, (xCtorInfo.Arguments[i].Size % 4 == 0 ? xCtorInfo.Arguments[i].Size : ((xCtorInfo.Arguments[i].Size / 4) * 4) + 1).ToString());
}
new CPUx86.Push(CPUx86.Registers.EAX);
aAssembler.StackContents.Push(new StackContent(4, aCtorDef.DeclaringType));
}

View file

@ -23,7 +23,7 @@ namespace Indy.IL2CPU.IL.X86 {
new CPUx86.Compare("dword " + aAddress, "0");
new CPUx86.JumpIfNotEquals(aNextLabel);
Type xNullRefExcType = typeof(NullReferenceException);
Newobj.Assemble(aAssembler, Engine.GetTypeInfo(xNullRefExcType).StorageSize, xNullRefExcType.GetConstructor(new Type[0]), Engine.RegisterType(xNullRefExcType), aCurrentLabel, aMethodInfo, aCurrentILOffset);
Newobj.Assemble(aAssembler, xNullRefExcType.GetConstructor(new Type[0]), Engine.RegisterType(xNullRefExcType), aCurrentLabel, aMethodInfo, aCurrentILOffset);
aAssembler.StackContents.Pop();
new CPUx86.Move("[" + DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax");
Engine.QueueMethod(CPU.Assembler.CurrentExceptionOccurredRef);

View file

@ -139,6 +139,8 @@ namespace Indy.IL2CPU.IL {
//Pushd("0");
Call(SetTypeInfoRef);
for (int j = 0; j < xEmittedMethods.Count; j++) {
MethodBase xMethod = xEmittedMethods[j];
#if MTW_DEBUG
xDebug.WriteStartElement("Method");
@ -146,6 +148,9 @@ namespace Indy.IL2CPU.IL {
xDebug.WriteAttributeString("Name", xMethod.GetFullName());
xDebug.WriteEndElement();
#endif
if (xMethod.DeclaringType.FullName == "System.Object" && xMethod.Name == "Equals" && xMethod.GetParameters().Length == 1 && xMethod.GetParameters()[0].ParameterType.FullName == "System.Object") {
System.Diagnostics.Debugger.Break();
}
Pushd("0" + i.ToString("X") + "h");
Pushd("0" + j.ToString("X") + "h");
ParameterInfo[] xParams = xMethod.GetParameters();

View file

@ -209,7 +209,7 @@ namespace Indy.IL2CPU {
if (!aInMetalMode) {
do {
int xOldCount = mMethods.Count;
ScanForMethodToIncludeForVMT();
ScanForMethodsToIncludeForVMT();
ProcessAllMethods();
if (xOldCount == mMethods.Count) {
break;
@ -243,7 +243,7 @@ namespace Indy.IL2CPU {
if (!aInMetalMode) {
do {
int xOldCount = mMethods.Count;
ScanForMethodToIncludeForVMT();
ScanForMethodsToIncludeForVMT();
ProcessAllMethods();
if (xOldCount == mMethods.Count) {
break;
@ -293,7 +293,7 @@ namespace Indy.IL2CPU {
xOp.Assemble();
}
private void ScanForMethodToIncludeForVMT() {
private void ScanForMethodsToIncludeForVMT() {
List<Type> xCheckedTypes = new List<Type>();
foreach (MethodBase xMethod in mMethods.Keys) {
if (xMethod.IsStatic) {
@ -330,7 +330,7 @@ namespace Indy.IL2CPU {
if (xTD.BaseType == null) {
continue;
}
if (xMethod.IsVirtual && !xMethod.IsConstructor) {
if (xMethod.IsVirtual && !xMethod.IsConstructor&&!xMethod.IsFinal) {
Type xCurrentInspectedType = xTD.BaseType;
ParameterInfo[] xParams = xMethod.GetParameters();
Type[] xMethodParams = new Type[xParams.Length];
@ -339,7 +339,6 @@ namespace Indy.IL2CPU {
}
MethodBase xBaseMethod = GetUltimateBaseMethod(xMethod, xMethodParams, xTD);
if (xBaseMethod != null && xBaseMethod != xMethod) {
//QueueMethod(xBaseMethod);
if (mMethods.ContainsKey(xBaseMethod)) {
QueueMethod(xMethod);
}
@ -359,6 +358,17 @@ namespace Indy.IL2CPU {
}
aCurrentInspectedType = aCurrentInspectedType.BaseType;
MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name, aMethodParams);
ParameterInfo[] xParams = xFoundMethod.GetParameters();
bool xContinue = true;
for (int i = 0; i < xParams.Length; i++) {
if (xParams[i].ParameterType != aMethodParams[i]) {
xContinue = false;
continue;
}
}
if (!xContinue) {
continue;
}
if (xFoundMethod != null) {
if (xFoundMethod.IsVirtual == aMethod.IsVirtual && xFoundMethod.IsPrivate == false && xFoundMethod.IsPublic == aMethod.IsPublic && xFoundMethod.IsFamily == aMethod.IsFamily && xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly && xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly && xFoundMethod.IsFinal == false) {
xBaseMethod = xFoundMethod;
@ -366,7 +376,6 @@ namespace Indy.IL2CPU {
}
}
} catch (Exception E) {
Console.WriteLine("Error while getting UltimateBaseMethod for method '{0}':\r\n{1}", aMethod.GetFullName(), E);
// todo: try to get rid of the try..catch
}
return xBaseMethod ?? aMethod;
@ -700,6 +709,9 @@ namespace Indy.IL2CPU {
continue;
}
string xMethodName = Label.GenerateLabelName(xCurrentMethod);
if (xMethodName=="System_Boolean__System_Object_Equals_System_Object_") {
System.Diagnostics.Debugger.Break();
}
TypeInformation xTypeInfo = null;
{
if (!xCurrentMethod.IsStatic) {
@ -1265,6 +1277,9 @@ namespace Indy.IL2CPU {
if (!aMethod.IsStatic) {
RegisterType(aMethod.DeclaringType);
}
if (aMethod.DeclaringType.FullName == "System.Object" && aMethod.Name == "Equals" && aMethod.GetParameters().Length == 1 && aMethod.GetParameters()[0].ParameterType.FullName == "System.Object") {
System.Diagnostics.Debugger.Break();
}
if (!mCurrent.mMethods.ContainsKey(aMethod)) {
mCurrent.mMethods.Add(aMethod, new QueuedMethodInformation() {
Processed = false,