public CodeDisassemblyForm(NesCore.Console console) { InitializeComponent(); this.console = console; this.processor = console.Processor; disassemblyLines = new DisassemblyLine[0x10000]; disassemblyLineSource = new string[0x10000]; addressLabels = new string[0x10000]; queuedAddresses = new bool[0x10000]; lastRefresh = DateTime.Now; needsRefresh = true; this.disassemblyQueue = new Queue <ushort>(); #if DEBUG disassemblyTimer.Enabled = false; #endif }
private void OnDisassemblyTick(object sender, EventArgs e) { int linesToDisassemble = Math.Min(10, disassemblyQueue.Count); if (linesToDisassemble-- > 0) { ushort address = disassemblyQueue.Dequeue(); queuedAddresses[address] = false; DisassembleLine(address); } if (needsRefresh && (DateTime.Now - lastRefresh).TotalSeconds > 5) { lastRefresh = DateTime.Now; SuspendRedraw(disassemblyRichTextBox); disassemblyRichTextBox.Clear(); for (int address = 0; address < 0x10000; address++) { /* * if (queuedAddresses[address]) * { * disassemblyRichTextBox.SelectionColor = Color.Gray; * disassemblyRichTextBox.AppendText("Queued for disassembly...\r\n"); * continue; * }*/ DisassemblyLine disassemblyLine = disassemblyLines[address]; if (disassemblyLine == null) { continue; } string label = disassemblyLine.Label; if (label != null) { disassemblyRichTextBox.SelectionColor = Color.Green; disassemblyRichTextBox.AppendText((label + ":").PadRight(16)); } else { disassemblyRichTextBox.AppendText("".PadRight(16)); } disassemblyRichTextBox.SelectionColor = Color.DarkRed; disassemblyRichTextBox.AppendText(disassemblyLine.Address + " "); disassemblyRichTextBox.SelectionColor = Color.DarkBlue; disassemblyRichTextBox.AppendText(disassemblyLine.MachineCode.PadRight(12)); disassemblyRichTextBox.SelectionColor = Color.Black; disassemblyRichTextBox.AppendText(disassemblyLine.Source.PadRight(14)); string remarks = disassemblyLine.Remarks; if (remarks != null) { disassemblyRichTextBox.SelectionColor = Color.Gray; disassemblyRichTextBox.AppendText("; " + remarks); } disassemblyRichTextBox.AppendText("\r\n"); } ResumeRedraw(disassemblyRichTextBox); needsRefresh = false; } }
private void DisassembleLine(ushort address) { if (disassemblyLines[address] != null) { return; } // prepare main labels ushort resetVector = processor.ReadWord(Mos6502.ResetVector); addressLabels[resetVector] = "Start"; ushort irqVector = processor.ReadWord(Mos6502.IrqVector); addressLabels[irqVector] = "IrqHandler"; ushort nmiVector = processor.ReadWord(Mos6502.NmiVector); addressLabels[nmiVector] = "NmiHandler"; DisassemblyLine disassemblyLine = new DisassemblyLine(); disassemblyLine.Address = Hex.Format(address); byte opCode = console.Memory[address]; // determine instruction meta data Instruction instruction = console.Processor.InstructionSet[opCode]; // machine code ushort operandAddress = (ushort)(address + 1); if (instruction.Size == 1) { disassemblyLine.MachineCode = Hex.Format(opCode); } else if (instruction.Size == 2) { disassemblyLine.MachineCode = Hex.Format(opCode) + " " + Hex.Format(processor.ReadByte(operandAddress)); } else // 3 { disassemblyLine.MachineCode = Hex.Format(opCode) + " " + Hex.Format(processor.ReadByte(operandAddress)) + " " + Hex.Format(processor.ReadByte((ushort)(operandAddress + 1))); } // format instruction source disassemblyLine.Source = instruction.Name + " " + FormatOperand(operandAddress, instruction.AddressingMode); // remarks if (instruction.Name == "RTS") { disassemblyLine.Remarks = "- end of subroutine ---------"; } if (instruction.Name == "RTI") { disassemblyLine.Remarks = "- end of interrupt handler --"; } // if label assigned by forward branching or jumping, assign to new disassembled line if (addressLabels[address] != null) { disassemblyLine.Label = addressLabels[address]; } // determine labels for relative branching if (instruction.AddressingMode == AddressingMode.Relative) { ushort nextInstructionAddress = (ushort)(address + 2); sbyte offset = (sbyte)processor.ReadByte(operandAddress); ushort branchAddress = (ushort)(nextInstructionAddress + offset); string addressLabel = GetAddressLabel("RelBr", branchAddress); disassemblyLine.Remarks = "branch to " + addressLabel; } // determine labels for absolute jumps if (instruction.AddressingMode == AddressingMode.Absolute) { ushort destAddress = processor.ReadWord(operandAddress); if (instruction.Name == "JMP") { string addressLabel = GetAddressLabel("AbsBr", destAddress); disassemblyLine.Remarks = "jump to " + addressLabel; } else if (instruction.Name == "JSR") { string addressLabel = GetAddressLabel("SubRt", destAddress); disassemblyLine.Remarks = "call subroutine at " + addressLabel; } } disassemblyLines[address] = disassemblyLine; disassemblyLineSource[address] = disassemblyLine.ToString(); needsRefresh = true; }