using System; using System.Linq; using Cosmos.Assembler; using Cosmos.Assembler.x86; namespace Cosmos.Debug.DebugStub { public class CmdSend : Cosmos.Assembler.Code { public CmdSend(Assembler.Assembler aAssembler) : base(aAssembler) {} public override void Assemble() { new Comment("X#: Group DebugStub"); new Comment("X#: procedure SendRegisters {"); new LiteralAssemblerCode("DebugStub_SendRegisters:"); new LiteralAssemblerCode("; Send the actual started signal"); new Comment("X#: AL = #Ds2Vs_Registers"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Registers"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new Comment("X#: ESI = .PushAllPtr"); new LiteralAssemblerCode("Mov ESI, [DebugStub_PushAllPtr]"); new Comment("X#: ECX = 32"); new LiteralAssemblerCode("Mov ECX, 32"); new Comment("X#: ComWriteX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteX"); new Comment("X#: ESI = @.CallerESP"); new LiteralAssemblerCode("Mov ESI, DebugStub_CallerESP"); new Comment("X#: ComWrite32()"); new LiteralAssemblerCode("Call DebugStub_ComWrite32"); new Comment("X#: ESI = @.CallerEIP"); new LiteralAssemblerCode("Mov ESI, DebugStub_CallerEIP"); new Comment("X#: ComWrite32()"); new LiteralAssemblerCode("Call DebugStub_ComWrite32"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendRegisters_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendFrame {"); new LiteralAssemblerCode("DebugStub_SendFrame:"); new Comment("X#: AL = #Ds2Vs_Frame"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Frame"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new Comment("X#: EAX = 32"); new LiteralAssemblerCode("Mov EAX, 32"); new Comment("X#: ComWriteAX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAX"); new Comment("X#: ESI = .CallerEBP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerEBP]"); new LiteralAssemblerCode("; Dont transmit EIP or old EBP"); new Comment("X#: ESI + 8"); new LiteralAssemblerCode("Add ESI, 8"); new Comment("X#: ECX = 32"); new LiteralAssemblerCode("Mov ECX, 32"); new Comment("X#: ComWriteX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteX"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendFrame_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendStack {"); new LiteralAssemblerCode("DebugStub_SendStack:"); new Comment("X#: AL = #Ds2Vs_Stack"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Stack"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; Send size of bytes"); new Comment("X#: ESI = .CallerESP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerESP]"); new Comment("X#: EAX = .CallerEBP"); new LiteralAssemblerCode("Mov EAX, [DebugStub_CallerEBP]"); new Comment("X#: EAX - ESI"); new LiteralAssemblerCode("Sub EAX, ESI"); new Comment("X#: ComWriteAX()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAX"); new LiteralAssemblerCode("; Send actual bytes"); new LiteralAssemblerCode("; "); new LiteralAssemblerCode("; Need to reload ESI, WriteAXToCompPort modifies it"); new Comment("X#: ESI = .CallerESP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerESP]"); new LiteralAssemblerCode("; TODO While"); new Comment("X#: SendByte:"); new LiteralAssemblerCode("DebugStub_SendStack_SendByte:"); new Comment("X#: if ESI = .CallerEBP exit"); new LiteralAssemblerCode("Cmp ESI, [DebugStub_CallerEBP]"); new LiteralAssemblerCode("JE DebugStub_SendStack_Exit"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new Comment("X#: goto SendByte"); new LiteralAssemblerCode("Jp DebugStub_SendStack_SendByte"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendStack_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendMethodContext2 {"); new LiteralAssemblerCode("DebugStub_SendMethodContext2:"); new LiteralAssemblerCode("; sends a stack value"); new LiteralAssemblerCode("; Serial Params:"); new LiteralAssemblerCode("; 1: x32 - offset relative to EBP"); new LiteralAssemblerCode("; 2: x32 - size of data to send"); new LiteralAssemblerCode("; [XSharp(PreserveStack = true)]"); new Comment("X#: AL = #Ds2Vs_MethodContext"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_MethodContext"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; offset relative to ebp"); new LiteralAssemblerCode("; size of data to send"); new Comment("X#: ComReadEAX()"); new LiteralAssemblerCode("Call DebugStub_ComReadEAX"); new Comment("X#: ECX = EAX"); new LiteralAssemblerCode("Mov ECX, EAX"); new Comment("X#: ComReadEAX()"); new LiteralAssemblerCode("Call DebugStub_ComReadEAX"); new LiteralAssemblerCode("; now ECX contains size of data (count)"); new LiteralAssemblerCode("; EAX contains relative to EBP"); new Comment("X#: ESI = .CallerEBP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerEBP]"); new Comment("X#: ESI + EAX"); new LiteralAssemblerCode("Add ESI, EAX"); new LiteralAssemblerCode("; TODO While"); new Comment("X#: SendByte:"); new LiteralAssemblerCode("DebugStub_SendMethodContext2_SendByte:"); new Comment("X#: if ECX = 0 goto AfterSendByte"); new LiteralAssemblerCode("Cmp ECX, 0"); new LiteralAssemblerCode("JE DebugStub_SendMethodContext2_AfterSendByte"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new Comment("X#: ECX--"); new LiteralAssemblerCode("Dec ECX"); new Comment("X#: goto SendByte"); new LiteralAssemblerCode("Jp DebugStub_SendMethodContext2_SendByte"); new Comment("X#: AfterSendByte:"); new LiteralAssemblerCode("DebugStub_SendMethodContext2_AfterSendByte:"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendMethodContext2_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendMemory2 {"); new LiteralAssemblerCode("DebugStub_SendMemory2:"); new LiteralAssemblerCode("; sends a stack value"); new LiteralAssemblerCode("; Serial Params:"); new LiteralAssemblerCode("; 1: x32 - offset relative to EBP"); new LiteralAssemblerCode("; 2: x32 - size of data to send"); new LiteralAssemblerCode("; [XSharp(PreserveStack = true)]"); new Comment("X#: ComReadEAX()"); new LiteralAssemblerCode("Call DebugStub_ComReadEAX"); new Comment("X#: ECX = EAX"); new LiteralAssemblerCode("Mov ECX, EAX"); new Comment("X#: AL = #Ds2Vs_MemoryData"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_MemoryData"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new Comment("X#: ComReadEAX()"); new LiteralAssemblerCode("Call DebugStub_ComReadEAX"); new Comment("X#: ESI = EAX"); new LiteralAssemblerCode("Mov ESI, EAX"); new LiteralAssemblerCode("; TODO - Make this a method and use it in above procedure too"); new LiteralAssemblerCode("; now ECX contains size of data (count)"); new LiteralAssemblerCode("; ESI contains address"); new Comment("X#: SendByte:"); new LiteralAssemblerCode("DebugStub_SendMemory2_SendByte:"); new Comment("X#: if ECX = 0 goto AfterSendByte"); new LiteralAssemblerCode("Cmp ECX, 0"); new LiteralAssemblerCode("JE DebugStub_SendMemory2_AfterSendByte"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new Comment("X#: ECX--"); new LiteralAssemblerCode("Dec ECX"); new Comment("X#: goto SendByte"); new LiteralAssemblerCode("Jp DebugStub_SendMemory2_SendByte"); new Comment("X#: AfterSendByte:"); new LiteralAssemblerCode("DebugStub_SendMemory2_AfterSendByte:"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendMemory2_Exit:"); new LiteralAssemblerCode("Ret"); new LiteralAssemblerCode("; Modifies: EAX, ESI"); new Comment("X#: procedure SendTrace {"); new LiteralAssemblerCode("DebugStub_SendTrace:"); new Comment("X#: if .DebugStatus = #Status_Run goto Normal"); new LiteralAssemblerCode("Cmp dword [DebugStub_DebugStatus], DebugStub_Const_Status_Run"); new LiteralAssemblerCode("JE DebugStub_SendTrace_Normal"); new Comment("X#: AL = #Ds2Vs_BreakPoint"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_BreakPoint"); new Comment("X#: goto Type"); new LiteralAssemblerCode("Jp DebugStub_SendTrace_Type"); new Comment("X#: Normal:"); new LiteralAssemblerCode("DebugStub_SendTrace_Normal:"); new Comment("X#: AL = #Ds2Vs_TracePoint"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_TracePoint"); new Comment("X#: Type:"); new LiteralAssemblerCode("DebugStub_SendTrace_Type:"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; Send Calling EIP."); new Comment("X#: ESI = .CallerEIP"); new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerEIP]"); new Comment("X#: ComWrite32()"); new LiteralAssemblerCode("Call DebugStub_ComWrite32"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendTrace_Exit:"); new LiteralAssemblerCode("Ret"); new Comment("X#: procedure SendText {"); new LiteralAssemblerCode("DebugStub_SendText:"); new LiteralAssemblerCode("; Input: Stack"); new LiteralAssemblerCode("; Output: None"); new LiteralAssemblerCode("; Modifies: EAX, ECX, EDX, ESI"); new LiteralAssemblerCode("; Write the type"); new Comment("X#: AL = #Ds2Vs_Message"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Message"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; Write Length"); new Comment("X#: ESI = EBP"); new LiteralAssemblerCode("Mov ESI, EBP"); new Comment("X#: ESI + 12"); new LiteralAssemblerCode("Add ESI, 12"); new Comment("X#: ECX = ESI[0]"); new LiteralAssemblerCode("Mov ECX, [ESI + 0]"); new Comment("X#: ComWrite16()"); new LiteralAssemblerCode("Call DebugStub_ComWrite16"); new LiteralAssemblerCode("; Address of string"); new Comment("X#: ESI = EBP[8]"); new LiteralAssemblerCode("Mov ESI, [EBP + 8]"); new Comment("X#: WriteChar:"); new LiteralAssemblerCode("DebugStub_SendText_WriteChar:"); new Comment("X#: if ECX = 0 exit"); new LiteralAssemblerCode("Cmp ECX, 0"); new LiteralAssemblerCode("JE DebugStub_SendText_Exit"); new Comment("X#: ComWrite8()"); new LiteralAssemblerCode("Call DebugStub_ComWrite8"); new Comment("X#: ECX--"); new LiteralAssemblerCode("Dec ECX"); new LiteralAssemblerCode("; We are storing as 16 bits, but for now I will transmit 8 bits"); new LiteralAssemblerCode("; So we inc again to skip the 0"); new Comment("X#: ESI++"); new LiteralAssemblerCode("Inc ESI"); new Comment("X#: goto WriteChar"); new LiteralAssemblerCode("Jp DebugStub_SendText_WriteChar"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendText_Exit:"); new LiteralAssemblerCode("Ret"); new LiteralAssemblerCode("; Input: Stack"); new LiteralAssemblerCode("; Output: None"); new LiteralAssemblerCode("; Modifies: EAX, ECX, EDX, ESI"); new Comment("X#: procedure SendPtr {"); new LiteralAssemblerCode("DebugStub_SendPtr:"); new LiteralAssemblerCode("; Write the type"); new Comment("X#: AL = #Ds2Vs_Pointer"); new LiteralAssemblerCode("Mov AL, DebugStub_Const_Ds2Vs_Pointer"); new Comment("X#: ComWriteAL()"); new LiteralAssemblerCode("Call DebugStub_ComWriteAL"); new LiteralAssemblerCode("; pointer value"); new Comment("X#: ESI = EBP[8]"); new LiteralAssemblerCode("Mov ESI, [EBP + 8]"); new Comment("X#: ComWrite32()"); new LiteralAssemblerCode("Call DebugStub_ComWrite32"); new Comment("X#: }"); new LiteralAssemblerCode("DebugStub_SendPtr_Exit:"); new LiteralAssemblerCode("Ret"); } } }