diff --git a/Build/Tools/NAsm/LICENSE b/Build/Tools/NAsm/LICENSE index f6ff4f01bb..f9917f00af 100644 --- a/Build/Tools/NAsm/LICENSE +++ b/Build/Tools/NAsm/LICENSE @@ -1,7 +1,7 @@ NASM is now licensed under the 2-clause BSD license, also known as the simplified BSD license. - Copyright 1996-2009 the NASM Authors - All rights reserved. + Copyright 1996-2010 the NASM Authors - All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following diff --git a/Build/Tools/NAsm/nasm.exe b/Build/Tools/NAsm/nasm.exe index 61c6be3bc8..d6d39f5216 100644 Binary files a/Build/Tools/NAsm/nasm.exe and b/Build/Tools/NAsm/nasm.exe differ diff --git a/Build/Tools/NAsm/ndisasm.exe b/Build/Tools/NAsm/ndisasm.exe index 8d2ef13f15..6907fe4fd8 100644 Binary files a/Build/Tools/NAsm/ndisasm.exe and b/Build/Tools/NAsm/ndisasm.exe differ diff --git a/Build/Tools/NAsm/version.txt b/Build/Tools/NAsm/version.txt index 3d46de4723..615f3761df 100644 --- a/Build/Tools/NAsm/version.txt +++ b/Build/Tools/NAsm/version.txt @@ -1,3 +1,3 @@ -0.98.38 +2.12.01 before updating, test.. \ No newline at end of file diff --git a/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj b/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj index 369995d3bb..f1896104be 100644 --- a/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj +++ b/Tests/Cosmos.TestRunner.Core/Cosmos.TestRunner.Core.csproj @@ -149,6 +149,10 @@ {C801F19C-A9D3-42D5-9A57-9FFDF9B4D05E} Cosmos.IL2CPU.Plugs + + {239E33A7-F0C3-4801-85CA-4D8F89A31DC0} + Cosmos.IL2CPU + {7C64B97F-516D-4A6D-B9E1-3FE48F561409} Cosmos.System.Plugs diff --git a/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs b/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs index 2ffb49367d..b83e2c141f 100644 --- a/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs +++ b/Tests/Cosmos.TestRunner.Core/Engine.Helpers.cs @@ -9,6 +9,7 @@ using Cosmos.Build.MSBuild; using Cosmos.Core.Plugs; using Cosmos.Debug.Kernel.Plugs; +using Cosmos.IL2CPU; using Cosmos.System.Plugs.System; using IL2CPU; using Microsoft.Win32; @@ -64,7 +65,7 @@ private void RunIL2CPU(string kernelFileName, string outputFile) throw new Exception("Cannot run multiple kernels with in-process compilation!"); } // ensure we're using the referenced (= solution) version - Assembler.Assembler.ReadDebugStubFromDisk = false; + CosmosAssembler.ReadDebugStubFromDisk = false; var xResult = Program.Run(xArguments, OutputHandler.LogMessage, OutputHandler.LogError); if (xResult != 0) { diff --git a/Users/Matthijs/DebugCompiler/MyEngine.cs b/Users/Matthijs/DebugCompiler/MyEngine.cs index 5b5d16d9b9..04cf4c83d2 100644 --- a/Users/Matthijs/DebugCompiler/MyEngine.cs +++ b/Users/Matthijs/DebugCompiler/MyEngine.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using Cosmos.Build.Common; using Cosmos.TestRunner.Core; using NUnit.Framework; @@ -11,19 +12,22 @@ public class RunKernels [Test] public void Test([ValueSource(typeof(MySource), nameof(MySource.ProvideData))] Type kernelToRun) { + Environment.CurrentDirectory = Path.GetDirectoryName(typeof(RunKernels).Assembly.Location); + var xEngine = new Engine(); // Sets the time before an error is registered. For example if set to 60 then if a kernel runs for more than 60 seconds then // that kernel will be marked as a failiure and terminated - xEngine.AllowedSecondsInKernel = 1800; + xEngine.AllowedSecondsInKernel = 30; // If you want to test only specific platforms, add them to the list, like next line. By default, all platforms are run. xEngine.RunTargets.Add(RunTargetEnum.Bochs); // If you're working on the compiler (or other lower parts), you can choose to run the compiler in process // one thing to keep in mind though, is that this only works with 1 kernel at a time! - xEngine.RunIL2CPUInProcess = false; + xEngine.RunIL2CPUInProcess = true; xEngine.TraceAssembliesLevel = TraceAssemblies.User; - xEngine.EnableStackCorruptionChecks = true; + + xEngine.EnableStackCorruptionChecks = false; xEngine.StackCorruptionChecksLevel = StackCorruptionDetectionLevel.AllInstructions; // Select kernels to be tested by adding them to the engine diff --git a/source/Cosmos.Assembler/Assembler.cs b/source/Cosmos.Assembler/Assembler.cs index 34ff30a119..3b313f24bd 100644 --- a/source/Cosmos.Assembler/Assembler.cs +++ b/source/Cosmos.Assembler/Assembler.cs @@ -11,18 +11,23 @@ using System.Runtime.InteropServices; using System.Xml; using Cosmos.Assembler.x86; -using Cosmos.Debug.DebugStub; namespace Cosmos.Assembler { public class Assembler { - public Assembler(int aComPort) { + public Assembler() { mCurrentInstance = this; - mComPort = aComPort; + mInstances.Push(this); } + public Assembler(bool addWhitespaceWhileFlushing): this() + { + mAddWhitespaceWhileFlushing = addWhitespaceWhileFlushing; + } + + private static readonly Stack mInstances = new Stack(); + public bool EmitAsmLabels { get; set; } - //TODO: COM Port info - should be in assembler? Assembler should not know about comports... - protected int mComPort = 0; + protected UInt16 mGdCode; protected UInt16 mGdData; @@ -33,67 +38,6 @@ public Assembler(int aComPort) { // as it will also cause problems when we thread the compiler private static Assembler mCurrentInstance; - private static string GetValidGroupName(string aGroup) { - return aGroup.Replace('-', '_').Replace('.', '_'); - } - public const string EntryPointName = "__ENGINE_ENTRYPOINT__"; - - protected byte[] GdtDescriptor(UInt32 aBase, UInt32 aSize, bool aCode) { - // Limit is a confusing word. Is it the max physical address or size? - // In fact it is the size, and 286 docs actually refer to it as size - // rather than limit. - // It is also size - 1, else there would be no way to specify - // all of RAM, and a limit of 0 is invalid. - - var xResult = new byte[8]; - - // Check the limit to make sure that it can be encoded - if ((aSize > 65536) && (aSize & 0x0FFF) != 0x0FFF) { - // If larger than 16 bit, must be an even page (4kb) size - throw new Exception("Invalid size in GDT descriptor."); - } - // Flags nibble - // 7: Granularity - // 0 = bytes - // 1 = 4kb pages - // 6: 1 = 32 bit mode - // 5: 0 - Reserved - // 4: 0 - Reserved - xResult[6] = 0x40; - if (aSize > 65536) { - // Set page sizing instead of byte sizing - aSize = aSize >> 12; - xResult[6] = (byte)(xResult[6] | 0x80); - } - - xResult[0] = (byte)(aSize & 0xFF); - xResult[1] = (byte)((aSize >> 8) & 0xFF); - xResult[6] = (byte)(xResult[6] | ((aSize >> 16) & 0x0F)); - - xResult[2] = (byte)(aBase & 0xFF); - xResult[3] = (byte)((aBase >> 8) & 0xFF); - xResult[4] = (byte)((aBase >> 16) & 0xFF); - xResult[7] = (byte)((aBase >> 24) & 0xFF); - - xResult[5] = (byte)( - // Bit 7: Present, must be 1 - 0x80 | - // Bit 6-5: Privilege, 0=kernel, 3=user - 0x00 | - // Reserved, must be 1 - 0x10 | - // Bit 3: 1=Code, 0=Data - (aCode ? 0x08 : 0x00) | - // Bit 2: Direction/Conforming - 0x00 | - // Bit 1: R/W Data (1=Writeable, 0=Read only) Code (1=Readable, 0=Not readable) - 0x02 | - // Bit 0: Accessed - Set to 0. Updated by CPU later. - 0x00 - ); - - return xResult; - } protected string mCurrentIlLabel; public string CurrentIlLabel { @@ -176,7 +120,7 @@ public void Add(params Instruction[] aReaders) { // Allows to emit footers to the code and datamember sections protected virtual void OnBeforeFlush() { - DataMembers.AddRange(new DataMember[] { new DataMember("_end_data", new byte[0]) }); + } private uint mDataMemberCounter = 0; @@ -215,17 +159,13 @@ public virtual void FlushBinary(Stream aOutput, ulong aBaseAddress) { public virtual void FlushText(TextWriter aOutput) { BeforeFlush(); - - aOutput.WriteLine("%ifndef ELF_COMPILATION"); - aOutput.WriteLine("use32"); - aOutput.WriteLine("org 0x1000000"); - aOutput.WriteLine("[map all main.map]"); - aOutput.WriteLine("%endif"); - + BeforeFlushText(aOutput); // Write out data declarations aOutput.WriteLine(); foreach (DataMember xMember in mDataMembers) { - aOutput.Write("\t"); + if (mAddWhitespaceWhileFlushing) { + aOutput.Write("\t"); + } if (xMember.IsComment) { aOutput.Write(xMember.Name); } else { @@ -238,11 +178,16 @@ public virtual void FlushText(TextWriter aOutput) { // Write out code for (int i = 0; i < mInstructions.Count; i++) { var xOp = mInstructions[i]; - string prefix = "\t\t\t"; + string prefix = null; + if (mAddWhitespaceWhileFlushing) { + prefix = "\t\t\t"; + } if (xOp is Label) { var xLabel = (Label)xOp; aOutput.WriteLine(); - prefix = "\t\t"; + if (mAddWhitespaceWhileFlushing) { + prefix = "\t\t"; + } aOutput.Write(prefix); xLabel.WriteText(this, aOutput); aOutput.WriteLine(); @@ -252,401 +197,37 @@ public virtual void FlushText(TextWriter aOutput) { aOutput.WriteLine(); } } - aOutput.WriteLine("SystemExceptionOccurred:"); - aOutput.WriteLine("\tret"); - aOutput.WriteLine("global Kernel_Start"); - aOutput.WriteLine("_end_code:"); - + OnFlushTextAfterEmitEverything(aOutput); aOutput.Flush(); } - public virtual void WriteDebugVideo(string aText) { - // This method emits a lot of ASM, but thats what we want becuase - // at this point we need ASM as simple as possible and completely transparent. - // No stack changes, no register mods, etc. + private bool mAddWhitespaceWhileFlushing = true; - // TODO: Add an option on the debug project properties to turn this off. - // Also see TokenPatterns.cs Checkpoint in X# - var xPreBootLogging = true; - if (xPreBootLogging) { - UInt32 xVideo = 0xB8000; - for (UInt32 i = xVideo; i < xVideo + 80 * 2; i = i + 2) { - new LiteralAssemblerCode("mov byte [0x" + i.ToString("X") + "], 0"); - new LiteralAssemblerCode("mov byte [0x" + (i + 1).ToString("X") + "], 0x02"); - } - - foreach (var xChar in aText) { - new LiteralAssemblerCode("mov byte [0x" + xVideo.ToString("X") + "], " + (byte)xChar); - xVideo = xVideo + 2; - } - } - } - - public void CreateGDT() { - new Comment(this, "BEGIN - Create GDT"); - var xGDT = new List(); - // Null Segment - Selector 0x00 - // Not used, but required by many emulators. - xGDT.AddRange(new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }); - // Code Segment - mGdCode = (byte)xGDT.Count; - xGDT.AddRange(GdtDescriptor(0x00000000, 0xFFFFFFFF, true)); - // Data Segment - Selector - mGdData = (byte)xGDT.Count; - xGDT.AddRange(GdtDescriptor(0x00000000, 0xFFFFFFFF, false)); - DataMembers.Add(new DataMember("_NATIVE_GDT_Contents", xGDT.ToArray())); - - new Comment("Tell CPU about GDT"); - var xGdtPtr = new UInt16[3]; - // Size of GDT Table - 1 - xGdtPtr[0] = (UInt16)(xGDT.Count - 1); - DataMembers.Add(new DataMember("_NATIVE_GDT_Pointer", xGdtPtr)); - new Mov { - DestinationRef = Cosmos.Assembler.ElementReference.New("_NATIVE_GDT_Pointer"), - DestinationIsIndirect = true, - DestinationDisplacement = 2, - SourceRef = Cosmos.Assembler.ElementReference.New("_NATIVE_GDT_Contents") - }; - new Mov { DestinationReg = Registers.EAX, SourceRef = Cosmos.Assembler.ElementReference.New("_NATIVE_GDT_Pointer") }; - new Lgdt { DestinationReg = Registers.EAX, DestinationIsIndirect = true }; - - new Comment("Set data segments"); - new Mov { DestinationReg = Registers.EAX, SourceValue = mGdData }; - new Mov { DestinationReg = Registers.DS, SourceReg = Registers.EAX }; - new Mov { DestinationReg = Registers.ES, SourceReg = Registers.EAX }; - new Mov { DestinationReg = Registers.FS, SourceReg = Registers.EAX }; - new Mov { DestinationReg = Registers.GS, SourceReg = Registers.EAX }; - new Mov { DestinationReg = Registers.SS, SourceReg = Registers.EAX }; + protected virtual void BeforeFlushText(TextWriter aOutput) + { - new Comment("Force reload of code segment"); - new JumpToSegment { Segment = mGdCode, DestinationLabel = "Boot_FlushCsGDT" }; - new Label("Boot_FlushCsGDT"); - new Cosmos.Assembler.Comment(this, "END - Create GDT"); } - protected void SetIdtDescriptor(int aNo, string aLabel, bool aDisableInts) { - int xOffset = aNo * 8; - new Mov { DestinationReg = Registers.EAX, SourceRef = Cosmos.Assembler.ElementReference.New(aLabel) }; - var xIDT = Cosmos.Assembler.ElementReference.New("_NATIVE_IDT_Contents"); - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset, SourceReg = Registers.AL }; - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset + 1, SourceReg = Registers.AH }; - new ShiftRight { DestinationReg = Registers.EAX, SourceValue = 16 }; - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset + 6, SourceReg = Registers.AL }; - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset + 7, SourceReg = Registers.AH }; - - // Code Segment - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset + 2, SourceValue = mGdCode, Size = 16 }; - - // Reserved - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset + 4, SourceValue = 0x00, Size = 8 }; + protected virtual void OnFlushTextAfterEmitEverything(TextWriter aOutput) + { - // Type - new Mov { DestinationRef = xIDT, DestinationIsIndirect = true, DestinationDisplacement = xOffset + 5, SourceValue = (byte)(aDisableInts ? 0x8E : 0x8F), Size = 8 }; } - public void CreateIDT() { - new Comment(this, "BEGIN - Create IDT"); - - // Create IDT - UInt16 xIdtSize = 8 * 256; - DataMembers.Add(new DataMember("_NATIVE_IDT_Contents", new byte[xIdtSize])); - // - if (mComPort > 0) { - SetIdtDescriptor(1, "DebugStub_TracerEntry", false); - SetIdtDescriptor(3, "DebugStub_TracerEntry", false); - - //for (int i = 0; i < 256; i++) - //{ - // if (i == 1 || i == 3) - // { - // continue; - // } - - // SetIdtDescriptor(i, "DebugStub_Interrupt_" + i.ToString(), true); - //} - } - //SetIdtDescriptor(1, "DebugStub_INT0"); - Change to GPF - - // Set IDT - DataMembers.Add(new DataMember("_NATIVE_IDT_Pointer", new UInt16[] { xIdtSize, 0, 0 })); - new Mov { - DestinationRef = Cosmos.Assembler.ElementReference.New("_NATIVE_IDT_Pointer"), - DestinationIsIndirect = true, - DestinationDisplacement = 2, - SourceRef = Cosmos.Assembler.ElementReference.New("_NATIVE_IDT_Contents") - }; - - new Mov { DestinationReg = Registers.EAX, SourceRef = Cosmos.Assembler.ElementReference.New("_NATIVE_IDT_Pointer") }; - - if (mComPort > 0) + public static void ClearCurrentInstance() + { + var xPopped = mInstances.Pop(); + if (xPopped != mCurrentInstance) { - new Mov {DestinationRef = ElementReference.New("static_field__Cosmos_Core_CPU_mInterruptsEnabled"), DestinationIsIndirect = true, SourceValue = 1}; - new Lidt {DestinationReg = Registers.EAX, DestinationIsIndirect = true}; - } - new Label("AfterCreateIDT"); - new Comment(this, "END - Create IDT"); - } - - public void Initialize() { - uint xSig = 0x1BADB002; - - DataMembers.Add(new DataIfNotDefined("ELF_COMPILATION")); - DataMembers.Add(new DataMember("MultibootSignature", new uint[] { xSig })); - uint xFlags = 0x10003; - DataMembers.Add(new DataMember("MultibootFlags", xFlags)); - DataMembers.Add(new DataMember("MultibootChecksum", (int)(0 - (xFlags + xSig)))); - DataMembers.Add(new DataMember("MultibootHeaderAddr", Cosmos.Assembler.ElementReference.New("MultibootSignature"))); - DataMembers.Add(new DataMember("MultibootLoadAddr", Cosmos.Assembler.ElementReference.New("MultibootSignature"))); - DataMembers.Add(new DataMember("MultibootLoadEndAddr", Cosmos.Assembler.ElementReference.New("_end_code"))); - DataMembers.Add(new DataMember("MultibootBSSEndAddr", Cosmos.Assembler.ElementReference.New("_end_code"))); - DataMembers.Add(new DataMember("MultibootEntryAddr", Cosmos.Assembler.ElementReference.New("Kernel_Start"))); - DataMembers.Add(new DataEndIfDefined()); - - DataMembers.Add(new DataIfDefined("ELF_COMPILATION")); - xFlags = 0x00003; - DataMembers.Add(new DataMember("MultibootSignature", new uint[] { xSig })); - DataMembers.Add(new DataMember("MultibootFlags", xFlags)); - DataMembers.Add(new DataMember("MultibootChecksum", (int)(0 - (xFlags + xSig)))); - DataMembers.Add(new DataEndIfDefined()); - - // graphics info fields - DataMembers.Add(new DataMember("MultibootGraphicsRuntime_VbeModeInfoAddr", Int32.MaxValue)); - DataMembers.Add(new DataMember("MultibootGraphicsRuntime_VbeControlInfoAddr", Int32.MaxValue)); - DataMembers.Add(new DataMember("MultibootGraphicsRuntime_VbeMode", Int32.MaxValue)); - // memory - DataMembers.Add(new DataMember("MultiBootInfo_Memory_High", 0)); - DataMembers.Add(new DataMember("MultiBootInfo_Memory_Low", 0)); - DataMembers.Add(new DataMember("Before_Kernel_Stack", new byte[0x50000])); - DataMembers.Add(new DataMember("Kernel_Stack", new byte[0])); - DataMembers.Add(new DataMember("MultiBootInfo_Structure", new uint[1])); - - if (mComPort > 0) { - new Define("DEBUGSTUB"); + throw new InvalidOperationException("Popped assembler isn't the correct one!"); } - - // This is our first entry point. Multiboot uses this as Cosmos entry point. - new Label("Kernel_Start", isGlobal: true); - new Mov + if (mInstances.Count == 0) { - DestinationReg = Registers.ESP, - SourceRef = Cosmos.Assembler.ElementReference.New("Kernel_Stack") - }; - - // Displays "Cosmos" in top left. Used to make sure Cosmos is booted in case of hang. - // ie bootloader debugging. This must be the FIRST code, even before setup so we know - // we are being called properly by the bootloader and that if there are problems its - // somwhere in our code, not the bootloader. - WriteDebugVideo("Cosmos pre boot"); - - // For when using Bochs, causes a break ASAP on entry after initial Cosmos display. - new LiteralAssemblerCode("xchg bx, bx"); - - // CLI ASAP - WriteDebugVideo("Clearing interrupts."); - new ClearInterruptFlag(); - - - WriteDebugVideo("Begin multiboot info."); - new LiteralAssemblerCode("%ifndef EXCLUDE_MULTIBOOT_MAGIC"); - new Comment(this, "MultiBoot compliant loader provides info in registers: "); - new Comment(this, "EBX=multiboot_info "); - new Comment(this, "EAX=0x2BADB002 - check if it's really Multiboot-compliant loader "); - new Comment(this, " ;- copy mb info - some stuff for you "); - new Comment(this, "BEGIN - Multiboot Info"); - new Mov { DestinationRef = Cosmos.Assembler.ElementReference.New("MultiBootInfo_Structure"), DestinationIsIndirect = true, SourceReg = Registers.EBX }; - new Add { DestinationReg = Registers.EBX, SourceValue = 4 }; - new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.EBX, SourceIsIndirect = true }; - new Mov { DestinationRef = Cosmos.Assembler.ElementReference.New("MultiBootInfo_Memory_Low"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; - new Add { DestinationReg = Registers.EBX, SourceValue = 4 }; - new Mov { - DestinationReg = Registers.EAX, - SourceReg = Registers.EBX, - SourceIsIndirect = true - }; - new Mov { DestinationRef = Cosmos.Assembler.ElementReference.New("MultiBootInfo_Memory_High"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; - new Comment(this, "END - Multiboot Info"); - new LiteralAssemblerCode("%endif"); - WriteDebugVideo("Creating GDT."); - CreateGDT(); - - WriteDebugVideo("Configuring PIC"); - ConfigurePIC(); - - WriteDebugVideo("Creating IDT."); - CreateIDT(); -#if LFB_1024_8 - new Comment("Set graphics fields"); - new Move { DestinationReg = Registers.EBX, SourceRef = Cosmos.Assembler.ElementReference.New("MultiBootInfo_Structure"), SourceIsIndirect = true }; - new Move { DestinationReg = Registers.EAX, SourceReg = Registers.EBX, SourceIsIndirect = true, SourceDisplacement = 72 }; - new Move { DestinationRef = Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeControlInfoAddr"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; - new Move { DestinationReg = Registers.EAX, SourceReg = Registers.EBX, SourceIsIndirect = true, SourceDisplacement = 76 }; - new Move { DestinationRef = Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeModeInfoAddr"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; - new Move { DestinationReg = Registers.EAX, SourceReg = Registers.EBX, SourceIsIndirect = true, SourceDisplacement = 80 }; - new Move { DestinationRef = Cosmos.Assembler.ElementReference.New("MultibootGraphicsRuntime_VbeMode"), DestinationIsIndirect = true, SourceReg = Registers.EAX }; -#endif - - //WriteDebugVideo("Initializing SSE."); - //new Comment(this, "BEGIN - SSE Init"); - //// CR4[bit 9]=1, CR4[bit 10]=1, CR0[bit 2]=0, CR0[bit 1]=1 - //new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.CR4 }; - //new Or { DestinationReg = Registers.EAX, SourceValue = 0x100 }; - //new Mov { DestinationReg = Registers.CR4, SourceReg = Registers.EAX }; - //new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.CR4 }; - //new Or { DestinationReg = Registers.EAX, SourceValue = 0x200 }; - //new Mov { DestinationReg = Registers.CR4, SourceReg = Registers.EAX }; - //new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.CR0 }; - - //new And { DestinationReg = Registers.EAX, SourceValue = 0xfffffffd }; - //new Mov { DestinationReg = Registers.CR0, SourceReg = Registers.EAX }; - //new Mov { DestinationReg = Registers.EAX, SourceReg = Registers.CR0 }; - - //new And { DestinationReg = Registers.EAX, SourceValue = 1 }; - //new Mov { DestinationReg = Registers.CR0, SourceReg = Registers.EAX }; - //new Comment(this, "END - SSE Init"); - - if (mComPort > 0) { - WriteDebugVideo("Initializing DebugStub."); - new Call { DestinationLabel = "DebugStub_Init" }; + mCurrentInstance = null; } - - // Jump to Kernel entry point - WriteDebugVideo("Jumping to kernel."); - new Call { DestinationLabel = EntryPointName }; - - new Comment(this, "Kernel done - loop till next IRQ"); - new Label(".loop"); - new ClearInterruptFlag(); - new Halt(); - new Jump { DestinationLabel = ".loop" }; - - if (mComPort > 0) { - var xGen = new XSharp.Compiler.AsmGenerator(); - - var xGenerateAssembler = - new Action(i => - { - XSharp.Nasm.Assembler xAsm; - if (i is StreamReader) - { - xAsm = xGen.Generate((StreamReader)i); - } - else if (i is string) - { - xAsm = xGen.Generate((string)i); - } - else - { - throw new Exception("Object type '" + i.ToString() + "' not supported!"); - } - foreach (var xData in xAsm.Data) - { - Cosmos.Assembler.Assembler.CurrentInstance.DataMembers.Add(new DataMember() {RawAsm = xData}); - } - foreach (var xCode in xAsm.Code) - { - new LiteralAssemblerCode(xCode); - } - }); - if (ReadDebugStubFromDisk) - { - foreach (var xFile in Directory.GetFiles(Cosmos.Build.Common.CosmosPaths.DebugStubSrc, "*.xs")) - { - xGenerateAssembler(xFile); - } - } - else - { - foreach (var xManifestName in typeof(ReferenceHelper).Assembly.GetManifestResourceNames()) - { - if (!xManifestName.EndsWith(".xs", StringComparison.OrdinalIgnoreCase)) - { - continue; - } - using (var xStream = typeof(ReferenceHelper).Assembly.GetManifestResourceStream(xManifestName)) - { - using (var xReader = new StreamReader(xStream)) - { - xGenerateAssembler(xReader); - } - } - } - } - OnAfterEmitDebugStub(); - } else { - new Label("DebugStub_Step"); - new Return(); + else + { + mCurrentInstance = mInstances.Peek(); } - // Start emitting assembly labels - Cosmos.Assembler.Assembler.CurrentInstance.EmitAsmLabels = true; - } - - private void ConfigurePIC() - { - // initial configuration of PIC - const byte PIC1 = 0x20; /* IO base address for master PIC */ - const byte PIC2 = 0xA0; /* IO base address for slave PIC */ - const byte PIC1_COMMAND = PIC1; - const byte PIC1_DATA = (PIC1 + 1); - const byte PIC2_COMMAND = PIC2; - const byte PIC2_DATA = (PIC2 + 1); - - const byte ICW1_ICW4 = 0x01;/* ICW4 (not) needed */ - const byte ICW1_SINGLE = 0x02; /* Single (cascade) mode */ - const byte ICW1_INTERVAL4 = 0x04; /* Call address interval 4 (8) */ - const byte ICW1_LEVEL = 0x08; /* Level triggered (edge) mode */ - const byte ICW1_INIT = 0x10; /* Initialization - required! */ - - const byte ICW4_8086 = 0x01; /* 8086/88 (MCS-80/85) mode */ - const byte ICW4_AUTO = 0x02; /* Auto (normal) EOI */ - const byte ICW4_BUF_SLAVE = 0x08; /* Buffered mode/slave */ - const byte ICW4_BUF_MASTER = 0x0C; /* Buffered mode/master */ - const byte ICW4_SFNM = 0x10; /* Special fully nested (not) */ - - // emit helper functions: - Action xOutBytes = (port, value) => - { - new Mov {DestinationReg = RegistersEnum.DX, SourceValue = port}; - new Mov {DestinationReg = RegistersEnum.EAX, SourceValue = value}; - new Out {DestinationReg = RegistersEnum.AL}; - }; - - Action xIOWait = () => - { - xOutBytes(0x80, 0x22); - }; - - xOutBytes(PIC1_COMMAND, ICW1_INIT + ICW1_ICW4); // starts the initialization sequence (in cascade mode) - xIOWait(); - xOutBytes(PIC2_COMMAND, ICW1_INIT + ICW1_ICW4); - xIOWait(); - xOutBytes(PIC1_DATA, 0x20); // ICW2: Master PIC vector offset - xIOWait(); - xOutBytes(PIC2_DATA, 0x29); // ICW2: Slave PIC vector offset - xIOWait(); - xOutBytes(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) - xIOWait(); - xOutBytes(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) - xIOWait(); - - xOutBytes(PIC1_DATA, ICW4_8086); - xIOWait(); - xOutBytes(PIC2_DATA, ICW4_8086); - xIOWait(); - - // for now, we don't want any irq's enabled: - xOutBytes(PIC1_DATA, 0xFF); // restore saved masks. - xOutBytes(PIC2_DATA, 0xFF); - } - - /// - /// Setting this field to false means the .xs files for the debug stub are read from the DebugStub assembly. - /// This allows the automated kernel tester to use the live ones, instead of the installed ones. - /// - public static bool ReadDebugStubFromDisk = true; - - protected virtual void OnAfterEmitDebugStub() - { - // } } } diff --git a/source/Cosmos.Assembler/Cosmos.Assembler.csproj b/source/Cosmos.Assembler/Cosmos.Assembler.csproj index 6ee3a06019..b5a2800f4f 100644 --- a/source/Cosmos.Assembler/Cosmos.Assembler.csproj +++ b/source/Cosmos.Assembler/Cosmos.Assembler.csproj @@ -294,22 +294,10 @@ - - {841A734E-9606-4AAB-9C4A-74E7E303FF5D} - XSharp.Nasm - {0462E82B-8C29-41A9-8265-9C89038ADB29} Cosmos.Build.Common - - {A281A1B1-C718-4BCB-A7BE-ED840A70449A} - XSharp.Compiler - - - {A7F3F078-CF99-4018-9A35-2D6DC9517ADB} - Cosmos.Debug.DebugStub -