diff --git a/Demos/Guess/GuessOS.cs b/Demos/Guess/GuessOS.cs index f08a40990..a93a2ed79 100644 --- a/Demos/Guess/GuessOS.cs +++ b/Demos/Guess/GuessOS.cs @@ -5,6 +5,10 @@ using System.Text; using Cosmos.Debug.Kernel; using Sys = Cosmos.System; +/* + * Beware Demo Kernels are not recompiled when its dependencies changes! + * To force recompilation right click on on the Cosmos icon of the demo solution and do "Build". + */ namespace GuessKernel { public class GuessOS : Sys.Kernel @@ -54,6 +58,8 @@ namespace GuessKernel else { Console.WriteLine("You guessed it!"); + Console.WriteLine("Press any key to end Guess Demo. Thanks for playing!"); + Console.ReadKey(); Stop(); } } diff --git a/Tests/BoxingTests/BoxingTests.csproj b/Tests/BoxingTests/BoxingTests.csproj index 9b2ab095f..f02d9a11f 100644 --- a/Tests/BoxingTests/BoxingTests.csproj +++ b/Tests/BoxingTests/BoxingTests.csproj @@ -58,6 +58,7 @@ + diff --git a/Tests/BoxingTests/Kernel.cs b/Tests/BoxingTests/Kernel.cs index 0c21c3cce..6f3eeeee8 100644 --- a/Tests/BoxingTests/Kernel.cs +++ b/Tests/BoxingTests/Kernel.cs @@ -4,6 +4,7 @@ using System.Text; using Cosmos.Debug.Kernel; using Cosmos.TestRunner; using Sys = Cosmos.System; +using System.Drawing; namespace BoxingTests { @@ -17,7 +18,10 @@ namespace BoxingTests protected override void Run() { Assert.IsTrue(TestBoxingCharToString(), "Boxing char to string test failed."); - Assert.IsTrue(TestBoxingCharArrayToString(), "Boxing char[] to string test failed."); + //Assert.IsTrue(TestBoxingCharArrayToString(), "Boxing char[] to string test failed."); + Assert.IsTrue(TestBoxingIntToString(), "Boxing int to string test failed."); + Assert.IsTrue(TestBoxingColorToString(), "Boxing of Color to string test failed."); + TestController.Completed(); } @@ -36,11 +40,12 @@ namespace BoxingTests } } + /* This test fails with "Object.ToString() not yet implemented" written in the Console */ private bool TestBoxingCharArrayToString() { try { - char[] xC = {'c'}; + char[] xC = { 'c' }; string xS = xC.ToString(); return (xS[0] == xC[0]); } @@ -50,5 +55,56 @@ namespace BoxingTests return false; } } + + private bool TestBoxingIntToString() + { + try + { + object boxMe; + int anInt = 42; + + boxMe = anInt; + + return (boxMe.ToString() == "42"); + } + catch (Exception E) + { + mDebugger.SendError("TestBoxingIntToString", E.Message); + return false; + } + } + + /* TODO add other tests: + * - a simple stucture with fixed layout (for example with the integers and a ToString() method implemented) + * - the structure of above but without layout set (that is sequential should be automatically taken by compiler) + * - a structure with auto layout + * - a strucuture with the packing attribute set with not a default value used + */ + + /* + * The struct Color of System.Drawging has really a weird layout that make so that the runtime should create + * padding between the fields to align the size of the structure to 4 bytes. + * Cosmos ignores this and put no padding / writes the struct wrongly in memory and then when it should be + * boxed garbage is copied instead of the structure itself! + */ + private bool TestBoxingColorToString() + { + try + { + object boxMe; + Color color = Color.Blue; + + boxMe = color; + + return (boxMe.ToString() == "Color[Blue]"); + } + catch (Exception E) + { + mDebugger.SendError("TestBoxingIntToString", E.Message); + return false; + } + } + + } } diff --git a/Tests/Cosmos.Compiler.Tests.Bcl/Kernel.cs b/Tests/Cosmos.Compiler.Tests.Bcl/Kernel.cs index 519939d4e..84e0f1254 100644 --- a/Tests/Cosmos.Compiler.Tests.Bcl/Kernel.cs +++ b/Tests/Cosmos.Compiler.Tests.Bcl/Kernel.cs @@ -39,11 +39,11 @@ namespace Cosmos.Compiler.Tests.Bcl BooleanTest.Execute(); SingleTest.Execute(); DoubleTest.Execute(); + //DecimalTest.Execute(); BitConverterTest.Execute(); UnsafeCodeTest.Execute(); DelegatesTest.Execute(); - //DecimalTest.Execute(); System.Collections.Generic.ListTest.Execute(); System.Collections.Generic.QueueTest.Execute(); //System.Collections.Generic.DictionaryTest.Execute(); diff --git a/Tests/Cosmos.TestRunner.Core/TestKernelSets.cs b/Tests/Cosmos.TestRunner.Core/TestKernelSets.cs index b2aa53982..6da364a5f 100644 --- a/Tests/Cosmos.TestRunner.Core/TestKernelSets.cs +++ b/Tests/Cosmos.TestRunner.Core/TestKernelSets.cs @@ -7,8 +7,7 @@ namespace Cosmos.TestRunner.Core { public static IEnumerable GetStableKernelTypes() { - yield return typeof(GraphicTest.Kernel); -#if false + yield return typeof(Cosmos.Compiler.Tests.Bcl.Kernel); yield return typeof(VGACompilerCrash.Kernel); yield return typeof(Cosmos.Compiler.Tests.Bcl.Kernel); yield return typeof(Cosmos.Compiler.Tests.SingleEchoTest.Kernel); @@ -22,7 +21,9 @@ namespace Cosmos.TestRunner.Core //yield return typeof(Cosmos.Compiler.Tests.Encryption.Kernel); //yield return typeof(FrotzKernel.Kernel); -#endif + + /* Please see the notes on the kernel itself before enabling it */ + //yield return typeof(GraphicTest.Kernel); } } } diff --git a/Tests/GraphicTest/GraphicTest.csproj b/Tests/GraphicTest/GraphicTest.csproj index 2d14bc888..91c0d9859 100644 --- a/Tests/GraphicTest/GraphicTest.csproj +++ b/Tests/GraphicTest/GraphicTest.csproj @@ -22,6 +22,7 @@ x86 prompt MinimumRecommendedRules.ruleset + false bin\Release\ @@ -45,6 +46,22 @@ + + {1fac100c-d732-4ea4-b518-5af4baf64f2e} + Cosmos.Common + + + {d9a87aad-fcc9-4517-b31d-e904dad00784} + Cosmos.Core.Plugs + + + {5ac4773c-cb4e-4cd9-8d50-02e10a07dee6} + Cosmos.Core + + + {C801F19C-A9D3-42D5-9A57-9FFDF9B4D05E} + Cosmos.IL2CPU.Plugs + {e6d3b644-c487-472d-a978-c1a82d0c099b} Cosmos.TestRunner.TestController diff --git a/Tests/GraphicTest/Kernel.cs b/Tests/GraphicTest/Kernel.cs index 0813103db..2bad02769 100644 --- a/Tests/GraphicTest/Kernel.cs +++ b/Tests/GraphicTest/Kernel.cs @@ -3,6 +3,16 @@ using Sys = Cosmos.System; using Cosmos.TestRunner; using Cosmos.System.Graphics; +/* + * Please note this is an atypical TestRunner: + * - no Assertion can be done + * - it cannot be executed automatically + * + * it exists to make easier tests while changing low level stuff (it would be better and faster to use the Demo kernel but + * sometimes it is a problem to make it see modifications done at low level) + * + * Remember to comment this test again on TestKernelSet.cs when you are ready to merge your modifications! + */ namespace GraphicTest { public class Kernel : Sys.Kernel @@ -14,6 +24,7 @@ namespace GraphicTest Console.WriteLine("Cosmos booted successfully. Let's go in Graphic Mode"); canvas = FullScreenCanvas.GetFullScreenCanvas(); + canvas.Clear(Color.Blue); } @@ -47,9 +58,9 @@ namespace GraphicTest /* Let's try to change mode...*/ canvas.Mode = new Mode(800, 600, ColorDepth.ColorDepth32); - - /* A Coral rectangle */ - pen.Color = Color.Coral; + + /* A LimeGreen rectangle */ + pen.Color = Color.LimeGreen; canvas.DrawRectangle(pen, 450, 450, 80, 60); Console.ReadKey(); diff --git a/source/Cosmos Graphic Subsytem/AssemblyInfo.cs b/source/Cosmos Graphic Subsytem/AssemblyInfo.cs new file mode 100644 index 000000000..6848b03ad --- /dev/null +++ b/source/Cosmos Graphic Subsytem/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Package Name")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Company")] +[assembly: AssemblyProduct("Package Name")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: ComVisible(false)] +[assembly: CLSCompliant(false)] +[assembly: NeutralResourcesLanguage("en-US")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Revision and Build Numbers +// by using the '*' as shown below: + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] + + + diff --git a/source/Cosmos Graphic Subsytem/Cosmos Graphic Subsytem.csproj b/source/Cosmos Graphic Subsytem/Cosmos Graphic Subsytem.csproj new file mode 100644 index 000000000..fa68ce07a --- /dev/null +++ b/source/Cosmos Graphic Subsytem/Cosmos Graphic Subsytem.csproj @@ -0,0 +1,54 @@ + + + + Debug + x86 + 9.0.30729 + 2.0 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1} + Library + Properties + Cosmos_Graphic_Subsytem + Cosmos Graphic Subsytem + 512 + v4.5.2 + + + + true + bin\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + bin\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/source/Cosmos Graphic Subsytem/Cosmos Graphic SubsytemBoot.Cosmos b/source/Cosmos Graphic Subsytem/Cosmos Graphic SubsytemBoot.Cosmos new file mode 100644 index 000000000..54c3ee86f --- /dev/null +++ b/source/Cosmos Graphic Subsytem/Cosmos Graphic SubsytemBoot.Cosmos @@ -0,0 +1,70 @@ + + + + Debug + 2.0 + {1bc71853-22f3-415d-a068-8e1fa8e8f05b} + false + Cosmos Graphic SubsytemBoot + elf + v4.5.2 + + + + Bochs + true + Source + User + False + false + Player + bin\Debug\ + Cosmos Graphic SubsytemBoot + Use Bochs emulator to deploy and debug. + ISO + Bochs + Pipe: Cosmos\Serial + 192.168.0.3 + Cosmos Graphic SubsytemBoot + Use VMware Player or Workstation to deploy and debug. + ISO + VMware + true + Source + Pipe: Cosmos\Serial + 192.168.0.3 + Player + bin\Debug\ + False + false + Cosmos Graphic SubsytemBoot + Use Bochs emulator to deploy and debug. + ISO + Bochs + true + Source + Pipe: Cosmos\Serial + 192.168.0.3 + Player + bin\Debug\ + False + false + + + + Cosmos Graphic Subsytem + {49f2c01d-d2c5-4564-810b-1ae92236c5c1} + + + + + + + + + + \ No newline at end of file diff --git a/source/Cosmos Graphic Subsytem/Kernel.cs b/source/Cosmos Graphic Subsytem/Kernel.cs new file mode 100644 index 000000000..774fe8295 --- /dev/null +++ b/source/Cosmos Graphic Subsytem/Kernel.cs @@ -0,0 +1,70 @@ +using System; +using Cosmos.System.Graphics; +using Sys = Cosmos.System; + +/* + * Beware Demo Kernels are not recompiled when its dependencies changes! + * To force recompilation right click on on the Cosmos icon of the demo solution and do "Build". + */ +namespace Cosmos_Graphic_Subsytem +{ + public class Kernel : Sys.Kernel + { + Canvas canvas; + protected override void BeforeRun() + { + Console.WriteLine("Cosmos booted successfully. Let's go in Graphic Mode"); + + /* Get on istance of the Canvas that is all the Screen */ + canvas = FullScreenCanvas.GetFullScreenCanvas(); + + /* Clear the Screen with the color 'Blue' */ + canvas.Clear(Color.Blue); + } + + protected override void Run() + { + mDebugger.Send("Run"); + + /* A red Point */ + Pen pen = new Pen(Color.Red); + canvas.DrawPoint(pen, 69, 69); + + /* A GreenYellow horizontal line */ + pen.Color = Color.GreenYellow; + canvas.DrawLine(pen, 250, 100, 400, 100); + + /* An IndianRed vertical line */ + pen.Color = Color.IndianRed; + canvas.DrawLine(pen, 350, 150, 350, 250); + + /* A MintCream diagonal line */ + pen.Color = Color.MintCream; + canvas.DrawLine(pen, 250, 150, 400, 250); + + /* A PaleVioletRed rectangle */ + pen.Color = Color.PaleVioletRed; + canvas.DrawRectangle(pen, 350, 350, 80, 60); + + /* + * It will be really beautiful to do here: + * canvas.DrawString(pen, "Please press any key to continue the Demo..."); + */ + Console.ReadKey(); + + /* Let's try to change mode...*/ + canvas.Mode = new Mode(800, 600, ColorDepth.ColorDepth32); + + /* A LimeGreen rectangle */ + pen.Color = Color.LimeGreen; + canvas.DrawRectangle(pen, 450, 450, 80, 60); + + /* + * It will be really beautiful to do here: + * canvas.DrawString(pen, "Please press any key to end the Demo..."); + */ + Console.ReadKey(); + Stop(); + } + } +} diff --git a/source/Cosmos.Assembler/Cosmos.Assembler.csproj b/source/Cosmos.Assembler/Cosmos.Assembler.csproj index f28229981..cd21ef99a 100644 --- a/source/Cosmos.Assembler/Cosmos.Assembler.csproj +++ b/source/Cosmos.Assembler/Cosmos.Assembler.csproj @@ -271,6 +271,7 @@ + diff --git a/source/Cosmos.Assembler/x86/SSEAndMMX2/Shufps.cs b/source/Cosmos.Assembler/x86/SSEAndMMX2/Shufps.cs new file mode 100644 index 000000000..b4b3187fc --- /dev/null +++ b/source/Cosmos.Assembler/x86/SSEAndMMX2/Shufps.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cosmos.Assembler.x86.SSE +{ + [Cosmos.Assembler.OpCode("shufps")] + public class Shufps : InstructionWithDestinationAndSourceAndPseudoOpcodes + { + } +} diff --git a/source/Cosmos.Core.Plugs/Cosmos.Core.Plugs.csproj b/source/Cosmos.Core.Plugs/Cosmos.Core.Plugs.csproj index 01c35d743..a168f26a2 100644 --- a/source/Cosmos.Core.Plugs/Cosmos.Core.Plugs.csproj +++ b/source/Cosmos.Core.Plugs/Cosmos.Core.Plugs.csproj @@ -95,6 +95,7 @@ + @@ -102,6 +103,7 @@ + diff --git a/source/Cosmos.Core.Plugs/MemoryOperations/MemoryOperationsFillFastAsm.cs b/source/Cosmos.Core.Plugs/MemoryOperations/MemoryOperationsFillFastAsm.cs new file mode 100644 index 000000000..6e1190976 --- /dev/null +++ b/source/Cosmos.Core.Plugs/MemoryOperations/MemoryOperationsFillFastAsm.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Cosmos.Assembler; +using XSharp.Compiler; +using static XSharp.Compiler.XSRegisters; +using CPUx86 = Cosmos.Assembler.x86; +using Cosmos.IL2CPU.Plugs; + +namespace Cosmos.Core.Plugs.MemoryOperations +{ + public class MemoryOperationsFill16BlocksAsm : AssemblerMethod + { + private const int DestDisplacement = 16; + private const int ValueDisplacement = 12; + private const int BlocksNumDisplacement = 8; + + /* + * + * public static unsafe void Fill16Blocks( + * byte *dest, [ebp + 8] + * int value, [ebp + 12] + * int BlocksNum) [ebp + 16] + */ + public override void AssembleNew(Assembler.Assembler aAssembler, object aMethodInfo) + { + /* First we copy dest, value and DestSize from EBP (stack) to 3 different registers */ + XS.Comment("Destination (int pointer)"); + XS.Set(EAX, EBP, sourceDisplacement: DestDisplacement); + + XS.Comment("Value"); + XS.Set(EBX, EBP, sourceDisplacement: ValueDisplacement); + + XS.Comment("BlocksNum"); + XS.Set(ECX, EBP, sourceDisplacement: BlocksNumDisplacement); + + /* + * Now we need to copy 'value' (EBX) to an SSE register but we should not simply do a copy (!) + * but all the register with 'value' repeating! + * That is in the 16 byte SSE register should go this repeating pattern: + * |value|value|value|value + * luckily we don't need to do a loop for this there is the SSE3 instruction for this shufps + */ + XS.SSE2.MoveD(XMM0, EBX); + XS.SSE.Shufps(XMM0, XMM0, 0x0000); // This broadcast the first element of XMM0 on the other 3 + + /* Do the 'loop' */ + XS.Xor(EDI, EDI); // EDI is 0 + XS.Label(".loop"); + //XS.SSE.MoveUPS(EAX, XMM0, destinationIsIndirect: true, destinationDisplacement: EDI); + XS.LiteralCode("movups[EAX + EDI], XMM0"); + XS.Add(EDI, 16); + XS.Sub(ECX, 1); + //XS.LiteralCode("jnz .loop"); + XS.Jump(CPUx86.ConditionalTestEnum.NotZero, ".loop"); + + //XS.Return(); + } + } +} diff --git a/source/Cosmos.Core.Plugs/MemoryOperations/MemoryOperationsImpl.cs b/source/Cosmos.Core.Plugs/MemoryOperations/MemoryOperationsImpl.cs new file mode 100644 index 000000000..5a0832a40 --- /dev/null +++ b/source/Cosmos.Core.Plugs/MemoryOperations/MemoryOperationsImpl.cs @@ -0,0 +1,187 @@ +#define COSMOSDEBUG +using System; +using System.Runtime.CompilerServices; + +using Cosmos.IL2CPU.Plugs; +//using Cosmos.IL2CPU.Plugs.Assemblers.MemoryOperations; + +namespace Cosmos.Core.Plugs.MemoryOperations +{ + [Plug(Target = typeof(Cosmos.Core.MemoryOperations))] + public unsafe class MemoryOperationsImpl + { + [PlugMethod(Assembler = typeof(MemoryOperationsFill16BlocksAsm))] + public static unsafe void Fill16Blocks(byte* dest, int value, int BlocksNum) + { + + } + + unsafe public static void Fill(byte* dest, int value, int size) + { + //Console.WriteLine("Filling array of size " + size + " with value 0x" + value.ToString("X")); + //Global.mDebugger.SendInternal("Filling array of size " + size + " with value " + value); + + /* For very little sizes (until 15 bytes) we hand unroll the loop */ + switch (size) + { + case 0: + return; + + case 1: + *dest = (byte)value; + return; + + case 2: + *(short*)dest = (short)value; + return; + + case 3: + *(short*)dest = (short)value; + *(dest + 2) = (byte)value; + return; + + case 4: + *(int*)dest = value; + return; + + case 5: + *(int*)dest = value; + *(dest + 4) = (byte)value; + return; + + case 6: + *(int*)dest = value; + *(short*)(dest + 4) = (short)value; + return; + + case 7: + *(int*)dest = value; + *(short*)(dest + 4) = (short)value; + *(dest + 6) = (byte)value; + return; + + case 8: + *(int*)dest = value; + *(int*)(dest + 4) = value; + return; + + case 9: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(dest + 8) = (byte)value; + return; + + case 10: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(short*)(dest + 8) = (short)value; + return; + + case 11: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(short*)(dest + 8) = (short)value; + *(dest + 10) = (byte)value; + return; + + case 12: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(int*)(dest + 8) = value; + return; + + case 13: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(int*)(dest + 8) = value; + *(dest + 12) = (byte)value; + return; + + case 14: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(int*)(dest + 8) = value; + *(short*)(dest + 12) = (byte)value; + return; + + case 15: + *(int*)dest = value; + *(int*)(dest + 4) = value; + *(int*)(dest + 8) = value; + *(short*)(dest + 12) = (short)value; + *(dest + 14) = (byte)value; + return; + } + + /* + * OK size is >= 16 it does not make any sense to do it with primitive types as C# + * has not a Int128 type, the Int128 operations will be done in assembler but we can + * do yet in the Managed world the two things: + * 1. Check of how many blocks of 16 bytes size is composed + * 2. If there are reaming bytes (that is size is not a perfect multiple of size) + * we do the Fill() using a simple managed for() loop of bytes + */ + int BlocksNum; + int ByteRemaining; + + BlocksNum = Math.DivRem(size, 16, out ByteRemaining); + + //Global.mDebugger.SendInternal("size " + size + " is composed of " + BlocksNum + " block of 16 bytes with " + ByteRemaining + " remainder"); + + for (int i = 0; i < ByteRemaining; i++) + *(dest + i) = (byte)value; + + /* Let's call the assembler version now to do the 16 byte block copies */ + Fill16Blocks(dest + ByteRemaining, value, BlocksNum); + + /* + * If needed there is yet space of optimization here for example: + * - you can check if size is a multiple of 64 and if yes use an yet more faster Fill64Blocks + * - or if it is not so try to see if it is a multiple of 32 + * at point probably it would be better to move a lot of the logic to assembler + */ + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(int[] dest, int value) + { + fixed (int* destPtr = dest) + { + Fill((byte*)destPtr, value, dest.Length * 4); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(ushort[] dest, ushort value) + { + fixed (ushort* destPtr = dest) + { + /* Broadcast 'value' fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = value * 0x10001; + Fill((byte*)destPtr, valueFiller, dest.Length * 2); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(short[] dest, short value) + { + fixed (short* destPtr = dest) + { + /* Broadcast 'value' fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = (ushort)value * 0x10001; + Fill((byte*)destPtr, valueFiller, dest.Length * 2); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(byte[] dest, byte value) + { + fixed (byte* destPtr = dest) + { + /* Broadcast 'value' fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = value * 0x1010101; + Fill(destPtr, valueFiller, dest.Length); + } + } + } +} diff --git a/source/Cosmos.Core/IOGroup/VBE.cs b/source/Cosmos.Core/IOGroup/VBE.cs index f18fbc8aa..df5b99825 100644 --- a/source/Cosmos.Core/IOGroup/VBE.cs +++ b/source/Cosmos.Core/IOGroup/VBE.cs @@ -15,5 +15,6 @@ namespace Cosmos.Core.IOGroup * This not a lot optimal as we are taking a lot of memory and then maybe the driver is configured to go at 320*240! */ public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1920 * 1200 * 4); + //public MemoryBlock LinearFrameBuffer = new MemoryBlock(0xE0000000, 1024 * 768 * 4); } } diff --git a/source/Cosmos.Core/MemoryBlock.cs b/source/Cosmos.Core/MemoryBlock.cs index a8e77f7c1..9e46a53c8 100644 --- a/source/Cosmos.Core/MemoryBlock.cs +++ b/source/Cosmos.Core/MemoryBlock.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using Cosmos.Common; -using System.Linq; -using System.Text; using Cosmos.IL2CPU.Plugs; namespace Cosmos.Core @@ -51,21 +47,16 @@ namespace Cosmos.Core public void Fill(UInt32 aData) { - Fill(0, Size / 4, aData); + //Fill(0, Size / 4, aData); + Fill(0, Size, aData); } [DebugStub(Off = true)] public unsafe void Fill(UInt32 aStart, UInt32 aCount, UInt32 aData) { - //TODO: before next step can at least check bounds here and do the addition just once to - //start the loop. - //TODO - When asm can check count against size just one time and use a native fill asm op + // TODO thow exception if aStart and aCount are not in bound. I've tried to do this but Bochs dies :-( UInt32* xDest = (UInt32*)(this.Base + aStart); - for (UInt32 i = 0; i < aCount; i++) - { - *xDest = aData; - xDest++; - } + MemoryOperations.Fill(xDest, aData, (int)aCount); } public void Fill(byte aData) @@ -75,35 +66,23 @@ namespace Cosmos.Core public void Fill(UInt16 aData) { - Fill(0, Size / 2, aData); + Fill(0, Size, aData); } [DebugStub(Off = true)] public unsafe void Fill(UInt32 aStart, UInt32 aCount, UInt16 aData) { - //TODO: before next step can at least check bounds here and do the addition just once to - //start the loop. - //TODO - When asm can check count against size just one time and use a native fill asm op + // TODO thow exception if aStart and aCount are not in bound. I've tried to do this but Bochs dies :-( UInt16* xDest = (UInt16*)(this.Base + aStart); - for (UInt32 i = 0; i < aCount; i++) - { - *xDest = aData; - xDest++; - } + MemoryOperations.Fill(xDest, aData, (int)aCount); } [DebugStub(Off = true)] public unsafe void Fill(UInt32 aStart, UInt32 aCount, byte aData) { - //TODO: before next step can at least check bounds here and do the addition just once to - //start the loop. - //TODO - When asm can check count against size just one time and use a native fill asm op + // TODO thow exception if aStart and aCount are not in bound. I've tried to do this but Bochs dies :-( byte* xDest = (byte*)(this.Base + aStart); - for (UInt32 i = 0; i < aCount; i++) - { - *xDest = aData; - xDest++; - } + MemoryOperations.Fill(xDest, aData, (int)aCount); } [DebugStub(Off = true)] diff --git a/source/Cosmos.Core/MemoryOperations.cs b/source/Cosmos.Core/MemoryOperations.cs new file mode 100644 index 000000000..446008e09 --- /dev/null +++ b/source/Cosmos.Core/MemoryOperations.cs @@ -0,0 +1,113 @@ +#define COSMOSDEBUG +using System.Runtime.CompilerServices; + +namespace Cosmos.Core +{ + public unsafe class MemoryOperations + { + public static unsafe void Fill16Blocks(byte* dest, int value, int BlocksNum) + { + // Plugged + } + + unsafe public static void Fill(byte* dest, int value, int size) + { + // Plugged + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(uint* dest, uint value, int size) + { + Fill((byte*)dest, (int)value, size); + } + + unsafe public static void Fill(int* dest, int value, int size) + { + Fill((byte*)dest, value, size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(uint[] dest, uint value) + { + fixed (uint* destPtr = dest) + { + Fill(destPtr, value, dest.Length * 4); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(int[] dest, int value) + { + fixed (int* destPtr = dest) + { + Fill(destPtr, value, dest.Length * 4); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(ushort* dest, ushort value, int size) + { + /* Broadcast 'value' to fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = value * 0x10001; + Fill((byte*)dest, valueFiller, size); + } + + unsafe public static void Fill(short* dest, short value, int size) + { + /* Broadcast 'value' to fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = (ushort)value * 0x10001; + Fill((byte*)dest, valueFiller, size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(ushort[] dest, ushort value) + { + fixed (ushort* destPtr = dest) + { + Fill(destPtr, value, dest.Length * 2); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(short[] dest, short value) + { + fixed (short* destPtr = dest) + { + Fill(destPtr, value, dest.Length * 2); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(byte* dest, byte value, int size) + { + /* Broadcast 'value' fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = value * 0x1010101; + Fill(dest, valueFiller, size); + } + + unsafe public static void Fill(sbyte* dest, sbyte value, int size) + { + /* Broadcast 'value' fill all the integer register (0x42 --> 0x42424242) */ + int valueFiller = (byte)value * 0x1010101; + Fill((byte*)dest, valueFiller, size); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(byte[] dest, byte value) + { + fixed (byte* destPtr = dest) + { + Fill(destPtr, value, dest.Length); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + unsafe public static void Fill(sbyte[] dest, sbyte value) + { + fixed (sbyte* destPtr = dest) + { + Fill(destPtr, value, dest.Length); + } + } + } +} diff --git a/source/Cosmos.HAL/Drivers/Video/VBEDriver.cs b/source/Cosmos.HAL/Drivers/Video/VBEDriver.cs index 9dadebe3e..cc0a53df7 100644 --- a/source/Cosmos.HAL/Drivers/Video/VBEDriver.cs +++ b/source/Cosmos.HAL/Drivers/Video/VBEDriver.cs @@ -22,8 +22,8 @@ namespace Cosmos.HAL.Drivers VBEDisplayBankMode, VBEDisplayVirtualWidth, VBEDisplayVirtualHeight, - VBEDisPlayXOffset, - VBEDislyYOffset + VBEDisplayXOffset, + VBEDisplayYOffset }; [Flags] diff --git a/source/Cosmos.sln b/source/Cosmos.sln index fc6a046cc..1758e679b 100644 --- a/source/Cosmos.sln +++ b/source/Cosmos.sln @@ -295,6 +295,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GraphicTest", "..\Tests\Gra EndProject Project("{471EC4BB-E47E-4229-A789-D1F5F83B52D4}") = "GraphicTestBoot", "..\Tests\GraphicTest\GraphicTestBoot.Cosmos", "{9246BA1F-FBDB-4B09-806A-7968BF4D3EB9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cosmos Graphic Subsytem", "Cosmos Graphic Subsytem\Cosmos Graphic Subsytem.csproj", "{49F2C01D-D2C5-4564-810B-1AE92236C5C1}" +EndProject +Project("{471EC4BB-E47E-4229-A789-D1F5F83B52D4}") = "Cosmos Graphic SubsytemBoot", "Cosmos Graphic Subsytem\Cosmos Graphic SubsytemBoot.Cosmos", "{1BC71853-22F3-415D-A068-8E1FA8E8F05B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cosmos Graphic Subsystem", "Cosmos Graphic Subsystem", "{7634AC43-FE21-487F-B16A-25DE5B33E22E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -1367,6 +1373,30 @@ Global {9246BA1F-FBDB-4B09-806A-7968BF4D3EB9}.Release|x64.Build.0 = Debug|x86 {9246BA1F-FBDB-4B09-806A-7968BF4D3EB9}.Release|x86.ActiveCfg = Debug|x86 {9246BA1F-FBDB-4B09-806A-7968BF4D3EB9}.Release|x86.Build.0 = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Debug|Any CPU.ActiveCfg = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Debug|Any CPU.Build.0 = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Debug|x64.ActiveCfg = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Debug|x64.Build.0 = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Debug|x86.ActiveCfg = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Debug|x86.Build.0 = Debug|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Release|Any CPU.ActiveCfg = Release|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Release|Any CPU.Build.0 = Release|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Release|x64.ActiveCfg = Release|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Release|x64.Build.0 = Release|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Release|x86.ActiveCfg = Release|x86 + {49F2C01D-D2C5-4564-810B-1AE92236C5C1}.Release|x86.Build.0 = Release|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Debug|Any CPU.ActiveCfg = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Debug|Any CPU.Build.0 = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Debug|x64.ActiveCfg = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Debug|x64.Build.0 = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Debug|x86.ActiveCfg = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Debug|x86.Build.0 = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Release|Any CPU.ActiveCfg = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Release|Any CPU.Build.0 = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Release|x64.ActiveCfg = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Release|x64.Build.0 = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Release|x86.ActiveCfg = Debug|x86 + {1BC71853-22F3-415D-A068-8E1FA8E8F05B}.Release|x86.Build.0 = Debug|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1483,5 +1513,8 @@ Global {156DAD1F-186F-4CFE-B769-573F44AB8439} = {2BE77488-5549-4957-8B23-A24828029093} {FB23BD72-AEC3-485E-B86C-8E7DB0B3BB9B} = {F104F6BC-EF8E-4408-A786-D570D7565231} {9246BA1F-FBDB-4B09-806A-7968BF4D3EB9} = {F104F6BC-EF8E-4408-A786-D570D7565231} + {49F2C01D-D2C5-4564-810B-1AE92236C5C1} = {7634AC43-FE21-487F-B16A-25DE5B33E22E} + {1BC71853-22F3-415D-A068-8E1FA8E8F05B} = {7634AC43-FE21-487F-B16A-25DE5B33E22E} + {7634AC43-FE21-487F-B16A-25DE5B33E22E} = {1698DD83-72A3-44CD-B088-4320A4014A95} EndGlobalSection EndGlobal diff --git a/source/XSharp.Compiler/XS.SSE.cs b/source/XSharp.Compiler/XS.SSE.cs index 933cedc13..1a06bbd5f 100644 --- a/source/XSharp.Compiler/XS.SSE.cs +++ b/source/XSharp.Compiler/XS.SSE.cs @@ -96,6 +96,26 @@ namespace XSharp.Compiler DoDestinationSource(destination, sourceLabel, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); } + public static void MoveUPS(Register32 destination, RegisterXMM source, bool destinationIsIndirect = false, int? destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + DoDestinationSource(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + } + +#if false + public static void MoveUPS(Register32 destination, RegisterXMM source, bool destinationIsIndirect = false, Register32 destinationDisplacement = null, bool sourceIsIndirect = false, int? sourceDisplacement = null) + { + //DoDestinationSource(destination, source, destinationIsIndirect, destinationDisplacement, sourceIsIndirect, sourceDisplacement); + new MoveUPS() + { + DestinationReg = destination, + DestinationIsIndirect = destinationIsIndirect, + DestinationDisplacement = (int)destinationDisplacement, + SourceDisplacement = sourceDisplacement, + SourceReg = source + }; + } +#endif + public static void ConvertSS2SD(RegisterXMM destination, Register32 source, bool sourceIsIndirect = false) { new ConvertSS2SD() @@ -150,6 +170,16 @@ namespace XSharp.Compiler DestinationIsIndirect = isIndirect }; } + + public static void Shufps(RegisterXMM destination, RegisterXMM source, int bitmask) + { + new Shufps() + { + DestinationReg = destination, + SourceReg = source, + pseudoOpcode = (byte)bitmask + }; + } } } }