void WriteParsedOperands(string fileName) { using (StreamWriter sw = new StreamWriter(fileName)) { foreach (Statement st in statements) { if (st is ExecutableStatement) { ExecutableStatement es = st as ExecutableStatement; sw.Write(es.OpCode); if (es.Op1 != "") { sw.Write(" | " + es.Op1); } if (es.Op2 != "") { sw.Write(" | " + es.Op2); } if (es.Op3 != "") { sw.Write(" | " + es.Op3); } if (es.TrailingComment != "" && es.TrailingComment != null) { sw.Write(" | " + es.TrailingComment); } sw.WriteLine(); } } } }
public bool IsValid(ExecutableStatement ex) { if (LangDef.LangDef.HasOpCode(ex.OpCode)) { throw new Exception("Invalid opcode:" + ex.OpCode); } return(true); }
/// <summary> /// If the instruction is a relative jump, the address /// is converted into signed byte. 2 is subtracted from /// the offset to take into account that PC has already /// been incremented when the jump needs to happed /// </summary> void FixRelativeAddresses() { foreach (Statement st in statements) { if (st is ExecutableStatement) { ExecutableStatement ex = st as ExecutableStatement; if (LangDef.LangDef.IsRelativeJump(ex.OpCode)) { ImmediateOperand op = (ex.LeftOperand as ImmediateOperand); int target = op.UshortVal; int relDist = (target - st.Address) - 2; op.UshortVal = (byte)relDist; } } } }
void FixBitInstructions() { foreach (Statement st in statements) { if (st is ExecutableStatement) { ExecutableStatement ex = st as ExecutableStatement; if (ex.OpCode == "BIT" || ex.OpCode == "RES" || ex.OpCode == "SET") { byte b = ex.LeftOperand.GetHexText().ToByte(); /* * b = (byte)(b << 3); * * if (ex.OpCode == "BIT") * {//and | 01000110 * b = (byte)(b | 01000110); * } * else if (ex.OpCode == "RES") * {//left shit b 3 and | 10000110 * b = (byte)(b | 10000110); * } * else if (ex.OpCode == "SET") * {//left shit b 3 and | 11000110 * b = (byte)(b | 11000110); * } */ if (ex.GetModeText() == "IMMEDIATE,IX_INDEXED_PLUS_OFFSET" || ex.GetModeText() == "IMMEDIATE,IY_INDEXED_PLUS_OFFSET") {//left shit b 3 or byte //now flip the operands because they //get written out in reverse order ex.LeftOperand.Value = ex.RightOperand.Value; ex.RightOperand.Value = string.Format("{0:2X}", b); } } } } }
/// <summary> /// Assigns actual address to operands in the executable statement /// </summary> void SetAddresses() { foreach (Statement st in statements) { if (st is ExecutableStatement) { ExecutableStatement ex = st as ExecutableStatement; try { ex.SetAddresses(labelOffsets); } catch (Exception x) { throw new Exception( string.Format("Line {0}: {1} \r\n Unable to find label's address.", st.LineNumber, st.Text) , x); } } } }
void ValidateOpCodes() { try { foreach (Statement s in statements) { if (s is ExecutableStatement) { ExecutableStatement ex = s as ExecutableStatement; if (!LangDef.LangDef.HasOpCode(ex.OpCode)) { throw new Exception("Error on line: " + ex.LineNumber + ". Invalid opcode " + ex.OpCode); } } } } catch (Exception ex) { throw new Exception("Error validating op codes.", ex); } }
/// <summary> /// makes sure the operands are supported /// </summary> void ValidateOperands() { for (int i = 0; i < statements.Count; i++) { Statement s = statements[i]; if (s is ExecutableStatement) { ExecutableStatement ex = s as ExecutableStatement; string mode = ex.GetModeText(); if (!LangDef.LangDef.SupportsMode(ex.OpCode, mode)) {// throw new Exception( String.Format( "Error on line {0}:{3} {1} does not support mode {2}", i, ex.OpCode, mode, ex.Text) ); } } } }
/// <summary> /// Breaks up the op code, and operands /// </summary> void SplitOperands() { foreach (Statement s in statements) { if (s is ExecutableStatement) { ExecutableStatement ex = s as ExecutableStatement; try { if (s.Text.Contains(";")) { char[] splitChars = { ';' }; string[] toks = s.Text.Split(splitChars); ex.TrailingComment = ";" + toks[1]; s.Text = toks[0]; //text is now the left side } //anything left is an opcode or an operand StringBuilder sb = new StringBuilder(s.Text); sb.Replace('\t', ' '); //get the first piece of text if (sb.ToString().IndexOf(",") != -1) {//opcode plus two operands char[] splitChars = { ',' }; string right = sb.ToString().Substring(s.Text.IndexOf(',') + 1).Trim(); string left = sb.ToString().Substring(0, s.Text.IndexOf(',')).Trim(); //is the 2nd operand a compound operand [Y] [X] string[] pieces = left.Split(' '); ex.OpCode = pieces[0].Trim(); ex.Op1 = pieces[1].Trim(); ex.Op2 = right.Trim(); //r2 is has a register offset if (ex.Op2.Contains("[")) { pieces = ex.Op2.Split('['); left = pieces[0].Trim(); right = ex.Op2.Substring(ex.Op2.IndexOf('[') + 1); right = right.Replace(']', ' '); right = right.Trim(); ex.Op2 = left; ex.Op3 = right; } } else { //opcoe or opcode + one operand if (s.Text.Contains(" ")) { //two operands char[] chars = { ' ' }; string[] pieces = s.Text.Split(chars); ex.OpCode = pieces[0].Trim(); ex.Op1 = pieces[1].Trim(); } else {//one operand ex.OpCode = s.Text; } } } catch (Exception x) { throw new Exception("Line " + s.LineNumber + ":Unable to split statement: " + s.Text, x); } } } }