Highlight processor stages in (assembly) source code
MODIFY
src/editor/codeeditor.cpp
src/editor/codeeditor.cpp
namespace Ripes {
-CodeEditor::CodeEditor(QWidget* parent) : QPlainTextEdit(parent) {
+CodeEditor::CodeEditor(QWidget* parent) : HighlightableTextEdit(parent) {
m_lineNumberArea = new LineNumberArea(this);
connect(this, &QPlainTextEdit::blockCountChanged, this, &CodeEditor::updateSidebarWidth);
connect(this, &QPlainTextEdit::updateRequest, this, &CodeEditor::updateSidebar);
updateSidebarWidth(0);
+ connect(ProcessorHandler::get(), &ProcessorHandler::procStateChangedNonRun, this, &CodeEditor::updateHighlighting);
+
// Set font for the entire widget. calls to fontMetrics() will get the
// dimensions of the currently set font
m_font = QFont(Fonts::monospace, 11);
@@ -390,4 +392,52 @@ void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent* event) {
}
}
+void CodeEditor::updateHighlighting() {
+ clearBlockHighlights();
+
+ if (!RipesSettings::value(RIPES_SETTING_EDITORSTAGEHIGHLIGHTING).toBool())
+ return;
+
+ auto* proc = ProcessorHandler::getProcessor();
+ auto program = ProcessorHandler::getProgram().get();
+
+ // Is the current source in sync with the in-memory source?
+ if (!program || !program->isSameSource(document()->toPlainText().toUtf8()))
+ return;
+
+ auto sourceMapping = program->sourceMapping;
+
+ // Do nothing if no soruce mappings are available.
+ if (sourceMapping.empty())
+ return;
+
+ // Iterate over the processor stages and use the source mappings to determine the source line which originated the
+ // instruction.
+ const unsigned stages = proc->stageCount();
+ auto colorGenerator = Colors::incrementalRedGenerator(stages);
+ QList<QTextEdit::ExtraSelection> highlights;
+
+ for (unsigned sid = 0; sid < stages; sid++) {
+ const auto stageInfo = proc->stageInfo(sid);
+ if (stageInfo.stage_valid) {
+ auto sourceLine = sourceMapping.find(stageInfo.pc);
+ if (sourceLine == sourceMapping.end()) {
+ // No source line registerred for this PC.
+ continue;
+ }
+
+ // Find block
+ QTextBlock block = document()->findBlockByLineNumber(sourceLine->second);
+ if (!block.isValid())
+ continue;
+
+ // Record the stage name for the highlighted block for later painting
+ QString stageString = ProcessorHandler::getProcessor()->stageName(sid);
+ if (!stageInfo.namedState.isEmpty())
+ stageString += " (" + stageInfo.namedState + ")";
+ highlightBlock(block, colorGenerator(), stageString);
+ }
+ }
+}
+
} // namespace Ripes

MODIFY
src/editor/codeeditor.h
src/editor/codeeditor.h
#include "assembler/assembler.h"
#include "assembler/program.h"
+#include "highlightabletextedit.h"
#include "syntaxhighlighter.h"
#include <memory>
@@ -20,7 +21,7 @@ namespace Ripes {
class LineNumberArea;
-class CodeEditor : public QPlainTextEdit {
+class CodeEditor : public HighlightableTextEdit {
Q_OBJECT
public:
CodeEditor(QWidget* parent = nullptr);
@@ -47,6 +48,7 @@ signals:
protected:
void resizeEvent(QResizeEvent* event) override;
bool event(QEvent* e) override;
+ void updateHighlighting();
private slots:
void updateSidebarWidth(int newBlockCount);

MODIFY
src/ripessettings.cpp
src/ripessettings.cpp
@@ -31,6 +31,7 @@ const std::map<QString, QVariant> s_defaultSettings = {
{RIPES_SETTING_PERIPHERALS_START, static_cast<unsigned>(0xF0000000)},
{RIPES_SETTING_EDITORREGS, true},
{RIPES_SETTING_EDITORCONSOLE, true},
+ {RIPES_SETTING_EDITORSTAGEHIGHLIGHTING, true},
{RIPES_SETTING_PIPEDIAGRAM_MAXCYCLES, 100},
{RIPES_SETTING_CACHE_MAXCYCLES, 10000},

MODIFY
src/ripessettings.h
src/ripessettings.h
@@ -51,6 +51,7 @@ namespace Ripes {
#define RIPES_SETTING_AUTOCLOCK_INTERVAL ("autoclock_interval")
#define RIPES_SETTING_EDITORREGS ("editor_regs")
#define RIPES_SETTING_EDITORCONSOLE ("editor_console")
+#define RIPES_SETTING_EDITORSTAGEHIGHLIGHTING ("editor_stage_highlighting")
#define RIPES_SETTING_HAS_SAVEFILE ("has_savefile")
#define RIPES_SETTING_SAVEPATH ("savepath")

MODIFY
src/settingsdialog.cpp
src/settingsdialog.cpp
@@ -302,6 +302,11 @@ QWidget* SettingsDialog::createEditorPage() {
appendToLayout({consoleLabel, consoleCheckbox}, pageLayout,
"Show (or hide) a view of the console in the editor tab.");
+ auto [editorStageHighlightingLabel, editorStageHighlightingCheckbox] =
+ createSettingsWidgets<QCheckBox>(RIPES_SETTING_EDITORSTAGEHIGHLIGHTING, "Highlight stages in source");
+ appendToLayout({editorStageHighlightingLabel, editorStageHighlightingCheckbox}, pageLayout,
+ "Show (or hide) highlighting of processor stages in the program source code.");
+
// ===== Source formatter
auto* formatterGroupBox = new QGroupBox("Formatter");
appendToLayout(formatterGroupBox, pageLayout);

Highlight processor stages in (assembly) source code