mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-12 03:01:32 +00:00
This commit is contained in:
parent
3f8e4f22be
commit
5a2f9cdff0
12 changed files with 473 additions and 32 deletions
|
|
@ -74,7 +74,7 @@ namespace Cosmos.Build.Builder {
|
|||
|
||||
// VS doesnt exit right away and user can try devkit again after VS window has closed but is still running.
|
||||
// So we wait a few seconds first.
|
||||
if (WaitForExit("devenv", 3000)) {
|
||||
if (WaitForExit("devenv", 5000)) {
|
||||
throw new Exception("Visual Studio is running. Please close it or kill it in task manager.");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
88
source2/Compiler/Cosmos.Compiler.DebugStub/CmdAsmBreak.cs
Normal file
88
source2/Compiler/Cosmos.Compiler.DebugStub/CmdAsmBreak.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Cosmos.Assembler;
|
||||
using Cosmos.Assembler.x86;
|
||||
|
||||
namespace Cosmos.Debug.DebugStub {
|
||||
public class CmdAsmBreak : Cosmos.Assembler.Code {
|
||||
|
||||
public CmdAsmBreak(Assembler.Assembler aAssembler) : base(aAssembler) {}
|
||||
|
||||
public override void Assemble() {
|
||||
new Comment("X#: Group DebugStub");
|
||||
|
||||
new Comment("Location where INT3 has been injected.");
|
||||
|
||||
new Comment("0 if no INT3 is active.");
|
||||
|
||||
new Comment("X#: var AsmBreakEIP");
|
||||
mAssembler.DataMembers.Add(new DataMember("DebugStub_AsmBreakEIP", 0));
|
||||
|
||||
new Comment("Old byte before INT3 was injected.");
|
||||
|
||||
new Comment("Only 1 byte is used.");
|
||||
|
||||
new Comment("X#: var AsmOrigByte");
|
||||
mAssembler.DataMembers.Add(new DataMember("DebugStub_AsmOrigByte", 0));
|
||||
|
||||
new Comment("X#: procedure SetAsmBreak {");
|
||||
new Label("DebugStub_SetAsmBreak");
|
||||
|
||||
new Comment("X#: ComReadEAX()");
|
||||
new Call { DestinationLabel = "DebugStub_ComReadEAX" };
|
||||
|
||||
new Comment("X#: EDI = EAX");
|
||||
new Mov{ DestinationReg = RegistersEnum.EDI, SourceReg = RegistersEnum.EAX };
|
||||
|
||||
new Comment("Save the old byte");
|
||||
|
||||
new Comment("X#: EAX = EDI[0]");
|
||||
new Mov{ DestinationReg = RegistersEnum.EAX, SourceReg = RegistersEnum.EDI, SourceIsIndirect = true, SourceDisplacement = 0 };
|
||||
|
||||
new Comment("X#: .AsmOrigByte = EAX");
|
||||
new Mov { DestinationRef = Cosmos.Assembler.ElementReference.New("DebugStub_AsmOrigByte"), DestinationIsIndirect = true , SourceReg = RegistersEnum.EAX };
|
||||
|
||||
new Comment("Inject INT3");
|
||||
|
||||
new Comment("X#: EDI[0] = $CC");
|
||||
new Mov{ DestinationReg = RegistersEnum.EDI, DestinationIsIndirect = true, DestinationDisplacement = 0, SourceValue = 0xCC };
|
||||
|
||||
new Comment("Save EIP of the break");
|
||||
|
||||
new Comment("X#: .AsmBreakEIP = EDI");
|
||||
new Mov { DestinationRef = Cosmos.Assembler.ElementReference.New("DebugStub_AsmBreakEIP"), DestinationIsIndirect = true , SourceReg = RegistersEnum.EDI };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_SetAsmBreak_Exit");
|
||||
new Return();
|
||||
|
||||
new Comment("X#: procedure ClearAsmBreak {");
|
||||
new Label("DebugStub_ClearAsmBreak");
|
||||
|
||||
new Comment("X#: EDI = .AsmBreakEIP");
|
||||
new Mov { DestinationReg = RegistersEnum.EDI , SourceRef = Cosmos.Assembler.ElementReference.New("DebugStub_AsmBreakEIP"), SourceIsIndirect = true };
|
||||
|
||||
new Comment("If 0, we don't need to clear an older one.");
|
||||
|
||||
new Comment("X#: if EDI = 0 exit");
|
||||
new Compare { DestinationReg = RegistersEnum.EDI, SourceValue = 0 };
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.Zero, DestinationLabel = "DebugStub_ClearAsmBreak_Exit" };
|
||||
|
||||
new Comment("Clear old break point and set back to original opcode / partial opcode");
|
||||
|
||||
new Comment("X#: EAX = .AsmOrigByte");
|
||||
new Mov { DestinationReg = RegistersEnum.EAX , SourceRef = Cosmos.Assembler.ElementReference.New("DebugStub_AsmOrigByte"), SourceIsIndirect = true };
|
||||
|
||||
new Comment("X#: EDI[0] = EAX");
|
||||
new Mov{ DestinationReg = RegistersEnum.EDI, DestinationIsIndirect = true, DestinationDisplacement = 0, SourceReg = RegistersEnum.EAX };
|
||||
|
||||
new Comment("X#: .AsmOrigByte = 0");
|
||||
new Mov { DestinationRef = Cosmos.Assembler.ElementReference.New("DebugStub_AsmOrigByte"), DestinationIsIndirect = true , SourceValue = 0 };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_ClearAsmBreak_Exit");
|
||||
new Return();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ procedure SetAsmBreak {
|
|||
procedure ClearAsmBreak {
|
||||
EDI = .AsmBreakEIP
|
||||
# If 0, we don't need to clear an older one.
|
||||
If (EDI = 0) exit
|
||||
if EDI = 0 exit
|
||||
|
||||
# Clear old break point and set back to original opcode / partial opcode
|
||||
EAX = .AsmOrigByte
|
||||
|
|
|
|||
92
source2/Compiler/Cosmos.Compiler.DebugStub/CmdProcess.cs
Normal file
92
source2/Compiler/Cosmos.Compiler.DebugStub/CmdProcess.cs
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Cosmos.Assembler;
|
||||
using Cosmos.Assembler.x86;
|
||||
|
||||
namespace Cosmos.Debug.DebugStub {
|
||||
public class CmdProcess : Cosmos.Assembler.Code {
|
||||
|
||||
public CmdProcess(Assembler.Assembler aAssembler) : base(aAssembler) {}
|
||||
|
||||
public override void Assemble() {
|
||||
new Comment("X#: Group DebugStub");
|
||||
|
||||
new Comment("test when emitted after usage too");
|
||||
|
||||
new Comment("X#: ! DebugStub_DsVsip_CmdCompleted equ 9");
|
||||
new LiteralAssemblerCode("DebugStub_DsVsip_CmdCompleted equ 9");
|
||||
|
||||
new Comment("X#: procedure AckCommand {");
|
||||
new Label("DebugStub_AckCommand");
|
||||
|
||||
new Comment("We acknowledge receipt of the command AND the processing of it.");
|
||||
|
||||
new Comment("-In the past the ACK only acknowledged receipt.");
|
||||
|
||||
new Comment("We have to do this because sometimes callers do more processing.");
|
||||
|
||||
new Comment("We ACK even ones we dont process here, but do not ACK Noop.");
|
||||
|
||||
new Comment("The buffers should be ok because more wont be sent till after our NACK");
|
||||
|
||||
new Comment("is received.");
|
||||
|
||||
new Comment("Right now our max cmd size is 2 (Cmd + Cmd ID) + 5 (Data) = 7.");
|
||||
|
||||
new Comment("UART buffer is 16.");
|
||||
|
||||
new Comment("We may need to revisit this in the future to ack not commands, but data chunks");
|
||||
|
||||
new Comment("and move them to a buffer.");
|
||||
|
||||
new Comment("The buffer problem exists only to inbound data, not outbound data (relative to DebugStub).");
|
||||
|
||||
new Comment("DsVsip.CmdCompleted");
|
||||
|
||||
new Comment("X#: AL = @.DsVsip_CmdCompleted");
|
||||
new Mov { DestinationReg = RegistersEnum.AL , SourceRef = Cosmos.Assembler.ElementReference.New("DebugStub_DsVsip_CmdCompleted") };
|
||||
|
||||
new Comment("AL = 9");
|
||||
|
||||
new Comment("X#: ComWriteAL()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWriteAL" };
|
||||
|
||||
new Comment("X#: EAX = .CommandID");
|
||||
new Mov { DestinationReg = RegistersEnum.EAX , SourceRef = Cosmos.Assembler.ElementReference.New("DebugStub_CommandID"), SourceIsIndirect = true };
|
||||
|
||||
new Comment("X#: ComWriteAL()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWriteAL" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_AckCommand_Exit");
|
||||
new Return();
|
||||
|
||||
new Comment("X#: procedure ProcessCommandBatch {");
|
||||
new Label("DebugStub_ProcessCommandBatch");
|
||||
|
||||
new Comment("X#: Begin:");
|
||||
new Label("DebugStub_ProcessCommandBatch_Begin");
|
||||
|
||||
new Comment("X#: ProcessCommand()");
|
||||
new Call { DestinationLabel = "DebugStub_ProcessCommand" };
|
||||
|
||||
new Comment("See if batch is complete");
|
||||
|
||||
new Comment("Loop and wait");
|
||||
|
||||
new Comment("VsipDs.BatchEnd");
|
||||
|
||||
new Comment("X#: if AL != 8 goto Begin");
|
||||
new Compare { DestinationReg = RegistersEnum.AL, SourceValue = 8 };
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.NotZero, DestinationLabel = "DebugStub_ProcessCommandBatch_Begin" };
|
||||
|
||||
new Comment("X#: AckCommand()");
|
||||
new Call { DestinationLabel = "DebugStub_AckCommand" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_ProcessCommandBatch_Exit");
|
||||
new Return();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,7 @@ procedure AckCommand {
|
|||
# The buffer problem exists only to inbound data, not outbound data (relative to DebugStub).
|
||||
|
||||
# DsVsip.CmdCompleted
|
||||
# ! mov AL, DebugStub_DsVsip_CmdCompleted
|
||||
#AL = .DsVsip_CmdCompleted
|
||||
AL = @.DsVsip_CmdCompleted
|
||||
#AL = 9
|
||||
ComWriteAL()
|
||||
|
||||
|
|
@ -33,7 +32,7 @@ Begin:
|
|||
# See if batch is complete
|
||||
# Loop and wait
|
||||
# VsipDs.BatchEnd
|
||||
if (AL != 8) goto Begin
|
||||
if AL != 8 goto Begin
|
||||
|
||||
AckCommand()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,16 +84,16 @@
|
|||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>CmdSend.xs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Main.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Main.xs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Init.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Init.xs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Main.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Main.xs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Old\Consts.cs" />
|
||||
<Compile Include="Old\DebugStub.cs" />
|
||||
<Compile Include="Old\ProcessCmds.cs" />
|
||||
|
|
|
|||
150
source2/Compiler/Cosmos.Compiler.DebugStub/Init.cs
Normal file
150
source2/Compiler/Cosmos.Compiler.DebugStub/Init.cs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Cosmos.Assembler;
|
||||
using Cosmos.Assembler.x86;
|
||||
|
||||
namespace Cosmos.Debug.DebugStub {
|
||||
public class Init : Cosmos.Assembler.Code {
|
||||
|
||||
public Init(Assembler.Assembler aAssembler) : base(aAssembler) {}
|
||||
|
||||
public override void Assemble() {
|
||||
new Comment("X#: Group DebugStub");
|
||||
|
||||
new Comment("Todo: Change these to a group level var");
|
||||
|
||||
new Comment("X#: var .DebugBPs int[256]");
|
||||
mAssembler.DataMembers.Add(new DataMember("DebugBPs", new int[256]));
|
||||
|
||||
new Comment("X#: var .DebugWaitMsg = 'Waiting for debugger connection...'");
|
||||
mAssembler.DataMembers.Add(new DataMember("DebugWaitMsg", "Waiting for debugger connection..."));
|
||||
|
||||
new Comment("Called before Kernel runs. Inits debug stub, etc");
|
||||
|
||||
new Comment("X#: procedure Init {");
|
||||
new Label("DebugStub_Init");
|
||||
|
||||
new Comment("X#: Cls()");
|
||||
new Call { DestinationLabel = "DebugStub_Cls" };
|
||||
|
||||
new Comment("Display message before even trying to init serial");
|
||||
|
||||
new Comment("X#: DisplayWaitMsg()");
|
||||
new Call { DestinationLabel = "DebugStub_DisplayWaitMsg" };
|
||||
|
||||
new Comment("X#: InitSerial()");
|
||||
new Call { DestinationLabel = "DebugStub_InitSerial" };
|
||||
|
||||
new Comment("X#: WaitForDbgHandshake()");
|
||||
new Call { DestinationLabel = "DebugStub_WaitForDbgHandshake" };
|
||||
|
||||
new Comment("X#: Cls()");
|
||||
new Call { DestinationLabel = "DebugStub_Cls" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_Init_Exit");
|
||||
new Return();
|
||||
|
||||
new Comment("X#: procedure WaitForSignature {");
|
||||
new Label("DebugStub_WaitForSignature");
|
||||
|
||||
new Comment("X#: EBX = 0");
|
||||
new Mov{ DestinationReg = RegistersEnum.EBX, SourceValue = 0 };
|
||||
|
||||
new Comment("X#: Read:");
|
||||
new Label("DebugStub_WaitForSignature_Read");
|
||||
|
||||
new Comment("X#: ComReadAL()");
|
||||
new Call { DestinationLabel = "DebugStub_ComReadAL" };
|
||||
|
||||
new Comment("X#: BL = AL");
|
||||
new Mov{ DestinationReg = RegistersEnum.BL, SourceReg = RegistersEnum.AL };
|
||||
|
||||
new Comment("X#: EBX ~> 8");
|
||||
new LiteralAssemblerCode("ROR EBX, 8");
|
||||
|
||||
new Comment("X#: if EBX != $19740807 goto Read");
|
||||
new Compare { DestinationReg = RegistersEnum.EBX, SourceValue = 0x19740807 };
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.NotZero, DestinationLabel = "DebugStub_WaitForSignature_Read" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_WaitForSignature_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 WaitForDbgHandshake {");
|
||||
new Label("DebugStub_WaitForDbgHandshake");
|
||||
|
||||
new Comment("\"Clear\" the UART out");
|
||||
|
||||
new Comment("X#: AL = 0");
|
||||
new Mov{ DestinationReg = RegistersEnum.AL, SourceValue = 0 };
|
||||
|
||||
new Comment("X#: ComWriteAL()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWriteAL" };
|
||||
|
||||
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#: ComWrite8()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWrite8" };
|
||||
|
||||
new Comment("X#: ComWrite8()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWrite8" };
|
||||
|
||||
new Comment("X#: ComWrite8()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWrite8" };
|
||||
|
||||
new Comment("X#: ComWrite8()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWrite8" };
|
||||
|
||||
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#: ComWriteAL()");
|
||||
new Call { DestinationLabel = "DebugStub_ComWriteAL" };
|
||||
|
||||
new Comment("X#: WaitForSignature()");
|
||||
new Call { DestinationLabel = "DebugStub_WaitForSignature" };
|
||||
|
||||
new Comment("X#: ProcessCommandBatch()");
|
||||
new Call { DestinationLabel = "DebugStub_ProcessCommandBatch" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_WaitForDbgHandshake_Exit");
|
||||
new Return();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ Read:
|
|||
ComReadAL()
|
||||
BL = AL
|
||||
EBX ~> 8
|
||||
if (EBX != $19740807) goto Read
|
||||
if EBX != $19740807 goto Read
|
||||
}
|
||||
|
||||
# QEMU (and possibly others) send some garbage across the serial line first.
|
||||
|
|
|
|||
111
source2/Compiler/Cosmos.Compiler.DebugStub/Screen.cs
Normal file
111
source2/Compiler/Cosmos.Compiler.DebugStub/Screen.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Cosmos.Assembler;
|
||||
using Cosmos.Assembler.x86;
|
||||
|
||||
namespace Cosmos.Debug.DebugStub {
|
||||
public class Screen : Cosmos.Assembler.Code {
|
||||
|
||||
public Screen(Assembler.Assembler aAssembler) : base(aAssembler) {}
|
||||
|
||||
public override void Assemble() {
|
||||
new Comment("X#: Group DebugStub");
|
||||
|
||||
new Comment("X#: procedure Cls {");
|
||||
new Label("DebugStub_Cls");
|
||||
|
||||
new Comment("VidBase");
|
||||
|
||||
new Comment("X#: ESI = $B8000");
|
||||
new Mov{ DestinationReg = RegistersEnum.ESI, SourceValue = 0xB8000 };
|
||||
|
||||
new Comment("X#: BeginLoop:");
|
||||
new Label("DebugStub_Cls_BeginLoop");
|
||||
|
||||
new Comment("Text");
|
||||
|
||||
new Comment("X#: AL = $00");
|
||||
new Mov{ DestinationReg = RegistersEnum.AL, SourceValue = 0x00 };
|
||||
|
||||
new Comment("X#: ESI[0] = AL");
|
||||
new Mov{ DestinationReg = RegistersEnum.ESI, DestinationIsIndirect = true, DestinationDisplacement = 0, SourceReg = RegistersEnum.AL };
|
||||
|
||||
new Comment("X#: ESI++");
|
||||
new INC { DestinationReg = RegistersEnum.ESI };
|
||||
|
||||
new Comment("Colour");
|
||||
|
||||
new Comment("X#: AL = $0A");
|
||||
new Mov{ DestinationReg = RegistersEnum.AL, SourceValue = 0x0A };
|
||||
|
||||
new Comment("X#: ESI[0] = AL");
|
||||
new Mov{ DestinationReg = RegistersEnum.ESI, DestinationIsIndirect = true, DestinationDisplacement = 0, SourceReg = RegistersEnum.AL };
|
||||
|
||||
new Comment("X#: ESI++");
|
||||
new INC { DestinationReg = RegistersEnum.ESI };
|
||||
|
||||
new Comment("End of Video Area");
|
||||
|
||||
new Comment("VidBase + 25 * 80 * 2 = B8FA0");
|
||||
|
||||
new Comment("X#: If ESI < $B8FA0 goto BeginLoop");
|
||||
new Compare { DestinationReg = RegistersEnum.ESI, SourceValue = 0xB8FA0 };
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.LessThan, DestinationLabel = "DebugStub_Cls_BeginLoop" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_Cls_Exit");
|
||||
new Return();
|
||||
|
||||
new Comment("X#: procedure DisplayWaitMsg {");
|
||||
new Label("DebugStub_DisplayWaitMsg");
|
||||
|
||||
new Comment("http://wiki.osdev.org/Text_UI");
|
||||
|
||||
new Comment("Later can cycle for x changes of second register:");
|
||||
|
||||
new Comment("http://wiki.osdev.org/Time_And_Date");
|
||||
|
||||
new Comment("X#: ESI = @..DebugWaitMsg");
|
||||
new Mov { DestinationReg = RegistersEnum.ESI , SourceRef = Cosmos.Assembler.ElementReference.New("DebugWaitMsg") };
|
||||
|
||||
new Comment("VidBase");
|
||||
|
||||
new Comment("X#: EDI = $B8000");
|
||||
new Mov{ DestinationReg = RegistersEnum.EDI, SourceValue = 0xB8000 };
|
||||
|
||||
new Comment("10 lines down, 20 cols in (10 * 80 + 20) * 2)");
|
||||
|
||||
new Comment("X#: EDI + 1640");
|
||||
new Add { DestinationReg = RegistersEnum.EDI, SourceValue = 1640 };
|
||||
|
||||
new Comment("Read and copy string till 0 terminator");
|
||||
|
||||
new Comment("X#: ReadChar:");
|
||||
new Label("DebugStub_DisplayWaitMsg_ReadChar");
|
||||
|
||||
new Comment("X#: AL = ESI[0]");
|
||||
new Mov{ DestinationReg = RegistersEnum.AL, SourceReg = RegistersEnum.ESI, SourceIsIndirect = true, SourceDisplacement = 0 };
|
||||
|
||||
new Comment("X#: if AL = 0 exit");
|
||||
new Compare { DestinationReg = RegistersEnum.AL, SourceValue = 0 };
|
||||
new ConditionalJump { Condition = ConditionalTestEnum.Zero, DestinationLabel = "DebugStub_DisplayWaitMsg_Exit" };
|
||||
|
||||
new Comment("X#: ESI++");
|
||||
new INC { DestinationReg = RegistersEnum.ESI };
|
||||
|
||||
new Comment("X#: EDI[0] = AL");
|
||||
new Mov{ DestinationReg = RegistersEnum.EDI, DestinationIsIndirect = true, DestinationDisplacement = 0, SourceReg = RegistersEnum.AL };
|
||||
|
||||
new Comment("X#: EDI + 2");
|
||||
new Add { DestinationReg = RegistersEnum.EDI, SourceValue = 2 };
|
||||
|
||||
new Comment("X#: Goto ReadChar");
|
||||
new Jump { DestinationLabel = "DebugStub_DisplayWaitMsg_ReadChar" };
|
||||
|
||||
new Comment("X#: }");
|
||||
new Label("DebugStub_DisplayWaitMsg_Exit");
|
||||
new Return();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ BeginLoop:
|
|||
|
||||
# End of Video Area
|
||||
# VidBase + 25 * 80 * 2 = B8FA0
|
||||
If (ESI < $B8FA0) goto BeginLoop
|
||||
If ESI < $B8FA0 goto BeginLoop
|
||||
}
|
||||
|
||||
procedure DisplayWaitMsg {
|
||||
|
|
@ -35,7 +35,7 @@ procedure DisplayWaitMsg {
|
|||
# Read and copy string till 0 terminator
|
||||
ReadChar:
|
||||
AL = ESI[0]
|
||||
if (AL = 0) exit
|
||||
if AL = 0 exit
|
||||
ESI++
|
||||
EDI[0] = AL
|
||||
EDI + 2
|
||||
|
|
|
|||
|
|
@ -219,35 +219,35 @@ namespace Cosmos.Compiler.XSharp {
|
|||
});
|
||||
|
||||
AddPattern(new string[] {
|
||||
//0 1 2 3 4 5 6 7
|
||||
"if (_REG < 123) goto _ABC",
|
||||
"if (_REG > 123) goto _ABC",
|
||||
"if (_REG = 123) goto _ABC",
|
||||
"if (_REG != 123) goto _ABC",
|
||||
"if (_REG <= 123) goto _ABC",
|
||||
"if (_REG >= 123) goto _ABC"
|
||||
//0 1 2 3 4 5
|
||||
"if _REG < 123 goto _ABC",
|
||||
"if _REG > 123 goto _ABC",
|
||||
"if _REG = 123 goto _ABC",
|
||||
"if _REG != 123 goto _ABC",
|
||||
"if _REG <= 123 goto _ABC",
|
||||
"if _REG >= 123 goto _ABC"
|
||||
},
|
||||
delegate(TokenList aTokens, ref List<string> rCode) {
|
||||
rCode.Add("new Compare {{ DestinationReg = RegistersEnum.{2}, SourceValue = {4} }};");
|
||||
rCode.Add("new Compare {{ DestinationReg = RegistersEnum.{1}, SourceValue = {3} }};");
|
||||
|
||||
var xCondition = GetCondition(aTokens[3]);
|
||||
string xLabel = GetLabel(aTokens[7]);
|
||||
var xCondition = GetCondition(aTokens[2]);
|
||||
string xLabel = GetLabel(aTokens[5]);
|
||||
rCode.Add("new ConditionalJump {{ Condition = " + xCondition + ", DestinationLabel = " + Quoted(xLabel) + " }};");
|
||||
}
|
||||
);
|
||||
AddPattern(new string[] {
|
||||
//0 1 2 3 4 5 6
|
||||
"if (_REG < 123) Exit",
|
||||
"if (_REG > 123) Exit",
|
||||
"if (_REG = 123) Exit",
|
||||
"if (_REG != 123) Exit",
|
||||
"if (_REG <= 123) Exit",
|
||||
"if (_REG >= 123) Exit"
|
||||
//0 1 2 3 4
|
||||
"if _REG < 123 Exit",
|
||||
"if _REG > 123 Exit",
|
||||
"if _REG = 123 Exit",
|
||||
"if _REG != 123 Exit",
|
||||
"if _REG <= 123 Exit",
|
||||
"if _REG >= 123 Exit"
|
||||
},
|
||||
delegate(TokenList aTokens, ref List<string> rCode) {
|
||||
rCode.Add("new Compare {{ DestinationReg = RegistersEnum.{2}, SourceValue = {4} }};");
|
||||
rCode.Add("new Compare {{ DestinationReg = RegistersEnum.{1}, SourceValue = {3} }};");
|
||||
|
||||
var xCondition = GetCondition(aTokens[3]);
|
||||
var xCondition = GetCondition(aTokens[2]);
|
||||
rCode.Add("new ConditionalJump {{ Condition = " + xCondition + ", DestinationLabel = " + Quoted(ProcLabel("Exit")) + " }};");
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
<li>msglen equ $-message</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Errors - show filename and line no</li>
|
||||
<li>Repeat 4 times { } - for comports, etc</li>
|
||||
<li>X# ProcessCmds.CS, ProcessCmdBatch - #TODO Make this a do while loop. Test
|
||||
elsewhere though, this method is not used currently.</li>
|
||||
|
|
|
|||
Loading…
Reference in a new issue