Example #1
0
        /// <summary>
        /// Generates a pseudo-op statement for the specified data operation.
        ///
        /// For most operations, only one output line will be generated.  For larger items,
        /// like long comments, the value may be split into multiple lines.  The sub-index
        /// indicates which line should be formatted.
        /// </summary>
        /// <param name="formatter">Format definition.</param>
        /// <param name="opNames">Table of pseudo-op names.</param>
        /// <param name="symbolTable">Project symbol table.</param>
        /// <param name="labelMap">Symbol label map.  May be null.</param>
        /// <param name="dfd">Data format descriptor.</param>
        /// <param name="data">File data array.</param>
        /// <param name="offset">Start offset.</param>
        /// <param name="subIndex">For multi-line items, which line.</param>
        public static PseudoOut FormatDataOp(Formatter formatter, PseudoOpNames opNames,
                                             SymbolTable symbolTable, Dictionary <string, string> labelMap,
                                             FormatDescriptor dfd, byte[] data, int offset, int subIndex)
        {
            if (dfd == null)
            {
                // should never happen
                //Debug.Assert(false, "Null dfd at offset+" + offset.ToString("x6"));
                PseudoOut failed = new PseudoOut();
                failed.Opcode = failed.Operand = "!FAILED!+" + offset.ToString("x6");
                return(failed);
            }

            int length = dfd.Length;

            Debug.Assert(length > 0);

            // All outputs for a given offset show the same offset and length, even for
            // multi-line items.
            PseudoOut po = new PseudoOut();

            switch (dfd.FormatType)
            {
            case FormatDescriptor.Type.Default:
                if (length != 1)
                {
                    // This shouldn't happen.
                    Debug.Assert(false);
                    length = 1;
                }
                po.Opcode = opNames.GetDefineData(length);
                int operand = RawData.GetWord(data, offset, length, false);
                po.Operand = formatter.FormatHexValue(operand, length * 2);
                break;

            case FormatDescriptor.Type.NumericLE:
                po.Opcode  = opNames.GetDefineData(length);
                operand    = RawData.GetWord(data, offset, length, false);
                po.Operand = FormatNumericOperand(formatter, symbolTable, labelMap, dfd,
                                                  operand, length, FormatNumericOpFlags.None);
                break;

            case FormatDescriptor.Type.NumericBE:
                po.Opcode  = opNames.GetDefineBigData(length);
                operand    = RawData.GetWord(data, offset, length, true);
                po.Operand = FormatNumericOperand(formatter, symbolTable, labelMap, dfd,
                                                  operand, length, FormatNumericOpFlags.None);
                break;

            case FormatDescriptor.Type.Fill:
                po.Opcode  = opNames.Fill;
                po.Operand = length + "," + formatter.FormatHexValue(data[offset], 2);
                break;

            case FormatDescriptor.Type.Dense: {
                int maxPerLine = MAX_OPERAND_LEN / 2;
                offset += subIndex * maxPerLine;
                length -= subIndex * maxPerLine;
                if (length > maxPerLine)
                {
                    length = maxPerLine;
                }
                po.Opcode  = opNames.Dense;
                po.Operand = formatter.FormatDenseHex(data, offset, length);
                //List<PseudoOut> outList = new List<PseudoOut>();
                //GenerateTextLines(text, "", "", po, outList);
                //po = outList[subIndex];
            }
            break;

            case FormatDescriptor.Type.String:
                // It's hard to do strings in single-line pieces because of prefix lengths,
                // terminating nulls, DCI polarity, and reverse-order strings.  We
                // really just want to convert the whole thing to a run of chars
                // and then pull out a chunk.  As an optimization we can handle
                // generic strings (subtype=None) more efficiently, which should solve
                // the problem of massive strings created by auto-analysis.
                if (dfd.FormatSubType == FormatDescriptor.SubType.None)
                {
                    int maxPerLine = MAX_OPERAND_LEN - 2;
                    offset += subIndex * maxPerLine;
                    length -= subIndex * maxPerLine;
                    if (length > maxPerLine)
                    {
                        length = maxPerLine;
                    }
                    char[] ltext = BytesToChars(formatter, opNames, dfd.FormatSubType, data,
                                                offset, length, out string lpopcode, out int unused);
                    po.Opcode  = lpopcode;
                    po.Operand = "\u201c" + new string(ltext) + "\u201d";
                }
                else
                {
                    char[] text = BytesToChars(formatter, opNames, dfd.FormatSubType, data,
                                               offset, length, out string popcode, out int showHexZeroes);

                    if (showHexZeroes == 1)
                    {
                        po.Opcode  = opNames.DefineData1;
                        po.Operand = formatter.FormatHexValue(0, 2);
                    }
                    else if (showHexZeroes == 2)
                    {
                        po.Opcode  = opNames.DefineData2;
                        po.Operand = formatter.FormatHexValue(0, 4);
                    }
                    else
                    {
                        Debug.Assert(showHexZeroes == 0);
                        po.Opcode = popcode;
                        List <PseudoOut> outList = new List <PseudoOut>();
                        GenerateTextLines(text, "\u201c", "\u201d", po, outList);
                        po = outList[subIndex];
                    }
                }
                break;

            default:
                Debug.Assert(false);
                po.Opcode  = ".???";
                po.Operand = "$" + data[offset].ToString("x2");
                break;
            }

            return(po);
        }
Example #2
0
        /// <summary>
        /// Generates a pseudo-op statement for the specified data operation.
        ///
        /// For most operations, only one output line will be generated.  For larger items,
        /// like dense hex, the value may be split into multiple lines.  The sub-index
        /// indicates which line should be formatted.
        /// </summary>
        /// <param name="formatter">Format definition.</param>
        /// <param name="opNames">Table of pseudo-op names.</param>
        /// <param name="symbolTable">Project symbol table.</param>
        /// <param name="labelMap">Symbol label map.  May be null.</param>
        /// <param name="dfd">Data format descriptor.</param>
        /// <param name="data">File data array.</param>
        /// <param name="offset">Start offset.</param>
        /// <param name="subIndex">For multi-line items, which line.</param>
        public static PseudoOut FormatDataOp(Formatter formatter, PseudoOpNames opNames,
                                             SymbolTable symbolTable, Dictionary <string, string> labelMap,
                                             FormatDescriptor dfd, byte[] data, int offset, int subIndex)
        {
            if (dfd == null)
            {
                // should never happen
                //Debug.Assert(false, "Null dfd at offset+" + offset.ToString("x6"));
                PseudoOut failed = new PseudoOut();
                failed.Opcode = failed.Operand = "!FAILED!+" + offset.ToString("x6");
                return(failed);
            }

            int length = dfd.Length;

            Debug.Assert(length > 0);

            // All outputs for a given offset show the same offset and length, even for
            // multi-line items.
            PseudoOut po = new PseudoOut();

            if (dfd.IsString)
            {
                Debug.Assert(false);        // shouldn't be calling here anymore
                List <string> lines = FormatStringOp(formatter, opNames, dfd, data,
                                                     offset, out string popcode);
                po.Opcode  = popcode;
                po.Operand = lines[subIndex];
            }
            else
            {
                switch (dfd.FormatType)
                {
                case FormatDescriptor.Type.Default:
                    if (length != 1)
                    {
                        // This shouldn't happen.
                        Debug.Assert(false);
                        length = 1;
                    }
                    po.Opcode = opNames.GetDefineData(length);
                    int operand = RawData.GetWord(data, offset, length, false);
                    po.Operand = formatter.FormatHexValue(operand, length * 2);
                    break;

                case FormatDescriptor.Type.NumericLE:
                    po.Opcode  = opNames.GetDefineData(length);
                    operand    = RawData.GetWord(data, offset, length, false);
                    po.Operand = FormatNumericOperand(formatter, symbolTable, labelMap,
                                                      dfd, operand, length, FormatNumericOpFlags.None);
                    break;

                case FormatDescriptor.Type.NumericBE:
                    po.Opcode  = opNames.GetDefineBigData(length);
                    operand    = RawData.GetWord(data, offset, length, true);
                    po.Operand = FormatNumericOperand(formatter, symbolTable, labelMap,
                                                      dfd, operand, length, FormatNumericOpFlags.None);
                    break;

                case FormatDescriptor.Type.Fill:
                    po.Opcode  = opNames.Fill;
                    po.Operand = length + "," + formatter.FormatHexValue(data[offset], 2);
                    break;

                case FormatDescriptor.Type.Junk:
                    if (dfd.FormatSubType != FormatDescriptor.SubType.None)
                    {
                        po.Opcode = opNames.Align;
                        int alignPow = FormatDescriptor.AlignmentToPower(dfd.FormatSubType);
                        po.Operand = formatter.FormatHexValue(1 << alignPow, 2) +
                                     " (" + length.ToString() + " bytes)";
                    }
                    else
                    {
                        po.Opcode  = opNames.Junk;
                        po.Operand = length.ToString();
                    }
                    break;

                case FormatDescriptor.Type.Dense: {
                    int maxPerLine = MAX_OPERAND_LEN / 2;
                    offset += subIndex * maxPerLine;
                    length -= subIndex * maxPerLine;
                    if (length > maxPerLine)
                    {
                        length = maxPerLine;
                    }
                    po.Opcode  = opNames.Dense;
                    po.Operand = formatter.FormatDenseHex(data, offset, length);
                    //List<PseudoOut> outList = new List<PseudoOut>();
                    //GenerateTextLines(text, "", "", po, outList);
                    //po = outList[subIndex];
                }
                break;

                default:
                    Debug.Assert(false);
                    po.Opcode  = ".???";
                    po.Operand = "$" + data[offset].ToString("x2");
                    break;
                }
            }

            return(po);
        }