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;
}
}
}
}