/// <summary> /// Gets the assembled machine code for section of code /// </summary> /// <param name="code">The lines of code for this section</param> /// <param name="labelDict">A dict of labels and their absolute compiled positions</param> /// <param name="regexOpcodes">A list of RegexOpcodes where each RegexOpcode matches with each corresponding line of code</param> /// <returns></returns> private static byte[] GetCode(string[] code, Dictionary <string, ushort> labelDict, RegexOpcode[] regexOpcodes) { var output = new List <byte>(); for (int i = 0; i < code.Length; i++) { RegexOpcode op = regexOpcodes[i]; if (op.Prefix != null) { output.Add((byte)op.Prefix); } output.Add(op.Code); if (op.BytesFollowing > 0) { Match m = op.Regex.Match(code[i]); // Group 1 is the number, either n, -n, nn, -nn, h or hh or a label int n; if (!int.TryParse(m.Groups[1].Value, out n)) { // Special case for JP opcode, as it can have a label to jump to var first2Chars = op.Op.Substring(0, 2); if (first2Chars == "JP" || first2Chars == "CA") { n = labelDict[m.Groups[1].Value]; } else { throw new ApplicationException(string.Format("The value {0} cannot be parsed", m.Groups[1].Value)); } } if (op.BytesFollowing >= 1) { output.Add(n > 0 ? (byte)n : (byte)(sbyte)n); } int top = n >> 8; if (op.BytesFollowing == 2) { output.Add(top > 0 ? (byte)top : (byte)(sbyte)top); } } } return(output.ToArray()); }
/// <summary> /// Goes through each line of code - if it is a valid opcode, it assigns a RegexOpcode to it. /// </summary> /// <param name="code"></param> /// <returns></returns> private static RegexOpcode[] GetRegexOpcodes(string[] code) { var regexOpcodes = new RegexOpcode[code.Length]; for (int i = 0; i < code.Length; i++) { RegexOpcode op = Program.Opcodes.FirstOrDefault(opcode => opcode.Regex.IsMatch(code[i])); if (op == null) { throw new ApplicationException(string.Format("Line {0} is incorrect: '{1}' does not exist, or a number in it is too big/small/malformed for the instruction.", i, code[i])); } regexOpcodes[i] = op; } return(regexOpcodes); }