This commit is contained in:
kudzu_cp 2012-07-11 20:23:01 +00:00
parent 813d06b570
commit 712dbacc44
7 changed files with 183 additions and 117 deletions

View file

@ -40,11 +40,12 @@ namespace Cosmos.Debug.DebugStub {
new LiteralAssemblerCode("Sub EAX, ESI");
new LiteralAssemblerCode("Call DebugStub_ComWriteAX");
new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerESP]");
new LiteralAssemblerCode("DebugStub_SendStack_SendByte:");
new LiteralAssemblerCode("DebugStub_SendStack_Block1Begin:");
new LiteralAssemblerCode("Cmp ESI, [DebugStub_CallerEBP]");
new LiteralAssemblerCode("JE DebugStub_SendStack_Exit");
new LiteralAssemblerCode("JE DebugStub_SendStack_Block1End");
new LiteralAssemblerCode("Call DebugStub_ComWrite8");
new LiteralAssemblerCode("Jmp DebugStub_SendStack_SendByte");
new LiteralAssemblerCode("jmp DebugStub_SendStack_Block1Begin");
new LiteralAssemblerCode("DebugStub_SendStack_Block1End:");
new LiteralAssemblerCode("DebugStub_SendStack_Exit:");
new LiteralAssemblerCode("Ret");
new LiteralAssemblerCode("DebugStub_SendMethodContext:");
@ -56,13 +57,13 @@ namespace Cosmos.Debug.DebugStub {
new LiteralAssemblerCode("Call DebugStub_ComReadEAX");
new LiteralAssemblerCode("Mov ESI, [DebugStub_CallerEBP]");
new LiteralAssemblerCode("Add ESI, EAX");
new LiteralAssemblerCode("DebugStub_SendMethodContext_SendByte:");
new LiteralAssemblerCode("DebugStub_SendMethodContext_Block2Begin:");
new LiteralAssemblerCode("Cmp ECX, 0");
new LiteralAssemblerCode("JE DebugStub_SendMethodContext_AfterSendByte");
new LiteralAssemblerCode("JE DebugStub_SendMethodContext_Block2End");
new LiteralAssemblerCode("Call DebugStub_ComWrite8");
new LiteralAssemblerCode("Dec ECX");
new LiteralAssemblerCode("Jmp DebugStub_SendMethodContext_SendByte");
new LiteralAssemblerCode("DebugStub_SendMethodContext_AfterSendByte:");
new LiteralAssemblerCode("jmp DebugStub_SendMethodContext_Block2Begin");
new LiteralAssemblerCode("DebugStub_SendMethodContext_Block2End:");
new LiteralAssemblerCode("DebugStub_SendMethodContext_Exit:");
new LiteralAssemblerCode("Popad");
new LiteralAssemblerCode("Ret");
@ -74,13 +75,13 @@ namespace Cosmos.Debug.DebugStub {
new LiteralAssemblerCode("Call DebugStub_ComWriteAL");
new LiteralAssemblerCode("Call DebugStub_ComReadEAX");
new LiteralAssemblerCode("Mov ESI, EAX");
new LiteralAssemblerCode("DebugStub_SendMemory_SendByte:");
new LiteralAssemblerCode("DebugStub_SendMemory_Block3Begin:");
new LiteralAssemblerCode("Cmp ECX, 0");
new LiteralAssemblerCode("JE DebugStub_SendMemory_AfterSendByte");
new LiteralAssemblerCode("JE DebugStub_SendMemory_Block3End");
new LiteralAssemblerCode("Call DebugStub_ComWrite8");
new LiteralAssemblerCode("Dec ECX");
new LiteralAssemblerCode("Jmp DebugStub_SendMemory_SendByte");
new LiteralAssemblerCode("DebugStub_SendMemory_AfterSendByte:");
new LiteralAssemblerCode("jmp DebugStub_SendMemory_Block3Begin");
new LiteralAssemblerCode("DebugStub_SendMemory_Block3End:");
new LiteralAssemblerCode("DebugStub_SendMemory_Exit:");
new LiteralAssemblerCode("Popad");
new LiteralAssemblerCode("Ret");

View file

@ -44,11 +44,9 @@ function SendStack {
//
// Need to reload ESI, WriteAXToCompPort modifies it
ESI = .CallerESP
//TODO While
SendByte:
if ESI = .CallerEBP return
ComWrite8()
goto SendByte
while ESI != .CallerEBP {
ComWrite8()
}
}
// sends a stack value
@ -72,13 +70,10 @@ function SendMethodContext {
ESI = .CallerEBP
ESI + EAX
// TODO While
SendByte:
if ECX = 0 goto AfterSendByte
ComWrite8()
ECX--
goto SendByte
AfterSendByte:
while ECX != 0 {
ComWrite8()
ECX--
}
Exit:
-All
@ -103,15 +98,12 @@ function SendMemory {
ComReadEAX()
ESI = EAX
// TODO - Make this a method and use it in above function too
// now ECX contains size of data (count)
// ESI contains address
SendByte:
if ECX = 0 goto AfterSendByte
ComWrite8()
ECX--
goto SendByte
AfterSendByte:
while ECX != 0 {
ComWrite8()
ECX--
}
Exit:
-All

View file

@ -9,14 +9,13 @@ namespace Cosmos.Debug.DebugStub {
public Screen(Assembler.Assembler aAssembler) : base(aAssembler) {}
public override void Assemble() {
new LiteralAssemblerCode("DebugStub_Const_VidBase equ 0xB8000");
new LiteralAssemblerCode("DebugStub_Cls:");
new LiteralAssemblerCode("Mov ESI, 0xB8000");
new LiteralAssemblerCode("Mov ESI, DebugStub_Const_VidBase");
new LiteralAssemblerCode("DebugStub_Cls_BeginLoop:");
new LiteralAssemblerCode("Mov AL, 0x00");
new LiteralAssemblerCode("Mov [ESI + 0], AL");
new LiteralAssemblerCode("Mov dword [ESI + 0], 0x00");
new LiteralAssemblerCode("Inc ESI");
new LiteralAssemblerCode("Mov AL, 0x0A");
new LiteralAssemblerCode("Mov [ESI + 0], AL");
new LiteralAssemblerCode("Mov dword [ESI + 0], 0x0A");
new LiteralAssemblerCode("Inc ESI");
new LiteralAssemblerCode("Cmp ESI, 0xB8FA0");
new LiteralAssemblerCode("JB DebugStub_Cls_BeginLoop");
@ -24,16 +23,18 @@ namespace Cosmos.Debug.DebugStub {
new LiteralAssemblerCode("Ret");
new LiteralAssemblerCode("DebugStub_DisplayWaitMsg:");
new LiteralAssemblerCode("Mov ESI, DebugWaitMsg");
new LiteralAssemblerCode("Mov EDI, 0xB8000");
new LiteralAssemblerCode("Mov EDI, DebugStub_Const_VidBase");
new LiteralAssemblerCode("Add EDI, 1640");
new LiteralAssemblerCode("DebugStub_DisplayWaitMsg_ReadChar:");
new LiteralAssemblerCode("Mov AL, [ESI + 0]");
new LiteralAssemblerCode("Mov AL, 1");
new LiteralAssemblerCode("DebugStub_DisplayWaitMsg_Block1Begin:");
new LiteralAssemblerCode("Cmp AL, 0");
new LiteralAssemblerCode("JE DebugStub_DisplayWaitMsg_Exit");
new LiteralAssemblerCode("Inc ESI");
new LiteralAssemblerCode("JE DebugStub_DisplayWaitMsg_Block1End");
new LiteralAssemblerCode("Mov AL, [ESI + 0]");
new LiteralAssemblerCode("Mov [EDI + 0], AL");
new LiteralAssemblerCode("Inc ESI");
new LiteralAssemblerCode("Add EDI, 2");
new LiteralAssemblerCode("Jmp DebugStub_DisplayWaitMsg_ReadChar");
new LiteralAssemblerCode("jmp DebugStub_DisplayWaitMsg_Block1Begin");
new LiteralAssemblerCode("DebugStub_DisplayWaitMsg_Block1End:");
new LiteralAssemblerCode("DebugStub_DisplayWaitMsg_Exit:");
new LiteralAssemblerCode("Ret");
}

View file

@ -1,18 +1,18 @@
Group DebugStub
const VidBase = $B8000
function Cls {
// VidBase
ESI = $B8000
ESI = #VidBase
BeginLoop:
// Text
AL = $00
ESI[0] = AL
ESI[0] = $00
ESI++
// Colour
AL = $0A
ESI[0] = AL
ESI[0] = $0A
ESI++
// End of Video Area
@ -27,17 +27,17 @@ function DisplayWaitMsg {
ESI = @..DebugWaitMsg
// VidBase
EDI = $B8000
EDI = #VidBase
// 10 lines down, 20 cols in (10 * 80 + 20) * 2)
EDI + 1640
// Read and copy string till 0 terminator
ReadChar:
AL = ESI[0]
if AL = 0 return
ESI++
EDI[0] = AL
EDI + 2
Goto ReadChar
AL = 1
while AL != 0 {
//while ESI[0] != 0 {
AL = ESI[0]
EDI[0] = AL
ESI++
EDI + 2
}
}

View file

@ -30,9 +30,9 @@ namespace Cosmos.Compiler.XSharp {
+ ",JUMP"
+ ",PORT"
+ ",RETURN,RETURNINTERRUPT,REPEAT"
+ ",TIMES"
+ ",VAR"
+ ",WORD"
+ ",times"
+ ",var"
+ ",word,while"
).ToUpper().Split(mComma);
public static readonly string[] Registers;

View file

@ -27,10 +27,25 @@ namespace Cosmos.Compiler.XSharp {
protected List<Pattern> mPatterns = new List<Pattern>();
protected string mGroup;
protected bool mInIntHandler;
protected string[] mCompareOps;
protected List<string> mCompares = new List<string>();
protected TokenList mBlockStarter = null;
protected List<string> mBlock = null;
protected int mBlockLabel = 0;
public TokenPatterns() {
mCompareOps = "< > = != <= >= 0".Split(" ".ToCharArray());
foreach (var xComparison in mCompareOps) {
if (xComparison != "0") {
mCompares.Add("_REG " + xComparison + " 123");
mCompares.Add("_REG " + xComparison + " _REG");
mCompares.Add("_REG " + xComparison + " _ABC");
mCompares.Add("_REG " + xComparison + " #_ABC");
mCompares.Add("_ABC " + xComparison + " #_ABC");
}
}
AddPatterns();
}
@ -55,6 +70,9 @@ namespace Cosmos.Compiler.XSharp {
protected string FuncLabel(string aLabel) {
return mGroup + "_" + mFuncName + "_" + aLabel;
}
protected string BlockLabel(string aLabel) {
return FuncLabel("Block" + mBlockLabel + aLabel);
}
protected string GetLabel(Token aToken) {
if (aToken.Type != TokenType.AlphaNum && !aToken.Matches("Exit")) {
throw new Exception("Label must be AlphaNum.");
@ -81,6 +99,14 @@ namespace Cosmos.Compiler.XSharp {
mFuncExitFound = false;
}
protected void StartBlock(TokenList aTokens, bool aIsCollector) {
mBlockStarter = aTokens;
if (aIsCollector) {
mBlock = new List<string>();
}
mBlockLabel++;
}
protected void EndFunc(ref List<string> rCode) {
if (!mFuncExitFound) {
rCode.Add(mGroup + "_" + mFuncName + "_Exit:");
@ -121,30 +147,73 @@ namespace Cosmos.Compiler.XSharp {
return xResult;
}
protected string GetCompare(TokenList aTokens, int aStart) {
string xLeft = aTokens[1].Value;
if (aTokens[1].Type == TokenType.AlphaNum) {
// Hardcoded to dword for now
xLeft = "dword [" + GetLabel(aTokens[1]) + "]";
}
string xRight = aTokens[3].Value;
if (aTokens[3].Type == TokenType.AlphaNum) {
xRight = "[" + GetLabel(aTokens[3]) + "]";
} else if (aTokens[3].Value == "#") {
xRight = ConstLabel(aTokens[4]);
}
return "Cmp " + xLeft + ", " + xRight;
}
protected string GetJump(Token aToken) {
if (aToken.Value == "<") {
return GetJump(aToken, false);
}
protected string GetJump(Token aToken, bool aInvert) {
string xOp = aToken.Value;
if (aInvert) {
if (xOp == "<") {
xOp = ">=";
} else if (xOp == ">") {
xOp = "<=";
} else if (xOp == "=") {
xOp = "!=";
} else if (xOp == "0") {
// Same as JE, but implies intent in .asm better
xOp = "!0";
} else if (xOp == "!=") {
xOp = "=";
} else if (xOp == "<=") {
xOp = ">";
} else if (xOp == ">=") {
xOp = "<";
} else {
throw new Exception("Unrecognized symbol in conditional: " + xOp);
}
}
if (xOp == "<") {
return "JB"; // unsigned
} else if (aToken.Value == ">") {
} else if (xOp == ">") {
return "JA"; // unsigned
} else if (aToken.Value == "=") {
} else if (xOp == "=") {
return "JE";
} else if (aToken.Value == "0") {
} else if (xOp == "0") {
// Same as JE, but implies intent in .asm better
return "JZ";
} else if (aToken.Value == "!=") {
} else if (xOp == "!=") {
return "JNE";
} else if (aToken.Value == "<=") {
} else if (xOp == "!0") {
// Same as JNE, but implies intent in .asm better
return "JNZ";
} else if (xOp == "<=") {
return "JBE"; // unsigned
} else if (aToken.Value == ">=") {
} else if (xOp == ">=") {
return "JAE"; // unsigned
} else {
throw new Exception("Unrecognized symbol in conditional: " + aToken.Value);
throw new Exception("Unrecognized symbol in conditional: " + xOp);
}
}
protected void AddPatterns() {
var xSpace = " ".ToCharArray();
AddPattern("! Move EAX, 0", "{0}");
AddPattern("// Comment", delegate(TokenList aTokens, ref List<string> rCode) {
@ -194,6 +263,16 @@ namespace Cosmos.Compiler.XSharp {
rCode.Add("mAssembler.DataMembers.Add(new DataMember(" + Quoted(GetLabel(aTokens[1])) + ", new " + aTokens[2].Value + "[" + aTokens[4].Value + "]));");
});
foreach (var xCompare in mCompares) {
// 0 1 2 3 4
AddPattern("while " + xCompare + " {", delegate(TokenList aTokens, ref List<string> rCode) {
StartBlock(aTokens, false);
rCode.Add(BlockLabel("Begin") + ":");
rCode.Add(GetCompare(aTokens, 1));
rCode.Add(GetJump(aTokens[2], true) + " " + BlockLabel("End"));
});
}
// Must test separate since !0 is two tokens
AddPattern("if !0 goto _ABC", delegate(TokenList aTokens, ref List<string> rCode) {
rCode.Add("JNZ " + GetLabel(aTokens[4]));
@ -201,45 +280,8 @@ namespace Cosmos.Compiler.XSharp {
AddPattern("if !0 return", delegate(TokenList aTokens, ref List<string> rCode) {
rCode.Add("JNZ " + FuncLabel("Exit"));
});
foreach (var xComparison in "< > = != <= >= 0".Split(xSpace)) {
foreach (var xTail in "goto _ABC|return".Split("|".ToCharArray())) {
if (xComparison != "0") {
AddPattern(new string[] {
//0 1 2 3 4
"if _REG " + xComparison + " 123 " + xTail,
"if _REG " + xComparison + " _REG " + xTail,
"if _REG " + xComparison + " _ABC " + xTail,
// 3 4 5
"if _REG " + xComparison + " #_ABC " + xTail,
"if _ABC " + xComparison + " #_ABC " + xTail,
}, delegate(TokenList aTokens, ref List<string> rCode) {
int xTailIdx = 4;
string xLeft = aTokens[1].Value;
if (aTokens[1].Type == TokenType.AlphaNum) {
// Hardcoded to dword for now
xLeft = "dword [" + GetLabel(aTokens[1]) + "]";
}
string xRight = aTokens[3].Value;
if (aTokens[3].Type == TokenType.AlphaNum) {
xRight = "[" + GetLabel(aTokens[3]) + "]";
} else if (aTokens[3].Value == "#") {
xRight = ConstLabel(aTokens[4]);
xTailIdx = 5;
}
rCode.Add("Cmp " + xLeft + ", " + xRight);
string xLabel;
if (aTokens[xTailIdx].Matches("return")) {
xLabel = FuncLabel("Exit");
} else {
xLabel = GetLabel(aTokens[xTailIdx + 1]);
}
rCode.Add(GetJump(aTokens[2]) + " " + xLabel);
});
}
foreach (var xTail in "goto _ABC|return".Split("|".ToCharArray())) {
foreach (var xComparison in mCompareOps) {
AddPattern("if " + xComparison + " " + xTail, delegate(TokenList aTokens, ref List<string> rCode) {
string xLabel;
if (string.Equals(aTokens[2].Value, "exit", StringComparison.InvariantCultureIgnoreCase)) {
@ -250,6 +292,22 @@ namespace Cosmos.Compiler.XSharp {
rCode.Add(GetJump(aTokens[1]) + " " + xLabel);
});
}
foreach (var xCompare in mCompares) {
// 0 1 2 3 4
AddPattern("if " + xCompare + " " + xTail, delegate(TokenList aTokens, ref List<string> rCode) {
int xTailIdx = aTokens[3].Value == "#" ? 5 : 4;
rCode.Add(GetCompare(aTokens, 1));
string xLabel;
if (aTokens[xTailIdx].Matches("return")) {
xLabel = FuncLabel("Exit");
} else {
xLabel = GetLabel(aTokens[xTailIdx + 1]);
}
rCode.Add(GetJump(aTokens[2]) + " " + xLabel);
});
}
}
AddPattern("_REG ?= 123", "Cmp {0}, {2}");
@ -405,19 +463,27 @@ namespace Cosmos.Compiler.XSharp {
AddPattern("_REG--", "Dec {0}");
AddPattern("}", delegate(TokenList aTokens, ref List<string> rCode) {
if (mBlock == null) {
// Use mBlockStarter, not mBlock because not all blocks use mBlock to collect
// (repeat does for example, but while does not)
if (mBlockStarter == null) {
EndFunc(ref rCode);
} else {
if (mBlockStarter.PatternMatches("repeat 4 times {")) {
if (mBlockStarter[0].Matches("repeat")) {
int xCount = int.Parse(mBlockStarter[1].Value);
for (int i = 1; i <= xCount; i++) {
rCode.AddRange(mBlock);
}
mBlockStarter = null;
mBlock = null;
} else if (mBlockStarter[0].Matches("while")) {
rCode.Add("jmp " + BlockLabel("Begin"));
rCode.Add(BlockLabel("End") + ":");
} else {
throw new Exception("Unknown block starter.");
}
mBlockStarter = null;
mBlock = null;
}
});
@ -430,8 +496,7 @@ namespace Cosmos.Compiler.XSharp {
});
AddPattern("Repeat 4 times {", delegate(TokenList aTokens, ref List<string> rCode) {
mBlockStarter = aTokens;
mBlock = new List<string>();
StartBlock(aTokens, true);
});
AddPattern("Interrupt _ABC {", delegate(TokenList aTokens, ref List<string> rCode) {

View file

@ -42,11 +42,18 @@
</ul>
</li>
<li>Complete X# Port<ul>
<li>PreserveRegisters</li>
<li>look for todo in cmdsend.xs</li>
<li>AL = ComRead8()</li>
<li>ComWrite(AL)</li>
<li>Screen.XS<ul>
<li>Loop in top</li>
<li>//while ESI[0] != 0 { </li>
</ul>
</li>
<li>Builder restores</li>
</ul>
<ul>
<li>PreserveRegisters</li>
<li>AL = ComRead8()</li>
<li>ComWrite(AL)</li>
</ul>
</li>
<ul>
<li>X# ProcessCmds.CS, ProcessCmdBatch - #TODO Make this a do while loop. Test