diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..aa359040c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -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#)? diff --git a/.github/ISSUE_TEMPLATE/build-error-and-visual-studio-problems.md b/.github/ISSUE_TEMPLATE/build-error-and-visual-studio-problems.md new file mode 100644 index 000000000..8125653cb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/build-error-and-visual-studio-problems.md @@ -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. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..5c6c65b4d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -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. diff --git a/.github/ISSUE_TEMPLATE/installation-error.md b/.github/ISSUE_TEMPLATE/installation-error.md new file mode 100644 index 000000000..a88743776 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/installation-error.md @@ -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. diff --git a/.github/ISSUE_TEMPLATE/installation-problem.md b/.github/ISSUE_TEMPLATE/installation-problem.md new file mode 100644 index 000000000..daceee95c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/installation-problem.md @@ -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. diff --git a/.github/ISSUE_TEMPLATE/plug-request.md b/.github/ISSUE_TEMPLATE/plug-request.md new file mode 100644 index 000000000..f073317d1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/plug-request.md @@ -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. diff --git a/Directory.Build.props b/Directory.Build.props index 1023084ed..7e7948729 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -30,7 +30,7 @@ - 0.1.0-build18 + 0.1.0-build37 0.1.0-build355 0.1.0-build562 diff --git a/Tests/Cosmos.TestRunner.Core/Engine.Qemu.cs b/Tests/Cosmos.TestRunner.Core/Engine.Qemu.cs new file mode 100644 index 000000000..91681cfa2 --- /dev/null +++ b/Tests/Cosmos.TestRunner.Core/Engine.Qemu.cs @@ -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 + { + {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); + } + } +} diff --git a/Tests/Cosmos.TestRunner.Core/Engine.Run.cs b/Tests/Cosmos.TestRunner.Core/Engine.Run.cs index 1e5b651f0..7a7cf21e9 100644 --- a/Tests/Cosmos.TestRunner.Core/Engine.Run.cs +++ b/Tests/Cosmos.TestRunner.Core/Engine.Run.cs @@ -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; diff --git a/Tests/Cosmos.TestRunner.Core/Engine.cs b/Tests/Cosmos.TestRunner.Core/Engine.cs index 911e0fc89..68bb6d035 100644 --- a/Tests/Cosmos.TestRunner.Core/Engine.cs +++ b/Tests/Cosmos.TestRunner.Core/Engine.cs @@ -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); } } } diff --git a/Tests/Cosmos.TestRunner.Core/Enums.cs b/Tests/Cosmos.TestRunner.Core/Enums.cs index 30d8a1c05..9e6d6fdcc 100644 --- a/Tests/Cosmos.TestRunner.Core/Enums.cs +++ b/Tests/Cosmos.TestRunner.Core/Enums.cs @@ -4,6 +4,7 @@ { Bochs, VMware, - HyperV + HyperV, + Qemu } } diff --git a/Tests/Cosmos.TestRunner.Core/RunConfiguration.cs b/Tests/Cosmos.TestRunner.Core/RunConfiguration.cs index 5331b9bae..e01656b8f 100644 --- a/Tests/Cosmos.TestRunner.Core/RunConfiguration.cs +++ b/Tests/Cosmos.TestRunner.Core/RunConfiguration.cs @@ -9,6 +9,11 @@ { IsELF = isElf; RunTarget = runTarget; + + if (runTarget == RunTargetEnum.Qemu) + { + IsELF = false; + } } } } diff --git a/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs b/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs index 09ffe9ab6..cb4a065e5 100644 --- a/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs +++ b/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs @@ -17,6 +17,7 @@ namespace Cosmos.TestRunner.Full yield return RunTargetEnum.Bochs; //yield return RunTargetEnum.VMware; //yield return RunTargetEnum.HyperV; + //yield return RunTargetEnum.Qemu; } } diff --git a/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/Kernel.cs b/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/Kernel.cs index a566becf6..a1e35d8ca 100644 --- a/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/Kernel.cs +++ b/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/Kernel.cs @@ -39,6 +39,7 @@ namespace Cosmos.Compiler.Tests.Bcl DelegatesTest.Execute(); EventsTest.Execute(); RandomTests.Execute(); + ConvertTests.Execute(); // System.Collections HashtableTest.Execute(); diff --git a/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/ConvertTests.cs b/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/ConvertTests.cs new file mode 100644 index 000000000..09ab43962 --- /dev/null +++ b/Tests/Kernels/Cosmos.Compiler.Tests.Bcl/System/ConvertTests.cs @@ -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"); + + } + } +} diff --git a/Tests/Kernels/Cosmos.Kernel.Tests.Fat/System.IO/DirectoryTest.cs b/Tests/Kernels/Cosmos.Kernel.Tests.Fat/System.IO/DirectoryTest.cs index c77b509b5..465dbb173 100644 --- a/Tests/Kernels/Cosmos.Kernel.Tests.Fat/System.IO/DirectoryTest.cs +++ b/Tests/Kernels/Cosmos.Kernel.Tests.Fat/System.IO/DirectoryTest.cs @@ -12,7 +12,6 @@ namespace Cosmos.Kernel.Tests.Fat.System.IO /// 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"); diff --git a/Tests/Kernels/GraphicTest/Kernel.cs b/Tests/Kernels/GraphicTest/Kernel.cs index 94ddbbe4e..ab9d54f59 100644 --- a/Tests/Kernels/GraphicTest/Kernel.cs +++ b/Tests/Kernels/GraphicTest/Kernel.cs @@ -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,7 +117,9 @@ 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)); /* Drawing ellipses */ diff --git a/Tests/Kernels/ProcessorTests/Kernel.cs b/Tests/Kernels/ProcessorTests/Kernel.cs index 9ef432177..d9f457134 100644 --- a/Tests/Kernels/ProcessorTests/Kernel.cs +++ b/Tests/Kernels/ProcessorTests/Kernel.cs @@ -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(); diff --git a/source/Cosmos.Core/Bootstrap.cs b/source/Cosmos.Core/Bootstrap.cs index b23955ace..c1d3ea4b3 100644 --- a/source/Cosmos.Core/Bootstrap.cs +++ b/source/Cosmos.Core/Bootstrap.cs @@ -1,4 +1,6 @@ -namespace Cosmos.Core +using Cosmos.Debug.Kernel; + +namespace Cosmos.Core { /// /// Bootstrap class. Used to invoke pre-boot methods. @@ -22,7 +24,7 @@ /// /// Multiboot header pointer. /// - public static Multiboot.Header* header; + public static Multiboot.Header* MultibootHeader; /// /// 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; } } } diff --git a/source/Cosmos.Core/CPU.cs b/source/Cosmos.Core/CPU.cs index a2618bcf7..b2374d334 100644 --- a/source/Cosmos.Core/CPU.cs +++ b/source/Cosmos.Core/CPU.cs @@ -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; } - - /// /// Get CPU vendor name. /// @@ -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(); } - - /// /// Check if can read CPU ID. Plugged. /// /// non-zero if can read. /// Thrown on fatal error, contact support. - internal static int CanReadCPUID() => throw new NotImplementedException(); + public static int CanReadCPUID() => throw new NotImplementedException(); /// /// Read CPU ID. Plugged. @@ -326,7 +325,7 @@ namespace Cosmos.Core /// ecx. /// edx. /// Thrown on fatal error, contact support. - 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(); /// /// Read timestamp counter. Plugged. @@ -341,5 +340,107 @@ namespace Cosmos.Core /// ulong value. /// Thrown on fatal error, contact support. internal static ulong ReadFromModelSpecificRegister() => throw new NotImplementedException(); + + /// + /// Checks if Multiboot returned a memory map + /// + /// + public static unsafe bool MemoryMapExists() + { + return (Bootstrap.MultibootHeader->Flags & 1 << 6) == 64; + } + + /// + /// Get the Memory Map Information from Multiboot + /// + /// Returns an array of MemoryMaps containing the Multiboot Memory Map information. The array may have empty values at the end. + 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 + { + /// + /// Base Address of the memory region + /// + public ulong Address; + /// + /// Length in bytes of the region + /// + public ulong Length; + /// + /// Type of RAM in region. 1 is available. 3 is for ACPI. All other is unavailable + /// + public uint Type; + } + + [StructLayout(LayoutKind.Explicit, Size = 24)] + public struct RawMemoryMap + { + /// + /// Size of this entry + /// + [FieldOffset(0)] + public uint Size; + /// + /// Low 32 bits of the base address + /// + [FieldOffset(4)] + public uint LowBaseAddr; + /// + /// High 32 bits of the base address + /// + [FieldOffset(8)] + public uint HighBaseAddr; + /// + /// Low 32 bits of the length of memory block in bytes + /// + [FieldOffset(12)] + public uint LowLength; + /// + /// High 32 bits of the length of memory block in bytes + /// + [FieldOffset(16)] + public uint HighLength; + /// + /// Type of memory area, 1 if usable RAM, everything else unusable. + /// + [FieldOffset(20)] + public uint Type; } } diff --git a/source/Cosmos.Core/MemoryOperations.cs b/source/Cosmos.Core/MemoryOperations.cs index 81c8be230..c66ce56ef 100644 --- a/source/Cosmos.Core/MemoryOperations.cs +++ b/source/Cosmos.Core/MemoryOperations.cs @@ -8,6 +8,7 @@ namespace Cosmos.Core /// public unsafe class MemoryOperations { + #region Fill /// /// Fill memory block. Plugged. /// @@ -183,6 +184,23 @@ namespace Cosmos.Core } } + /// + /// Fill source to destination. + /// + /// Destination. + /// Source. + [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 /// /// Copy source to destination. /// plugged. @@ -329,19 +347,6 @@ namespace Cosmos.Core } } - /// - /// Fill source to destination. - /// - /// Destination. - /// Source. - [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 } } diff --git a/source/Cosmos.Core/Multiboot.cs b/source/Cosmos.Core/Multiboot.cs index 341de394e..99e41484d 100644 --- a/source/Cosmos.Core/Multiboot.cs +++ b/source/Cosmos.Core/Multiboot.cs @@ -139,7 +139,7 @@ namespace Cosmos.Core /// True if is available, false if not public static bool IsAvailable() { - if ((Bootstrap.header->Flags & VBEINFO_PRESENT) == 0) + if ((Bootstrap.MultibootHeader->Flags & VBEINFO_PRESENT) == 0) { return false; } diff --git a/source/Cosmos.Core/ProcessorInformation.cs b/source/Cosmos.Core/ProcessorInformation.cs deleted file mode 100644 index 68c2be024..000000000 --- a/source/Cosmos.Core/ProcessorInformation.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace Cosmos.Core -{ - /// - /// ProcessorInformation class. Used to get vendor information from the CPU. - /// - public unsafe class ProcessorInformation - { - /// - /// Returns the Processor's vendor name - /// - /// CPU Vendor name - 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"; - } - - /// - /// Check if can read CPU ID. - /// - /// int value. - internal static int CanReadCPUID() => 0; //plugged - - /// - /// Fetch CPU vendor. - /// - /// pointer to target. - internal static void FetchCPUVendor(int* target) { } //plugged - - /// - /// Returns the number of CPU cycles since startup of the current CPU core - /// - /// Number of CPU cycles since startup - public static long GetCycleCount() => 0; //plugged - - /// - /// Returns the number of CPU cycles per seconds - /// - /// Number of CPU cycles per seconds - public static long GetCycleRate() => 0; //plugged - } -} diff --git a/source/Cosmos.Core_Asm/MultibootImpl.cs b/source/Cosmos.Core_Asm/MultibootImpl.cs index d3c9226ac..bd7153769 100644 --- a/source/Cosmos.Core_Asm/MultibootImpl.cs +++ b/source/Cosmos.Core_Asm/MultibootImpl.cs @@ -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); + } } } diff --git a/source/Cosmos.Core_Asm/ProcessorInformationImpl.cs b/source/Cosmos.Core_Asm/ProcessorInformationImpl.cs deleted file mode 100644 index 2bd7d4c4a..000000000 --- a/source/Cosmos.Core_Asm/ProcessorInformationImpl.cs +++ /dev/null @@ -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; - - /// - /// Returns the number of CPU cycles since startup - /// - /// Number of CPU cycles - public static long GetCycleCount() - { - int[] val = new int[2]; - - fixed (int* ptr = val) - { - __cyclesrdtsc(ptr); - } - - return ((long)val[0] << 32) | (uint)val[1]; - } - - /// - /// Returns the CPU cycle rate (in cycles/µs) - /// - /// CPU cycle rate - 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; - } - - /// - /// Copies the maximum cpu rate set by the bios at startup to the given int pointer - /// - [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; - } - - /// - /// Copies the cycle count to the given int pointer - /// - [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(); - } - - /// - /// Copies the cycle rate to the given int pointer - /// - [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 - } - } -} diff --git a/source/Cosmos.Core_Plugs/System/Diagnostics/StopwatchImpl.cs b/source/Cosmos.Core_Plugs/System/Diagnostics/StopwatchImpl.cs index c2f117ac2..19f86361b 100644 --- a/source/Cosmos.Core_Plugs/System/Diagnostics/StopwatchImpl.cs +++ b/source/Cosmos.Core_Plugs/System/Diagnostics/StopwatchImpl.cs @@ -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; } diff --git a/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs b/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs index 383dd9505..9c28ca3ef 100644 --- a/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs +++ b/source/Cosmos.Core_Plugs/System/Threading/ThreadImpl.cs @@ -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) diff --git a/source/Cosmos.Debug.Hosts/Qemu.cs b/source/Cosmos.Debug.Hosts/Qemu.cs new file mode 100644 index 000000000..821a50027 --- /dev/null +++ b/source/Cosmos.Debug.Hosts/Qemu.cs @@ -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 LogOutput; + + public Action LogError; + + public Qemu(Dictionary 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; + } + } +} diff --git a/source/Cosmos.HAL2/PS2Controller.cs b/source/Cosmos.HAL2/PS2Controller.cs index 83584df81..ab450a56e 100644 --- a/source/Cosmos.HAL2/PS2Controller.cs +++ b/source/Cosmos.HAL2/PS2Controller.cs @@ -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(); diff --git a/source/Cosmos.System2/FileSystem/FAT/Listing/FatDiretoryEntry.cs b/source/Cosmos.System2/FileSystem/FAT/Listing/FatDiretoryEntry.cs index 55c1da0fc..c66dcb93d 100644 --- a/source/Cosmos.System2/FileSystem/FAT/Listing/FatDiretoryEntry.cs +++ b/source/Cosmos.System2/FileSystem/FAT/Listing/FatDiretoryEntry.cs @@ -512,6 +512,8 @@ namespace Cosmos.System.FileSystem.FAT.Listing /// Thrown when FAT type is unknown. 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()) diff --git a/source/Cosmos.System2/Graphics/Canvas.cs b/source/Cosmos.System2/Graphics/Canvas.cs index 427f1d084..bd5d6efca 100644 --- a/source/Cosmos.System2/Graphics/Canvas.cs +++ b/source/Cosmos.System2/Graphics/Canvas.cs @@ -855,7 +855,48 @@ 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; + } + /// + /// Draw a Scaled Bitmap. + /// + /// Image to Scale. + /// X coordinate. + /// Y coordinate. + /// Desired Width. + /// Desired Height. + 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); + } + } + } + /// /// Draw image with alpha channel. /// diff --git a/source/Cosmos.System2_Plugs/System/Drawing/ColorImpl.cs b/source/Cosmos.System2_Plugs/System/Drawing/ColorImpl.cs new file mode 100644 index 000000000..4a005b644 --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/Drawing/ColorImpl.cs @@ -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 + { + /// Implements System.Drawing.Color.FromName + /// See https://docs.microsoft.com/de-de/dotnet/api/system.drawing.color.fromname?view=netcore-3.1 for Usage Explanation + /// + 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); + + } + } + } +} diff --git a/source/Cosmos.System2_Plugs/System/Int32Impl.cs b/source/Cosmos.System2_Plugs/System/Int32Impl.cs index 0c65a0b35..b9ccbce72 100644 --- a/source/Cosmos.System2_Plugs/System/Int32Impl.cs +++ b/source/Cosmos.System2_Plugs/System/Int32Impl.cs @@ -20,6 +20,11 @@ namespace Cosmos.System_Plugs.System { string result = ""; + if(aThis == 0) + { + result = "0"; + } + while (aThis != 0) { if ((aThis % 16) < 10) diff --git a/source/Cosmos.System2_Plugs/System/ParseNumbersImpl.cs b/source/Cosmos.System2_Plugs/System/ParseNumbersImpl.cs new file mode 100644 index 000000000..1b712789f --- /dev/null +++ b/source/Cosmos.System2_Plugs/System/ParseNumbersImpl.cs @@ -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; + } + } +} diff --git a/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs b/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs index ad218501d..d1ee6f6c6 100644 --- a/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs +++ b/source/Cosmos.VS.DebugEngine/AD7.Impl/AD7Process.cs @@ -281,7 +281,7 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl private void CreateDebugConnector() { mDbgConnector = null; - + mDebugInfo.TryGetValue(BuildPropertyNames.VisualStudioDebugPortString, out var xPort); // using (var xDebug = new StreamWriter(@"e:\debug.info", false)) @@ -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(DbgCmdBreak); @@ -560,6 +557,13 @@ namespace Cosmos.VS.DebugEngine.AD7.Impl //((Host.Bochs)mHost).FixBochsConfiguration(new KeyValuePair[] { new KeyValuePair("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; diff --git a/source/Cosmos.VS.ProjectSystem/BuildSystem/Rules/LaunchConfiguration.xaml b/source/Cosmos.VS.ProjectSystem/BuildSystem/Rules/LaunchConfiguration.xaml index 0906b9571..aadbcf278 100644 --- a/source/Cosmos.VS.ProjectSystem/BuildSystem/Rules/LaunchConfiguration.xaml +++ b/source/Cosmos.VS.ProjectSystem/BuildSystem/Rules/LaunchConfiguration.xaml @@ -28,6 +28,7 @@ + diff --git a/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.Designer.cs b/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.Designer.cs index 5af38bf08..456d75f83 100644 --- a/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.Designer.cs +++ b/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.Designer.cs @@ -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,14 +112,15 @@ this.tabLaunch.SuspendLayout(); this.tabVMware.SuspendLayout(); this.tabBochs.SuspendLayout(); + this.tabQemu.SuspendLayout(); this.tabPXE.SuspendLayout(); this.tabUSB.SuspendLayout(); this.tabISO.SuspendLayout(); this.tabSlave.SuspendLayout(); this.SuspendLayout(); - // + // // panel1 - // + // this.panel1.Controls.Add(this.lablCurrentProfile); this.panel1.Controls.Add(this.label11); this.panel1.Dock = System.Windows.Forms.DockStyle.Top; @@ -126,27 +128,27 @@ this.panel1.Name = "panel1"; this.panel1.Size = new System.Drawing.Size(635, 43); this.panel1.TabIndex = 3; - // + // // lablCurrentProfile - // + // this.lablCurrentProfile.AutoSize = true; this.lablCurrentProfile.Location = new System.Drawing.Point(99, 17); this.lablCurrentProfile.Name = "lablCurrentProfile"; this.lablCurrentProfile.Size = new System.Drawing.Size(41, 13); this.lablCurrentProfile.TabIndex = 1; this.lablCurrentProfile.Text = "label12"; - // + // // label11 - // + // this.label11.AutoSize = true; this.label11.Location = new System.Drawing.Point(17, 17); this.label11.Name = "label11"; this.label11.Size = new System.Drawing.Size(76, 13); this.label11.TabIndex = 0; this.label11.Text = "Current Profile:"; - // + // // TabControl1 - // + // this.TabControl1.Controls.Add(this.tabProfile); this.TabControl1.Controls.Add(this.tabCompile); this.TabControl1.Controls.Add(this.tabAssembler); @@ -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); @@ -167,9 +170,9 @@ this.TabControl1.SelectedIndex = 0; this.TabControl1.Size = new System.Drawing.Size(635, 512); this.TabControl1.TabIndex = 1; - // + // // tabProfile - // + // this.tabProfile.Controls.Add(this.lablPreset); this.tabProfile.Controls.Add(this.panel2); this.tabProfile.Controls.Add(this.lablDeployText); @@ -181,9 +184,9 @@ this.tabProfile.TabIndex = 8; this.tabProfile.Text = "Profile"; this.tabProfile.UseVisualStyleBackColor = true; - // + // // lablPreset - // + // this.lablPreset.AutoSize = true; this.lablPreset.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lablPreset.ForeColor = System.Drawing.SystemColors.HotTrack; @@ -192,9 +195,9 @@ this.lablPreset.Size = new System.Drawing.Size(247, 13); this.lablPreset.TabIndex = 7; this.lablPreset.Text = "** This is a preset. Some options are restricted."; - // + // // panel2 - // + // this.panel2.Controls.Add(this.lboxProfile); this.panel2.Controls.Add(this.toolStrip1); this.panel2.Dock = System.Windows.Forms.DockStyle.Left; @@ -202,9 +205,9 @@ this.panel2.Name = "panel2"; this.panel2.Size = new System.Drawing.Size(200, 480); this.panel2.TabIndex = 6; - // + // // lboxProfile - // + // this.lboxProfile.Dock = System.Windows.Forms.DockStyle.Fill; this.lboxProfile.FormattingEnabled = true; this.lboxProfile.Location = new System.Drawing.Point(0, 27); @@ -212,9 +215,9 @@ this.lboxProfile.Size = new System.Drawing.Size(200, 453); this.lboxProfile.Sorted = true; this.lboxProfile.TabIndex = 3; - // + // // toolStrip1 - // + // this.toolStrip1.ImageScalingSize = new System.Drawing.Size(20, 20); this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.butnProfileClone, @@ -225,9 +228,9 @@ this.toolStrip1.Size = new System.Drawing.Size(200, 27); this.toolStrip1.TabIndex = 2; this.toolStrip1.Text = "toolStrip1"; - // + // // butnProfileClone - // + // this.butnProfileClone.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.butnProfileClone.Image = ((System.Drawing.Image)(resources.GetObject("butnProfileClone.Image"))); this.butnProfileClone.ImageTransparentColor = System.Drawing.Color.Magenta; @@ -235,9 +238,9 @@ this.butnProfileClone.Size = new System.Drawing.Size(24, 24); this.butnProfileClone.Text = "Clone"; this.butnProfileClone.ToolTipText = "Create a new profile from an existing one."; - // + // // butnProfileDelete - // + // this.butnProfileDelete.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.butnProfileDelete.Image = ((System.Drawing.Image)(resources.GetObject("butnProfileDelete.Image"))); this.butnProfileDelete.ImageTransparentColor = System.Drawing.Color.Magenta; @@ -245,9 +248,9 @@ this.butnProfileDelete.Size = new System.Drawing.Size(24, 24); this.butnProfileDelete.Text = "Delete"; this.butnProfileDelete.ToolTipText = "Delete selected profile"; - // + // // butnProfileRename - // + // this.butnProfileRename.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image; this.butnProfileRename.Image = ((System.Drawing.Image)(resources.GetObject("butnProfileRename.Image"))); this.butnProfileRename.ImageTransparentColor = System.Drawing.Color.Magenta; @@ -255,17 +258,17 @@ this.butnProfileRename.Size = new System.Drawing.Size(24, 24); this.butnProfileRename.Text = "Rename"; this.butnProfileRename.ToolTipText = "Rename selected profile."; - // + // // lablDeployText - // + // this.lablDeployText.Location = new System.Drawing.Point(217, 44); this.lablDeployText.Name = "lablDeployText"; this.lablDeployText.Size = new System.Drawing.Size(228, 137); this.lablDeployText.TabIndex = 4; this.lablDeployText.Text = "label1"; - // + // // lablBuildOnly - // + // this.lablBuildOnly.AutoSize = true; this.lablBuildOnly.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.lablBuildOnly.ForeColor = System.Drawing.SystemColors.HotTrack; @@ -274,9 +277,9 @@ this.lablBuildOnly.Size = new System.Drawing.Size(310, 13); this.lablBuildOnly.TabIndex = 3; this.lablBuildOnly.Text = "** This is a build only option. No process will be launched."; - // + // // tabCompile - // + // this.tabCompile.AutoScroll = true; this.tabCompile.Controls.Add(this.labelBinFormat); this.tabCompile.Controls.Add(this.comboBinFormat); @@ -290,10 +293,10 @@ this.tabCompile.TabIndex = 0; this.tabCompile.Text = "Compile"; this.tabCompile.UseVisualStyleBackColor = true; - // + // // labelBinFormat - // - this.labelBinFormat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + // + this.labelBinFormat.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.labelBinFormat.AutoSize = true; this.labelBinFormat.Enabled = false; @@ -305,18 +308,18 @@ this.labelBinFormat.TabIndex = 23; this.labelBinFormat.Text = "Bin format:"; this.labelBinFormat.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // + // // comboBinFormat - // + // this.comboBinFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBinFormat.FormattingEnabled = true; this.comboBinFormat.Location = new System.Drawing.Point(34, 136); this.comboBinFormat.Name = "comboBinFormat"; this.comboBinFormat.Size = new System.Drawing.Size(228, 21); this.comboBinFormat.TabIndex = 22; - // + // // comboFramework - // + // this.comboFramework.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboFramework.Enabled = false; this.comboFramework.FormattingEnabled = true; @@ -324,10 +327,10 @@ this.comboFramework.Name = "comboFramework"; this.comboFramework.Size = new System.Drawing.Size(228, 21); this.comboFramework.TabIndex = 5; - // + // // labelFramework - // - this.labelFramework.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + // + this.labelFramework.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.labelFramework.AutoSize = true; this.labelFramework.Enabled = false; @@ -339,9 +342,9 @@ this.labelFramework.TabIndex = 21; this.labelFramework.Text = "Framework:"; this.labelFramework.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // + // // tabAssembler - // + // this.tabAssembler.Controls.Add(this.checkUseInternalAssembler); this.tabAssembler.Controls.Add(this.labelInternalAssembler); this.tabAssembler.Location = new System.Drawing.Point(4, 22); @@ -350,10 +353,10 @@ this.tabAssembler.TabIndex = 10; this.tabAssembler.Text = "Assembler"; this.tabAssembler.UseVisualStyleBackColor = true; - // + // // checkUseInternalAssembler - // - this.checkUseInternalAssembler.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + // + this.checkUseInternalAssembler.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left))); this.checkUseInternalAssembler.AutoSize = true; this.checkUseInternalAssembler.Enabled = false; @@ -365,9 +368,9 @@ this.checkUseInternalAssembler.TabIndex = 6; this.checkUseInternalAssembler.Text = "Use Internal Assembler"; this.checkUseInternalAssembler.UseVisualStyleBackColor = true; - // + // // labelInternalAssembler - // + // this.labelInternalAssembler.Enabled = false; this.labelInternalAssembler.Location = new System.Drawing.Point(40, 32); this.labelInternalAssembler.Margin = new System.Windows.Forms.Padding(44, 0, 3, 0); @@ -375,9 +378,9 @@ this.labelInternalAssembler.Size = new System.Drawing.Size(224, 18); this.labelInternalAssembler.TabIndex = 20; this.labelInternalAssembler.Text = "Experimental. Check if you like to crash!"; - // + // // tabDebug - // + // this.tabDebug.AutoScroll = true; this.tabDebug.Controls.Add(this.chckEnableDebugStub); this.tabDebug.Controls.Add(this.panlDebugSettings); @@ -388,9 +391,9 @@ this.tabDebug.TabIndex = 2; this.tabDebug.Text = "Debug"; this.tabDebug.UseVisualStyleBackColor = true; - // + // // chckEnableDebugStub - // + // this.chckEnableDebugStub.AutoSize = true; this.chckEnableDebugStub.Location = new System.Drawing.Point(14, 6); this.chckEnableDebugStub.Name = "chckEnableDebugStub"; @@ -398,9 +401,9 @@ this.chckEnableDebugStub.TabIndex = 7; this.chckEnableDebugStub.Text = "Enable Remote Debugging"; this.chckEnableDebugStub.UseVisualStyleBackColor = true; - // + // // panlDebugSettings - // + // this.panlDebugSettings.Controls.Add(this.stackCorruptionDetectionGroupBox); this.panlDebugSettings.Controls.Add(this.debugLevelGroupBox); this.panlDebugSettings.Controls.Add(this.debugStubGroupBox); @@ -408,9 +411,9 @@ this.panlDebugSettings.Name = "panlDebugSettings"; this.panlDebugSettings.Size = new System.Drawing.Size(280, 400); this.panlDebugSettings.TabIndex = 33; - // + // // stackCorruptionDetectionGroupBox - // + // this.stackCorruptionDetectionGroupBox.Controls.Add(this.label12); this.stackCorruptionDetectionGroupBox.Controls.Add(this.comboStackCorruptionDetectionLevel); this.stackCorruptionDetectionGroupBox.Controls.Add(this.chkEnableStackCorruptionDetection); @@ -419,18 +422,18 @@ this.stackCorruptionDetectionGroupBox.Size = new System.Drawing.Size(260, 90); this.stackCorruptionDetectionGroupBox.TabIndex = 34; this.stackCorruptionDetectionGroupBox.TabStop = false; - // + // // label12 - // + // this.label12.AutoSize = true; this.label12.Location = new System.Drawing.Point(3, 42); this.label12.Name = "label12"; this.label12.Size = new System.Drawing.Size(85, 13); this.label12.TabIndex = 30; this.label12.Text = "Detection Level:"; - // + // // comboStackCorruptionDetectionLevel - // + // this.comboStackCorruptionDetectionLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboStackCorruptionDetectionLevel.FormattingEnabled = true; this.comboStackCorruptionDetectionLevel.Location = new System.Drawing.Point(33, 58); @@ -438,9 +441,9 @@ this.comboStackCorruptionDetectionLevel.Size = new System.Drawing.Size(220, 21); this.comboStackCorruptionDetectionLevel.TabIndex = 9; this.comboStackCorruptionDetectionLevel.SelectedIndexChanged += new System.EventHandler(this.stackCorruptionDetectionLevelComboBox_SelectedIndexChanged); - // + // // chkEnableStackCorruptionDetection - // + // this.chkEnableStackCorruptionDetection.AutoSize = true; this.chkEnableStackCorruptionDetection.Location = new System.Drawing.Point(6, 19); this.chkEnableStackCorruptionDetection.Name = "chkEnableStackCorruptionDetection"; @@ -449,9 +452,9 @@ this.chkEnableStackCorruptionDetection.Text = "Enable Stack Corruption Detection"; this.chkEnableStackCorruptionDetection.UseVisualStyleBackColor = true; this.chkEnableStackCorruptionDetection.CheckedChanged += new System.EventHandler(this.chkEnableStacckCorruptionDetection_CheckedChanged); - // + // // debugLevelGroupBox - // + // this.debugLevelGroupBox.Controls.Add(this.comboTraceMode); this.debugLevelGroupBox.Controls.Add(this.label5); this.debugLevelGroupBox.Controls.Add(this.label4); @@ -461,18 +464,18 @@ this.debugLevelGroupBox.Size = new System.Drawing.Size(260, 125); this.debugLevelGroupBox.TabIndex = 34; this.debugLevelGroupBox.TabStop = false; - // + // // comboTraceMode - // + // this.comboTraceMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboTraceMode.FormattingEnabled = true; this.comboTraceMode.Location = new System.Drawing.Point(34, 94); this.comboTraceMode.Name = "comboTraceMode"; this.comboTraceMode.Size = new System.Drawing.Size(220, 21); this.comboTraceMode.TabIndex = 10; - // + // // label5 - // + // this.label5.AutoSize = true; this.label5.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label5.Location = new System.Drawing.Point(3, 73); @@ -482,9 +485,9 @@ this.label5.TabIndex = 26; this.label5.Text = "Tracing:"; this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // + // // label4 - // + // this.label4.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.label4.Location = new System.Drawing.Point(3, 19); this.label4.Margin = new System.Windows.Forms.Padding(0, 3, 0, 3); @@ -493,18 +496,18 @@ this.label4.TabIndex = 24; this.label4.Text = "Debug Level:"; this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // + // // comboDebugMode - // + // this.comboDebugMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboDebugMode.FormattingEnabled = true; this.comboDebugMode.Location = new System.Drawing.Point(34, 46); this.comboDebugMode.Name = "comboDebugMode"; this.comboDebugMode.Size = new System.Drawing.Size(220, 21); this.comboDebugMode.TabIndex = 9; - // + // // debugStubGroupBox - // + // this.debugStubGroupBox.Controls.Add(this.checkIgnoreDebugStubAttribute); this.debugStubGroupBox.Controls.Add(this.label9); this.debugStubGroupBox.Controls.Add(this.cmboVisualStudioDebugPort); @@ -515,9 +518,9 @@ this.debugStubGroupBox.Size = new System.Drawing.Size(260, 140); this.debugStubGroupBox.TabIndex = 31; this.debugStubGroupBox.TabStop = false; - // + // // checkIgnoreDebugStubAttribute - // + // this.checkIgnoreDebugStubAttribute.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.checkIgnoreDebugStubAttribute.Location = new System.Drawing.Point(6, 19); this.checkIgnoreDebugStubAttribute.Name = "checkIgnoreDebugStubAttribute"; @@ -525,18 +528,18 @@ this.checkIgnoreDebugStubAttribute.TabIndex = 11; this.checkIgnoreDebugStubAttribute.Text = "Ignore DebugStub Attribute Settings"; this.checkIgnoreDebugStubAttribute.UseVisualStyleBackColor = true; - // + // // label9 - // + // this.label9.AutoSize = true; this.label9.Location = new System.Drawing.Point(6, 42); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(69, 13); this.label9.TabIndex = 29; this.label9.Text = "Cosmos Port:"; - // + // // cmboVisualStudioDebugPort - // + // this.cmboVisualStudioDebugPort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cmboVisualStudioDebugPort.FormattingEnabled = true; this.cmboVisualStudioDebugPort.Items.AddRange(new object[] { @@ -550,9 +553,9 @@ this.cmboVisualStudioDebugPort.Size = new System.Drawing.Size(220, 21); this.cmboVisualStudioDebugPort.Sorted = true; this.cmboVisualStudioDebugPort.TabIndex = 13; - // + // // cmboCosmosDebugPort - // + // this.cmboCosmosDebugPort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cmboCosmosDebugPort.FormattingEnabled = true; this.cmboCosmosDebugPort.Items.AddRange(new object[] { @@ -566,18 +569,18 @@ this.cmboCosmosDebugPort.Size = new System.Drawing.Size(220, 21); this.cmboCosmosDebugPort.Sorted = true; this.cmboCosmosDebugPort.TabIndex = 12; - // + // // label10 - // + // this.label10.AutoSize = true; this.label10.Location = new System.Drawing.Point(6, 90); this.label10.Name = "label10"; this.label10.Size = new System.Drawing.Size(93, 13); this.label10.TabIndex = 30; this.label10.Text = "Visual Studio Port:"; - // + // // tabDeployment - // + // this.tabDeployment.Controls.Add(this.lboxDeployment); this.tabDeployment.Location = new System.Drawing.Point(4, 22); this.tabDeployment.Name = "tabDeployment"; @@ -585,9 +588,9 @@ this.tabDeployment.TabIndex = 11; this.tabDeployment.Text = "Deployment"; this.tabDeployment.UseVisualStyleBackColor = true; - // + // // lboxDeployment - // + // this.lboxDeployment.Dock = System.Windows.Forms.DockStyle.Left; this.lboxDeployment.FormattingEnabled = true; this.lboxDeployment.Location = new System.Drawing.Point(0, 0); @@ -595,9 +598,9 @@ this.lboxDeployment.Size = new System.Drawing.Size(206, 486); this.lboxDeployment.Sorted = true; this.lboxDeployment.TabIndex = 15; - // + // // tabLaunch - // + // this.tabLaunch.Controls.Add(this.lboxLaunch); this.tabLaunch.Location = new System.Drawing.Point(4, 22); this.tabLaunch.Name = "tabLaunch"; @@ -605,9 +608,9 @@ this.tabLaunch.TabIndex = 12; this.tabLaunch.Text = "Launch"; this.tabLaunch.UseVisualStyleBackColor = true; - // + // // lboxLaunch - // + // this.lboxLaunch.Dock = System.Windows.Forms.DockStyle.Left; this.lboxLaunch.FormattingEnabled = true; this.lboxLaunch.Location = new System.Drawing.Point(0, 0); @@ -615,9 +618,9 @@ this.lboxLaunch.Size = new System.Drawing.Size(206, 486); this.lboxLaunch.Sorted = true; this.lboxLaunch.TabIndex = 16; - // + // // tabVMware - // + // this.tabVMware.Controls.Add(this.checkEnableGDB); this.tabVMware.Controls.Add(this.checkStartCosmosGDB); this.tabVMware.Controls.Add(this.label3); @@ -629,9 +632,9 @@ this.tabVMware.TabIndex = 4; this.tabVMware.Text = "VMware"; this.tabVMware.UseVisualStyleBackColor = true; - // + // // checkEnableGDB - // + // this.checkEnableGDB.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.checkEnableGDB.Location = new System.Drawing.Point(9, 77); this.checkEnableGDB.Name = "checkEnableGDB"; @@ -639,9 +642,9 @@ this.checkEnableGDB.TabIndex = 19; this.checkEnableGDB.Text = "Enable GDB Debugger"; this.checkEnableGDB.UseVisualStyleBackColor = true; - // + // // checkStartCosmosGDB - // + // this.checkStartCosmosGDB.AutoSize = true; this.checkStartCosmosGDB.Enabled = false; this.checkStartCosmosGDB.Location = new System.Drawing.Point(24, 103); @@ -651,18 +654,18 @@ this.checkStartCosmosGDB.TabIndex = 20; this.checkStartCosmosGDB.Text = "Use Cosmos GDB Client"; this.checkStartCosmosGDB.UseVisualStyleBackColor = true; - // + // // label3 - // + // this.label3.AutoSize = true; this.label3.Location = new System.Drawing.Point(6, 12); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(42, 13); this.label3.TabIndex = 18; this.label3.Text = "Edition:"; - // + // // cmboVMwareEdition - // + // this.cmboVMwareEdition.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cmboVMwareEdition.FormattingEnabled = true; this.cmboVMwareEdition.Location = new System.Drawing.Point(26, 37); @@ -670,9 +673,9 @@ this.cmboVMwareEdition.Size = new System.Drawing.Size(143, 21); this.cmboVMwareEdition.Sorted = true; this.cmboVMwareEdition.TabIndex = 18; - // + // // tabBochs - // + // this.tabBochs.Controls.Add(this.checkStartBochsDebugGui); this.tabBochs.Controls.Add(this.checkEnableBochsDebug); this.tabBochs.Location = new System.Drawing.Point(4, 22); @@ -682,9 +685,9 @@ this.tabBochs.TabIndex = 5; this.tabBochs.Text = "Bochs"; this.tabBochs.UseVisualStyleBackColor = true; - // + // // checkStartBochsDebugGui - // + // this.checkStartBochsDebugGui.Enabled = false; this.checkStartBochsDebugGui.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.checkStartBochsDebugGui.Location = new System.Drawing.Point(24, 43); @@ -693,9 +696,9 @@ this.checkStartBochsDebugGui.TabIndex = 35; this.checkStartBochsDebugGui.Text = "Use Bochs Debugger GUI"; this.checkStartBochsDebugGui.UseVisualStyleBackColor = true; - // + // // checkEnableBochsDebug - // + // this.checkEnableBochsDebug.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); this.checkEnableBochsDebug.Location = new System.Drawing.Point(9, 17); this.checkEnableBochsDebug.Name = "checkEnableBochsDebug"; @@ -703,9 +706,19 @@ this.checkEnableBochsDebug.TabIndex = 21; 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); this.tabPXE.Controls.Add(this.comboPxeInterface); this.tabPXE.Controls.Add(this.label1); @@ -716,9 +729,9 @@ this.tabPXE.TabIndex = 6; this.tabPXE.Text = "PXE"; this.tabPXE.UseVisualStyleBackColor = true; - // + // // butnPxeRefresh - // + // this.butnPxeRefresh.AutoSize = true; this.butnPxeRefresh.Image = ((System.Drawing.Image)(resources.GetObject("butnPxeRefresh.Image"))); this.butnPxeRefresh.Location = new System.Drawing.Point(177, 31); @@ -727,25 +740,25 @@ this.butnPxeRefresh.Size = new System.Drawing.Size(23, 23); this.butnPxeRefresh.TabIndex = 23; this.butnPxeRefresh.UseVisualStyleBackColor = true; - // + // // comboPxeInterface - // + // this.comboPxeInterface.Location = new System.Drawing.Point(28, 32); this.comboPxeInterface.Name = "comboPxeInterface"; this.comboPxeInterface.Size = new System.Drawing.Size(146, 21); this.comboPxeInterface.TabIndex = 22; - // + // // label1 - // + // this.label1.AutoSize = true; this.label1.Location = new System.Drawing.Point(13, 16); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(52, 13); this.label1.TabIndex = 0; this.label1.Text = "Interface:"; - // + // // tabUSB - // + // this.tabUSB.Controls.Add(this.label7); this.tabUSB.Location = new System.Drawing.Point(4, 22); this.tabUSB.Name = "tabUSB"; @@ -754,18 +767,18 @@ this.tabUSB.TabIndex = 7; this.tabUSB.Text = "USB"; this.tabUSB.UseVisualStyleBackColor = true; - // + // // label7 - // + // this.label7.Location = new System.Drawing.Point(16, 15); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(375, 102); this.label7.TabIndex = 1; this.label7.Text = "There are no current USB options. The target drive will be requested when you run" + " the project."; - // + // // tabISO - // + // this.tabISO.Controls.Add(this.label8); this.tabISO.Location = new System.Drawing.Point(4, 22); this.tabISO.Name = "tabISO"; @@ -774,17 +787,17 @@ this.tabISO.TabIndex = 8; this.tabISO.Text = "ISO"; this.tabISO.UseVisualStyleBackColor = true; - // + // // label8 - // + // this.label8.Location = new System.Drawing.Point(17, 16); this.label8.Name = "label8"; this.label8.Size = new System.Drawing.Size(375, 102); this.label8.TabIndex = 1; this.label8.Text = "There are currently no ISO options."; - // + // // tabSlave - // + // this.tabSlave.Controls.Add(this.cmboSlavePort); this.tabSlave.Controls.Add(this.label6); this.tabSlave.Location = new System.Drawing.Point(4, 22); @@ -794,9 +807,9 @@ this.tabSlave.TabIndex = 13; this.tabSlave.Text = "Slave"; this.tabSlave.UseVisualStyleBackColor = true; - // + // // cmboSlavePort - // + // this.cmboSlavePort.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cmboSlavePort.FormattingEnabled = true; this.cmboSlavePort.Items.AddRange(new object[] { @@ -810,18 +823,18 @@ this.cmboSlavePort.Size = new System.Drawing.Size(146, 21); this.cmboSlavePort.Sorted = true; this.cmboSlavePort.TabIndex = 23; - // + // // label6 - // + // this.label6.AutoSize = true; this.label6.Location = new System.Drawing.Point(15, 15); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(59, 13); this.label6.TabIndex = 34; this.label6.Text = "Slave Port:"; - // + // // tabHyperV - // + // this.tabHyperV.Location = new System.Drawing.Point(4, 22); this.tabHyperV.Name = "tabHyperV"; this.tabHyperV.Padding = new System.Windows.Forms.Padding(3); @@ -829,9 +842,9 @@ this.tabHyperV.TabIndex = 14; this.tabHyperV.Text = "Hyper-V"; this.tabHyperV.UseVisualStyleBackColor = true; - // + // // CosmosPage - // + // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.TabControl1); @@ -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; diff --git a/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.cs b/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.cs index ca090899e..dd9d423e0 100644 --- a/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.cs +++ b/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/OldCosmosPropertyPageControl.cs @@ -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(); } diff --git a/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/ProfilePresets.cs b/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/ProfilePresets.cs index a91c3d875..2514cafcf 100644 --- a/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/ProfilePresets.cs +++ b/source/Cosmos.VS.ProjectSystem/ProjectSystem/VS/PropertyPages/ProfilePresets.cs @@ -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"); }