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))); } } }
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); }
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); }