using XSharp.Assembler;
using IL2CPU.API;
using IL2CPU.API.Attribs;
using XSharp;
namespace Cosmos.Debug.Kernel.Plugs.Asm
{
[Plug(Target = typeof(Cosmos.Debug.Kernel.Debugger))]
public static class Debugger
{
[PlugMethod(Assembler = typeof(DebugBreak))]
public static void Break(Cosmos.Debug.Kernel.Debugger aThis) { }
//[PlugMethod(Assembler = typeof(DebugActualSend))]
//public static unsafe void ActualSend(int aLength, char* aText) { }
[PlugMethod(Assembler = typeof(DebugDoSend))]
public static void DoSend(string aText) { }
[PlugMethod(Assembler = typeof(DebugDoSendNumber))]
public static void DoSendNumber(int aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendNumber))]
public static void DoSendNumber(uint aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendLongNumber))]
public static void DoSendNumber(long aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendLongNumber))]
public static void DoSendNumber(ulong aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendComplexNumber))]
public static void DoSendNumber(float aNumber) { }
[PlugMethod(Assembler = typeof(DebugDoSendComplexLongNumber))]
public static void DoSendNumber(double aNumber) { }
[PlugMethod(Assembler = typeof(DebugSendMessageBox))]
public static unsafe void SendMessageBox(Kernel.Debugger aThis, int aLength, char* aText) { }
[PlugMethod(Assembler = typeof(DebugSendPtr))]
public static unsafe void SendPtr(Kernel.Debugger aThis, object aPtr) { }
[PlugMethod(Assembler = typeof(DebugSendChannelCommand))]
public static unsafe void SendChannelCommand(byte aChannel, byte aCommand, int aByteCount, byte* aData) { }
[PlugMethod(Assembler = typeof(DebugSendChannelCommandNoData))]
public static unsafe void SendChannelCommand(byte aChannel, byte aCommand) { }
[PlugMethod(Assembler = typeof(DoBochsBreak))]
public static void DoBochsBreak()
{
}
[Inline]
public static void SendKernelPanic(uint id)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendKernelPanic");
new LiteralAssemblerCode("add ESP, 4");
new LiteralAssemblerCode("%endif");
}
[PlugMethod(Assembler = typeof(DoRealHalt))]
public static void DoRealHalt()
{
}
//[PlugMethod(Assembler = typeof(DebugTraceOff))]
//public static void TraceOff() { }
//[PlugMethod(Assembler = typeof(DebugTraceOn))]
//public static void TraceOn() { }
}
//TODO: Make a new plug attrib that assembly plug methods dont need
// an empty stub also, its just extra fluff - although they allow signature matching
// Maybe could merge this into the same unit as the plug
public class DebugTraceOff : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_TraceOff");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
public class DebugTraceOn : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_TraceOn");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
///
/// Assembler for SendChannelCommand
///
///
/// AL contains channel
/// BL contains command
/// ECX contains number of bytes to send as command data
/// ESI contains data start pointer
///
public class DebugSendChannelCommand : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("mov AL, [EBP + 20]");
new LiteralAssemblerCode("mov BL, [EBP + 16]");
new LiteralAssemblerCode("mov ECX, [EBP + 12]");
new LiteralAssemblerCode("mov ESI, [EBP + 8]");
new LiteralAssemblerCode("call DebugStub_SendCommandOnChannel");
new LiteralAssemblerCode("%endif");
}
}
///
/// Assembler for SendChannelCommandNoData
///
///
/// AL contains channel
/// BL contains command
/// ECX contains number of bytes to send as command data
/// ESI contains data start pointer
///
public class DebugSendChannelCommandNoData : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("mov AL, [EBP + 12]");
new LiteralAssemblerCode("mov BL, [EBP + 8]");
new LiteralAssemblerCode("mov ECX, 0");
new LiteralAssemblerCode("mov ESI, EBP");
new LiteralAssemblerCode("call DebugStub_SendCommandOnChannel");
new LiteralAssemblerCode("%endif");
}
}
public class DebugBreak : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("mov dword [DebugStub_DebugBreakOnNextTrace], 1");
new LiteralAssemblerCode("%endif");
}
}
///
/// Assembler for DoSend
///
///
/// EBP + 12 contains length
/// EBP + 8 contains first char pointer
///
public class DebugDoSend : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
XS.Label(".BeforeArgumentsPrepare");
new LiteralAssemblerCode("mov EBX, [EBP + 12]");
new LiteralAssemblerCode("push dword [EBX + 12]");
new LiteralAssemblerCode("add EBX, 16");
new LiteralAssemblerCode("push dword EBX");
XS.Label(".BeforeCall");
new LiteralAssemblerCode("Call DebugStub_SendText");
new LiteralAssemblerCode("add ESP, 8");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendNumber : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendSimpleNumber");
new LiteralAssemblerCode("add ESP, 4");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendLongNumber : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 12]");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendSimpleLongNumber");
new LiteralAssemblerCode("add ESP, 8");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendComplexNumber : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendComplexNumber");
new LiteralAssemblerCode("add ESP, 4");
new LiteralAssemblerCode("%endif");
}
}
public class DebugDoSendComplexLongNumber : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("push dword [EBP + 12]");
new LiteralAssemblerCode("push dword [EBP + 8]");
new LiteralAssemblerCode("Call DebugStub_SendComplexLongNumber");
new LiteralAssemblerCode("add ESP, 8");
new LiteralAssemblerCode("%endif");
}
}
public class DebugSendMessageBox : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_SendMessageBox");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
public class DebugSendPtr : AssemblerMethod
{
public override void AssembleNew(XSharp.Assembler.Assembler aAssembler, object aMethodInfo)
{
new LiteralAssemblerCode("%ifdef DEBUGSTUB");
new LiteralAssemblerCode("pushad");
new LiteralAssemblerCode("Call DebugStub_SendPtr");
new LiteralAssemblerCode("popad");
new LiteralAssemblerCode("%endif");
}
}
public class DoBochsBreak : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
XS.Exchange(XSRegisters.BX, XSRegisters.BX);
}
}
public class DoRealHalt : AssemblerMethod
{
public override void AssembleNew(Assembler aAssembler, object aMethodInfo)
{
XS.DisableInterrupts();
// bochs magic break
//Exchange(BX, BX);
XS.Halt();
}
}
}