Example #1
0
        void PreloadDisassembly(DisasmLine pDisasm, Stack <DisasmRequest> pAddressStack, int pDepth)
        {
            if (pDisasm.Instruction.Operands == null)
            {
                return;
            }

            foreach (var op in pDisasm.Instruction.Operands)
            {
                if (op.Type == Disassembler.Operand.TypeEnum.CodeAddr)
                {
                    pAddressStack.Push(new DisasmRequest(pDepth, op.Value));
                }
                else if (op.Type == Disassembler.Operand.TypeEnum.CodeRel)
                {
                    pAddressStack.Push(new DisasmRequest(pDepth, (ushort)(pDisasm.Offset + (sbyte)op.Value)));
                }
            }
        }
Example #2
0
        string FormatInstruction(DisasmLine line, BankID bankId, ushort bankOffset)
        {
            var instruction = line.Instruction;

            string comment = null;
            var    text    = instruction.Text;

            if (instruction.Operands != null && instruction.Operands.Length > 0)
            {
                foreach (var op in instruction.Operands)
                {
                    int          offset;
                    int          absOffset;
                    char         sign;
                    List <Label> labels;

                    switch (op.Type)
                    {
                    case Disassembler.Operand.TypeEnum.Imm8:
                        text = text.ReplaceFirst("{b}", ((byte)op.Value).ToHex());
                        break;

                    case Disassembler.Operand.TypeEnum.Imm16:
                        text = text.ReplaceFirst("{w}", op.Value.ToHex());
                        break;

                    case Disassembler.Operand.TypeEnum.Index:
                        offset    = (sbyte)op.Value;
                        sign      = offset < 0 ? '-' : '+';
                        absOffset = Math.Abs(offset);
                        text      = text.ReplaceFirst("{+i}", $"{sign}{( (byte) absOffset ).ToHex()}");
                        break;

                    case Disassembler.Operand.TypeEnum.CodeRel:
                        offset = (sbyte)op.Value;
                        sign   = offset < 0 ? '-' : '+';

                        var addr = (ushort)(bankOffset + line.Offset + offset + line.Instruction.Length);

                        labels    = GetLabels(bankId, addr)?.Labels;
                        absOffset = Math.Abs(offset);

                        if (labels != null)
                        {
                            text    = text.ReplaceFirst("{+b}", labels[0].Name);
                            comment = $"{sign}{( (byte) absOffset ).ToHex()} {addr.ToHex()} ";
                        }
                        else
                        {
                            text    = text.ReplaceFirst("{+b}", addr.ToHex());
                            comment = $"{sign}{( (byte) absOffset ).ToHex()}";
                        }

                        break;

                    case Disassembler.Operand.TypeEnum.DataAddr:

                        labels = GetLabels(bankId, op.Value)?.Labels;

                        if (labels != null)
                        {
                            text    = text.ReplaceFirst("{data}", labels[0].Name);
                            comment = op.Value.ToHex();
                        }
                        else
                        {
                            text = text.ReplaceFirst("{data}", op.Value.ToHex());
                        }

                        break;

                    case Disassembler.Operand.TypeEnum.CodeAddr:

                        labels = GetLabels(bankId, op.Value)?.Labels;

                        if (labels != null)
                        {
                            text    = text.ReplaceFirst("{code}", labels[0].Name);
                            comment = op.Value.ToHex();
                        }
                        else
                        {
                            text = text.ReplaceFirst("{code}", op.Value.ToHex());
                        }

                        break;
                    }
                }
            }

            if (comment != null)
            {
                text = text.PadRight(30) + "; " + comment;
            }

            return(text);
        }
Example #3
0
        bool UpdateDisassemblyInternal(ushort address, Stack <DisasmRequest> requests, int maxDepth)
        {
            // note: assumes disassembly can only cover a maximum of two memory slots

            // find starting slot & bank
            var minSlot = Memory.GetSlot(address);
            var minBank = GetDisasmBank(minSlot.Bank.ID);

            if (!NeedDisassembly(address, minSlot, minBank))
            {
                return(false);
            }

            Connection.ReadMemory(address, _tempBytes, 0, _tempBytes.Length);

            var index = 0;

            try
            {
                Disassembler.Instruction instruction;

                while ((instruction = Disassembler.Disassemble(_tempBytes, index)) != null && _tempDisasm.Count < 30)
                {
                    var il = new DisasmLine()
                    {
                        Bank        = minBank,
                        Offset      = (ushort)(address + index),
                        Instruction = instruction
                    };

                    _tempDisasm.Add(il);

                    index += instruction.Length;

                    // check for recursive disassembly
                    if (maxDepth > 0)
                    {
                        PreloadDisassembly(il, requests, maxDepth - 1);
                    }
                }
            }
            catch (Exception e)
            {
                LogError(e.ToString());
            }

            if (_tempDisasm.Count == 0)
            {
                return(false);
            }


            // record newly-disassembled lines

            var maxLine = _tempDisasm[_tempDisasm.Count - 1];
            var maxSlot = Memory.GetSlot(maxLine.Offset);
            var maxBank = GetDisasmBank(maxSlot.Bank.ID);

            foreach (var line in _tempDisasm)
            {
                var slot  = line.Offset <= minSlot.Max ? minSlot : maxSlot;
                var bank  = line.Offset <= minSlot.Max ? minBank : maxBank;
                var lines = bank.Lines;

                var offset = (ushort)(line.Offset - slot.Min);
                if (!lines.ContainsKey(offset))
                {
                    line.Offset   = offset;
                    lines[offset] = line;
                    bank.SortedLines.Add(line);
                }

                if (ShouldFinishDisassembling(line.Instruction.Bytes))
                {
                    break;
                }
            }

            _tempDisasm.Clear();

            return(true);
        }