mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-21 21:38:52 +00:00
216 lines
9.4 KiB
C#
216 lines
9.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Indy.IL2CPU.Assembler;
|
|
using Indy.IL2CPU.IL.NativeX86.CustomImplementations.System;
|
|
using Indy.IL2CPU.IL.NativeX86.CustomImplementations.System.Diagnostics;
|
|
using Mono.Cecil;
|
|
using CPU = Indy.IL2CPU.Assembler.X86;
|
|
using CPUNative = Indy.IL2CPU.Assembler.NativeX86;
|
|
|
|
namespace Indy.IL2CPU.IL.NativeX86 {
|
|
public class NativeX86OpCodeMap: X86.X86OpCodeMap {
|
|
protected override Type GetCustomMethodImplementationOp() {
|
|
return typeof(NativeX86CustomMethodImplementationOp);
|
|
}
|
|
|
|
protected override Type GetMethodHeaderOp() {
|
|
return typeof(NativeX86MethodHeaderOp);
|
|
}
|
|
|
|
public override MethodReference GetCustomMethodImplementation(string aOrigMethodName, bool aInMetalMode) {
|
|
switch (aOrigMethodName) {
|
|
case "System_Void___System_Console_Clear____": {
|
|
return ConsoleImplRefs.ClearRef;
|
|
}
|
|
case "System_Void___System_Console_WriteLine___System_String___": {
|
|
return ConsoleImplRefs.WriteLineRef;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_RuntimeEngine_InitializeEngine____": {
|
|
return RuntimeEngineImplRefs.InitializeEngineRef;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_RuntimeEngine_FinalizeEngine____": {
|
|
return RuntimeEngineImplRefs.FinalizeEngineRef;
|
|
}
|
|
default:
|
|
return base.GetCustomMethodImplementation(aOrigMethodName, aInMetalMode);
|
|
}
|
|
}
|
|
|
|
public override bool HasCustomAssembleImplementation(string aMethodName, bool aInMetalMode) {
|
|
switch (aMethodName) {
|
|
case "System_Byte___Indy_IL2CPU_IL_X86_CustomImplementations_System_StringImpl_GetByteFromChar___System_Char___": {
|
|
if (aInMetalMode) {
|
|
return true;
|
|
}
|
|
break;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_IDT_LoadArray____": {
|
|
return true;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_IDT_RegisterIDT____": {
|
|
return true;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_GDT_LoadArray____": {
|
|
return true;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_GDT_RegisterGDT____": {
|
|
return true;
|
|
}
|
|
case "System_Void___System_Diagnostics_Debugger_Break____": {
|
|
return true;
|
|
}
|
|
}
|
|
return base.HasCustomAssembleImplementation(aMethodName, aInMetalMode);
|
|
}
|
|
|
|
public override void DoCustomAssembleImplementation(string aMethodName, bool aInMetalMode, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
|
|
switch (aMethodName) {
|
|
case "System_Byte___Indy_IL2CPU_IL_X86_CustomImplementations_System_StringImpl_GetByteFromChar___System_Char___": {
|
|
if (aInMetalMode) {
|
|
DoAssemble_String_GetByteFromChar(aAssembler, aMethodInfo);
|
|
return;
|
|
}
|
|
break;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_IDT_LoadArray____": {
|
|
DoAssemble_IDT_LoadArray(aAssembler, aMethodInfo);
|
|
return;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_IDT_RegisterIDT____": {
|
|
DoAssemble_IDT_RegisterIDT(aAssembler, aMethodInfo);
|
|
return;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_GDT_LoadArray____": {
|
|
DoAssemble_GDT_LoadArray(aAssembler, aMethodInfo);
|
|
return;
|
|
}
|
|
case "System_Void___Indy_IL2CPU_IL_NativeX86_RuntimeEngineImpl_GDT_RegisterGDT____": {
|
|
DoAssemble_GDT_RegisterGDT(aAssembler, aMethodInfo);
|
|
return;
|
|
}
|
|
case "System_Void___System_Diagnostics_Debugger_Break____": {
|
|
aAssembler.Add(new Literal("xchg bx, bx"));
|
|
return;
|
|
}
|
|
}
|
|
base.DoCustomAssembleImplementation(aMethodName, aInMetalMode, aAssembler, aMethodInfo);
|
|
}
|
|
|
|
private void DoAssemble_IDT_RegisterIDT(Assembler.Assembler aAssembler, MethodInformation aInfo) {
|
|
TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName);
|
|
FieldDefinition xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mIDTPointer");
|
|
string xPointerFieldName;
|
|
Engine.QueueStaticField(xFieldDef, out xPointerFieldName);
|
|
MethodDefinition xTheMethod = Engine.GetMethodDefinition(xRuntimeEngineTypeDef, "IDT_SetHandler", "System.Byte", "System.UInt32", "System.UInt16", xRuntimeEngineTypeDef.FullName + "/IDTEntryStruct/FlagsEnum");
|
|
Engine.QueueMethod(xTheMethod);
|
|
mIDTSetHandlerMethodName = new Label(xTheMethod).Name;
|
|
aAssembler.Add(new CPU.Call("___________REGISTER___ISRS_____"));
|
|
aAssembler.Add(new CPU.Move("eax", xPointerFieldName));
|
|
aAssembler.Add(new CPUNative.Lidt("eax"));
|
|
}
|
|
|
|
private string mIDTSetHandlerMethodName;
|
|
|
|
private void DoAssemble_IDT_LoadArray(Indy.IL2CPU.Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
|
|
//aAssembler.Add(new Literal("XCHG BX, BX "));
|
|
TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName);
|
|
FieldDefinition xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mIDTEntries");
|
|
string xFieldName = Assembler.DataMember.GetStaticFieldName(xFieldDef);
|
|
string xFieldData = "0,0,0,0,2,0,0,0,0,0,0,0";
|
|
for (int i = 0; i < 256; i++) {
|
|
xFieldData += ",0,0,0,0,0,0,0,0";
|
|
}
|
|
aAssembler.DataMembers.RemoveAll(delegate(DataMember aItem) {
|
|
return aItem.Name == xFieldName;
|
|
});
|
|
aAssembler.DataMembers.Add(new DataMember(xFieldName, "db", xFieldData));
|
|
xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mIDTPointer");
|
|
string xPointerFieldName;
|
|
Engine.QueueStaticField(xFieldDef, out xPointerFieldName);
|
|
aAssembler.Add(new CPU.Move("eax", xPointerFieldName));
|
|
aAssembler.Add(new CPU.Move("word [eax]", "0x" + ((8 * 1) - 1).ToString("X")));
|
|
aAssembler.Add(new CPU.Move("dword [eax + 2]", xFieldName));
|
|
}
|
|
|
|
private static void DoAssemble_String_GetByteFromChar(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
|
|
X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddress);
|
|
}
|
|
|
|
public override void PostProcess(Indy.IL2CPU.Assembler.Assembler aAssembler) {
|
|
base.PostProcess(aAssembler);
|
|
X86.X86MethodHeaderOp.AssembleHeader(aAssembler, "___________REGISTER___ISRS_____", 0);
|
|
for (int i = 0; i < aAssembler.Instructions.Count; i++) {
|
|
Label xLbl = aAssembler.Instructions[i] as Label;
|
|
if (xLbl == null) {
|
|
continue;
|
|
}
|
|
if (!xLbl.Name.EndsWith(NativeX86MethodHeaderOp.ISR_Suffix)) {
|
|
continue;
|
|
}
|
|
Literal xLiteral = aAssembler.Instructions[i + 1] as Literal;
|
|
if (xLiteral == null)
|
|
continue;
|
|
byte theNum;
|
|
if (!Byte.TryParse(xLiteral.Data.Substring(1), out theNum)) {
|
|
continue;
|
|
}
|
|
aAssembler.Add(new CPU.Push("0x" + theNum.ToString("X")));
|
|
aAssembler.Add(new CPU.Push(xLbl.Name));
|
|
aAssembler.Add(new CPU.Push("0x08"));
|
|
aAssembler.Add(new CPU.Push("0x8E"));
|
|
aAssembler.Add(new CPU.Call(mIDTSetHandlerMethodName));
|
|
}
|
|
X86.X86MethodFooterOp.AssembleFooter(false, aAssembler, 0, 0);
|
|
}
|
|
|
|
private void DoAssemble_GDT_RegisterGDT(Assembler.Assembler aAssembler, MethodInformation aInfo) {
|
|
TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName);
|
|
FieldDefinition xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mGDTPointer");
|
|
string xPointerFieldName;
|
|
Engine.QueueStaticField(xFieldDef, out xPointerFieldName);
|
|
//aAssembler.Add(new Literal("XCHG BX, BX "));
|
|
aAssembler.Add(new CPU.Move("eax", xPointerFieldName));
|
|
aAssembler.Add(new CPUNative.Lgdt("eax"));
|
|
aAssembler.Add(new CPU.Move("ax", "0x10"));
|
|
aAssembler.Add(new CPU.Move("ds", "ax"));
|
|
aAssembler.Add(new CPU.Move("es", "ax"));
|
|
aAssembler.Add(new CPU.Move("fs", "ax"));
|
|
aAssembler.Add(new CPU.Move("gs", "ax"));
|
|
aAssembler.Add(new CPU.Move("ss", "ax"));
|
|
aAssembler.Add(new CPU.JumpAlways("0x8:___GDT_REGISTERGDT____FLUSH2"));
|
|
aAssembler.Add(new Label("___GDT_REGISTERGDT____FLUSH2"));
|
|
|
|
}
|
|
|
|
private void DoAssemble_GDT_LoadArray(Indy.IL2CPU.Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
|
|
TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName);
|
|
string xFieldName = "_______GDT____ENTRIES____";
|
|
string xFieldData = "0,0,2,0,";
|
|
// system segment
|
|
xFieldData += "0,0,0,0,";
|
|
// code
|
|
xFieldData += "1111111111111111b,";
|
|
xFieldData += "0000000000000000b,";
|
|
xFieldData += "0000000010011010b,";
|
|
xFieldData += "1100111100000000b,";
|
|
// data
|
|
xFieldData += "1111111111111111b,";
|
|
xFieldData += "0000000000000000b,";
|
|
xFieldData += "0000000010010010b,";
|
|
xFieldData += "1100111100000000b";
|
|
aAssembler.DataMembers.RemoveAll(delegate(DataMember aItem) {
|
|
return aItem.Name == xFieldName;
|
|
});
|
|
aAssembler.DataMembers.Add(new DataMember(xFieldName, "dw", xFieldData));
|
|
FieldDefinition xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mGDTPointer");
|
|
string xPointerFieldName;
|
|
Engine.QueueStaticField(xFieldDef, out xPointerFieldName);
|
|
aAssembler.Add(new CPU.Move("eax", xPointerFieldName));
|
|
//aAssembler.Add(new Literal("XCHG BX, BX "));
|
|
aAssembler.Add(new CPU.Move("word [eax]", "0x" + ((8 * 3) - 1).ToString("X")));
|
|
aAssembler.Add(new CPU.Move("dword [eax + 2]", xFieldName));
|
|
}
|
|
}
|
|
}
|