Cosmos/source2/Compiler/Cosmos.Compiler.DebugStub/Init.cs
kudzu_cp 44c6e98f84
2012-06-27 05:26:23 +00:00

138 lines
4.5 KiB
C#

using System;
using System.Linq;
using Cosmos.Assembler;
using Cosmos.Assembler.x86;
namespace Cosmos.Debug.DebugStub {
public class Init : Cosmos.Assembler.Code {
public override void Assemble() {
new Comment("X#: Group DebugStub");
new Comment("Called before Kernel runs. Inits debug stub, etc");
new Comment("X#: procedure Init {");
new Label("DebugStub_Init");
new Comment("X#: Call .Cls");
new Call { DestinationLabel = "DebugStub_Cls" };
new Comment("Display message before even trying to init serial");
new Comment("X#: Call .DisplayWaitMsg");
new Call { DestinationLabel = "DebugStub_DisplayWaitMsg" };
new Comment("X#: Call .InitSerial");
new Call { DestinationLabel = "DebugStub_InitSerial" };
new Comment("X#: Call .WaitForDbgHandshake");
new Call { DestinationLabel = "DebugStub_WaitForDbgHandshake" };
new Comment("X#: Call .Cls");
new Call { DestinationLabel = "DebugStub_Cls" };
new Comment("X#: }");
new Label("DebugStub_Init_Exit");
new Return();
new Comment("X#: procedure WaitForSignatureNew {");
new Label("DebugStub_WaitForSignatureNew");
new Comment("X#: EBX = 0");
new Mov{ DestinationReg = RegistersEnum.EBX, SourceValue = 0 };
new Comment("X#: Read:");
new Label("DebugStub_WaitForSignatureNew_Read");
new Comment("X#: Call .ReadALFromComPort");
new Call { DestinationLabel = "DebugStub_ReadALFromComPort" };
new Comment("X#: BL = AL");
new Mov{ DestinationReg = RegistersEnum.BL, SourceReg = RegistersEnum.AL };
new Comment("EBX.RotateRight(8)");
new Comment("EBX.Compare(Cosmos.Debug.Consts.Consts.SerialSignature)");
new Comment("JumpIf(Flags.NotEqual, \"DebugStub_WaitForSignature_Read\")");
new Comment("X#: }");
new Label("DebugStub_WaitForSignatureNew_Exit");
new Return();
new Comment("QEMU (and possibly others) send some garbage across the serial line first.");
new Comment("Actually they send the garbage inbound, but garbage could be inbound as well so we");
new Comment("keep this.");
new Comment("To work around this we send a signature. DC then discards everything before the signature.");
new Comment("QEMU has other serial issues too, and we dont support it anymore, but this signature is a good");
new Comment("feature so we kept it.");
new Comment("X#: procedure WaitForDbgHandshakeNew {");
new Label("DebugStub_WaitForDbgHandshakeNew");
new Comment("\"Clear\" the UART out");
new Comment("X#: AL = 0");
new Mov{ DestinationReg = RegistersEnum.AL, SourceValue = 0 };
new Comment("X#: Call .WriteALToComPort");
new Call { DestinationLabel = "DebugStub_WriteALToComPort" };
new Comment("Cosmos.Debug.Consts.Consts.SerialSignature");
new Comment("X#: +$19740807");
new Push { DestinationValue = 0x19740807, Size = 32 };
new Comment("X#: ESI = ESP");
new Mov{ DestinationReg = RegistersEnum.ESI, SourceReg = RegistersEnum.ESP };
new Comment("TODO pass a count register");
new Comment("X#: Call .WriteByteToComPort");
new Call { DestinationLabel = "DebugStub_WriteByteToComPort" };
new Comment("X#: Call .WriteByteToComPort");
new Call { DestinationLabel = "DebugStub_WriteByteToComPort" };
new Comment("X#: Call .WriteByteToComPort");
new Call { DestinationLabel = "DebugStub_WriteByteToComPort" };
new Comment("X#: Call .WriteByteToComPort");
new Call { DestinationLabel = "DebugStub_WriteByteToComPort" };
new Comment("Restore ESP, we actually dont care about EAX or the value on the stack anymore.");
new Comment("X#: -EAX");
new Pop { DestinationReg = RegistersEnum.EAX};
new Comment("We could use the signature as the start signal, but I prefer");
new Comment("to keep the logic separate, especially in DC.");
new Comment("Send the actual started signal");
new Comment("DsVsip.Started = 6");
new Comment("X#: AL = 6");
new Mov{ DestinationReg = RegistersEnum.AL, SourceValue = 6 };
new Comment("X#: Call .WriteALToComPort");
new Call { DestinationLabel = "DebugStub_WriteALToComPort" };
new Comment("X#: Call .WaitForSignature");
new Call { DestinationLabel = "DebugStub_WaitForSignature" };
new Comment("X#: Call .ProcessCommandBatch");
new Call { DestinationLabel = "DebugStub_ProcessCommandBatch" };
new Comment("X#: }");
new Label("DebugStub_WaitForDbgHandshakeNew_Exit");
new Return();
}
}
}