private OpParamResult ParseParam(string _param, out string errortext) { errortext = ""; OpParamResult opParamResult = new OpParamResult(); // Find easy ones. string Param = _param.Replace(" ", "").Trim(); // strip spaces if (m_regDictionary.ContainsKey(Param)) { // Ok things are really easy in this case. opParamResult.Param = (ushort)m_regDictionary[Param]; } else { if (Param[0] == '[' && Param[Param.Length - 1] == ']') { if (Param.Contains("+")) { string[] psplit = Param.Replace("[", "").Replace("]", "").Replace(" ", "").Split('+'); if (psplit.Length < 2) { errortext = string.Format("malformated memory reference '{0}'", Param); throw new Exception(string.Format("malformated memory reference '{0}'", Param)); } string addressValue = psplit[0]; if (m_regDictionary.ContainsKey("[+" + psplit[1] + "]") != true) { errortext = string.Format("Invalid register reference in '{0}'", Param); throw new Exception(string.Format("Invalid register reference in '{0}'", Param)); } opParamResult.Param = (ushort)m_regDictionary["[+" + psplit[1] + "]"]; opParamResult.nextWord = true; try { if (psplit[0][0] == '\'' && psplit[0][psplit[0].Length - 1] == '\'' && psplit[0].Length == 3) // nasty { ushort val = (ushort)psplit[0][1]; opParamResult.NextWordValue = (ushort)val; } else if (psplit[0].Contains("0x")) { ushort val = Convert.ToUInt16(psplit[0].Trim(), 16); opParamResult.NextWordValue = (ushort)val; } else { ushort val = Convert.ToUInt16(psplit[0].Trim(), 10); opParamResult.NextWordValue = (ushort)val; } } catch { opParamResult.nextWord = true; opParamResult.labelName = psplit[0].Trim(); } } else { opParamResult.Param = (ushort)dcpuRegisterCodes.NextWord_Literal_Mem; opParamResult.nextWord = true; try { if (Param[1] == '\'' && Param[Param.Length - 2] == '\'' && Param.Length == 5) // nasty { ushort val = (ushort)Param[1]; opParamResult.NextWordValue = (ushort)val; } else if (Param.Contains("0x")) { ushort val = (ushort)Convert.ToUInt16(Param.Replace("[", "").Replace("]", "").Trim(), 16); opParamResult.NextWordValue = val; } else { ushort val = (ushort)Convert.ToUInt16(Param.Replace("[", "").Replace("]", "").Trim(), 10); opParamResult.NextWordValue = val; } } catch { opParamResult.nextWord = true; opParamResult.labelName = Param.Replace("[", "").Replace("]", "").Trim(); } } } else { // if value is < 0x1F we can encode it into the param directly, // else it has to be next value! UInt16 maxValue = Convert.ToUInt16("0x1F", 16); UInt16 literalValue = 0; try { if (Param[0] == '\'' && Param[Param.Length - 1] == '\'' && Param.Length == 3) { literalValue = (ushort)Param[1]; } else if (Param.Contains("0x")) { literalValue = Convert.ToUInt16(Param, 16); } else { literalValue = Convert.ToUInt16(Param, 10); } if (literalValue < maxValue) { opParamResult.Param = Convert.ToUInt16("0x20", 16); opParamResult.Param += literalValue; } else { opParamResult.Param = (ushort)dcpuRegisterCodes.NextWord_Literal_Value; opParamResult.nextWord = true; opParamResult.NextWordValue = literalValue; } } catch { opParamResult.Param = (ushort)dcpuRegisterCodes.NextWord_Literal_Value; opParamResult.nextWord = true; opParamResult.labelName = Param; } } } return(opParamResult); }
private void AssembleLine(string _line, out string errortext) { errortext = ""; if (_line.Trim().Length == 0) { return; } string line = _line.ToLower(); if (line[0] == ':') { // this is awful int sIndex = -1; int sIndex1 = line.IndexOf(' '); int sIndex2 = line.IndexOf('\t'); if (sIndex1 < sIndex2 || sIndex2 == -1) { sIndex = sIndex1; } else if (sIndex2 < sIndex1 || sIndex1 != -1) { sIndex = sIndex2; } string labelName = line.Substring(1, line.Length - 1); if (sIndex > 1) { labelName = line.Substring(1, sIndex - 1); } if (m_labelAddressDitionary.ContainsKey(labelName)) { errortext = string.Format("Error! Label '{0}' already exists!", labelName); throw new Exception(string.Format("Error! Label '{0}' already exists!", labelName)); } m_labelAddressDitionary.Add(labelName.Trim(), (ushort)machineCode.Count); if (sIndex < 0) { return; } line = line.Remove(0, sIndex).Trim(); if (line.Length < 1) { return; } } string[] splitLine = SafeSplit(line); uint opCode = 0x0; string opCommand = splitLine[0].Trim(); if (opCommand.ToLower() == "dat") { ParseData(line, out errortext); return; } string opParam1 = splitLine[1].Trim(); string opParam2 = ""; if (!m_opDictionary.ContainsKey(opCommand)) { errortext = string.Format("Illegal cpu opcode --> {0}", splitLine[0]); throw new Exception(string.Format("Illegal cpu opcode --> {0}", splitLine[0])); } opCode = (uint)m_opDictionary[opCommand] & 0xF; if (opCode > 0x0) { opParam2 = splitLine[2];// basic function, has second param. } if (opCode > 0x00) { // Basic! OpParamResult p1 = ParseParam(opParam1, out errortext); OpParamResult p2 = ParseParam(opParam2, out errortext); opCode |= ((uint)p1.Param << 4) & 0x3F0; opCode |= ((uint)p2.Param << 10) & 0xFC00; machineCode.Add((ushort)opCode); if (p1.nextWord) { if (p1.labelName.Length > 0) { m_labelReferences.Add((ushort)machineCode.Count, p1.labelName); } machineCode.Add(p1.NextWordValue); } if (p2.nextWord) { if (p2.labelName.Length > 0) { m_labelReferences.Add((ushort)machineCode.Count, p2.labelName); } machineCode.Add(p2.NextWordValue); } } else { // Non basic opCode = (uint)m_opDictionary[opCommand]; OpParamResult p1 = ParseParam(opParam1, out errortext); opCode |= ((uint)p1.Param << 10) & 0xFC00; machineCode.Add((ushort)opCode); if (p1.nextWord) { if (p1.labelName.Length > 0) { m_labelReferences.Add((ushort)machineCode.Count, p1.labelName); } machineCode.Add(p1.NextWordValue); } } }
private OpParamResult ParseParam(string _param, out string errortext) { errortext = ""; OpParamResult opParamResult = new OpParamResult(); // Find easy ones. string Param = _param.Replace(" ", "").Trim(); // strip spaces if (m_regDictionary.ContainsKey(Param)) { // Ok things are really easy in this case. opParamResult.Param = (ushort)m_regDictionary[Param]; } else { if (Param[0] == '[' && Param[Param.Length - 1] == ']') { if (Param.Contains("+")) { string[] psplit = Param.Replace("[", "").Replace("]", "").Replace(" ", "").Split('+'); if (psplit.Length < 2) { errortext = string.Format("malformated memory reference '{0}'", Param); throw new Exception(string.Format("malformated memory reference '{0}'", Param)); } string addressValue = psplit[0]; if (m_regDictionary.ContainsKey("[+" + psplit[1] + "]") != true) { errortext = string.Format("Invalid register reference in '{0}'", Param); throw new Exception(string.Format("Invalid register reference in '{0}'", Param)); } opParamResult.Param = (ushort)m_regDictionary["[+" + psplit[1] + "]"]; opParamResult.nextWord = true; try { if (psplit[0][0] == '\'' && psplit[0][psplit[0].Length - 1] == '\'' && psplit[0].Length == 3) // nasty { ushort val = (ushort)psplit[0][1]; opParamResult.NextWordValue = (ushort)val; } else if (psplit[0].Contains("0x")) { ushort val = Convert.ToUInt16(psplit[0].Trim(), 16); opParamResult.NextWordValue = (ushort)val; } else { ushort val = Convert.ToUInt16(psplit[0].Trim(), 10); opParamResult.NextWordValue = (ushort)val; } } catch { opParamResult.nextWord = true; opParamResult.labelName = psplit[0].Trim(); } } else { opParamResult.Param = (ushort)dcpuRegisterCodes.NextWord_Literal_Mem; opParamResult.nextWord = true; try { if (Param[1] == '\'' && Param[Param.Length - 2] == '\'' && Param.Length == 5) // nasty { ushort val = (ushort)Param[1]; opParamResult.NextWordValue = (ushort)val; } else if (Param.Contains("0x")) { ushort val = (ushort)Convert.ToUInt16(Param.Replace("[", "").Replace("]", "").Trim(), 16); opParamResult.NextWordValue = val; } else { ushort val = (ushort)Convert.ToUInt16(Param.Replace("[", "").Replace("]", "").Trim(), 10); opParamResult.NextWordValue = val; } } catch { opParamResult.nextWord = true; opParamResult.labelName = Param.Replace("[", "").Replace("]", "").Trim(); } } } else { // if value is < 0x1F we can encode it into the param directly, // else it has to be next value! UInt16 maxValue = Convert.ToUInt16("0x1F", 16); UInt16 literalValue = 0; try { if (Param[0] == '\'' && Param[Param.Length - 1] == '\'' && Param.Length == 3) { literalValue = (ushort)Param[1]; } else if (Param.Contains("0x")) literalValue = Convert.ToUInt16(Param, 16); else literalValue = Convert.ToUInt16(Param, 10); if (literalValue < maxValue) { opParamResult.Param = Convert.ToUInt16("0x20", 16); opParamResult.Param += literalValue; } else { opParamResult.Param = (ushort)dcpuRegisterCodes.NextWord_Literal_Value; opParamResult.nextWord = true; opParamResult.NextWordValue = literalValue; } } catch { opParamResult.Param = (ushort)dcpuRegisterCodes.NextWord_Literal_Value; opParamResult.nextWord = true; opParamResult.labelName = Param; } } } return opParamResult; }