diff --git a/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs b/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs index 4a74a7df1..37e52b1ab 100644 --- a/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs +++ b/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs @@ -216,7 +216,7 @@ namespace Cosmos.TestRunner.Core "EnableDebug:True", "EnableStackCorruptionDetection:" + EnableStackCorruptionChecks, "StackCorruptionDetectionLevel:" + StackCorruptionDetectionLevel, - "DebugMode:Source", + "DebugMode:" + DebugMode, "TraceAssemblies:" + TraceAssembliesLevel, "DebugCom:1", "TargetAssembly:" + kernelFileName, diff --git a/Tests/Cosmos.TestRunner.Core/Engine.cs b/Tests/Cosmos.TestRunner.Core/Engine.cs index 815c6ec04..911e0fc89 100644 --- a/Tests/Cosmos.TestRunner.Core/Engine.cs +++ b/Tests/Cosmos.TestRunner.Core/Engine.cs @@ -19,6 +19,7 @@ namespace Cosmos.TestRunner.Core protected TraceAssemblies TraceAssembliesLevel => mConfiguration.TraceAssembliesLevel; protected bool EnableStackCorruptionChecks => mConfiguration.EnableStackCorruptionChecks; protected StackCorruptionDetectionLevel StackCorruptionDetectionLevel => mConfiguration.StackCorruptionDetectionLevel; + protected DebugMode DebugMode => mConfiguration.DebugMode; protected bool RunWithGDB => mConfiguration.RunWithGDB; protected bool StartBochsDebugGui => mConfiguration.StartBochsDebugGUI; diff --git a/Tests/Cosmos.TestRunner.Core/IEngineConfiguration.cs b/Tests/Cosmos.TestRunner.Core/IEngineConfiguration.cs index 050283bb4..ca4ad8ddd 100644 --- a/Tests/Cosmos.TestRunner.Core/IEngineConfiguration.cs +++ b/Tests/Cosmos.TestRunner.Core/IEngineConfiguration.cs @@ -28,6 +28,7 @@ namespace Cosmos.TestRunner.Core TraceAssemblies TraceAssembliesLevel { get; } bool EnableStackCorruptionChecks { get; } StackCorruptionDetectionLevel StackCorruptionDetectionLevel { get; } + DebugMode DebugMode { get; } /// /// An enumerable of kernel assemblies which will be run. diff --git a/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs b/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs index 34eac84ed..09ffe9ab6 100644 --- a/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs +++ b/Tests/Cosmos.TestRunner.Full/DefaultEngineConfiguration.cs @@ -28,6 +28,7 @@ namespace Cosmos.TestRunner.Full public virtual TraceAssemblies TraceAssembliesLevel => TraceAssemblies.User; public virtual bool EnableStackCorruptionChecks => true; public virtual StackCorruptionDetectionLevel StackCorruptionDetectionLevel => StackCorruptionDetectionLevel.AllInstructions; + public virtual DebugMode DebugMode => DebugMode.Source; public virtual IEnumerable KernelAssembliesToRun { diff --git a/Tests/Cosmos.TestRunner.TestAdapter/EngineConfiguration.cs b/Tests/Cosmos.TestRunner.TestAdapter/EngineConfiguration.cs index 31cfceff6..4d01c3763 100644 --- a/Tests/Cosmos.TestRunner.TestAdapter/EngineConfiguration.cs +++ b/Tests/Cosmos.TestRunner.TestAdapter/EngineConfiguration.cs @@ -20,6 +20,7 @@ namespace Cosmos.TestRunner.TestAdapter public TraceAssemblies TraceAssembliesLevel { get; } public bool EnableStackCorruptionChecks { get; } public StackCorruptionDetectionLevel StackCorruptionDetectionLevel { get; } + public DebugMode DebugMode { get; } public IEnumerable KernelAssembliesToRun { get; } diff --git a/Tests/Cosmos.TestRunner.UI/ViewModels/SettingsDialogViewModel.cs b/Tests/Cosmos.TestRunner.UI/ViewModels/SettingsDialogViewModel.cs index c9373df66..6a5d712b0 100644 --- a/Tests/Cosmos.TestRunner.UI/ViewModels/SettingsDialogViewModel.cs +++ b/Tests/Cosmos.TestRunner.UI/ViewModels/SettingsDialogViewModel.cs @@ -97,6 +97,13 @@ namespace Cosmos.TestRunner.UI.ViewModels set => SetProperty(ref mStackCorruptionDetectionLevel, value); } + private DebugMode mDebugMode = defaultEngineConfiguration.DebugMode; + public DebugMode DebugMode + { + get => mDebugMode; + set => SetProperty(ref mDebugMode, value); + } + public IEnumerable KernelAssembliesToRun { get diff --git a/Tests/Cosmos.TestRunner/.vscode/launch.json b/Tests/Cosmos.TestRunner/.vscode/launch.json deleted file mode 100644 index b1e73178b..000000000 --- a/Tests/Cosmos.TestRunner/.vscode/launch.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": ".NET Core Launch (console)", - "type": "coreclr", - "request": "launch", - "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/netcoreapp2.0/Cosmos.TestRunner.dll", - "args": [], - "cwd": "${workspaceFolder}", - "console": "internalConsole", - "stopAtEntry": false - }, - { - "name": ".NET Core Attach", - "type": "coreclr", - "request": "attach", - "processId": "${command:pickProcess}" - } - ] -} \ No newline at end of file diff --git a/Tests/Cosmos.TestRunner/.vscode/tasks.json b/Tests/Cosmos.TestRunner/.vscode/tasks.json deleted file mode 100644 index bd652ecd7..000000000 --- a/Tests/Cosmos.TestRunner/.vscode/tasks.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "build", - "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/Cosmos.TestRunner.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/Cosmos.TestRunner.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "${workspaceFolder}/Cosmos.TestRunner.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - } - ] -} \ No newline at end of file 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/ProcessorTests/Kernel.cs b/Tests/Kernels/ProcessorTests/Kernel.cs index 93f9588cc..9ef432177 100644 --- a/Tests/Kernels/ProcessorTests/Kernel.cs +++ b/Tests/Kernels/ProcessorTests/Kernel.cs @@ -36,6 +36,14 @@ namespace ProcessorTests } } + public void TestBrandStringBlank() + { + string brandString = CPU.GetCPUBrandString(); + mDebugger.Send("Brand String: " + brandString); + bool isBrandStringBlank = string.IsNullOrWhiteSpace(brandString); + Assert.IsFalse(isBrandStringBlank, "Processor brand string is blank."); + } + public void TestVendorNameIsNotBlank() { string vendorName = CPU.GetCPUVendorName(); diff --git a/build/Targets/Versions.props b/build/Targets/Versions.props index 20ce54cea..6444582a0 100644 --- a/build/Targets/Versions.props +++ b/build/Targets/Versions.props @@ -3,7 +3,7 @@ 3.0.22 0.7.0 - 16.0.461 + 16.7.0 1.0.0 16.0.1 16.0.1 diff --git a/source/Cosmos.Core/CPU.cs b/source/Cosmos.Core/CPU.cs index cda877076..26defb248 100644 --- a/source/Cosmos.Core/CPU.cs +++ b/source/Cosmos.Core/CPU.cs @@ -110,6 +110,8 @@ namespace Cosmos.Core return xResult; } + + /// /// Get CPU vendor name. /// @@ -179,15 +181,15 @@ namespace Cosmos.Core { ReadCPUID(0x80000002 + i, ref eax, ref ebx, ref ecx, ref edx); s += (char)(ebx % 256); - s += (char)((ebx >> 8) % 256); - s += (char)((ebx>> 16) % 256); - s += (char)((ebx >> 24) % 256); + s += (char)((ebx >> 8) % 256); + s += (char)((ebx >> 16) % 256); + s += (char)((ebx >> 24) % 256); s += (char)(edx % 256); - s += (char)((edx >> 8) % 256); - s += (char)((edx >> 16) % 256); - s += (char)((edx >> 24) % 256); + s += (char)((edx >> 8) % 256); + s += (char)((edx >> 16) % 256); + s += (char)((edx >> 24) % 256); s += (char)(ecx % 256); - s += (char)((ecx >> 8) % 256); + s += (char)((ecx >> 8) % 256); s += (char)((ecx >> 16) % 256); s += (char)((ecx >> 24) % 256); } @@ -247,12 +249,73 @@ namespace Cosmos.Core throw new NotSupportedException(); } + /// + /// Get CPU cycle speed. + /// + /// long value. + /// Thrown on fatal error, contact support. + /// Thrown if can not read CPU ID. + public static string GetCPUBrandString() + { + if (CanReadCPUID() != 0) + { + // See https://c9x.me/x86/html/file_module_x86_id_45.html + + int eax = 0; + int ebx = 0; + int ecx = 0; + int edx = 0; + int[] s = new int[64]; + string rs = ""; + + for (uint i = 0; i < 3; i++) + { + ReadCPUID(0x80000002 + i, ref eax, ref ebx, ref ecx, ref edx); + s[(i * 16) + 0] = (eax % 256); + s[(i * 16) + 1] = ((eax >> 8) % 256); + s[(i * 16) + 2] = ((eax >> 16) % 256); + s[(i * 16) + 3] = ((eax >> 24) % 256); + s[(i * 16) + 4] = (ebx % 256); + s[(i * 16) + 5] = ((ebx >> 8) % 256); + s[(i * 16) + 6] = ((ebx >> 16) % 256); + s[(i * 16) + 7] = ((ebx >> 24) % 256); + s[(i * 16) + 8] = (ecx % 256); + s[(i * 16) + 9] = ((ecx >> 8) % 256); + s[(i * 16) + 10] = ((ecx >> 16) % 256); + s[(i * 16) + 11] = ((ecx >> 24) % 256); + s[(i * 16) + 12] = (edx % 256); + s[(i * 16) + 13] = ((edx >> 8) % 256); + s[(i * 16) + 14] = ((edx >> 16) % 256); + s[(i * 16) + 15] = ((edx >> 24) % 256); + } + for (int i = 0; i < s.Length; i++) + { + if (s[i] == 0x00) + { + continue; + } + rs += (char)s[i]; + } + + if (!(rs == "")) + { + return rs; + } else + { + throw new NotSupportedException(); + } + } + 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. @@ -263,7 +326,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. 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/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.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_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; + } + } +}