private static FXRegisterMN GetRegisterMN(OperandDetails details, Dictionary<string, FXRegister> registerList, ref int valueValue) { if (details.Name.Equals(FXConfigReader.KCONSTANT, StringComparison.CurrentCultureIgnoreCase)) //如果是K常数 { FXRegisterMN mn = new FXRegisterMN(); mn.M = 0; mn.N = 0; mn.From = 0; mn.To = 0; valueValue = Convert.ToInt32(details.Value, 10); return mn; } if (details.Name.Equals(FXConfigReader.HCONSTANT, StringComparison.CurrentCultureIgnoreCase)) //如果是H常数 { FXRegisterMN mn = new FXRegisterMN(); mn.M = 2; mn.N = 0; mn.From = 0; mn.To = 0; valueValue = Convert.ToInt32(details.Value, 16); return mn; } if (registerList.ContainsKey(details.Name)) { FXRegister register = registerList[details.Name]; int detailsValue = Convert.ToInt32(details.Value, (int)register.NameFormatType); foreach (FXRegisterMN mn in register.MN) { if (detailsValue >= mn.From && detailsValue <= mn.To) { if (!mn.IsPoint) { //valueValue = (detailsValue - mn.From + mn.Offset) * 2; valueValue = ((detailsValue - mn.From) * mn.Step + mn.Offset) * 2; return mn; } else { valueValue = detailsValue - register.From + register.AddrFrom + register.Offset; FXRegisterMN tempMN = new FXRegisterMN(); tempMN.From = mn.From; tempMN.To = mn.To; tempMN.IsPoint = mn.IsPoint; tempMN.Offset = mn.Offset; tempMN.M = 4; tempMN.N = details.Bits / 2; return tempMN; } } } throw new Exception("No Such Operand Value! " + details.Value + ". At " + FXComplier.m_nowProcessLine.BasicLineStr); } else throw new Exception("No Such Operand Name! " + details.Name + ". At " + FXComplier.m_nowProcessLine.BasicLineStr); }
private static string ComplieAppCmdStr(FXAppCmd cmd, OperandDetails[] detailsArray, Dictionary<string, FXRegister> registerList) { int funcValue = (cmd.FuncNO + 8) * 2; //命令的值 bool is32bit = false; if (cmd.AppCmdType == FXAppCmdType.D) { funcValue = funcValue + 1; is32bit = true; } if (cmd.AppCmdType == FXAppCmdType.P) { funcValue = funcValue + 0x1000; } if (cmd.AppCmdType == FXAppCmdType.DP) { funcValue = funcValue + 0x1001; is32bit = true; } string valueStr = Utils.FillStringWithChar(funcValue.ToString("X"), FXConfigReader.ZEROCHAR, 4, true); foreach (OperandDetails details in detailsArray) { int valueValue = 0; FXRegisterMN mn = GetRegisterMN(details, registerList, ref valueValue); if (!is32bit) //如果是16bit的 { int valueLow = 0x8000 + 0x100 * mn.M + (valueValue & 0xFF); int valueHigh = 0x8000 + 0x100 * mn.N + ((valueValue & 0xFF00) >> 8); valueStr = valueStr + " " + valueLow.ToString("X") + " " + valueHigh.ToString("X"); } else { int valueLowest = 0x8000 + 0x100 * mn.M + (valueValue & 0xFF); int valueLow = 0x8000 + 0x100 * mn.N + ((valueValue & 0xFF00) >> 8); int valueHigh = 0x8000 + ((valueValue & 0xFF0000) >> 16); int valueHighest = 0x8000 + (int)((valueValue & 0xFF000000) >> 24); valueStr = valueStr + " " + valueLowest.ToString("X") + " " + valueLow.ToString("X") + " " + valueHigh.ToString("X") + " " + valueHighest.ToString("X"); } } return valueStr; }
/// <summary> /// 将一个软元件符号分解为"类型"+"编号"的形式,如M800=>M,800 /// 也有可能是K4M100之类的组合操作数,这时候类型依然为M,编号依然为100,但OperandDetails.Bits=4*4 /// </summary> /// <param name="operandStr">形如Y001的软元件编号</param> /// <returns>返回OperandDetails实例</returns> private static OperandDetails GetOperandDetails(string operandStr, List<OperandMap> mapList) { List<int> letterIndex = new List<int>(); letterIndex.Add(0); for (int i = 1; i < operandStr.Length; i++) { char tempChar = operandStr[i]; if (!((0x30 <= tempChar && 0x39 >= tempChar) || 0x2D == tempChar)) letterIndex.Add(i); } OperandDetails details = new OperandDetails(); if (letterIndex.Count == 1) //单一操作数 { details.Name = operandStr.Substring(0, letterIndex[0] + 1); details.Value = operandStr.Substring(letterIndex[0] + 1, operandStr.Length - letterIndex[0] - 1); //int value = GetKHConstantValue(details.Name, details.Value); //if (value != -1) // details.Value = value.ToString("X"); details.Bits = -1; } else if (letterIndex.Count == 2) //iron { string constName = operandStr.Substring(0, letterIndex[0] + 1); string constValue = operandStr.Substring(letterIndex[0] + 1, letterIndex[1] - letterIndex[0] - 1); string operandName = operandStr.Substring(letterIndex[1], 1); string operandValue = operandStr.Substring(letterIndex[1] + 1, operandStr.Length - letterIndex[1] - 1); NumberParseResult bitsResult = GetKHConstantValue(constName, constValue); details.Bits = bitsResult.Value * 4; details.Name = operandName; details.Value = operandValue; } DoRegisterMapping(mapList, ref details); return details; }
private static string GetOneLineCmdStr(IFXCmd cmd, List<string> paramArray, Dictionary<string, FXRegister> registerList, List<OperandMap> mapList) { string result = null; OperandDetails[] operandDetails = new OperandDetails[paramArray.Count]; string[] paramNameArray = new string[paramArray.Count]; for (int i = 0; i < paramArray.Count; i++) { operandDetails[i] = GetOperandDetails(paramArray[i], mapList); paramNameArray[i] = operandDetails[i].Name; } if (cmd.CmdType == FXCmdType.Basic) //如果是基本型的命令 { FXBasicCmd basicCmd = (FXBasicCmd)cmd; FXBasicCmdCharacter character = GetBasicCmdCharacter(basicCmd, paramNameArray); result = ComplieBasicCmdStr(character, operandDetails, registerList); } else //如果是应用型的命令 { FXAppCmd appCmd = (FXAppCmd)cmd; result = ComplieAppCmdStr(appCmd, operandDetails, registerList); } return result; }
/// <summary> /// 获得基本指令的操作数的绝对地址,以10进制的数字表示 /// </summary> /// <param name="details">操作数的具体信息</param> /// <param name="registerList">寄存器对照表</param> /// <returns></returns> private static NumberParseResult GetBasicCmdOperandAbsAddr(OperandDetails details, Dictionary<string, FXRegister> registerList) { NumberParseResult result = GetKHConstantValue(details.Name, details.Value); if (!result.IsSuccess) { if (registerList.ContainsKey(details.Name)) { FXRegister register = registerList[details.Name]; int relative = Convert.ToInt32(details.Value, (int)register.NameFormatType); result.Value = relative - register.From + register.AddrFrom + register.Offset; result.IsSuccess = true; } else throw new Exception("Operand not exist. At " + FXComplier.m_nowProcessLine.BasicLineStr); } return result; }
private static void DoRegisterMapping(List<OperandMap> mapLst, ref OperandDetails details) { foreach (OperandMap map in mapLst) { if ((!details.Name.Equals(FXConfigReader.HCONSTANT, StringComparison.CurrentCultureIgnoreCase)) && (!details.Name.Equals(FXConfigReader.KCONSTANT, StringComparison.CurrentCultureIgnoreCase))) { int detailsValue = Convert.ToInt32(details.Value, 16); bool isValueInRange = (detailsValue >= map.From) & (detailsValue <= map.To); bool isSameName = details.Name.Equals(map.Name); if (isSameName && isValueInRange) { details.Name = map.ReName; break; } } } }
private static string ComplieBasicCmdStr(FXBasicCmdCharacter character, OperandDetails[] detailsArray, Dictionary<string, FXRegister> registerList) { if (character.BasicCmdType == FXBasicCmdType.PureSingle) //如果是纯单字指令,那么需要判断是否有ppp占位符 { return character.Value; } if (character.BasicCmdType == FXBasicCmdType.Single || character.BasicCmdType == FXBasicCmdType.Double) { int absAddr = GetBasicCmdOperandAbsAddr(detailsArray[0], registerList).Value; int indexOfLastBlank = character.Value.LastIndexOf(FXConfigReader.BLANKSTR); int indexOfPPP = character.Value.IndexOf(FXConfigReader.PPPSTR); //int indexOfN = character.Value.IndexOf(FXComplier.NSTR); if (indexOfPPP > 0) //如果是ppp表达式,那么从最后一个空格到+ppp之间的就是需要相加的数 { int index = indexOfPPP;// > 0 ? indexOfPPP : indexOfN; string toBeAddStr = character.Value.Substring(indexOfLastBlank + 1, index - indexOfLastBlank - 1); int resultInt = Convert.ToInt32(toBeAddStr, 16) + absAddr; string resultStr = resultInt.ToString("X"); resultStr = Utils.FillStringWithChar(resultStr, FXConfigReader.ZEROCHAR, 4, true); //return indexOfPPP > 0 ? character.Value.Replace(toBeAddStr + FXComplier.PPPSTR, resultStr) : character.Value.Replace(toBeAddStr + FXComplier.NSTR, resultStr); return character.Value.Replace(toBeAddStr + FXConfigReader.PPPSTR, resultStr); } } if (character.BasicCmdType == FXBasicCmdType.Triple || character.BasicCmdType == FXBasicCmdType.Five) { int[] absAddrArray = new int[detailsArray.Length]; for (int i = 0; i < detailsArray.Length; i++) { absAddrArray[i] = GetBasicCmdOperandAbsAddr(detailsArray[i], registerList).Value; } string cmdReplaced = ReplacePlaceHolder(character.Value, absAddrArray); cmdReplaced = ReplaceDigitIndecaterAndDoAddition(cmdReplaced); return cmdReplaced; } return null; }