Merge branch 'master' into fix/vgacanvas

This commit is contained in:
Quajak 2020-10-21 12:53:47 +02:00 committed by GitHub
commit b980508ed3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
39 changed files with 1303 additions and 478 deletions

22
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View file

@ -0,0 +1,22 @@
---
name: Bug report
about: For bugs in Cosmos
title: ''
labels: Bug
assignees: ''
---
#### Area of Cosmos - What area of Cosmos are we dealing with?
#### Expected Behaviour - What do you think that should happen?
#### Actual Behaviour - What unexpectedly happens?
#### Reproduction - How did you get this error to appear?
#### Version - Were you using the User Kit or Dev Kit? And what User Kit version or Dev Kit commit (Cosmos, IL2CPU, X#)?

View file

@ -0,0 +1,29 @@
---
name: Build Error and Visual Studio Problems
about: For errors when trying to build a Cosmos Kernel or use VS
title: ''
labels: ''
assignees: ''
---
Have you checked Github Issues for similar errors?
**Exception**
Post the exception returned by Visual Studio
** VS Output Logs **
Post the entire output log given by Visual Studio for the build
**To Reproduce**
Describe any changes done to a clean kernel for this error to occur.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Context**
Before posting please confirm that the following are in order
[ ] Both Cosmos VS Extensions are installed
[ ] The Cosmos nuget packages are installed
Add any other context about the problem which might be helpful.

View file

@ -0,0 +1,22 @@
---
name: Feature request
about: Suggest an idea for Cosmos
title: ''
labels: Question
assignees: ''
---
Have you checked for similar suggestions?
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View file

@ -0,0 +1,28 @@
---
name: Installation Error
about: For errors while trying to install Cosmos
title: ''
labels: 'Area: Installer'
assignees: ''
---
**Describe the problem**
A clear and concise description of where the installation is going wrong.
**Steps of installation up to now**
Steps to reproduce the behavior:
**Expected behavior**
A clear and concise description of what you expected to happen.
**Logs**
Please post the entire log given by Cosmos. For long logs please use pastebin.
**Steup (please complete the following information):**
- Cosmos Version (Userkit/Devkit)
- Are you using an admin account?
- VS Version if applicable
**Additional context**
Add any other context about the problem here.

View file

@ -0,0 +1,28 @@
---
name: Installation Problem
about: Create a report to help us improve
title: ''
labels: 'Area: Installer'
assignees: ''
---
**Describe the problem**
A clear and concise description of where the installation is going wrong/what error messages you got.
**Steps of installation up to now**
What steps of the installation have you done up to now:
**Expected behavior**
A clear and concise description of what you expected to happen.
**Logs**
Please post the entire log given by Cosmos. For long logs please use pastebin.
**Setup (please complete the following information):**
- Cosmos Version (Userkit/Devkit)
- Are you using an admin account?
- VS Version if applicable
**Additional context**
Add any other context about the problem here.

20
.github/ISSUE_TEMPLATE/plug-request.md vendored Normal file
View file

@ -0,0 +1,20 @@
---
name: Plug request
about: Suggest that a certain method should be plugged
title: ''
labels: ''
assignees: ''
---
**What is the usecase for this plug**
A clear and concise description of where the plug is needed
** Complexity of plug **
Can this plug be added without requiring new drivers or a lot of work? (Methods requiring Linq, Reflection or Networking etc. are too complex for this request)
**Describe alternatives you've considered**
Are there ways to work around this plug not existing?
**Additional context**
Add any other context about the plug request here.

View file

@ -30,7 +30,7 @@
</PropertyGroup>
<PropertyGroup>
<CommonVersion>0.1.0-build18</CommonVersion>
<CommonVersion>0.1.0-build37</CommonVersion>
<IL2CPUVersion>0.1.0-build355</IL2CPUVersion>
<XSharpVersion>0.1.0-build562</XSharpVersion>
</PropertyGroup>

View file

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using Cosmos.Build.Common;
using Cosmos.Debug.DebugConnectors;
using Cosmos.Debug.Hosts;
namespace Cosmos.TestRunner.Core
{
partial class Engine
{
private void RunIsoInQemu(string iso, string harddisk, string workingDir)
{
if (!File.Exists(harddisk))
{
throw new FileNotFoundException("Harddisk file not found!", harddisk);
}
var xParams = new Dictionary<string, string>
{
{BuildPropertyNames.IsoFileString, iso}
};
var xDebugConnector = new DebugConnectorPipeClient("Cosmos\\Serial");
InitializeDebugConnector(xDebugConnector);
var xQemu = new Qemu(xParams, RunWithGDB, harddisk)
{
OnShutDown = (a, b) => { mKernelRunning = false; },
RedirectOutput = false,
LogError = s => OutputHandler.LogDebugMessage(s),
LogOutput = s => OutputHandler.LogDebugMessage(s)
};
HandleRunning(xDebugConnector, xQemu);
}
}
}

View file

@ -54,6 +54,9 @@ namespace Cosmos.TestRunner.Core
case RunTargetEnum.Bochs:
RunTask("RunISO", () => RunIsoInBochs(xIsoFile, xHarddiskPath, workingDirectory));
break;
case RunTargetEnum.Qemu:
RunTask("RunISO", () => RunIsoInQemu(xIsoFile, xHarddiskPath, workingDirectory));
break;
case RunTargetEnum.VMware:
RunTask("RunISO", () => RunIsoInVMware(xIsoFile, xHarddiskPath));
break;

View file

@ -106,7 +106,6 @@ namespace Cosmos.TestRunner.Core
foreach (var xTarget in RunTargets)
{
yield return new RunConfiguration(isElf: true, runTarget: xTarget);
//yield return new RunConfiguration(isElf: false, runTarget: xTarget);
}
}
}

View file

@ -4,6 +4,7 @@
{
Bochs,
VMware,
HyperV
HyperV,
Qemu
}
}

View file

@ -9,6 +9,11 @@
{
IsELF = isElf;
RunTarget = runTarget;
if (runTarget == RunTargetEnum.Qemu)
{
IsELF = false;
}
}
}
}

View file

@ -17,6 +17,7 @@ namespace Cosmos.TestRunner.Full
yield return RunTargetEnum.Bochs;
//yield return RunTargetEnum.VMware;
//yield return RunTargetEnum.HyperV;
//yield return RunTargetEnum.Qemu;
}
}

View file

@ -39,6 +39,7 @@ namespace Cosmos.Compiler.Tests.Bcl
DelegatesTest.Execute();
EventsTest.Execute();
RandomTests.Execute();
ConvertTests.Execute();
// System.Collections
HashtableTest.Execute();

View file

@ -0,0 +1,23 @@
using Cosmos.TestRunner;
using System;
using System.Collections.Generic;
using System.Text;
namespace Cosmos.Compiler.Tests.Bcl.System
{
public static class ConvertTests
{
public static void Execute()
{
Assert.AreEqual("1010", Convert.ToString(10, 2), "Convert.ToString(int, 2) works");
Assert.AreEqual("12", Convert.ToString(10, 8), "Convert.ToString(int, 8) works");
Assert.AreEqual("10", Convert.ToString(10, 10), "Convert.ToString(int, 10) works");
Assert.AreEqual("A", Convert.ToString(10, 16), "Convert.ToString(int, 16) works");
Assert.AreEqual("11000100000", Convert.ToString(1568, 2), "Convert.ToString(int, 2) works");
Assert.AreEqual("3040", Convert.ToString(1568, 8), "Convert.ToString(int, 8) works");
Assert.AreEqual("1568", Convert.ToString(1568, 10), "Convert.ToString(int, 10) works");
Assert.AreEqual("620", Convert.ToString(1568, 16), "Convert.ToString(int, 16) works");
}
}
}

View file

@ -12,7 +12,6 @@ namespace Cosmos.Kernel.Tests.Fat.System.IO
/// </summary>
public static void Execute(Debugger mDebugger)
{
mDebugger.Send("START TEST: Delete a directory:");
Directory.CreateDirectory(@"0:\TestDir1");
Assert.IsTrue(Directory.Exists(@"0:\TestDir1"), "TestDir1 wasn't created!");
@ -97,22 +96,20 @@ namespace Cosmos.Kernel.Tests.Fat.System.IO
mDebugger.Send("");
#if false
mDebugger.Send("START TEST: Delete a file with Directory.Delete:");
File.Create(@"0:\file1.txt");
mDebugger.Send("START TEST: Creating a subdirecty with Directory.CreateDirectory:");
try
{
Directory.Delete(@"0:\file1.txt");
}
catch (Exception e)
{
Assert.IsTrue(File.Exists(@"0:\file1.txt"), "The file was deleted by Directory.Delete.");
}
Directory.CreateDirectory(@"0:\TestDir1");
Assert.IsTrue(Directory.Exists(@"0:\TestDir1"), "TestDir1 was created!");
Directory.CreateDirectory(@"0:\TestDir1\test");
Assert.IsTrue(Directory.Exists(@"0:\TestDir1\test"), "test subdirectory was created!");
Directory.Delete(@"0:\TestDir1\test");
Assert.IsFalse(Directory.Exists(@"0:\TestDir1\test"), "test subdirectory was deleted!");
Directory.Delete(@"0:\TestDir1");
Assert.IsFalse(Directory.Exists(@"0:\TestDir1"), "TestDir1 was deleted!");
mDebugger.Send("END TEST");
mDebugger.Send("");
#endif
mDebugger.Send("START TEST: Create a directory with a Long Filename:");
Directory.CreateDirectory(@"0:\TestDir1");

View file

@ -83,6 +83,9 @@ namespace GraphicTest
pen.Color = Color.MediumPurple;
aCanvas.DrawPolygon(pen, new Point(200, 250), new Point(250, 300), new Point(220, 350), new Point(210, 275));
/* Color.FromName */
aCanvas.Clear(Color.FromName("Navy"));
/* A LimeGreen rectangle */
pen.Color = Color.LimeGreen;
aCanvas.DrawRectangle(pen, 450, 300, 80, 60);
@ -114,6 +117,8 @@ namespace GraphicTest
aCanvas.DrawImage(bitmap, new Point(0, 0));
aCanvas.DrawImage(bitmap2, new Point(200, 0));
//Scale Bitmap
aCanvas.DrawImage(bitmap,0,0,50,50);
aCanvas.DrawImageAlpha(bitmap3, new Point(0, 300));

View file

@ -22,9 +22,12 @@ namespace ProcessorTests
{
try
{
TestMultibootMemoryMap();
TestGetRam();
TestVendorNameIsNotBlank();
TestCycleCount();
TestCycleRateIsNotZero();
TestMultiboot();
TestController.Completed();
}
@ -36,6 +39,27 @@ namespace ProcessorTests
}
}
public void TestGetRam()
{
Assert.IsTrue(CPU.GetAmountOfRAM() > 0, "CPU.GetAmountOfRAM() returns a positive value: " + CPU.GetAmountOfRAM());
}
public void TestMultibootMemoryMap()
{
var memoryMap = CPU.GetMemoryMap();
for (int i = 0; i < memoryMap.Length; i++)
{
mDebugger.Send($"Memory Map: {memoryMap[i].Address} " +
$"Length: {memoryMap[i].Length} Type: {memoryMap[i].Type}");
}
Assert.IsTrue(memoryMap.Length != 0, "Memory Map is not empty! Length " + memoryMap.Length);
}
public void TestMultiboot()
{
Assert.IsTrue(Multiboot.GetMBIAddress() != 0, $"Multiboot.GetMBIAddress works {Multiboot.GetMBIAddress()}");
}
public void TestBrandStringBlank()
{
string brandString = CPU.GetCPUBrandString();

View file

@ -1,4 +1,6 @@
namespace Cosmos.Core
using Cosmos.Debug.Kernel;
namespace Cosmos.Core
{
/// <summary>
/// Bootstrap class. Used to invoke pre-boot methods.
@ -22,7 +24,7 @@
/// <summary>
/// Multiboot header pointer.
/// </summary>
public static Multiboot.Header* header;
public static Multiboot.Header* MultibootHeader;
/// <summary>
/// VBE mode info pointer.
@ -59,13 +61,10 @@
*/
CPU.InitFloat();
header = (Multiboot.Header*)Multiboot.GetMBIAddress();
MultibootHeader = (Multiboot.Header*)Multiboot.GetMBIAddress();
modeinfo = (Core.VBE.ModeInfo*)header->vbeModeInfo;
controllerinfo = (Core.VBE.ControllerInfo*)header->vbeControlInfo;
// Managed_Memory_System.ManagedMemory.Initialize();
// Managed_Memory_System.ManagedMemory.SetUpMemoryArea();
modeinfo = (Core.VBE.ModeInfo*)MultibootHeader->vbeModeInfo;
controllerinfo = (Core.VBE.ControllerInfo*)MultibootHeader->vbeControlInfo;
}
}
}

View file

@ -1,5 +1,7 @@
#define COSMOSDEBUG
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using IL2CPU.API.Attribs;
namespace Cosmos.Core
@ -110,8 +112,6 @@ namespace Cosmos.Core
return xResult;
}
/// <summary>
/// Get CPU vendor name.
/// </summary>
@ -300,7 +300,8 @@ namespace Cosmos.Core
if (!(rs == ""))
{
return rs;
} else
}
else
{
throw new NotSupportedException();
}
@ -308,14 +309,12 @@ namespace Cosmos.Core
throw new NotSupportedException();
}
/// <summary>
/// Check if can read CPU ID. Plugged.
/// </summary>
/// <returns>non-zero if can read.</returns>
/// <exception cref="NotImplementedException">Thrown on fatal error, contact support.</exception>
internal static int CanReadCPUID() => throw new NotImplementedException();
public static int CanReadCPUID() => throw new NotImplementedException();
/// <summary>
/// Read CPU ID. Plugged.
@ -326,7 +325,7 @@ namespace Cosmos.Core
/// <param name="ecx">ecx.</param>
/// <param name="edx">edx.</param>
/// <exception cref="NotImplementedException">Thrown on fatal error, contact support.</exception>
internal static void ReadCPUID(uint type, ref int eax, ref int ebx, ref int ecx, ref int edx) => throw new NotImplementedException();
public static void ReadCPUID(uint type, ref int eax, ref int ebx, ref int ecx, ref int edx) => throw new NotImplementedException();
/// <summary>
/// Read timestamp counter. Plugged.
@ -341,5 +340,107 @@ namespace Cosmos.Core
/// <returns>ulong value.</returns>
/// <exception cref="NotImplementedException">Thrown on fatal error, contact support.</exception>
internal static ulong ReadFromModelSpecificRegister() => throw new NotImplementedException();
/// <summary>
/// Checks if Multiboot returned a memory map
/// </summary>
/// <returns></returns>
public static unsafe bool MemoryMapExists()
{
return (Bootstrap.MultibootHeader->Flags & 1 << 6) == 64;
}
/// <summary>
/// Get the Memory Map Information from Multiboot
/// </summary>
/// <returns>Returns an array of MemoryMaps containing the Multiboot Memory Map information. The array may have empty values at the end.</returns>
public static unsafe MemoryMap[] GetMemoryMap()
{
if (!MemoryMapExists())
{
throw new Exception("No Memory Map was returned by Multiboot");
}
var rawMap = new RawMemoryMap[64];
var currentMap = (RawMemoryMap*)Bootstrap.MultibootHeader->memMapAddress;
int counter = 0;
while ((uint)currentMap < (Bootstrap.MultibootHeader->memMapAddress + Bootstrap.MultibootHeader->memMapLength) && counter < 64)
{
rawMap[counter++] = *currentMap;
currentMap = (RawMemoryMap*)((uint*)currentMap + ((currentMap->Size + 4 )>> 2)); //The size is in bits, not bytes
if (currentMap->Size == 0)
{
break;
}
}
if (counter >= 64)
{
throw new Exception("Memory Map returned too many segments");
}
var entireMap = new MemoryMap[counter];
for (int i = 0; i < counter; i++)
{
var rawMemoryMap = rawMap[i];
entireMap[i] = new MemoryMap
{
Address = (ulong)rawMemoryMap.HighBaseAddr << 32 | rawMemoryMap.LowBaseAddr,
Length = (ulong)rawMemoryMap.HighLength << 32 | rawMemoryMap.LowLength,
Type = rawMemoryMap.Type
};
}
return entireMap;
}
}
public class MemoryMap
{
/// <summary>
/// Base Address of the memory region
/// </summary>
public ulong Address;
/// <summary>
/// Length in bytes of the region
/// </summary>
public ulong Length;
/// <summary>
/// Type of RAM in region. 1 is available. 3 is for ACPI. All other is unavailable
/// </summary>
public uint Type;
}
[StructLayout(LayoutKind.Explicit, Size = 24)]
public struct RawMemoryMap
{
/// <summary>
/// Size of this entry
/// </summary>
[FieldOffset(0)]
public uint Size;
/// <summary>
/// Low 32 bits of the base address
/// </summary>
[FieldOffset(4)]
public uint LowBaseAddr;
/// <summary>
/// High 32 bits of the base address
/// </summary>
[FieldOffset(8)]
public uint HighBaseAddr;
/// <summary>
/// Low 32 bits of the length of memory block in bytes
/// </summary>
[FieldOffset(12)]
public uint LowLength;
/// <summary>
/// High 32 bits of the length of memory block in bytes
/// </summary>
[FieldOffset(16)]
public uint HighLength;
/// <summary>
/// Type of memory area, 1 if usable RAM, everything else unusable.
/// </summary>
[FieldOffset(20)]
public uint Type;
}
}

View file

@ -8,6 +8,7 @@ namespace Cosmos.Core
/// </summary>
public unsafe class MemoryOperations
{
#region Fill
/// <summary>
/// Fill memory block. Plugged.
/// </summary>
@ -183,6 +184,23 @@ namespace Cosmos.Core
}
}
/// <summary>
/// Fill source to destination.
/// </summary>
/// <param name="dest">Destination.</param>
/// <param name="src">Source.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Fill(sbyte[] dest, sbyte[] src)
{
fixed (sbyte* destPtr = dest)
fixed (sbyte* srcPtr = src)
{
Copy(destPtr, srcPtr, dest.Length);
}
}
#endregion Fill
#region Copy
/// <summary>
/// Copy source to destination.
/// plugged.
@ -329,19 +347,6 @@ namespace Cosmos.Core
}
}
/// <summary>
/// Fill source to destination.
/// </summary>
/// <param name="dest">Destination.</param>
/// <param name="src">Source.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Fill(sbyte[] dest, sbyte[] src)
{
fixed (sbyte* destPtr = dest)
fixed (sbyte* srcPtr = src)
{
Copy(destPtr, srcPtr, dest.Length);
}
}
#endregion Copy
}
}

View file

@ -139,7 +139,7 @@ namespace Cosmos.Core
/// <returns>True if is available, false if not</returns>
public static bool IsAvailable()
{
if ((Bootstrap.header->Flags & VBEINFO_PRESENT) == 0)
if ((Bootstrap.MultibootHeader->Flags & VBEINFO_PRESENT) == 0)
{
return false;
}

View file

@ -1,64 +0,0 @@
namespace Cosmos.Core
{
/// <summary>
/// ProcessorInformation class. Used to get vendor information from the CPU.
/// </summary>
public unsafe class ProcessorInformation
{
/// <summary>
/// Returns the Processor's vendor name
/// </summary>
/// <returns>CPU Vendor name</returns>
public static string GetVendorName()
{
if (CanReadCPUID() > 0)
{
int[] raw = new int[3];
fixed (int* ptr = raw)
FetchCPUVendor(ptr);
return new string(new char[] {
(char)(raw[0] >> 24),
(char)((raw[0] >> 16) & 0xff),
(char)((raw[0] >> 8) & 0xff),
(char)(raw[0] & 0xff),
(char)(raw[1] >> 24),
(char)((raw[1] >> 16) & 0xff),
(char)((raw[1] >> 8) & 0xff),
(char)(raw[1] & 0xff),
(char)(raw[2] >> 24),
(char)((raw[2] >> 16) & 0xff),
(char)((raw[2] >> 8) & 0xff),
(char)(raw[2] & 0xff),
});
}
else
return "\0";
}
/// <summary>
/// Check if can read CPU ID.
/// </summary>
/// <returns>int value.</returns>
internal static int CanReadCPUID() => 0; //plugged
/// <summary>
/// Fetch CPU vendor.
/// </summary>
/// <param name="target">pointer to target.</param>
internal static void FetchCPUVendor(int* target) { } //plugged
/// <summary>
/// Returns the number of CPU cycles since startup of the current CPU core
/// </summary>
/// <returns>Number of CPU cycles since startup</returns>
public static long GetCycleCount() => 0; //plugged
/// <summary>
/// Returns the number of CPU cycles per seconds
/// </summary>
/// <returns>Number of CPU cycles per seconds</returns>
public static long GetCycleRate() => 0; //plugged
}
}

View file

@ -1,12 +1,25 @@
using Cosmos.Core;
using IL2CPU.API.Attribs;
using XSharp;
using XSharp.Assembler;
namespace Cosmos.Core_Asm
{
[Plug(Target = typeof(Multiboot))]
public class MultibootImpl
{
[PlugMethod(Assembler = typeof(MultibootAsm))]
public static uint GetMBIAddress() => throw null;
[PlugMethod(Assembler = typeof(MultibootImplAsm))]
public static uint GetMBIAddress()
{
return 0;
}
}
public class MultibootImplAsm : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
XS.Push("MultiBootInfo_Structure", isIndirect: true);
}
}
}

View file

@ -1,212 +0,0 @@
using Cosmos.Core;
using IL2CPU.API;
using IL2CPU.API.Attribs;
using XSharp;
namespace Cosmos.Core_Asm
{
[Plug(Target = typeof(ProcessorInformation))]
public unsafe class ProcessorInformationImpl
{
/* The following three int*-pointers are needed for the lea instruction due to the following reason:
* When comiling, the IL-code will be translated into x86-ASM, which has specific and unique names for local variables.
* To access these local variables, I have to pass their excat name to the instruction in question. This is rather
* difficult with reflection, if these variables reside in the local function scope. For this reason, I move the
* pointer to class scope to access them quicker and more easily
*/
private static int* __cyclesrdtscptr, __raterdmsrptr, __vendortargetptr;
private static long __ticktate = -1;
/// <summary>
/// Returns the number of CPU cycles since startup
/// </summary>
/// <returns>Number of CPU cycles</returns>
public static long GetCycleCount()
{
int[] val = new int[2];
fixed (int* ptr = val)
{
__cyclesrdtsc(ptr);
}
return ((long)val[0] << 32) | (uint)val[1];
}
/// <summary>
/// Returns the CPU cycle rate (in cycles/µs)
/// </summary>
/// <returns>CPU cycle rate</returns>
public static long GetCycleRate()
{
if (__ticktate == -1)
{
int[] raw = new int[4];
fixed (int* ptr = raw)
{
__raterdmsr(ptr);
}
ulong l1 = (ulong)__maxrate();
ulong l2 = ((ulong)raw[0] << 32) | (uint)raw[1];
ulong l3 = ((ulong)raw[2] << 32) | (uint)raw[3];
__ticktate = (long)l2; // (long)((double)l1 * l3 / l2);
}
return __ticktate;
}
/// <summary>
/// Copies the maximum cpu rate set by the bios at startup to the given int pointer
/// </summary>
[Inline]
private static int __maxrate()
{
/*
* mov eax, 16h
* cpuid
* and eax, ffffh
* ret
*/
XS.Set(XSRegisters.EAX, 0x00000016);
XS.Cpuid();
XS.And(XSRegisters.EAX, 0x0000ffff);
XS.Return();
return 0;
}
/// <summary>
/// Copies the cycle count to the given int pointer
/// </summary>
[Inline]
private static void __cyclesrdtsc(int* target)
{
/*
* push eax
* push ecx
* push edx
* lea esi, target
* rdtsc
* mov [esi+4], eax
* mov [esi], edx
* pop edx
* pop ecx
* pop eax
* ret
*/
__cyclesrdtscptr = target;
string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__cyclesrdtscptr)));
XS.Push(XSRegisters.EAX);
XS.Push(XSRegisters.ECX);
XS.Push(XSRegisters.EDX);
XS.Lea(XSRegisters.ESI, intname);
XS.Rdtsc();
XS.Set(XSRegisters.ESI, XSRegisters.EAX, destinationIsIndirect: true, destinationDisplacement: 4);
XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true);
XS.Push(XSRegisters.EDX);
XS.Push(XSRegisters.ECX);
XS.Push(XSRegisters.EAX);
XS.Return();
}
/// <summary>
/// Copies the cycle rate to the given int pointer
/// </summary>
[Inline]
private static void __raterdmsr(int* target)
{
/*
* ; esi register layout: (mperf_hi, mperf_lo, aperf_hi, aperf_lo)
* ;
* ; int* ptr = new int[4];
* ;
* lea esi, ptr ;equivalent with `mov esi, &ptr`
* mov ecx, e7h
* rdmsr
* mov [esi + 4], eax
* mov [esi], edx
* mov ecx, e8h
* rdmsr
* mov [esi + 12], eax
* mov [esi + 8], edx
* xor eax, eax
* ret
*/
__raterdmsrptr = target;
string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__raterdmsrptr)));
XS.Lea(XSRegisters.ESI, intname);
XS.Set(XSRegisters.ECX, 0xe7);
XS.Rdmsr();
XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 4);
XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 0);
XS.Set(XSRegisters.ECX, 0xe8);
XS.Rdmsr();
XS.Set(XSRegisters.EAX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 12);
XS.Set(XSRegisters.EDX, XSRegisters.ESI, destinationIsIndirect: true, destinationDisplacement: 8);
XS.Xor(XSRegisters.EAX, XSRegisters.EAX); // XS.Set(XSRegisters.EAX, 0);
XS.Return();
}
[Inline]
internal static void FetchCPUVendor(int* target)
{
/*
* lea esi, target
* xor eax, eax
* cpuid
* mov [esi], ebx
* mov [esi + 4], edx
* mov [esi + 8], ecx
* ret
*/
__vendortargetptr = target;
string intname = LabelName.GetStaticFieldName(typeof(CPUImpl).GetField(nameof(__vendortargetptr)));
XS.Lea(XSRegisters.ESI, intname); // new Lea { DestinationReg = RegistersEnum.ESI, SourceRef = ElementReference.New(intname) };
XS.Cpuid();
XS.Set(XSRegisters.ESI, XSRegisters.EBX, destinationIsIndirect: true);
XS.Set(XSRegisters.ESI, XSRegisters.EDX, destinationIsIndirect: true, destinationDisplacement: 4);
XS.Set(XSRegisters.ESI, XSRegisters.ECX, destinationIsIndirect: true, destinationDisplacement: 8);
XS.Return();
}
[Inline]
internal static int CanReadCPUID()
{
/*
* pushfd
* pushfd
* xor dword [esp], 00200000h
* popfd
* pushfd
* pop eax
* xor eax, [esp]
* and eax, 00200000h
* ret
*/
XS.Pushfd();
XS.Pushfd();
XS.Xor(XSRegisters.ESP, 0x00200000, destinationIsIndirect: true);
XS.Popfd();
XS.Pushfd();
XS.Pop(XSRegisters.EAX);
XS.Xor(XSRegisters.EAX, XSRegisters.ESP, destinationIsIndirect: true);
XS.Popfd();
XS.And(XSRegisters.EAX, 0x00200000);
XS.Return();
return 0; // should be ignored by the compiler
}
}
}

View file

@ -13,7 +13,7 @@ namespace Cosmos.Core_Plugs.System.Diagnostics
{
if (Stopwatch.IsHighResolution)
// see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx for more details
return (long)(ProcessorInformation.GetCycleCount() / (double)ProcessorInformation.GetCycleRate() * 1000000d);
return (long)(CPU.GetCPUUptime() / (double)CPU.GetCPUUptime() * 1000000d);
else
return DateTime.UtcNow.Ticks;
}

View file

@ -23,10 +23,10 @@ namespace Cosmos.Core_Plugs.System.Threading
// if ((ms > 0) && (ms != Timeout.Infinite))
// {
// double fac = ProcessorInformation.GetCycleRate() / 1000d;
// double ticks = ms / 1000d * Stopwatch.Frequency + ProcessorInformation.GetCycleCount() * fac;
// double fac = CPU.GetCycleRate() / 1000d;
// double ticks = ms / 1000d * Stopwatch.Frequency + CPU.GetCycleCount() * fac;
// while (ticks < ProcessorInformation.GetCycleCount() * fac)
// while (ticks < CPU.GetCycleCount() * fac)
// new Action(() => { }).Invoke(); // execute an empty operation
// }
// else if (ms < 0)

View file

@ -0,0 +1,127 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using Cosmos.Build.Common;
namespace Cosmos.Debug.Hosts
{
public class Qemu : Host
{
private static Process qemuProcess;
private string _harddiskFile;
private string _isoFile;
private string _debugPortString;
public bool RedirectOutput = false;
public Action<string> LogOutput;
public Action<string> LogError;
public Qemu(Dictionary<string, string> aParams, bool aUseGDB, string aHarddisk = null)
: base(aParams, aUseGDB)
{
if (String.IsNullOrWhiteSpace(aHarddisk))
{
_harddiskFile = Path.Combine(CosmosPaths.Build, @"VMWare\Workstation\Filesystem.vmdk");
}
else
{
_harddiskFile = aHarddisk;
}
if (aParams.ContainsKey("ISOFile"))
{
_isoFile = aParams["IOSFile"];
}
_debugPortString = "Cosmos\\Serial";
}
public override void Start()
{
qemuProcess = new Process();
var qemuStartInfo = qemuProcess.StartInfo;
qemuStartInfo.FileName = QemuSupport.QemuExe.FullName;
string xQemuArguments = "-m 128";
xQemuArguments += $" -cdrom {_isoFile}";
if (!string.IsNullOrWhiteSpace(_harddiskFile))
{
xQemuArguments += $" -hda {_harddiskFile}";
}
if (!string.IsNullOrWhiteSpace(_debugPortString))
{
xQemuArguments += $" -chardev pipe,path=\\\\Cosmos\\Serial,id=Cosmos -device isa-serial,chardev=Cosmos";
}
xQemuArguments += " -boot d";
qemuStartInfo.Arguments = xQemuArguments;
if (RedirectOutput)
{
if (LogOutput == null)
{
throw new Exception("No LogOutput handler specified!");
}
if (LogError == null)
{
throw new Exception("No LogError handler specified!");
}
}
qemuProcess.EnableRaisingEvents = true;
qemuProcess.Exited += ExitCallback;
qemuProcess.Start();
if (RedirectOutput)
{
qemuProcess.BeginErrorReadLine();
qemuProcess.BeginOutputReadLine();
}
}
private void ExitCallback(object sender, EventArgs e)
{
if (OnShutDown != null)
{
try
{
OnShutDown(sender, e);
}
catch
{
}
}
}
public override void Stop()
{
if (qemuProcess != null)
{
try
{
qemuProcess.Kill();
}
catch
{
}
}
Cleanup();
}
private void Cleanup()
{
OnShutDown(this, null);
qemuProcess.Exited -= ExitCallback;
}
}
}

View file

@ -176,8 +176,10 @@ namespace Cosmos.HAL
* |--------|---------------------------|
* | 0x04 | 5-button mouse |
* |--------|---------------------------|
* | 0x50 | Laptop Touchpad |
* |--------|---------------------------|
*/
if (xFirstByte == 0x00 || xFirstByte == 0x03 || xFirstByte == 0x04)
if (xFirstByte == 0x00 || xFirstByte == 0x03 || xFirstByte == 0x04 || xFirstByte == 0x50)
{
var xDevice = new PS2Mouse(aPort, xFirstByte);
xDevice.Initialize();

View file

@ -512,6 +512,8 @@ namespace Cosmos.System.FileSystem.FAT.Listing
/// <exception cref="NotSupportedException">Thrown when FAT type is unknown.</exception>
public void DeleteDirectoryEntry()
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.DeleteDirectoryEntry --");
if (mEntryType == DirectoryEntryTypeEnum.Unknown)
{
throw new NotImplementedException();
@ -524,12 +526,17 @@ namespace Cosmos.System.FileSystem.FAT.Listing
var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData();
var xEntryOffset = mEntryHeaderDataOffset - 32;
while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName)
if(mEntryHeaderDataOffset > 32)
{
xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry;
xEntryOffset -= 32;
var xEntryOffset = mEntryHeaderDataOffset - 32;
Global.mFileSystemDebugger.SendInternal("xEntryOffset: " + xEntryOffset);
while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName)
{
xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry;
xEntryOffset -= 32;
}
}
((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData);
@ -988,6 +995,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, byte aValue)
{
Global.mFileSystemDebugger.SendInternal(" -- FatDirectoryEntry.SetDirectoryEntryMetadataValue(uint) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue = " + aValue);
if (IsRootDirectory())
@ -1043,6 +1051,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, ushort aValue)
{
Global.mFileSystemDebugger.SendInternal(" -- FatDirectoryEntry.SetDirectoryEntryMetadataValue(uint) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue = " + aValue);
if (IsRootDirectory())
@ -1054,6 +1063,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
if (xData.Length > 0)
{
Global.mFileSystemDebugger.SendInternal("mEntryHeaderDataOffset = " + mEntryHeaderDataOffset);
var xValue = new byte[aEntryMetadata.DataLength];
xValue.SetUInt16(0, aValue);
uint offset = mEntryHeaderDataOffset + aEntryMetadata.DataOffset;
@ -1100,6 +1110,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, uint aValue)
{
Global.mFileSystemDebugger.SendInternal(" -- FatDirectoryEntry.SetDirectoryEntryMetadataValue(uint) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue = " + aValue);
if (IsRootDirectory())
@ -1157,6 +1168,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, long aValue)
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.SetDirectoryEntryMetadataValue(long) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal("aValue =");
Global.mFileSystemDebugger.SendInternal(aValue);
@ -1218,6 +1230,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing
internal void SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata aEntryMetadata, string aValue)
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.SetDirectoryEntryMetadataValue(string) --");
Global.mFileSystemDebugger.SendInternal("aEntryMetadata = " + aEntryMetadata.DataOffset);
Global.mFileSystemDebugger.SendInternal($"aValue = {aValue}");
if (IsRootDirectory())

View file

@ -856,6 +856,47 @@ namespace Cosmos.System.Graphics
}
}
private int[] scaleImage(Image image, int newWidth, int newHeight)
{
int[] pixels = image.rawData;
int w1 = (int)image.Width;
int h1 = (int)image.Height;
int[] temp = new int[newWidth * newHeight];
int x_ratio = (int)((w1 << 16) / newWidth) + 1;
int y_ratio = (int)((h1 << 16) / newHeight) + 1;
int x2, y2;
for (int i = 0; i < newHeight; i++)
{
for (int j = 0; j < newWidth; j++)
{
x2 = ((j * x_ratio) >> 16);
y2 = ((i * y_ratio) >> 16);
temp[(i * newWidth) + j] = pixels[(y2 * w1) + x2];
}
}
return temp;
}
/// <summary>
/// Draw a Scaled Bitmap.
/// </summary>
/// <param name="image">Image to Scale.</param>
/// <param name="x">X coordinate.</param>
/// <param name="y">Y coordinate.</param>
/// <param name="w">Desired Width.</param>
/// <param name="h">Desired Height.</param>
public virtual void DrawImage(Image image, int x, int y,int w,int h)
{
int[] pixels = scaleImage(image, w, h);
for (int _x = 0; _x < w; _x++)
{
for (int _y = 0; _y < h; _y++)
{
Global.mDebugger.SendInternal(pixels[_x + _y * w]);
DrawPoint(new Pen(Color.FromArgb(pixels[_x + _y * w])), x + _x, y + _y);
}
}
}
/// <summary>
/// Draw image with alpha channel.
/// </summary>

View file

@ -0,0 +1,440 @@
//#define COSMOSDEBUG
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using IL2CPU.API.Attribs;
namespace Cosmos.System_Plugs.System.Drawing
{
[Plug(Target = typeof(global::System.Drawing.Color))]
class ColorImpl
{
/// <summary>Implements System.Drawing.Color.FromName
/// <para>See https://docs.microsoft.com/de-de/dotnet/api/system.drawing.color.fromname?view=netcore-3.1 for Usage Explanation</para>
/// </summary>
public static Color FromName(string name)
{
switch(name)
{
case "AliceBlue":
return Color.AliceBlue;
case "AntiqueWhite":
return Color.AntiqueWhite;
case "Aqua":
return Color.Aqua;
case "Aquamarine":
return Color.Aquamarine;
case "Azure":
return Color.Azure;
case "Beige":
return Color.Beige;
case "Bisque":
return Color.Bisque;
case "Black":
return Color.Black;
case "BlueViolet":
return Color.BlueViolet;
case "Brown":
return Color.Brown;
case "BurlyWood":
return Color.BurlyWood;
case "CadetBlue":
return Color.CadetBlue;
case "Chartreuse":
return Color.Chartreuse;
case "Chocolate":
return Color.Chocolate;
case "Coral":
return Color.Coral;
case "CornflowerBlue":
return Color.CornflowerBlue;
case "Cornsilk":
return Color.Cornsilk;
case "Crimson":
return Color.Crimson;
case "Cyan":
return Color.Cyan;
case "DarkBlue":
return Color.DarkBlue;
case "DarkCyan":
return Color.DarkCyan;
case "DarkGoldenrod":
return Color.DarkGoldenrod;
case "DarkGray":
return Color.DarkGray;
case "DarkGreen":
return Color.DarkGreen;
case "DarkKhaki":
return Color.DarkKhaki;
case "DarkMagenta":
return Color.DarkMagenta;
case "DarkOliveGreen":
return Color.DarkOliveGreen;
case "AliceOrange":
return Color.DarkOrange;
case "DarkOrchid":
return Color.DarkOrchid;
case "DarkRed":
return Color.DarkRed;
case "DarkSalmon":
return Color.DarkSalmon;
case "DarkSeaGreen":
return Color.DarkSeaGreen;
case "DarkSlateBlue":
return Color.DarkSlateBlue;
case "DarkSlateGray":
return Color.DarkSlateGray;
case "DarkTurquoise":
return Color.DarkTurquoise;
case "DarkViolet":
return Color.DarkViolet;
case "DeepPink":
return Color.DeepPink;
case "DeepSkyBlue":
return Color.DeepSkyBlue;
case "DimGray":
return Color.DimGray;
case "DodgerBlue":
return Color.DodgerBlue;
case "Firebrick":
return Color.Firebrick;
case "FloralWhite":
return Color.FloralWhite;
case "ForestGreen":
return Color.ForestGreen;
case "Fuchsia":
return Color.Fuchsia;
case "Gainsboro":
return Color.Gainsboro;
case "GhostWhite":
return Color.GhostWhite;
case "Gold":
return Color.Gold;
case "Goldenrod":
return Color.Goldenrod;
case "Gray":
return Color.Gray;
case "Green":
return Color.Green;
case "GreenYellow":
return Color.GreenYellow;
case "Honeydew":
return Color.Honeydew;
case "HotPink":
return Color.HotPink;
case "IndianRed":
return Color.IndianRed;
case "Indigo":
return Color.Indigo;
case "Ivory":
return Color.Ivory;
case "Khaki":
return Color.Khaki;
case "Lavender":
return Color.Lavender;
case "LavenderBlush":
return Color.LavenderBlush;
case "LawnGreen":
return Color.LawnGreen;
case "LemonChiffon":
return Color.LemonChiffon;
case "LightBlue":
return Color.LightBlue;
case "LightCoral":
return Color.LightCoral;
case "LightCyan":
return Color.LightCyan;
case "LightGoldenrodYellow":
return Color.LightGoldenrodYellow;
case "LightGreen":
return Color.LightGreen;
case "LightGray":
return Color.LightGray;
case "LightPink":
return Color.LightPink;
case "LightSalmon":
return Color.LightSalmon;
case "LightSeaGreen":
return Color.LightSeaGreen;
case "LightSkyBlue":
return Color.LightSkyBlue;
case "LightSlateGray":
return Color.LightSlateGray;
case "LightSteelBlue":
return Color.LightSteelBlue;
case "LightYellow":
return Color.LightYellow;
case "Lime":
return Color.Lime;
case "LimeGreen":
return Color.LimeGreen;
case "Linen":
return Color.Linen;
case "Magenta":
return Color.Magenta;
case "Maroon":
return Color.Maroon;
case "MediumAquamarine":
return Color.MediumAquamarine ;
case "MediumBlue":
return Color.MediumBlue;
case "MediumOrchid":
return Color.MediumOrchid;
case "MediumPurple":
return Color.MediumPurple;
case "MediumSeaGreen":
return Color.MediumSeaGreen;
case "MediumSlateBlue":
return Color.MediumSlateBlue;
case "MediumSpringGreen":
return Color.MediumSpringGreen;
case "MediumTurquoise":
return Color.MediumTurquoise;
case "MediumVioletRed":
return Color.MediumVioletRed;
case "MidnightBlue":
return Color.MidnightBlue;
case "MintCream":
return Color.MintCream;
case "MistyRose":
return Color.MistyRose;
case "Moccasin":
return Color.Moccasin;
case "NavajoWhite":
return Color.NavajoWhite;
case "Navy":
return Color.Navy;
case "OldLace":
return Color.OldLace;
case "Olive":
return Color.Olive;
case "OliveDrab":
return Color.OliveDrab;
case "Orange":
return Color.Orange;
case "OrangeRed":
return Color.OrangeRed;
case "Orchid":
return Color.Orchid;
case "PaleGoldenrod":
return Color.PaleGoldenrod;
case "PaleGreen":
return Color.PaleGreen;
case "PaleTurquoise":
return Color.PaleTurquoise;
case "PaleVioletRed":
return Color.PaleVioletRed;
case "PapayaWhip":
return Color.PapayaWhip;
case "PeachPuff":
return Color.PeachPuff;
case "Peru":
return Color.Peru;
case "Pink":
return Color.Pink;
case "Plum":
return Color.Plum;
case "PowderBlue":
return Color.PowderBlue;
case "Purple":
return Color.Purple;
case "Red":
return Color.Red;
case "RosyBrown":
return Color.RosyBrown;
case "RoyalBlue":
return Color.RoyalBlue;
case "SaddleBrown":
return Color.SaddleBrown;
case "Salmon":
return Color.Salmon;
case "SandyBrown":
return Color.SandyBrown;
case "SeaGreen":
return Color.SeaGreen;
case "Sienna":
return Color.Sienna;
case "Silver":
return Color.Silver;
case "SkyBlue":
return Color.SkyBlue;
case "SlateBlue":
return Color.SlateBlue;
case "SlateGray":
return Color.SlateGray;
case "Snow":
return Color.Snow;
case "SpringGreen":
return Color.SpringGreen;
case "SteelBlue":
return Color.SteelBlue;
case "Tan":
return Color.Tan;
case "Thistle":
return Color.Thistle;
case "Tomato":
return Color.Tomato;
case "Transparent":
return Color.Transparent;
case "Turquoise":
return Color.Turquoise;
case "Violet":
return Color.Violet;
case "Wheat":
return Color.Wheat;
case "White":
return Color.White;
case "WhiteSmoke":
return Color.WhiteSmoke;
case "Yellow":
return Color.Yellow;
case "YellowGreen":
return Color.YellowGreen;
case "":
throw new ArgumentException("Color Name must be passed to FromName");
default:
throw new ArgumentException("{0} is not a valid Color Name", name);
}
}
}
}

View file

@ -20,6 +20,11 @@ namespace Cosmos.System_Plugs.System
{
string result = "";
if(aThis == 0)
{
result = "0";
}
while (aThis != 0)
{
if ((aThis % 16) < 10)

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Text;
using Cosmos.Common.Extensions;
using IL2CPU.API.Attribs;
namespace Cosmos.System_Plugs.System
{
[Plug(TargetName = "System.ParseNumbers, System.Private.CoreLib")]
class ParseNumbersImpl
{
public static string IntToString(int value, int radix, int width, char paddingChar, int flags)
{
if (flags != 0)
{
throw new NotImplementedException("IntToString with non-zero flags is not supported");
}
string valueString = "";
if (radix == 2 || radix == 8 || radix == 16)
{
int shiftRightAmount = 1;
if (radix == 8)
{
shiftRightAmount = 3;
}
else if (radix == 16)
{
shiftRightAmount = 4;
}
if (value < 0)
{
throw new NotImplementedException();
}
while (value > 0)
{
valueString = (value % radix).ToString("X") + valueString;
value >>= shiftRightAmount;
}
}
else if (radix == 10)
{
valueString = value.ToString();
}
else
{
throw new ArgumentException(nameof(radix));
}
if (width == -1)
{
return valueString;
}
if (valueString.Length > width)
{
throw new NotImplementedException("IntToString Case not handled when value is longer than width");
}
int count = width - valueString.Length;
for (int i = 0; i < count; i++)
{
valueString = paddingChar + valueString;
}
return valueString;
}
}
}

View file

@ -309,13 +309,11 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
string xPortType = xParts[0].ToLower();
string xPortParam = xParts[1].ToLower();
var xLaunch = mDebugInfo[BuildPropertyNames.LaunchString];
OutputText("Starting debug connector.");
switch (xPortType)
{
case "pipe:":
if (xLaunch == "HyperV")
if (mLaunch == LaunchType.HyperV || mLaunch == LaunchType.Qemu)
{
mDbgConnector = new DebugConnectorPipeClient(xPortParam);
}
@ -325,7 +323,7 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
}
break;
case "serial:":
if (xLaunch == "IntelEdison")
if (mLaunch == LaunchType.IntelEdison)
{
mDbgConnector = new DebugConnectorEdison(xPortParam, Path.ChangeExtension(mDebugInfo["ISOFile"], ".bin"));
}
@ -336,7 +334,6 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
break;
default:
throw new Exception("No debug connector found for port type '" + xPortType + "'");
}
mDbgConnector.SetConnectionHandler(DebugConnectorConnected);
mDbgConnector.CmdBreak += new Action<uint>(DbgCmdBreak);
@ -560,6 +557,13 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl
//((Host.Bochs)mHost).FixBochsConfiguration(new KeyValuePair<string, string>[] { new KeyValuePair<string, string>("IsoFileName", mISO) });
break;
case LaunchType.Qemu:
if (!QemuSupport.QemuEnabled)
{
throw new Exception("The Qemu emulator doesn't seem to be installed on this machine.");
}
mHost = new Qemu(mDebugInfo, xUseGDB);
break;
case LaunchType.IntelEdison:
mHost = new IntelEdison(mDebugInfo, false);
break;

View file

@ -28,6 +28,7 @@
<EnumValue Name="VMware" DisplayName="VMware" />
<EnumValue Name="Slave" DisplayName="Attached Slave (CanaKit)" />
<EnumValue Name="Bochs" DisplayName="Bochs" />
<EnumValue Name="Qemu" DisplayName="Qemu" />
<EnumValue Name="IntelEdison" DisplayName="Intel Edison" />
<EnumValue Name="HyperV" DisplayName="Hyper-V" />
</EnumProperty>

View file

@ -82,6 +82,7 @@
this.tabBochs = new System.Windows.Forms.TabPage();
this.checkStartBochsDebugGui = new System.Windows.Forms.CheckBox();
this.checkEnableBochsDebug = new System.Windows.Forms.CheckBox();
this.tabQemu = new System.Windows.Forms.TabPage();
this.tabPXE = new System.Windows.Forms.TabPage();
this.butnPxeRefresh = new System.Windows.Forms.Button();
this.comboPxeInterface = new System.Windows.Forms.ComboBox();
@ -111,6 +112,7 @@
this.tabLaunch.SuspendLayout();
this.tabVMware.SuspendLayout();
this.tabBochs.SuspendLayout();
this.tabQemu.SuspendLayout();
this.tabPXE.SuspendLayout();
this.tabUSB.SuspendLayout();
this.tabISO.SuspendLayout();
@ -156,6 +158,7 @@
this.TabControl1.Controls.Add(this.tabVMware);
this.TabControl1.Controls.Add(this.tabHyperV);
this.TabControl1.Controls.Add(this.tabBochs);
this.TabControl1.Controls.Add(this.tabQemu);
this.TabControl1.Controls.Add(this.tabPXE);
this.TabControl1.Controls.Add(this.tabUSB);
this.TabControl1.Controls.Add(this.tabISO);
@ -704,6 +707,16 @@
this.checkEnableBochsDebug.Text = "Enable Bochs Debugger";
this.checkEnableBochsDebug.UseVisualStyleBackColor = true;
//
// tabQemu
//
this.tabQemu.Location = new System.Drawing.Point(4, 22);
this.tabQemu.Name = "tabQemu";
this.tabQemu.Padding = new System.Windows.Forms.Padding(3);
this.tabQemu.Size = new System.Drawing.Size(627, 486);
this.tabQemu.TabIndex = 5;
this.tabQemu.Text = "Qemu";
this.tabQemu.UseVisualStyleBackColor = true;
//
// tabPXE
//
this.tabPXE.Controls.Add(this.butnPxeRefresh);
@ -865,6 +878,7 @@
this.tabVMware.ResumeLayout(false);
this.tabVMware.PerformLayout();
this.tabBochs.ResumeLayout(false);
this.tabQemu.ResumeLayout(false);
this.tabPXE.ResumeLayout(false);
this.tabPXE.PerformLayout();
this.tabUSB.ResumeLayout(false);
@ -909,6 +923,7 @@
private System.Windows.Forms.CheckBox checkIgnoreDebugStubAttribute;
private System.Windows.Forms.TabPage tabBochs;
private System.Windows.Forms.CheckBox checkEnableBochsDebug;
private System.Windows.Forms.TabPage tabQemu;
private System.Windows.Forms.TabPage tabVMware;
private System.Windows.Forms.CheckBox checkEnableGDB;
private System.Windows.Forms.CheckBox checkStartCosmosGDB;

View file

@ -36,6 +36,7 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
protected int mHyperVDebugPipe;
protected bool mShowTabBochs;
protected bool mShowTabQemu;
protected bool mShowTabDebug;
protected bool mShowTabDeployment;
protected bool mShowTabLaunch;
@ -98,8 +99,8 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
if (xValue != mViewModel.BuildProperties.Launch)
{
mViewModel.BuildProperties.Launch = xValue;
// Bochs requires an ISO. Force Deployment property.
if (LaunchType.Bochs == xValue)
// Bochs and Qemu requires an ISO. Force Deployment property.
if (xValue == LaunchType.Bochs)
{
if (DeploymentType.ISO != mViewModel.BuildProperties.Deployment)
{
@ -329,6 +330,7 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
RemoveTab(tabISO);
RemoveTab(tabSlave);
RemoveTab(tabBochs);
RemoveTab(tabQemu);
if (mShowTabDebug)
{
@ -372,6 +374,10 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
{
TabControl1.TabPages.Add(tabBochs);
}
if (mShowTabQemu)
{
TabControl1.TabPages.Add(tabQemu);
}
if (TabControl1.TabPages.Contains(xTab))
{
@ -435,6 +441,15 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
cmboVisualStudioDebugPort.Enabled = false;
cmboVisualStudioDebugPort.SelectedIndex = mVMwareAndBochsDebugPipe;
}
else if (mViewModel.BuildProperties.Profile == "Qemu")
{
mShowTabQemu = true;
chckEnableDebugStub.Checked = true;
chkEnableStackCorruptionDetection.Checked = true;
cmboCosmosDebugPort.Enabled = false;
cmboVisualStudioDebugPort.Enabled = false;
cmboVisualStudioDebugPort.SelectedIndex = mVMwareAndBochsDebugPipe;
}
else if (mViewModel.BuildProperties.Profile == "IntelEdison")
{
mShowTabBochs = false;
@ -513,7 +528,8 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
mShowTabVMware = mViewModel.BuildProperties.Launch == LaunchType.VMware;
mShowTabHyperV = mViewModel.BuildProperties.Launch == LaunchType.HyperV;
mShowTabSlave = mViewModel.BuildProperties.Launch == LaunchType.Slave;
mShowTabBochs = (LaunchType.Bochs == mViewModel.BuildProperties.Launch);
mShowTabBochs = mViewModel.BuildProperties.Launch == LaunchType.Bochs;
mShowTabQemu = mViewModel.BuildProperties.Launch == LaunchType.Qemu;
//
UpdateTabs();
}

View file

@ -15,6 +15,10 @@ namespace Cosmos.VS.ProjectSystem.VS.PropertyPages
{
Add("Bochs", "Bochs");
}
if (QemuSupport.QemuEnabled)
{
Add("Qemu", "Qemu");
}
Add("IntelEdison", "Intel Edison Serial boot");
Add("HyperV", "Hyper-V");
}