Initial keyboard work. Does not work due to bug in the compiler. (Ldelem_ref)

This commit is contained in:
Matthijs ter Woord 2015-05-24 16:33:21 +02:00
parent 8a6872c600
commit dd93b7d2b9
12 changed files with 628 additions and 490 deletions

View file

@ -0,0 +1,2 @@
[*.cs]
indent_size=4

View file

@ -80,6 +80,7 @@
<Compile Include="BlockDevice\Partition.cs" />
<Compile Include="Bootstrap.cs" />
<Compile Include="DebugTextScreen.cs" />
<Compile Include="DefaultKeyboard.cs" />
<Compile Include="Device.cs" />
<Compile Include="Drivers\PCI\Audio\ES1370\Components\DACak4531.cs" />
<Compile Include="Drivers\PCI\Audio\ES1370\ES1370.cs" />
@ -145,6 +146,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
<None Include="Cosmos.snk" />
</ItemGroup>
<ItemGroup>

View file

@ -0,0 +1,480 @@
using System;
using System.Collections.Generic;
namespace Cosmos.HAL
{
//public delegate void HandleKeyboardDelegate(byte aScanCode, bool aReleased);
public class DefaultKeyboard: Keyboard
{
protected override void Initialize()
{
if (mKeys == null)
{
CreateDefaultKeymap();
}
}
private bool mEscaped;
private List<KeyMapping> mKeys;
private bool mShiftState;
private bool mCtrlState;
private bool mAltState;
public bool ShiftPressed
{
get
{
return mShiftState;
}
}
public bool CtrlPressed
{
get
{
return mCtrlState;
}
}
public bool AltPressed
{
get
{
return mAltState;
}
}
protected override void HandleScancode(byte aScancode, bool aReleased)
{
uint xTheScancode = aScancode;
if (mEscaped)
{
xTheScancode = (ushort)(xTheScancode << 8);
mEscaped = false;
}
switch (xTheScancode)
{
case 0x36:
case 0x2A:
{
mShiftState = !aReleased;
break;
}
case 0x1D:
{
mCtrlState = !aReleased;
break;
}
case 0x38:
{
mAltState = !aReleased;
break;
}
default:
{
if ((mCtrlState) && (mAltState) && (xTheScancode == 0x53))
{
Console.WriteLine("Detected Ctrl-Alt-Delete! Rebooting System...");
Core.Global.CPU.Reboot();
}
if (mShiftState)
{
xTheScancode = xTheScancode << 16;
}
if (!aReleased)
{
ConsoleKeyInfo xKeyInfo;
if (!GetKey(xTheScancode, out xKeyInfo))
{
//DebugUtil.SendError("Keyboard", "error while getting scancode character!");
}
else
{
//DebugUtil.SendDoubleNumber("Keyboard", "Scancode and Char", xTheScancode, 32, xTheChar, 16);
Enqueue(xKeyInfo);
}
}
break;
}
}
}
private void CreateDefaultKeymap()
{
mKeys = new List<KeyMapping>(164);
//TODO: fn (for laptops)
#region Letters
AddKey(0x10, 'q', ConsoleKey.Q);
AddKey(0x100000, 'Q', ConsoleKey.Q);
AddKey(0x11, 'w', ConsoleKey.W);
AddKey(0x110000, 'W', ConsoleKey.W);
AddKey(0x12, 'e', ConsoleKey.E);
AddKey(0x120000, 'E', ConsoleKey.E);
AddKey(0x13, 'r', ConsoleKey.R);
AddKey(0x130000, 'R', ConsoleKey.R);
AddKey(0x14, 't', ConsoleKey.T);
AddKey(0x140000, 'T', ConsoleKey.T);
AddKey(0x15, 'y', ConsoleKey.Y);
AddKey(0x150000, 'Y', ConsoleKey.Y);
AddKey(0x16, 'u', ConsoleKey.U);
AddKey(0x160000, 'U', ConsoleKey.U);
AddKey(0x17, 'i', ConsoleKey.I);
AddKey(0x170000, 'I', ConsoleKey.I);
AddKey(0x18, 'o', ConsoleKey.O);
AddKey(0x180000, 'O', ConsoleKey.O);
AddKey(0x19, 'p', ConsoleKey.P);
AddKey(0x190000, 'P', ConsoleKey.P);
AddKey(0x1E, 'a', ConsoleKey.A);
AddKey(0x1E0000, 'A', ConsoleKey.A);
AddKey(0x1F, 's', ConsoleKey.S);
AddKey(0x1F0000, 'S', ConsoleKey.S);
AddKey(0x20, 'd', ConsoleKey.D);
AddKey(0x200000, 'D', ConsoleKey.D);
AddKey(0x21, 'f', ConsoleKey.F);
AddKey(0x210000, 'F', ConsoleKey.F);
AddKey(0x22, 'g', ConsoleKey.G);
AddKey(0x220000, 'G', ConsoleKey.G);
AddKey(0x23, 'h', ConsoleKey.H);
AddKey(0x230000, 'H', ConsoleKey.H);
AddKey(0x24, 'j', ConsoleKey.J);
AddKey(0x240000, 'J', ConsoleKey.J);
AddKey(0x25, 'k', ConsoleKey.K);
AddKey(0x250000, 'K', ConsoleKey.K);
AddKey(0x26, 'l', ConsoleKey.L);
AddKey(0x260000, 'L', ConsoleKey.L);
AddKey(0x2C, 'z', ConsoleKey.Z);
AddKey(0x2C0000, 'Z', ConsoleKey.Z);
AddKey(0x2D, 'x', ConsoleKey.X);
AddKey(0x2D0000, 'X', ConsoleKey.X);
AddKey(0x2E, 'c', ConsoleKey.C);
AddKey(0x2E0000, 'C', ConsoleKey.C);
AddKey(0x2F, 'v', ConsoleKey.V);
AddKey(0x2F0000, 'V', ConsoleKey.V);
AddKey(0x30, 'b', ConsoleKey.B);
AddKey(0x300000, 'B', ConsoleKey.B);
AddKey(0x31, 'n', ConsoleKey.N);
AddKey(0x310000, 'N', ConsoleKey.N);
AddKey(0x32, 'm', ConsoleKey.M);
AddKey(0x320000, 'M', ConsoleKey.M);
#endregion
#region digits
//AddKey(0x1, '`');
//AddKey(0x10000, '~');
AddKey(0x29, '`', ConsoleKey.NoName);
AddKey(0x290000, '~', ConsoleKey.NoName);
AddKey(0x2, '1', ConsoleKey.D1);
AddKey(0x20000, '!', ConsoleKey.D1);
AddKey(0x3, '2', ConsoleKey.D2);
AddKey(0x30000, '@', ConsoleKey.D2);
AddKey(0x4, '3', ConsoleKey.D3);
AddKey(0x40000, '#', ConsoleKey.D3);
AddKey(0x5, '4', ConsoleKey.D4);
AddKey(0x50000, '$', ConsoleKey.D5);
AddKey(0x6, '5', ConsoleKey.D5);
AddKey(0x60000, '%', ConsoleKey.D5);
AddKey(0x7, '6', ConsoleKey.D6);
AddKey(0x70000, '^', ConsoleKey.D6);
AddKey(0x8, '7', ConsoleKey.D7);
AddKey(0x80000, '&', ConsoleKey.D7);
AddKey(0x9, '8', ConsoleKey.D8);
AddKey(0x90000, '*', ConsoleKey.D8);
AddKey(0xA, '9', ConsoleKey.D9);
AddKey(0xA0000, '(', ConsoleKey.D9);
AddKey(0xB, '0', ConsoleKey.D0);
AddKey(0xB0000, ')', ConsoleKey.D0);
#endregion
#region Special
AddKeyWithShift(0x0E, '\u0968', ConsoleKey.Backspace); //Backspace
AddKeyWithShift(0x0F, '\t', ConsoleKey.Tab); //Tabulator
AddKeyWithShift(0x1C, '\n', ConsoleKey.Enter); //Enter
AddKeyWithShift(0x39, ' ', ConsoleKey.Spacebar); //Space
AddKeyWithShift(0x4b, '\u2190', ConsoleKey.LeftArrow); //Left arrow
AddKeyWithShift(0x48, '\u2191', ConsoleKey.UpArrow); //Up arrow
AddKeyWithShift(0x4d, '\u2192', ConsoleKey.RightArrow); //Right arrow
AddKeyWithShift(0x50, '\u2193', ConsoleKey.DownArrow); //Down arrow
AddKeyWithShift(0x5b, ConsoleKey.LeftWindows);
AddKeyWithShift(0x5c, ConsoleKey.RightWindows);
//AddKey(0x5d, ConsoleKey.NoName); //Context Menu
AddKeyWithShift(0x52, ConsoleKey.Insert);
AddKeyWithShift(0x47, ConsoleKey.Home);
AddKeyWithShift(0x49, ConsoleKey.PageUp);
AddKeyWithShift(0x53, ConsoleKey.Delete);
AddKeyWithShift(0x4f, ConsoleKey.End);
AddKeyWithShift(0x51, ConsoleKey.PageDown);
AddKeyWithShift(0x37, ConsoleKey.PrintScreen);
//AddKeyWithShift(0x46, ConsoleKey.NoName); //Scroll Lock
//AddKeyWithShift(0x3a, ConsoleKey.NoName); //Caps Lock
AddKeyWithShift(0x45, ConsoleKey.Pause);
AddKeyWithShift(0x3b, ConsoleKey.F1);
AddKeyWithShift(0x3c, ConsoleKey.F2);
AddKeyWithShift(0x3d, ConsoleKey.F3);
AddKeyWithShift(0x3e, ConsoleKey.F4);
AddKeyWithShift(0x3f, ConsoleKey.F5);
AddKeyWithShift(0x40, ConsoleKey.F6);
AddKeyWithShift(0x41, ConsoleKey.F7);
AddKeyWithShift(0x42, ConsoleKey.F8);
AddKeyWithShift(0x43, ConsoleKey.F9);
AddKeyWithShift(0x44, ConsoleKey.F10);
AddKeyWithShift(0x57, ConsoleKey.F11);
AddKeyWithShift(0x58, ConsoleKey.F12);
AddKeyWithShift(0x1, ConsoleKey.Escape);
#endregion
#region Punctuation and Signs
AddKey(0x27, ';', ConsoleKey.NoName);
AddKey(0x270000, ':', ConsoleKey.NoName);
AddKey(0x28, '\'', ConsoleKey.NoName);
AddKey(0x280000, '"', ConsoleKey.NoName);
AddKey(0x2B, '\\', ConsoleKey.NoName);
AddKey(0x2B0000, '|', ConsoleKey.NoName);
AddKey(0x33, ',', ConsoleKey.OemComma);
AddKey(0x330000, '<', ConsoleKey.OemComma);
AddKey(0x34, '.', ConsoleKey.OemPeriod);
AddKey(0x340000, '>', ConsoleKey.OemPeriod);
AddKey(0x35, '/', ConsoleKey.Divide);
AddKey(0x350000, '?', ConsoleKey.Divide);
//AddKey(0x4A, '-');
AddKey(0x0C, '-', ConsoleKey.Subtract);
AddKey(0x0C0000, '_', ConsoleKey.Subtract);
AddKey(0x0D, '=', ConsoleKey.OemPlus);
AddKey(0x0D0000, '+', ConsoleKey.OemPlus);
//AddKey(0x4E, '+');
AddKey(0x1A, '[', ConsoleKey.NoName);
AddKey(0x1A0000, '{', ConsoleKey.NoName);
AddKey(0x1B, ']', ConsoleKey.NoName);
AddKey(0x1B0000, '}', ConsoleKey.NoName);
AddKeyWithShift(0x4c, '5', ConsoleKey.NumPad5);
AddKeyWithShift(0x4a, '-', ConsoleKey.OemMinus);
AddKeyWithShift(0x4e, '+', ConsoleKey.OemPlus);
AddKeyWithShift(0x37, '*', ConsoleKey.Multiply);
#endregion
}
private void AddKey(uint p, char p_2, ConsoleKey p_3)
{
mKeys.Add(new KeyMapping(p, p_2, p_3));
}
private void AddKeyWithShift(uint p, char p_2, ConsoleKey p_3)
{
AddKey(p, p_2, p_3);
AddKey(p << 16, p_2, p_3);
}
private void AddKey(uint p, ConsoleKey p_3)
{
AddKey(p, '\0', p_3);
}
private void AddKeyWithShift(uint p, ConsoleKey p_3)
{
AddKeyWithShift(p, '\0', p_3);
}
public void ChangeKeyMap(List<KeyMapping> aKeys)
{
mKeys = aKeys;
}
public bool GetCharValue(uint aScanCode, out char aValue)
{
for (int i = 0; i < mKeys.Count; i++)
{
//if (i == 0) {
// Console.Write("ScanCode in KeyMapping: ");
// Interrupts.WriteNumber(mKeys[i].Scancode, 32);
// Console.WriteLine("");
//}
if (mKeys[i].Scancode == aScanCode)
{
if (mKeys[i].Value != '\0')
{
aValue = mKeys[i].Value;
return true;
}
break;
}
}
aValue = '\0';
return false;
}
public bool GetKeyValue(uint aScanCode, out ConsoleKey aValue)
{
for (int i = 0; i < mKeys.Count; i++)
{
if (mKeys[i].Scancode == aScanCode)
{
aValue = mKeys[i].Key;
return true;
}
}
aValue = ConsoleKey.NoName;
return false;
}
public bool GetKeyMapping(uint aScanCode, out KeyMapping aValue)
{
for (int i = 0; i < mKeys.Count; i++)
{
if (mKeys[i].Scancode == aScanCode)
{
aValue = mKeys[i];
return true;
}
}
aValue = null;
return false;
}
//public char ReadChar()
//{
// char xResult = '\0';
// while (mBuffer.Count == 0 || !GetCharValue(mBuffer.Dequeue(), out xResult))
// {
// //Global.Sleep(10); //ToDo optimize value
// if (Core.Global.CPU == null)
// {
// return '\0';
// }
// Core.Global.CPU.Halt();
// }
// return xResult;
//}
//public bool GetChar(out char c)
//{
// c = '\0';
// if (mBuffer.Count > 0)
// {
// GetCharValue(mBuffer.Dequeue(), out c);
// return true;
// }
// else
// {
// return false;
// }
//}
//public ConsoleKey ReadKey()
//{
// ConsoleKey xResult = ConsoleKey.NoName;
// while (mBuffer.Count == 0 || !GetKeyValue(mBuffer.Dequeue(), out xResult))
// {
// //Global.Sleep(10); //ToDo optimize value
// Core.Global.CPU.Halt();
// }
// return xResult;
//}
public bool GetKey(uint aScancode, out ConsoleKeyInfo keyInfo)
{
ConsoleKey xKey;
if (!GetKeyValue(aScancode, out xKey))
{
keyInfo = new ConsoleKeyInfo();
return false;
}
char xChar;
if (!GetCharValue(aScancode, out xChar))
{
keyInfo = new ConsoleKeyInfo();
return false;
}
keyInfo = new ConsoleKeyInfo(xChar, xKey, ShiftPressed, AltPressed, ControlPressed);
return true;
}
//public bool GetMapping(out KeyMapping c)
//{
// c = null;
// if (mBuffer.Count > 0)
// {
// GetKeyMapping(mBuffer.Dequeue(), out c);
// return true;
// }
// else
// {
// return false;
// }
//}
//public uint ReadScancode()
//{
// while (mBuffer.Count == 0)
// {
// Core.Global.CPU.Halt();
// }
// return mBuffer.Dequeue();
//}
//public bool GetScancode(out uint c)
//{
// if (mBuffer.Count > 0)
// {
// c = mBuffer.Dequeue();
// return true;
// }
// else
// {
// c = 0;
// return false;
// }
//}
public class KeyMapping
{
public uint Scancode;
public char Value;
public ConsoleKey Key;
public KeyMapping(uint aScanCode, char aValue, ConsoleKey aKey)
{
Scancode = aScanCode;
Value = aValue;
Key = aKey;
}
public KeyMapping(uint aScanCode, ConsoleKey aKey)
{
Scancode = aScanCode;
Value = '\0';
Key = aKey;
}
}
}
}

View file

@ -18,7 +18,7 @@ namespace Cosmos.HAL {
var xIO = aControllerID == BlockDevice.Ata.ControllerIdEnum.Primary ? Cosmos.Core.Global.BaseIOGroups.ATA1 : Cosmos.Core.Global.BaseIOGroups.ATA2;
var xATA = new BlockDevice.AtaPio(xIO, aControllerID, aBusPosition);
if (xATA.DriveType != BlockDevice.AtaPio.SpecLevel.Null) {
BlockDevice.BlockDevice.Devices.Add(xATA);
BlockDevice.BlockDevice.Devices.Add(xATA);
var xMbrData = new byte[512];
xATA.ReadBlock(0UL, 1U, xMbrData);
var xMBR = new BlockDevice.MBR(xMbrData);
@ -64,21 +64,21 @@ namespace Cosmos.HAL {
static internal void InitStaticDevices() {
//TextScreen = new TextScreen();
Global.Dbg.Send("CLS");
TextScreen.Clear();
Global.Dbg.Send("Keyboard");
Keyboard = new Keyboard();
Keyboard = new DefaultKeyboard();
// Find hardcoded ATA controllers
Global.Dbg.Send("ATA Master");
InitAta(BlockDevice.Ata.ControllerIdEnum.Primary, BlockDevice.Ata.BusPositionEnum.Master);
//Global.Dbg.Send("ATA Slave");
//InitAta(BlockDevice.Ata.ControllerIdEnum.Primary, BlockDevice.Ata.BusPositionEnum.Slave);
//InitAta(BlockDevice.Ata.ControllerIdEnum.Primary, BlockDevice.Ata.BusPositionEnum.Slave);
//TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum?
// They do show up in PCI space as well as the fixed space.
//TODO Need to change code to detect if ATA controllers are present or not. How to do this? via PCI enum?
// They do show up in PCI space as well as the fixed space.
// Or is it always here, and was our compiler stack corruption issue?
//InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Master);
//InitAta(BlockDevice.Ata.ControllerIdEnum.Secondary, BlockDevice.Ata.BusPositionEnum.Slave);

View file

@ -4,439 +4,78 @@ using System.Linq;
using System.Text;
namespace Cosmos.HAL {
public delegate void HandleKeyboardDelegate(byte aScanCode, bool aReleased);
public class Keyboard : Device {
public abstract class Keyboard : Device {
// TODO: MtW: I don't like the following line in the baseclass, but for now, lets keep it here.
protected Core.IOGroup.Keyboard IO = Core.Global.BaseIOGroups.Keyboard;
protected Keyboard()
{
mQueuedKeys = new Queue<ConsoleKeyInfo>();
private HandleKeyboardDelegate mHandleKeyboardKey;
public void Initialize(HandleKeyboardDelegate aHandleKeyboardKeyDelegate) {
mHandleKeyboardKey = aHandleKeyboardKeyDelegate;
}
public Keyboard() {
mBuffer = new Queue<uint>(BufferSize);
Initialize(HandleScancode);
Initialize();
Core.INTs.SetIrqHandler(0x01, HandleIRQ);
// TODO: Need to add support for mult keyboards. ie one in PS2 and one in USB, or even more
}
if (mKeys == null) {
CreateDefaultKeymap();
/// <summary>
/// Initialize the device. Happens before the interrupt is registered, ie before the class is being used.
/// </summary>
protected abstract void Initialize();
private void HandleIRQ(ref Core.INTs.IRQContext aContext)
{
byte xScanCode = IO.Port60.Byte;
bool xReleased = (xScanCode & 0x80) == 0x80;
if (xReleased)
{
xScanCode = (byte)(xScanCode ^ 0x80);
}
HandleScancode(xScanCode, xReleased);
}
public void HandleIRQ(ref Core.INTs.IRQContext aContext) {
if (mHandleKeyboardKey != null) {
byte xScanCode = IO.Port60.Byte;
bool xReleased = (xScanCode & 0x80) == 0x80;
if (xReleased) {
xScanCode = (byte)(xScanCode ^ 0x80);
}
mHandleKeyboardKey(xScanCode, xReleased);
protected abstract void HandleScancode(byte aScancode, bool aReleased);
private readonly Queue<ConsoleKeyInfo> mQueuedKeys;
protected void Enqueue(ConsoleKeyInfo aKey)
{
mQueuedKeys.Enqueue(aKey);
}
public bool TryReadKey(out ConsoleKeyInfo oKey)
{
if (mQueuedKeys.Count > 0)
{
oKey = mQueuedKeys.Dequeue();
return true;
}
}
private Queue<uint> mBuffer;
private const int BufferSize = 64;
private bool mEscaped;
private List<KeyMapping> mKeys;
private bool mShiftState;
private bool mCtrlState;
private bool mAltState;
public bool ShiftPressed {
get {
return mShiftState;
}
}
public bool CtrlPressed {
get {
return mCtrlState;
}
}
public bool AltPressed {
get {
return mAltState;
}
}
protected void HandleScancode(byte aScancode, bool aReleased) {
uint xTheScancode = aScancode;
if (mEscaped) {
xTheScancode = (ushort)(xTheScancode << 8);
mEscaped = false;
}
switch (xTheScancode) {
case 0x36:
case 0x2A: {
mShiftState = !aReleased;
break;
}
case 0x1D: {
mCtrlState = !aReleased;
break;
}
case 0x38: {
mAltState = !aReleased;
break;
}
default: {
if ((mCtrlState) && (mAltState) && (xTheScancode == 0x53)) {
Console.WriteLine("Detected Ctrl-Alt-Delete! Rebooting System...");
Core.Global.CPU.Reboot();
}
if (mShiftState) {
xTheScancode = xTheScancode << 16;
}
if (mBuffer.Count < BufferSize) {
if (!aReleased) {
char xTheChar;
if (!GetCharValue(xTheScancode, out xTheChar)) {
//DebugUtil.SendError("Keyboard", "error while getting scancode character!");
} else {
//DebugUtil.SendDoubleNumber("Keyboard", "Scancode and Char", xTheScancode, 32, xTheChar, 16);
}
mBuffer.Enqueue(xTheScancode);
}
}
break;
}
}
}
// Can merge HandleScancode after we remove old code
// Remove the static.. Make it a real class
protected void ByteReceived(byte aValue) {
bool xReleased = (aValue & 0x80) == 0x80;
if (xReleased) {
aValue = (byte)(aValue ^ 0x80);
}
mHandleKeyboardKey(aValue, xReleased);
}
private void CreateDefaultKeymap() {
mKeys = new List<KeyMapping>(164);
//TODO: fn (for laptops)
#region Letters
AddKey(0x10, 'q', ConsoleKey.Q);
AddKey(0x100000, 'Q', ConsoleKey.Q);
AddKey(0x11, 'w', ConsoleKey.W);
AddKey(0x110000, 'W', ConsoleKey.W);
AddKey(0x12, 'e', ConsoleKey.E);
AddKey(0x120000, 'E', ConsoleKey.E);
AddKey(0x13, 'r', ConsoleKey.R);
AddKey(0x130000, 'R', ConsoleKey.R);
AddKey(0x14, 't', ConsoleKey.T);
AddKey(0x140000, 'T', ConsoleKey.T);
AddKey(0x15, 'y', ConsoleKey.Y);
AddKey(0x150000, 'Y', ConsoleKey.Y);
AddKey(0x16, 'u', ConsoleKey.U);
AddKey(0x160000, 'U', ConsoleKey.U);
AddKey(0x17, 'i', ConsoleKey.I);
AddKey(0x170000, 'I', ConsoleKey.I);
AddKey(0x18, 'o', ConsoleKey.O);
AddKey(0x180000, 'O', ConsoleKey.O);
AddKey(0x19, 'p', ConsoleKey.P);
AddKey(0x190000, 'P', ConsoleKey.P);
AddKey(0x1E, 'a', ConsoleKey.A);
AddKey(0x1E0000, 'A', ConsoleKey.A);
AddKey(0x1F, 's', ConsoleKey.S);
AddKey(0x1F0000, 'S', ConsoleKey.S);
AddKey(0x20, 'd', ConsoleKey.D);
AddKey(0x200000, 'D', ConsoleKey.D);
AddKey(0x21, 'f', ConsoleKey.F);
AddKey(0x210000, 'F', ConsoleKey.F);
AddKey(0x22, 'g', ConsoleKey.G);
AddKey(0x220000, 'G', ConsoleKey.G);
AddKey(0x23, 'h', ConsoleKey.H);
AddKey(0x230000, 'H', ConsoleKey.H);
AddKey(0x24, 'j', ConsoleKey.J);
AddKey(0x240000, 'J', ConsoleKey.J);
AddKey(0x25, 'k', ConsoleKey.K);
AddKey(0x250000, 'K', ConsoleKey.K);
AddKey(0x26, 'l', ConsoleKey.L);
AddKey(0x260000, 'L', ConsoleKey.L);
AddKey(0x2C, 'z', ConsoleKey.Z);
AddKey(0x2C0000, 'Z', ConsoleKey.Z);
AddKey(0x2D, 'x', ConsoleKey.X);
AddKey(0x2D0000, 'X', ConsoleKey.X);
AddKey(0x2E, 'c', ConsoleKey.C);
AddKey(0x2E0000, 'C', ConsoleKey.C);
AddKey(0x2F, 'v', ConsoleKey.V);
AddKey(0x2F0000, 'V', ConsoleKey.V);
AddKey(0x30, 'b', ConsoleKey.B);
AddKey(0x300000, 'B', ConsoleKey.B);
AddKey(0x31, 'n', ConsoleKey.N);
AddKey(0x310000, 'N', ConsoleKey.N);
AddKey(0x32, 'm', ConsoleKey.M);
AddKey(0x320000, 'M', ConsoleKey.M);
#endregion
#region digits
//AddKey(0x1, '`');
//AddKey(0x10000, '~');
AddKey(0x29, '`', ConsoleKey.NoName);
AddKey(0x290000, '~', ConsoleKey.NoName);
AddKey(0x2, '1', ConsoleKey.D1);
AddKey(0x20000, '!', ConsoleKey.D1);
AddKey(0x3, '2', ConsoleKey.D2);
AddKey(0x30000, '@', ConsoleKey.D2);
AddKey(0x4, '3', ConsoleKey.D3);
AddKey(0x40000, '#', ConsoleKey.D3);
AddKey(0x5, '4', ConsoleKey.D4);
AddKey(0x50000, '$', ConsoleKey.D5);
AddKey(0x6, '5', ConsoleKey.D5);
AddKey(0x60000, '%', ConsoleKey.D5);
AddKey(0x7, '6', ConsoleKey.D6);
AddKey(0x70000, '^', ConsoleKey.D6);
AddKey(0x8, '7', ConsoleKey.D7);
AddKey(0x80000, '&', ConsoleKey.D7);
AddKey(0x9, '8', ConsoleKey.D8);
AddKey(0x90000, '*', ConsoleKey.D8);
AddKey(0xA, '9', ConsoleKey.D9);
AddKey(0xA0000, '(', ConsoleKey.D9);
AddKey(0xB, '0', ConsoleKey.D0);
AddKey(0xB0000, ')', ConsoleKey.D0);
#endregion
#region Special
AddKeyWithShift(0x0E, '\u0968', ConsoleKey.Backspace); //Backspace
AddKeyWithShift(0x0F, '\t', ConsoleKey.Tab); //Tabulator
AddKeyWithShift(0x1C, '\n', ConsoleKey.Enter); //Enter
AddKeyWithShift(0x39, ' ', ConsoleKey.Spacebar); //Space
AddKeyWithShift(0x4b, '\u2190', ConsoleKey.LeftArrow); //Left arrow
AddKeyWithShift(0x48, '\u2191', ConsoleKey.UpArrow); //Up arrow
AddKeyWithShift(0x4d, '\u2192', ConsoleKey.RightArrow); //Right arrow
AddKeyWithShift(0x50, '\u2193', ConsoleKey.DownArrow); //Down arrow
AddKeyWithShift(0x5b, ConsoleKey.LeftWindows);
AddKeyWithShift(0x5c, ConsoleKey.RightWindows);
//AddKey(0x5d, ConsoleKey.NoName); //Context Menu
AddKeyWithShift(0x52, ConsoleKey.Insert);
AddKeyWithShift(0x47, ConsoleKey.Home);
AddKeyWithShift(0x49, ConsoleKey.PageUp);
AddKeyWithShift(0x53, ConsoleKey.Delete);
AddKeyWithShift(0x4f, ConsoleKey.End);
AddKeyWithShift(0x51, ConsoleKey.PageDown);
AddKeyWithShift(0x37, ConsoleKey.PrintScreen);
//AddKeyWithShift(0x46, ConsoleKey.NoName); //Scroll Lock
//AddKeyWithShift(0x3a, ConsoleKey.NoName); //Caps Lock
AddKeyWithShift(0x45, ConsoleKey.Pause);
AddKeyWithShift(0x3b, ConsoleKey.F1);
AddKeyWithShift(0x3c, ConsoleKey.F2);
AddKeyWithShift(0x3d, ConsoleKey.F3);
AddKeyWithShift(0x3e, ConsoleKey.F4);
AddKeyWithShift(0x3f, ConsoleKey.F5);
AddKeyWithShift(0x40, ConsoleKey.F6);
AddKeyWithShift(0x41, ConsoleKey.F7);
AddKeyWithShift(0x42, ConsoleKey.F8);
AddKeyWithShift(0x43, ConsoleKey.F9);
AddKeyWithShift(0x44, ConsoleKey.F10);
AddKeyWithShift(0x57, ConsoleKey.F11);
AddKeyWithShift(0x58, ConsoleKey.F12);
AddKeyWithShift(0x1, ConsoleKey.Escape);
#endregion
#region Punctuation and Signs
AddKey(0x27, ';', ConsoleKey.NoName);
AddKey(0x270000, ':', ConsoleKey.NoName);
AddKey(0x28, '\'', ConsoleKey.NoName);
AddKey(0x280000, '"', ConsoleKey.NoName);
AddKey(0x2B, '\\', ConsoleKey.NoName);
AddKey(0x2B0000, '|', ConsoleKey.NoName);
AddKey(0x33, ',', ConsoleKey.OemComma);
AddKey(0x330000, '<', ConsoleKey.OemComma);
AddKey(0x34, '.', ConsoleKey.OemPeriod);
AddKey(0x340000, '>', ConsoleKey.OemPeriod);
AddKey(0x35, '/', ConsoleKey.Divide);
AddKey(0x350000, '?', ConsoleKey.Divide);
//AddKey(0x4A, '-');
AddKey(0x0C, '-', ConsoleKey.Subtract);
AddKey(0x0C0000, '_', ConsoleKey.Subtract);
AddKey(0x0D, '=', ConsoleKey.OemPlus);
AddKey(0x0D0000, '+', ConsoleKey.OemPlus);
//AddKey(0x4E, '+');
AddKey(0x1A, '[', ConsoleKey.NoName);
AddKey(0x1A0000, '{', ConsoleKey.NoName);
AddKey(0x1B, ']', ConsoleKey.NoName);
AddKey(0x1B0000, '}', ConsoleKey.NoName);
AddKeyWithShift(0x4c, '5', ConsoleKey.NumPad5);
AddKeyWithShift(0x4a, '-', ConsoleKey.OemMinus);
AddKeyWithShift(0x4e, '+', ConsoleKey.OemPlus);
AddKeyWithShift(0x37, '*', ConsoleKey.Multiply);
#endregion
}
private uint KeyCount = 0;
private void AddKey(uint p, char p_2, ConsoleKey p_3) {
mKeys.Add(new KeyMapping(p, p_2, p_3));
KeyCount++;
}
private void AddKeyWithShift(uint p, char p_2, ConsoleKey p_3) {
AddKey(p, p_2, p_3);
AddKey(p << 16, p_2, p_3);
}
private void AddKey(uint p, ConsoleKey p_3) {
AddKey(p, '\0', p_3);
}
private void AddKeyWithShift(uint p, ConsoleKey p_3) {
AddKeyWithShift(p, '\0', p_3);
}
public void ChangeKeyMap(List<KeyMapping> aKeys) {
mKeys = aKeys;
}
public bool GetCharValue(uint aScanCode, out char aValue) {
for (int i = 0; i < mKeys.Count; i++) {
//if (i == 0) {
// Console.Write("ScanCode in KeyMapping: ");
// Interrupts.WriteNumber(mKeys[i].Scancode, 32);
// Console.WriteLine("");
//}
if (mKeys[i].Scancode == aScanCode) {
if (mKeys[i].Value != '\0') {
aValue = mKeys[i].Value;
return true;
}
break;
}
}
aValue = '\0';
return false;
}
public bool GetKeyValue(uint aScanCode, out ConsoleKey aValue) {
for (int i = 0; i < mKeys.Count; i++) {
if (mKeys[i].Scancode == aScanCode) {
aValue = mKeys[i].Key;
return true;
}
}
aValue = ConsoleKey.NoName;
return false;
}
public bool GetKeyMapping(uint aScanCode, out KeyMapping aValue) {
for (int i = 0; i < mKeys.Count; i++) {
if (mKeys[i].Scancode == aScanCode) {
aValue = mKeys[i];
return true;
}
}
aValue = null;
oKey = default(ConsoleKeyInfo);
return false;
}
public char ReadChar() {
char xResult = '\0';
while (mBuffer.Count == 0 || !GetCharValue(mBuffer.Dequeue(), out xResult)) {
//Global.Sleep(10); //ToDo optimize value
if (Core.Global.CPU == null)
{
return '\0';
}
public ConsoleKeyInfo ReadKey()
{
while (mQueuedKeys.Count == 0)
{
Core.Global.CPU.Halt();
}
return xResult;
return mQueuedKeys.Dequeue();
}
public bool GetChar(out char c) {
c = '\0';
if (mBuffer.Count > 0) {
GetCharValue(mBuffer.Dequeue(), out c);
return true;
} else {
return false;
}
public bool ShiftPressed
{
get;
protected set;
}
public ConsoleKey ReadKey() {
ConsoleKey xResult = ConsoleKey.NoName;
while (mBuffer.Count == 0 || !GetKeyValue(mBuffer.Dequeue(), out xResult)) {
//Global.Sleep(10); //ToDo optimize value
Core.Global.CPU.Halt();
}
return xResult;
}
public bool GetKey(out ConsoleKey c) {
c = ConsoleKey.NoName;
if (mBuffer.Count > 0) {
GetKeyValue(mBuffer.Dequeue(), out c);
return true;
} else {
return false;
}
public bool ControlPressed
{
get;
protected set;
}
public KeyMapping ReadMapping() {
KeyMapping xResult = null;
while (mBuffer.Count == 0 || !GetKeyMapping(mBuffer.Dequeue(), out xResult)) {
//Global.Sleep(10); //ToDo optimize value
Core.Global.CPU.Halt();
}
return xResult;
}
public bool GetMapping(out KeyMapping c) {
c = null;
if (mBuffer.Count > 0) {
GetKeyMapping(mBuffer.Dequeue(), out c);
return true;
} else {
return false;
}
}
public uint ReadScancode() {
while (mBuffer.Count == 0) {
Core.Global.CPU.Halt();
}
return mBuffer.Dequeue();
}
public bool GetScancode(out uint c) {
if (mBuffer.Count > 0) {
c = mBuffer.Dequeue();
return true;
} else {
c = 0;
return false;
}
}
public class KeyMapping {
public uint Scancode;
public char Value;
public ConsoleKey Key;
public KeyMapping(uint aScanCode, char aValue, ConsoleKey aKey) {
Scancode = aScanCode;
Value = aValue;
Key = aKey;
}
public KeyMapping(uint aScanCode, ConsoleKey aKey) {
Scancode = aScanCode;
Value = '\0';
Key = aKey;
}
public bool AltPressed
{
get;
protected set;
}
}
}

View file

@ -445,73 +445,80 @@ namespace Cosmos.IL2CPU
public void ProcessMethod(MethodInfo aMethod, List<ILOpCode> aOpCodes)
{
// We check this here and not scanner as when scanner makes these
// plugs may still have not yet been scanned that it will depend on.
// But by the time we make it here, they have to be resolved.
if (aMethod.Type == MethodInfo.TypeEnum.NeedsPlug && aMethod.PlugMethod == null)
try
{
throw new Exception("Method needs plug, but no plug was assigned.");
}
// We check this here and not scanner as when scanner makes these
// plugs may still have not yet been scanned that it will depend on.
// But by the time we make it here, they have to be resolved.
if (aMethod.Type == MethodInfo.TypeEnum.NeedsPlug && aMethod.PlugMethod == null)
{
throw new Exception("Method needs plug, but no plug was assigned.");
}
// todo: MtW: how to do this? we need some extra space.
// see ConstructLabel for extra info
if (aMethod.UID > 0x00FFFFFF)
{
throw new Exception("Too many methods.");
}
// todo: MtW: how to do this? we need some extra space.
// see ConstructLabel for extra info
if (aMethod.UID > 0x00FFFFFF)
{
throw new Exception("Too many methods.");
}
MethodBegin(aMethod);
mLog.WriteLine("Method '{0}', ID = '{1}'", aMethod.MethodBase.GetFullName(), aMethod.UID);
mLog.Flush();
if (aMethod.MethodAssembler != null)
{
var xAssembler = (AssemblerMethod)Activator.CreateInstance(aMethod.MethodAssembler);
xAssembler.AssembleNew(Assembler, aMethod.PluggedMethod);
}
else if (aMethod.IsInlineAssembler)
{
aMethod.MethodBase.Invoke("", new object[aMethod.MethodBase.GetParameters().Length]);
}
else
{
// now emit the actual assembler code for this method.
MethodBegin(aMethod);
mLog.WriteLine("Method '{0}', ID = '{1}'", aMethod.MethodBase.GetFullName(), aMethod.UID);
mLog.Flush();
if (aMethod.MethodAssembler != null)
{
var xAssembler = (AssemblerMethod)Activator.CreateInstance(aMethod.MethodAssembler);
xAssembler.AssembleNew(Assembler, aMethod.PluggedMethod);
}
else if (aMethod.IsInlineAssembler)
{
aMethod.MethodBase.Invoke("", new object[aMethod.MethodBase.GetParameters().Length]);
}
else
{
// now emit the actual assembler code for this method.
//Conditions under which we should emit an INT3 instead of a plceholder NOP:
/* - First instruction in a Method / Loop / If / Else etc.
//Conditions under which we should emit an INT3 instead of a plceholder NOP:
/* - First instruction in a Method / Loop / If / Else etc.
* -- In essence, whenever there is a opening {
* -- C# Debug builds automatically insert NOPs at these locations (otherwise NOP is not used)
* -- So only insert an INT3 when we are about to insert a NOP that came from IL code
*/
/* We group opcodes together by logical statement. Each statement will have its logical stack cleared.
/* We group opcodes together by logical statement. Each statement will have its logical stack cleared.
* Also, this lets us do optimizations later on.
*/
bool emitINT3 = true;
DebugInfo.SequencePoint xPreviousSequencePoint = null;
var xCurrentGroup = new List<ILOpCode>();
ILOpCode.ILInterpretationDebugLine(() => String.Format("Method: {0}", aMethod.MethodBase.GetFullName()));
foreach (var xRawOpcode in aOpCodes)
{
var xSP = mSequences.FirstOrDefault(q => q.Offset == xRawOpcode.Position && q.LineStart != 0xFEEFEE);
// detect if we're at a new statement.
if (xPreviousSequencePoint == null && xSP != null)
bool emitINT3 = true;
DebugInfo.SequencePoint xPreviousSequencePoint = null;
var xCurrentGroup = new List<ILOpCode>();
ILOpCode.ILInterpretationDebugLine(() => String.Format("Method: {0}", aMethod.MethodBase.GetFullName()));
foreach (var xRawOpcode in aOpCodes)
{
var xSP = mSequences.FirstOrDefault(q => q.Offset == xRawOpcode.Position && q.LineStart != 0xFEEFEE);
// detect if we're at a new statement.
if (xPreviousSequencePoint == null && xSP != null)
{
}
if (xSP != null && xCurrentGroup.Count > 0)
{
EmitInstructions(aMethod, xCurrentGroup, ref emitINT3);
xCurrentGroup.Clear();
xPreviousSequencePoint = xSP;
}
xCurrentGroup.Add(xRawOpcode);
}
if (xSP != null && xCurrentGroup.Count > 0)
if (xCurrentGroup.Count > 0)
{
EmitInstructions(aMethod, xCurrentGroup, ref emitINT3);
xCurrentGroup.Clear();
xPreviousSequencePoint = xSP;
}
xCurrentGroup.Add(xRawOpcode);
}
if (xCurrentGroup.Count > 0)
{
EmitInstructions(aMethod, xCurrentGroup, ref emitINT3);
}
MethodEnd(aMethod);
}
catch (Exception E)
{
throw new Exception("Error compiling method '" + aMethod.MethodBase.GetFullName() + "': " + E.ToString(), E);
}
MethodEnd(aMethod);
}
private void BeforeEmitInstructions(MethodInfo aMethod, List<ILOpCode> aCurrentGroup)

View file

@ -14,8 +14,8 @@ namespace Cosmos.IL2CPU.X86.IL
public static void Assemble(Cosmos.Assembler.Assembler aAssembler, uint aElementSize,bool isSigned , bool debugEnabled)
{
DoNullReferenceCheck(aAssembler, debugEnabled, 4);
if (aElementSize <= 0 || aElementSize > 8 || (aElementSize > 4 && aElementSize < 8))
throw new Exception("Unsupported size for Ldelem_Ref: " + aElementSize);
if (aElementSize <= 0 || aElementSize > 8 || (aElementSize > 4 && aElementSize < 8))
throw new Exception("Unsupported size for Ldelem_Ref: " + aElementSize);
new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX };
new CPUx86.Mov { DestinationReg = CPUx86.Registers.EDX, SourceValue = aElementSize };
@ -58,4 +58,4 @@ namespace Cosmos.IL2CPU.X86.IL
Assemble( Assembler, 4, false, DebugEnabled);
}
}
}
}

View file

@ -370,7 +370,8 @@ namespace Cosmos.IL2CPU {
aSituationChanged = true;
}
if (StackPopTypes[i] != xActualStackItem
&& !StackPopTypes[i].IsAssignableFrom(xActualStackItem))
&& !StackPopTypes[i].IsAssignableFrom(xActualStackItem)
&& !((StackPopTypes[i].IsPointer || StackPopTypes[i].IsByRef) && (xActualStackItem.IsPointer || xActualStackItem.IsByRef)))
{
throw new Exception(String.Format("OpCode {0} tries to pop item at stack position {1} with type {2}, but actual type is {3}",
this, i, StackPopTypes[i], xActualStackItem));

View file

@ -303,25 +303,28 @@ namespace Cosmos.System.Plugs.System {
public static int Read() {
// TODO special cases, if needed, that returns -1
return HAL.Global.Keyboard.ReadChar();
ConsoleKeyInfo xResult;
if (HAL.Global.Keyboard.TryReadKey(out xResult))
{
return xResult.KeyChar;
}
else
{
return -1;
}
}
// ReadKey() pure CIL
public static ConsoleKeyInfo ReadKey(Boolean intercept) {
var key = Cosmos.HAL.Global.Keyboard.ReadMapping();
var returnValue = new ConsoleKeyInfo(
key.Value,
key.Key,
Cosmos.HAL.Global.Keyboard.ShiftPressed,
Cosmos.HAL.Global.Keyboard.AltPressed,
Cosmos.HAL.Global.Keyboard.CtrlPressed);
var key = Cosmos.HAL.Global.Keyboard.ReadKey();
if (false == intercept)
{
Write(returnValue.KeyChar);
Write(key.KeyChar);
}
return returnValue;
return key;
}
public static String ReadLine() {
@ -332,13 +335,13 @@ namespace Cosmos.System.Plugs.System {
return null;
}
List<char> chars = new List<char>(32);
char current;
ConsoleKeyInfo current;
int currentCount = 0;
while ((current = HAL.Global.Keyboard.ReadChar()) != '\n')
while ((current = HAL.Global.Keyboard.ReadKey()).KeyChar != '\n')
{
//Check for "special" keys
if (current == '\u0968') // Backspace
if (current.Key == ConsoleKey.Backspace) // Backspace
{
if (currentCount > 0)
{
@ -360,7 +363,7 @@ namespace Cosmos.System.Plugs.System {
}
continue;
}
else if (current == '\u2190') // Arrow Left
else if (current.Key == ConsoleKey.LeftArrow)
{
if (currentCount > 0)
{
@ -369,7 +372,7 @@ namespace Cosmos.System.Plugs.System {
}
continue;
}
else if (current == '\u2192') // Arrow Right
else if (current.Key == ConsoleKey.RightArrow)
{
if (currentCount < chars.Count)
{
@ -382,7 +385,7 @@ namespace Cosmos.System.Plugs.System {
//Write the character to the screen
if (currentCount == chars.Count)
{
chars.Add(current);
chars.Add(current.KeyChar);
Write(current);
currentCount++;
}
@ -397,7 +400,7 @@ namespace Cosmos.System.Plugs.System {
{
if (x == currentCount)
{
temp.Add(current);
temp.Add(current.KeyChar);
}
temp.Add(chars[x]);

View file

@ -0,0 +1,2 @@
[*.cs]
indent_size=4

View file

@ -119,6 +119,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include=".editorconfig" />
<None Include="Cosmos.snk" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View file

@ -1,2 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GDB/@EntryIndexedValue">GDB</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GDB/@EntryIndexedValue">GDB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IRQ/@EntryIndexedValue">IRQ</s:String></wpf:ResourceDictionary>