mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-27 05:52:11 +00:00
This commit is contained in:
parent
7457359fa6
commit
00f47697f3
18 changed files with 65 additions and 87 deletions
|
|
@ -13,6 +13,14 @@
|
||||||
<p>
|
<p>
|
||||||
Can do reg = reg + 4 - define the + overload as a type that can then be
|
Can do reg = reg + 4 - define the + overload as a type that can then be
|
||||||
reimplicitly converted to a register, or whatever type goes inside Memory[x]</p>
|
reimplicitly converted to a register, or whatever type goes inside Memory[x]</p>
|
||||||
|
<p>
|
||||||
|
Make it so X# doesnt require the 32 and that it checks register size Memory[EBX,
|
||||||
|
32] = ECX; </p>
|
||||||
|
<p>
|
||||||
|
Register.cs - public void Push() { // TODO: This emits Push dword which
|
||||||
|
generates warnings about dword being ignored new Push { DestinationReg = GetId()
|
||||||
|
}; } |<br />
|
||||||
|
AL.Push does not work at all.</p>
|
||||||
<h3>
|
<h3>
|
||||||
X#milation would need to be implemented.</li>
|
X#milation would need to be implemented.</li>
|
||||||
<li>One of the goals of Cosmos is the need to write very little assembly, so only
|
<li>One of the goals of Cosmos is the need to write very little assembly, so only
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ namespace Cosmos.Compiler.Debug {
|
||||||
public enum Command : byte {
|
public enum Command : byte {
|
||||||
Noop = 0
|
Noop = 0
|
||||||
, TraceOff = 1, TraceOn = 2
|
, TraceOff = 1, TraceOn = 2
|
||||||
// Break command is also for continuing from breakstate.
|
|
||||||
, Break = 3
|
, Break = 3
|
||||||
, Step = 4
|
, Continue = 4 // After a Break
|
||||||
, BreakOnAddress = 5
|
, Step = 5
|
||||||
, BatchBegin = 6
|
, BreakOnAddress = 6
|
||||||
, BatchEnd = 7
|
, BatchBegin = 7
|
||||||
|
, BatchEnd = 8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,6 @@ namespace Cosmos.IL2CPU.X86 {
|
||||||
EAX = EAX << 2;
|
EAX = EAX << 2;
|
||||||
EBX.Add(EAX);
|
EBX.Add(EAX);
|
||||||
|
|
||||||
//TODO: Make it so X# doesnt require the 32 and that it checks register size
|
|
||||||
Memory[EBX, 32] = ECX;
|
Memory[EBX, 32] = ECX;
|
||||||
|
|
||||||
PopAll32();
|
PopAll32();
|
||||||
|
|
@ -105,36 +104,27 @@ namespace Cosmos.IL2CPU.X86 {
|
||||||
|
|
||||||
// Wait for a command
|
// Wait for a command
|
||||||
Label = "DebugStub_WaitCmd";
|
Label = "DebugStub_WaitCmd";
|
||||||
Call("ReadALFromComPort");
|
// Check for common commands
|
||||||
|
Call("DebugStub_ProcessCommand");
|
||||||
|
|
||||||
AL.Compare((byte)Command.TraceOff);
|
// Now check for commands that are only valid in break state
|
||||||
CallIf(Flags.Equal, "DebugStub_TraceOff", "DebugStub_WaitCmd");
|
// or commands that require additional handling while in break
|
||||||
AL.Compare((byte)Command.TraceOn);
|
// state.
|
||||||
CallIf(Flags.Equal, "DebugStub_TraceOn", "DebugStub_WaitCmd");
|
|
||||||
AL.Compare((byte)Command.Break);
|
AL.Compare((byte)Command.Continue);
|
||||||
// Break command is also the continue command
|
|
||||||
// If received while in break, then it continues
|
|
||||||
JumpIf(Flags.Equal, "DebugStub_Break_Exit");
|
JumpIf(Flags.Equal, "DebugStub_Break_Exit");
|
||||||
|
|
||||||
AL.Compare((byte)Command.Step);
|
AL.Compare((byte)Command.Step);
|
||||||
CallIf(Flags.Equal, "DebugStub_Step", "DebugStub_Break_Exit");
|
JumpIf(Flags.NotEqual, "DebugStub_Break_Step_After");
|
||||||
|
Memory["DebugBreakOnNextTrace", 32] = 1;
|
||||||
|
Jump("DebugStub_ProcessCmd_Exit");
|
||||||
|
Label = "DebugStub_Break_Step_After";
|
||||||
|
// Loop around and wait for another command
|
||||||
|
Jump("DebugStub_WaitCmd");
|
||||||
|
|
||||||
Label = "DebugStub_Break_Exit";
|
Label = "DebugStub_Break_Exit";
|
||||||
Memory["DebugStatus", 32] = (int)Status.Run;
|
Memory["DebugStatus", 32] = (int)Status.Run;
|
||||||
Return();
|
Return();
|
||||||
|
|
||||||
/////////////////////
|
|
||||||
|
|
||||||
Label = "DebugStub_TraceOff";
|
|
||||||
Memory["DebugTraceMode", 32] = (int)Tracing.Off;
|
|
||||||
Return();
|
|
||||||
|
|
||||||
Label = "DebugStub_TraceOn";
|
|
||||||
Memory["DebugTraceMode", 32] = (int)Tracing.On;
|
|
||||||
Return();
|
|
||||||
|
|
||||||
Label = "DebugStub_Step";
|
|
||||||
Memory["DebugBreakOnNextTrace", 32] = 1;
|
|
||||||
Return();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modifies: EAX, ESI
|
// Modifies: EAX, ESI
|
||||||
|
|
@ -379,6 +369,10 @@ namespace Cosmos.IL2CPU.X86 {
|
||||||
public void ProcessCommand() {
|
public void ProcessCommand() {
|
||||||
Label = "DebugStub_ProcessCommand";
|
Label = "DebugStub_ProcessCommand";
|
||||||
Call("ReadALFromComPort");
|
Call("ReadALFromComPort");
|
||||||
|
// Some callers expect AL to be returned, so we preserve it
|
||||||
|
// in case any commands modify AL.
|
||||||
|
//TODO: But in ASM wont let us push AL, so we push EAX for now
|
||||||
|
EAX.Push();
|
||||||
|
|
||||||
AL.Compare((byte)Command.Noop);
|
AL.Compare((byte)Command.Noop);
|
||||||
JumpIf(Flags.Equal, "DebugStub_ProcessCmd_Exit");
|
JumpIf(Flags.Equal, "DebugStub_ProcessCmd_Exit");
|
||||||
|
|
@ -408,6 +402,7 @@ namespace Cosmos.IL2CPU.X86 {
|
||||||
Label = "DebugStub_ProcessCmd_BreakOnAddress_After";
|
Label = "DebugStub_ProcessCmd_BreakOnAddress_After";
|
||||||
|
|
||||||
Label = "DebugStub_ProcessCmd_Exit";
|
Label = "DebugStub_ProcessCmd_Exit";
|
||||||
|
EAX.Pop();
|
||||||
Return();
|
Return();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace Cosmos.IL2CPU.X86.X {
|
||||||
public readonly int Displacement;
|
public readonly int Displacement;
|
||||||
|
|
||||||
public AddressIndirect(Register32 aBaseRegister, Int32 aDisplacement) {
|
public AddressIndirect(Register32 aBaseRegister, Int32 aDisplacement) {
|
||||||
Register = Registers.GetRegister(aBaseRegister.GetName());
|
Register = Registers.GetRegister(aBaseRegister.Name);
|
||||||
Displacement = aDisplacement;
|
Displacement = aDisplacement;
|
||||||
}
|
}
|
||||||
public AddressIndirect(uint aBaseAddress, int aDisplacement) {
|
public AddressIndirect(uint aBaseAddress, int aDisplacement) {
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,27 @@ using X86 = Cosmos.IL2CPU.X86;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public abstract class Register {
|
public abstract class Register {
|
||||||
|
protected byte mBitSize;
|
||||||
|
public byte BitSize {
|
||||||
|
get { return mBitSize; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly string Name;
|
||||||
|
|
||||||
|
public Register() {
|
||||||
|
Name = GetType().Name.Substring(typeof(Register).Name.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
|
||||||
public RegistersEnum GetId() {
|
public RegistersEnum GetId() {
|
||||||
return Registers.GetRegister(GetName()).Value;
|
return Registers.GetRegister(Name).Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Push() {
|
public void Push() {
|
||||||
|
// TODO: This emits Push dword which generates warnings about dword being ignored
|
||||||
new Push { DestinationReg = GetId() };
|
new Push { DestinationReg = GetId() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,12 +51,10 @@ namespace Cosmos.IL2CPU.X86.X {
|
||||||
new Move { DestinationReg = GetId(), SourceRef = aReference, Size = Registers.GetSize(GetId())};
|
new Move { DestinationReg = GetId(), SourceRef = aReference, Size = Registers.GetSize(GetId())};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetName() {
|
|
||||||
return GetType().Name.Substring("Register".Length);
|
|
||||||
}
|
|
||||||
public bool isPort(){
|
public bool isPort(){
|
||||||
if (GetId().Equals(Registers.AX) || GetId().Equals(Registers.AL) || GetId().Equals(Registers.EAX))
|
if (GetId().Equals(Registers.AX) || GetId().Equals(Registers.AL) || GetId().Equals(Registers.EAX)) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ using X86 = Cosmos.IL2CPU.X86;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class Register08 : Register {
|
public class Register08 : Register {
|
||||||
|
public Register08() {
|
||||||
|
mBitSize = 8;
|
||||||
|
}
|
||||||
|
|
||||||
public void Compare(byte aValue) {
|
public void Compare(byte aValue) {
|
||||||
new Compare { DestinationReg = GetId(), SourceValue = aValue, Size = 8 };
|
new Compare { DestinationReg = GetId(), SourceValue = aValue, Size = 8 };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,5 +5,9 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class Register16 : Register {
|
public class Register16 : Register {
|
||||||
|
public Register16() {
|
||||||
|
mBitSize = 16;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class Register32 : Register {
|
public class Register32 : Register {
|
||||||
|
public Register32() {
|
||||||
|
mBitSize = 32;
|
||||||
|
}
|
||||||
|
|
||||||
// Not all overloads can go here.
|
// Not all overloads can go here.
|
||||||
// 1- C# overloads specifically by exact class and does not inherit in many cases
|
// 1- C# overloads specifically by exact class and does not inherit in many cases
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,8 @@ using X86 = Cosmos.IL2CPU.X86;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterAL : Register08 {
|
public class RegisterAL : Register08 {
|
||||||
public const string Name = "AL";
|
|
||||||
public static readonly RegisterAL Instance = new RegisterAL();
|
public static readonly RegisterAL Instance = new RegisterAL();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Use an attribute to find the register name
|
// TODO: Use an attribute to find the register name
|
||||||
// Also useful for Memory conversion - Can find attribute
|
// Also useful for Memory conversion - Can find attribute
|
||||||
// of descendant? or no?
|
// of descendant? or no?
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterAX : Register16 {
|
public class RegisterAX : Register16 {
|
||||||
public const string Name = "AX";
|
|
||||||
public static readonly RegisterAX Instance = new RegisterAX();
|
public static readonly RegisterAX Instance = new RegisterAX();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterAX(ElementReference aReference) {
|
public static implicit operator RegisterAX(ElementReference aReference) {
|
||||||
Instance.Move(aReference);
|
Instance.Move(aReference);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterDX : Register16 {
|
public class RegisterDX : Register16 {
|
||||||
public const string Name = "DX";
|
|
||||||
public static readonly RegisterDX Instance = new RegisterDX();
|
public static readonly RegisterDX Instance = new RegisterDX();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterDX(UInt16 aValue) {
|
public static implicit operator RegisterDX(UInt16 aValue) {
|
||||||
Instance.Move(aValue);
|
Instance.Move(aValue);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterEBP : Register32 {
|
public class RegisterEBP : Register32 {
|
||||||
public const string Name = "EBP";
|
|
||||||
public static readonly RegisterEBP Instance = new RegisterEBP();
|
public static readonly RegisterEBP Instance = new RegisterEBP();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterEBP(UInt32 aValue) {
|
public static implicit operator RegisterEBP(UInt32 aValue) {
|
||||||
Instance.Move(aValue);
|
Instance.Move(aValue);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterEBX : Register32 {
|
public class RegisterEBX : Register32 {
|
||||||
public const string Name = "EBX";
|
|
||||||
public static readonly RegisterEBX Instance = new RegisterEBX();
|
public static readonly RegisterEBX Instance = new RegisterEBX();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterEBX(ElementReference aReference) {
|
public static implicit operator RegisterEBX(ElementReference aReference) {
|
||||||
Instance.Move(aReference);
|
Instance.Move(aReference);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterECX : Register32 {
|
public class RegisterECX : Register32 {
|
||||||
public const string Name = "ECX";
|
|
||||||
public static readonly RegisterECX Instance = new RegisterECX();
|
public static readonly RegisterECX Instance = new RegisterECX();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterECX(ElementReference aReference) {
|
public static implicit operator RegisterECX(ElementReference aReference) {
|
||||||
Instance.Move(aReference);
|
Instance.Move(aReference);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterEDI : Register32 {
|
public class RegisterEDI : Register32 {
|
||||||
public const string Name = "EDI";
|
|
||||||
public static readonly RegisterEDI Instance = new RegisterEDI();
|
public static readonly RegisterEDI Instance = new RegisterEDI();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RegisterEDI operator ++(RegisterEDI aRegister) {
|
public static RegisterEDI operator ++(RegisterEDI aRegister) {
|
||||||
new Inc { DestinationReg = aRegister.GetId() };
|
new Inc { DestinationReg = aRegister.GetId() };
|
||||||
return aRegister;
|
return aRegister;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterEDX : Register32 {
|
public class RegisterEDX : Register32 {
|
||||||
public const string Name = "EDX";
|
|
||||||
public static readonly RegisterEDX Instance = new RegisterEDX();
|
public static readonly RegisterEDX Instance = new RegisterEDX();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterEDX(MemoryAction aAction) {
|
public static implicit operator RegisterEDX(MemoryAction aAction) {
|
||||||
Instance.Move(aAction);
|
Instance.Move(aAction);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterESI : Register32 {
|
public class RegisterESI : Register32 {
|
||||||
public const string Name = "ESI";
|
|
||||||
public static readonly RegisterESI Instance = new RegisterESI();
|
public static readonly RegisterESI Instance = new RegisterESI();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterESI(ElementReference aReference) {
|
public static implicit operator RegisterESI(ElementReference aReference) {
|
||||||
Instance.Move(aReference);
|
Instance.Move(aReference);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,8 @@ using System.Text;
|
||||||
|
|
||||||
namespace Cosmos.IL2CPU.X86.X {
|
namespace Cosmos.IL2CPU.X86.X {
|
||||||
public class RegisterESP : Register32 {
|
public class RegisterESP : Register32 {
|
||||||
public const string Name = "ESP";
|
|
||||||
public static readonly RegisterESP Instance = new RegisterESP();
|
public static readonly RegisterESP Instance = new RegisterESP();
|
||||||
|
|
||||||
public override string ToString() {
|
|
||||||
return Name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static implicit operator RegisterESP(UInt32 aValue) {
|
public static implicit operator RegisterESP(UInt32 aValue) {
|
||||||
Instance.Move(aValue);
|
Instance.Move(aValue);
|
||||||
return Instance;
|
return Instance;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue