Cosmos/source/Indy.IL2CPU.IL.X86.Native/NativeOpCodeMap.cs
2007-10-29 10:04:17 +00:00

286 lines
No EOL
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Indy.IL2CPU.Assembler;
using Indy.IL2CPU.IL.X86.Native.CustomImplementations.System;
using Indy.IL2CPU.IL.X86.Native.CustomImplementations.System.Diagnostics;
using Mono.Cecil;
using CPU = Indy.IL2CPU.Assembler.X86;
using CPUNative = Indy.IL2CPU.Assembler.X86.Native;
namespace Indy.IL2CPU.IL.X86.Native {
public class NativeOpCodeMap: X86.X86OpCodeMap {
protected override Type GetCustomMethodImplementationOp() {
return typeof(NativeCustomMethodImplementationOp);
}
protected override Type GetMethodFooterOp() {
return typeof(NativeMethodFooterOp);
}
protected override Type GetMethodHeaderOp() {
return typeof(NativeMethodHeaderOp);
}
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___System_Console_Write___System_String___": {
return ConsoleImplRefs.WriteRef;
}
case "System_Void___System_Diagnostics_Debug_WriteLine___System_String___": {
return DebugImplRefs.WriteLineRef;
}
case "System_Void___System_Diagnostics_Debug_WriteLineIf___System_Boolean__System_String___": {
return DebugImplRefs.WriteLineIfRef;
}
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_X86_Native_RuntimeEngineImpl_IDT_LoadArray____": {
return true;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IDT_RegisterIDT____": {
return true;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_GDT_LoadArray____": {
return true;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_GDT_RegisterGDT____": {
return true;
}
case "System_Void___System_Diagnostics_Debugger_Break____": {
return true;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IO_WriteToPort___System_UInt16__System_Byte__": {
return true;
}
case "System_Byte___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IO_ReadFromPort___System_UInt16__": {
return true;
}
case "System_Void___Cosmos_Kernel_ConsoleDrv_TestIDT____": {
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_X86_Native_RuntimeEngineImpl_IDT_LoadArray____": {
DoAssemble_IDT_LoadArray(aAssembler, aMethodInfo);
return;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IDT_RegisterIDT____": {
DoAssemble_IDT_RegisterIDT(aAssembler, aMethodInfo);
return;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_GDT_LoadArray____": {
DoAssemble_GDT_LoadArray(aAssembler, aMethodInfo);
return;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_GDT_RegisterGDT____": {
DoAssemble_GDT_RegisterGDT(aAssembler, aMethodInfo);
return;
}
case "System_Void___System_Diagnostics_Debugger_Break____": {
//aAssembler.Add(new Literal("xchg bx, bx"));
return;
}
case "System_Void___Cosmos_Kernel_ConsoleDrv_TestIDT____": {
aAssembler.Add(new Literal("xchg bx, bx"));
aAssembler.Add(new Literal("int 3"));
break;
}
case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IO_WriteToPort___System_UInt16__System_Byte__": {
IL.X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size);
aAssembler.Add(new CPU.Pop("eax"));
IL.X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[1].VirtualAddresses, aMethodInfo.Arguments[1].Size);
aAssembler.Add(new CPU.Pop("ecx"));
aAssembler.Add(new CPUNative.Out("ax", "cl"));
break;
}
case "System_Byte___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IO_ReadFromPort___System_UInt16__": {
IL.X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size);
aAssembler.Add(new CPU.Pop("ecx"));
aAssembler.Add(new CPU.Move("eax", "0"));
aAssembler.Add(new CPUNative.In("ecx", "al"));
break;
}
}
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 Literal("XCHG BX, BX "));
aAssembler.Add(new CPUNative.Cli());
aAssembler.Add(new CPUNative.Lidt("eax"));
aAssembler.Add(new CPUNative.Sti());
}
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 CPU.Move("eax", xPointerFieldName));
//aAssembler.Add(new Literal("XCHG BX, BX "));
aAssembler.Add(new CPUNative.Cli());
aAssembler.Add(new CPUNative.Lgdt("eax"));
aAssembler.Add(new CPU.Move("eax", "0x8"));
//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("0x0008:flush____gdt______table"));
aAssembler.Add(new Label("flush____gdt______table"));
//aAssembler.Add(new CPUNative.Sti());
}
private string mIDTSetHandlerMethodName;
private void DoAssemble_GDT_LoadArray(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName);
FieldDefinition xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mGDTEntries");
string xFieldName = Assembler.DataMember.GetStaticFieldName(xFieldDef);
string xFieldData = "0,0,0,0,2,0,0,0,1,0,0,0";
for (int i = 0; i < 3; 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, "dd", xFieldName));
aAssembler.DataMembers.Add(new DataMember(xFieldName + "___Contents", "db", xFieldData));
xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mGDTPointer");
string xPointerFieldName;
Engine.QueueStaticField(xFieldDef, out xPointerFieldName);
aAssembler.Add(new CPU.Move("eax", xPointerFieldName));
aAssembler.Add(new CPU.Move("word [eax]", "0x" + ((8 * 3) - 1).ToString("X")));
aAssembler.Add(new CPU.Move("ecx", xFieldName));
aAssembler.Add(new CPU.Add("ecx", "0xC"));
aAssembler.Add(new CPU.Move("dword [eax + 2]", "ecx"));
}
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);
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;
FieldDefinition xFieldDef = xRuntimeEngineTypeDef.Fields.GetField("mIDTEntries");
string xFieldName = Assembler.DataMember.GetStaticFieldName(xFieldDef);
string xFieldData = "0,0,0,0,2,0,0,0,1,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, "dd", xFieldName + "___Contents"));
aAssembler.DataMembers.Add(new DataMember(xFieldName + "___Contents", "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 * 256) - 1).ToString("X")));
aAssembler.Add(new CPU.Move("ecx", xFieldName));
aAssembler.Add(new CPU.Add("ecx", "0xC"));
aAssembler.Add(new CPU.Move("dword [eax + 2]", "ecx"));
}
private static void DoAssemble_String_GetByteFromChar(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) {
X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size);
}
public override void PostProcess(Indy.IL2CPU.Assembler.Assembler aAssembler) {
base.PostProcess(aAssembler);
return;
TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName);
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;
X86.X86MethodHeaderOp.AssembleHeader(aAssembler, "___________REGISTER___ISRS_____", new int[0]);
string xInterruptHandlerLabel = new Label(Engine.GetMethodDefinition(Engine.GetTypeDefinition("Indy.IL2CPU.IL.X86.Native", "Indy.IL2CPU.IL.X86.Native.RuntimeEngineImpl"), "InterruptHandler", "System.Byte", "System.Byte")).Name;
int[] xInterruptsWithParam = new int[] { 8, 10, 11, 12, 13, 14 };
for (int i = 0; i < 256; i++) {
aAssembler.Add(new CPU.Push("0x" + i.ToString("X")));
//if (i == 3) {
// aAssembler.Add(new Literal("xchg bx, bx"));
//}
aAssembler.Add(new CPU.Push("____INTERRUPT_HANDLER___" + i));
aAssembler.Add(new CPU.Push("0x08"));
aAssembler.Add(new CPU.Push("0x8E"));
aAssembler.Add(new CPU.Call(mIDTSetHandlerMethodName));
}
X86.X86MethodFooterOp.AssembleFooter(0, aAssembler, new int[0], 0);
for (int j = 0; j < 256; j++) {
aAssembler.Add(new Label("____INTERRUPT_HANDLER___" + j));
aAssembler.Add(new CPUNative.Cli());
aAssembler.Add(new CPU.Push(j.ToString()));
if (!xInterruptsWithParam.Contains(j)) {
aAssembler.Add(new CPU.Push("0"));
}
aAssembler.Add(new CPU.JumpAlways("____INTERRUPT_HANDLER___GENERIC"));
}
aAssembler.Add(new Label("____INTERRUPT_HANDLER___GENERIC"));
aAssembler.Add(new CPUNative.Pushad());
aAssembler.Add(new CPU.Move("ax", "ds"));
aAssembler.Add(new CPU.Push("eax"));
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.Call(xInterruptHandlerLabel));
aAssembler.Add(new CPU.Pop("ebx"));
aAssembler.Add(new CPU.Move("ds", "bx"));
aAssembler.Add(new CPU.Move("es", "bx"));
aAssembler.Add(new CPU.Move("fs", "bx"));
aAssembler.Add(new CPU.Move("gs", "bx"));
aAssembler.Add(new CPUNative.Popad());
aAssembler.Add(new CPUNative.Sti());
aAssembler.Add(new CPUNative.IRet());
}
}
}