public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xSource = aOpCode.StackPopTypes[0]; var xSourceSize = SizeOfType(xSource); var xSourceIsFloat = TypeIsFloat(xSource); switch (xSourceSize) { case 1: case 2: case 4: XS.Pop(XSRegisters.EAX); XS.SignExtendAX(XSRegisters.RegisterSize.Int32); XS.Push(XSRegisters.EDX); XS.Push(XSRegisters.EAX); break; case 8: XS.Noop(); break; default: //EmitNotImplementedException( Assembler, GetServiceProvider(), "Conv_Ovf_I8: SourceSize " + xSource + " not supported!", mCurLabel, mMethodInformation, mCurOffset, mNextLabel ); throw new NotImplementedException(); } }
public static void DoExecute(uint xSourceSize, bool SourceIsSigned, Assembler assembler, _MethodInfo aMethod, ILOpCode aOpCode) { var xBaseLabel = GetLabel(aMethod, aOpCode) + "."; var xSuccessLabel = xBaseLabel + "Success"; switch (xSourceSize) { case 1: case 2: case 4: XS.Pop(EAX); XS.SignExtendAX(RegisterSize.Int32); XS.Push(EDX); XS.Push(EAX); break; case 8: if (SourceIsSigned) { XS.Set(EAX, ESP, sourceIsIndirect: true); XS.And(EAX, 0b1000000000000000000000000000); XS.Compare(EAX, 0); XS.Jump(XSharp.Assembler.x86.ConditionalTestEnum.Equal, xSuccessLabel); XS.Pop(EAX); // remove long from stack XS.Pop(EAX); Call.DoExecute(assembler, aMethod, ExceptionHelperRefs.ThrowOverflowExceptionRef, aOpCode, xSuccessLabel, false); XS.Label(xSuccessLabel); } else { XS.Noop(); } break; default: throw new NotImplementedException(); } }
public override void AssembleNew(Assembler aAssembler, object aMethodInfo) { // IDT is already initialized but just for base hooks, and asm only. // ie Int 1, 3 and GPF // This routine updates the IDT now that we have C# running to allow C# hooks to handle // the other INTs // We are updating the IDT, disable interrupts XS.ClearInterruptFlag(); for (int i = 0; i < 256; i++) { // These are already mapped, don't remap them. // Maybe in the future we can look at ones that are present // and skip them, but some we may want to overwrite anyways. if (i == 1 || i == 3) { continue; } XS.Set(EAX, "__ISR_Handler_" + i.ToString("X2")); XS.Set("_NATIVE_IDT_Contents", AL, destinationDisplacement: (i * 8) + 0); XS.Set("_NATIVE_IDT_Contents", AH, destinationDisplacement: (i * 8) + 1); XS.Set("_NATIVE_IDT_Contents", 0x8, destinationDisplacement: (i * 8) + 2, size: RegisterSize.Byte8); XS.Set("_NATIVE_IDT_Contents", 0x8E, destinationDisplacement: (i * 8) + 5, size: RegisterSize.Byte8); XS.ShiftRight(EAX, 16); XS.Set("_NATIVE_IDT_Contents", AL, destinationDisplacement: (i * 8) + 6); XS.Set("_NATIVE_IDT_Contents", AH, destinationDisplacement: (i * 8) + 7); } XS.Jump("__AFTER__ALL__ISR__HANDLER__STUBS__"); var xInterruptsWithParam = new[] { 8, 10, 11, 12, 13, 14 }; for (int j = 0; j < 256; j++) { XS.Label("__ISR_Handler_" + j.ToString("X2")); XS.Call("__INTERRUPT_OCCURRED__"); if (Array.IndexOf(xInterruptsWithParam, j) == -1) { XS.Push(0); } XS.Push((uint)j); if (j != 0x20) { XS.PushAllRegisters(); XS.Sub(ESP, 4); XS.Set(EAX, ESP); // preserve old stack address for passing to interrupt handler // store floating point data XS.And(ESP, 0xfffffff0); // fxsave needs to be 16-byte alligned XS.Sub(ESP, 512); // fxsave needs 512 bytes XS.SSE.FXSave(ESP, isIndirect: true); // save the registers XS.Set(EAX, ESP, destinationIsIndirect: true); XS.Push(EAX); // XS.Push(EAX); // pass old stack address (pointer to InterruptContext struct) to the interrupt handler XS.JumpToSegment(8, "__ISR_Handler_" + j.ToString("X2") + "_SetCS"); XS.Label("__ISR_Handler_" + j.ToString("X2") + "_SetCS"); MethodBase xHandler = GetInterruptHandler((byte)j); if (xHandler == null) { xHandler = GetMethodDef(typeof(Cosmos.Core.INTs).Assembly, typeof(Cosmos.Core.INTs).FullName, "HandleInterrupt_Default", true); } XS.Call(LabelName.Get(xHandler)); XS.Pop(EAX); XS.SSE.FXRestore(ESP, isIndirect: true); XS.Set(ESP, EAX); // this restores the stack for the FX stuff, except the pointer to the FX data XS.Add(ESP, 4); // "pop" the pointer XS.PopAllRegisters(); } else { new LiteralAssemblerCode("pushad"); new LiteralAssemblerCode("mov eax, ds"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov eax, es"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov eax, fs"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov eax, gs"); new LiteralAssemblerCode("push eax"); new LiteralAssemblerCode("mov ax, 0x10"); new LiteralAssemblerCode("mov ds, ax"); new LiteralAssemblerCode("mov es, ax"); new LiteralAssemblerCode("mov fs, ax"); new LiteralAssemblerCode("mov gs, ax"); new LiteralAssemblerCode("mov eax, esp"); XS.Set("static_field__Cosmos_Core_INTs_mStackContext", EAX, destinationIsIndirect: true); XS.Call(LabelName.Get(GetMethodDef(typeof(Cosmos.Core.Processing.ProcessorScheduler).Assembly, typeof(Cosmos.Core.Processing.ProcessorScheduler).FullName, "SwitchTask", true))); XS.Set(EAX, "static_field__Cosmos_Core_INTs_mStackContext", sourceIsIndirect: true); new LiteralAssemblerCode("mov esp, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov gs, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov fs, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov es, eax"); new LiteralAssemblerCode("pop eax"); new LiteralAssemblerCode("mov ds, eax"); new LiteralAssemblerCode("popad"); } XS.Add(ESP, 8); XS.Label("__ISR_Handler_" + j.ToString("X2") + "_END"); XS.InterruptReturn(); } XS.Label("__INTERRUPT_OCCURRED__"); XS.Return(); XS.Label("__AFTER__ALL__ISR__HANDLER__STUBS__"); XS.Noop(); XS.Set(EAX, EBP, sourceDisplacement: 8); XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.Zero, ".__AFTER_ENABLE_INTERRUPTS"); // reload interrupt list XS.Set(EAX, "_NATIVE_IDT_Pointer"); XS.Set(AsmMarker.Labels[AsmMarker.Type.Processor_IntsEnabled], 1, destinationIsIndirect: true, size: RegisterSize.Byte8); XS.LoadIdt(EAX, isIndirect: true); // Reenable interrupts XS.EnableInterrupts(); XS.Label(".__AFTER_ENABLE_INTERRUPTS"); }
public override void AssembleNew(object aAssembler, object aMethodInfo) { XS.Mov(XSRegisters.BL, 0xa8); XS.Call("send_mouse_cmd"); XS.Call("mouse_read"); XS.Noop(); XS.Mov(XSRegisters.BL, 0x20); XS.Call("send_mouse_cmd"); XS.Call("mouse_read"); XS.Or(XSRegisters.AL, 3); XS.Mov(XSRegisters.BL, 0x60); XS.Push(XSRegisters.EAX); XS.Call("send_mouse_cmd"); XS.Pop(XSRegisters.EAX); XS.Call("mouse_write"); XS.Noop(); XS.Mov(XSRegisters.BL, 0xd4); XS.Call("send_mouse_cmd"); XS.Mov(XSRegisters.AL, 0xf4); XS.Call("mouse_write"); XS.Call("mouse_read"); #region mouse_read XS.Label("mouse_read"); { XS.Push(XSRegisters.ECX); XS.Push(XSRegisters.EDX); XS.Mov(XSRegisters.ECX, 0xffff); XS.Label("mouse_read_loop"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 1); XS.Jump(ConditionalTestEnum.NotZero, "mouse_read_ready"); new Loop { DestinationLabel = "mouse_read_loop" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_read_exit"); } XS.Label("mouse_read_ready"); { XS.Push(XSRegisters.ECX); XS.Mov(XSRegisters.ECX, 32); } XS.Label("mouse_read_delay"); { new Loop { DestinationLabel = "mouse_read_delay" }; XS.Pop(XSRegisters.ECX); new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x60, Size = 8 }; XS.Xor(XSRegisters.AH, XSRegisters.RegistersEnum.AH); } XS.Label("mouse_read_exit"); { XS.Pop(XSRegisters.EDX); XS.Pop(XSRegisters.ECX); XS.Return(); } } #endregion #region mouse_write XS.Label("mouse_write"); { XS.Push(XSRegisters.ECX); XS.Push(XSRegisters.EDX); XS.Mov(XSRegisters.BH, XSRegisters.RegistersEnum.AL); XS.Mov(XSRegisters.ECX, 0xffff); XS.Label("mouse_write_loop1"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 32); XS.Jump(ConditionalTestEnum.Zero, "mouse_write_ok1"); new Loop { DestinationLabel = "mouse_write_loop1" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_write_exit"); } XS.Label("mouse_write_ok1"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x60, Size = 8 }; XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_write_loop"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.Zero, "mouse_write_ok"); new Loop { DestinationLabel = "mouse_write_loop" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_write_exit"); } XS.Label("mouse_write_ok"); { XS.Mov(XSRegisters.AL, XSRegisters.RegistersEnum.BH); new Out2Port { DestinationValue = 0x60, SourceReg = RegistersEnum.AL, Size = 8 }; XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_write_loop3"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.Zero, "mouse_write_ok3"); new Loop { DestinationLabel = "mouse_write_loop3" }; XS.Mov(XSRegisters.AH, 1); XS.Jump("mouse_write_exit"); } XS.Label("mouse_write_ok3"); { XS.Mov(XSRegisters.AH, 0x08); } XS.Label("mouse_write_loop4"); { XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_write_loop5"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 1); XS.Jump(ConditionalTestEnum.NotZero, "mouse_write_ok4"); new Loop { DestinationLabel = "mouse_write_loop5" }; XS.Dec(XSRegisters.AH); XS.Jump(ConditionalTestEnum.NotZero, "mouse_write_loop4"); } XS.Label("mouse_write_ok4"); { XS.Xor(XSRegisters.AH, XSRegisters.RegistersEnum.AH); } XS.Label("mouse_write_exit"); { XS.Pop(XSRegisters.EDX); XS.Pop(XSRegisters.ECX); XS.Return(); } } #endregion #region send_mouse_cmd XS.Label("send_mouse_cmd"); { XS.Mov(XSRegisters.ECX, 0xffff); XS.Label("mouse_cmd_wait"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 2); XS.Jump(ConditionalTestEnum.Zero, "mouse_cmd_send"); new Loop { DestinationLabel = "mouse_cmd_wait" }; XS.Jump("mouse_cmd_error"); } XS.Label("mouse_cmd_send"); { XS.Mov(XSRegisters.AL, XSRegisters.RegistersEnum.BL); new Out2Port { #if DebugMouse SourceValue = 0x64, DestinationReg = RegistersEnum.AL, #else DestinationValue = 0x64, SourceReg = RegistersEnum.AL, #endif Size = 8 }; XS.Mov(XSRegisters.ECX, 0xffff); } XS.Label("mouse_cmd_accept"); { new In2Port { DestinationReg = RegistersEnum.AL, SourceValue = 0x64, Size = 8 }; XS.Test(XSRegisters.AL, 0x02); XS.Jump(ConditionalTestEnum.Zero, "mouse_cmd_ok"); new Loop { DestinationLabel = "mouse_cmd_accept" }; } XS.Label("mouse_cmd_error"); { XS.Mov(XSRegisters.AH, 0x01); XS.Jump("mouse_cmd_exit"); } XS.Label("mouse_cmd_ok"); { XS.Xor(XSRegisters.AH, XSRegisters.RegistersEnum.AH); } XS.Label("mouse_cmd_exit"); { XS.Return(); } } #endregion }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { XS.Comment("Readonly - for now do nothing"); XS.Noop(); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { XS.Noop(); }