using System; using sysIO = System.IO; using Cosmos.Debug.Kernel; using Cosmos.HAL; using Cosmos.System.ScanMaps; namespace Cosmos.System { // MtW: if the fullname (namespace + name) of this class changes, please also change IL2CPU msbuild task /// /// Provides a base kernel class for a Cosmos-based system /// public abstract class Kernel { /// /// User ring debugger instance, with the tag "Kernel". /// public readonly Debugger mDebugger = new Debugger("User", "Kernel"); /// /// Clear screen. /// public bool ClearScreen = true; // Set after initial start. Can be started and stopped at same time /// /// Kernel started. /// protected bool mStarted = false; // Set to signal stopped /// /// Kernel stopped. /// protected bool mStopped = false; /// /// Get text screen device. /// /// null protected virtual TextScreenBase GetTextScreen() { // null means use default return null; } /// /// Get keyboard key layout. /// /// Keyboard key layout. protected ScanMapBase GetKeyboardScanMap() { return KeyboardManager.GetKeyLayout(); } /// /// Set keyboard key layout. /// /// Keyboard key layout. protected void SetKeyboardScanMap(ScanMapBase ScanMap) { KeyboardManager.SetKeyLayout(ScanMap); } /// /// Start the system up using the properties for configuration. /// /// Thrown on IO error. public virtual void Start() { try { Global.mDebugger.Send("Starting kernel"); if (mStarted) { Global.mDebugger.Send("ERROR: Kernel Already Started"); throw new Exception("Kernel has already been started. A kernel cannot be started twice."); } mStarted = true; if (string.Empty == null) { throw new Exception("Compiler didn't initialize System.String.Empty!"); } Global.mDebugger.Send("HW Bootstrap Init"); HAL.Bootstrap.Init(); Global.mDebugger.Send("Global Init"); Global.Init(GetTextScreen()); // Provide the user with a clear screen if they requested it if (ClearScreen) { Global.mDebugger.Send("Cls"); //Global.Console.Clear(); } Global.mDebugger.Send("Before Run"); BeforeRun(); // now enable interrupts: HAL.Global.EnableInterrupts(); Global.mDebugger.Send("Run"); if (mStopped) { Global.mDebugger.Send("Already stopped"); } else { Global.mDebugger.Send("Not yet stopped"); } while (!mStopped) { //Network.NetworkStack.Update(); Global.mDebugger.Send("Really before Run"); Run(); Global.mDebugger.Send("Really after Run"); } Global.mDebugger.Send("AfterRun"); AfterRun(); //bool xTest = 1 != 3; //while (xTest) { //} } catch (Exception E) { // todo: better ways to handle? global::System.Console.WriteLine("Exception occurred while running kernel:"); global::System.Console.WriteLine(E.ToString()); } } /// /// Pre-run events /// protected virtual void BeforeRun() { } /// /// Main kernel loop /// protected abstract void Run(); /// /// After the Run() method is exited (?) /// protected virtual void AfterRun() { } /// /// Shut down the system and power off /// public void Stop() { mStopped = true; } /// /// Kernal object constructor. /// public Kernel() { Global.mDebugger.Send("In Cosmos.System.Kernel..ctor"); } // Shutdown and restart /// /// Shutdown and restart. /// Not implemented. /// public void Restart() { } /// /// Print message to the debbuger at system ring with "Global"-tag. /// /// A message to print. public static void PrintDebug(string message) { Global.mDebugger.Send(message); } /// /// Get interrupts status. /// public static bool InterruptsEnabled { get { return HAL.Global.InterruptsEnabled; } } } }