Skip to content

Commit 73b0a03

Browse files
committed
Merge remote-tracking branch 'origin/master' into blendsplitter
Keeping up to date with the latest work on the BreakpointViewer
2 parents 39c7752 + 2b781b5 commit 73b0a03

File tree

10 files changed

+289
-261
lines changed

10 files changed

+289
-261
lines changed

src/BreakpointViewer.cpp

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "BreakpointViewer.h"
22
#include "Convert.h"
33
#include "CommClient.h"
4+
#include "DebugSession.h"
45
#include "OpenMSXConnection.h"
56
#include "ScopedAssign.h"
67
#include "ranges.h"
@@ -17,17 +18,18 @@ enum TableColumns {
1718
ENABLED = 0,
1819
WP_TYPE = 1,
1920
LOCATION = 2,
20-
BP_ADDRESS = 2,
2121
WP_REGION = 2,
2222
T_CONDITION = 3,
2323
SLOT = 4,
2424
SEGMENT = 5,
25-
ID = 6
25+
ID = 6,
26+
REAL_ADDRESS = 7,
2627
};
2728

28-
BreakpointViewer::BreakpointViewer(QWidget* parent)
29-
: QTabWidget(parent),
30-
ui(new Ui::BreakpointViewer)
29+
BreakpointViewer::BreakpointViewer(DebugSession& session, QWidget* parent)
30+
: QTabWidget(parent),
31+
ui(new Ui::BreakpointViewer),
32+
debugSession(session)
3133
{
3234
setupUi(this);
3335

@@ -39,9 +41,10 @@ BreakpointViewer::BreakpointViewer(QWidget* parent)
3941
connect(btnRemoveCn, &QPushButton::clicked, this, &BreakpointViewer::on_btnRemoveCn_clicked);
4042

4143
bpTableWidget->horizontalHeader()->setHighlightSections(false);
42-
bpTableWidget->sortByColumn(BP_ADDRESS, Qt::AscendingOrder);
44+
bpTableWidget->sortByColumn(LOCATION, Qt::AscendingOrder);
4345
bpTableWidget->setColumnHidden(WP_TYPE, true);
4446
bpTableWidget->setColumnHidden(ID, true);
47+
bpTableWidget->setColumnHidden(REAL_ADDRESS, true);
4548
bpTableWidget->resizeColumnsToContents();
4649
bpTableWidget->setSortingEnabled(true);
4750
connect(bpTableWidget, &QTableWidget::itemPressed, this, &BreakpointViewer::on_itemPressed);
@@ -51,6 +54,7 @@ BreakpointViewer::BreakpointViewer(QWidget* parent)
5154

5255
wpTableWidget->horizontalHeader()->setHighlightSections(false);
5356
wpTableWidget->setColumnHidden(ID, true);
57+
wpTableWidget->setColumnHidden(REAL_ADDRESS, true);
5458
wpTableWidget->sortByColumn(WP_REGION, Qt::AscendingOrder);
5559
wpTableWidget->resizeColumnsToContents();
5660
wpTableWidget->setSortingEnabled(true);
@@ -254,7 +258,7 @@ void BreakpointViewer::setBreakpointChecked(BreakpointRef::Type type, int row, Q
254258
table->setSortingEnabled(oldValue);
255259
}
256260

257-
void BreakpointViewer::setTextField(BreakpointRef::Type type, int row, int column, const QString& value)
261+
void BreakpointViewer::setTextField(BreakpointRef::Type type, int row, int column, const QString& value, const QString& tooltip)
258262
{
259263
auto sa = ScopedAssign(userMode, false);
260264

@@ -264,6 +268,7 @@ void BreakpointViewer::setTextField(BreakpointRef::Type type, int row, int colum
264268

265269
table->setSortingEnabled(false);
266270
item->setText(value);
271+
item->setToolTip(tooltip);
267272
table->setSortingEnabled(oldValue);
268273
}
269274

@@ -309,13 +314,24 @@ std::optional<uint8_t> BreakpointViewer::parseSegmentField(std::optional<int> in
309314
return {};
310315
}
311316

317+
std::optional<AddressRange> BreakpointViewer::parseSymbolOrValue(const QString& field) const
318+
{
319+
if (Symbol* s = debugSession.symbolTable().getAddressSymbol(field)) {
320+
return AddressRange{uint16_t(s->value())};
321+
}
322+
if (auto address = stringToValue<uint16_t>(field)) {
323+
return AddressRange{*address};
324+
}
325+
return {};
326+
}
327+
312328
static const char* ComboTypeNames[] = { "read_mem", "write_mem", "read_io", "write_io" };
313329

314330
std::optional<AddressRange> BreakpointViewer::parseLocationField(
315331
std::optional<int> index, BreakpointRef::Type type, const QString& field, const QString& comboTxt)
316332
{
317333
if (type == BreakpointRef::BREAKPOINT) {
318-
auto value = stringToValue<uint16_t>(field);
334+
auto value = parseSymbolOrValue(field);
319335
return value ? AddressRange{*value}
320336
: (index ? breakpoints->getBreakpoint(*index).range : std::optional<AddressRange>());
321337
}
@@ -367,27 +383,32 @@ void BreakpointViewer::changeTableItem(BreakpointRef::Type type, QTableWidgetIte
367383
case LOCATION: {
368384
auto* model = table->model();
369385
auto* combo = (QComboBox*) table->indexWidget(model->index(row, WP_TYPE));
370-
int adrLen;
386+
int adrLen;
371387

372388
if (type == BreakpointRef::CONDITION) {
373389
return;
374390
} else if (type == BreakpointRef::WATCHPOINT) {
375391
auto wType = static_cast<Breakpoint::Type>(combo->currentIndex() + 1);
376392
adrLen = (wType == Breakpoint::WATCHPOINT_IOREAD || wType == Breakpoint::WATCHPOINT_IOWRITE)
377-
? 2 : 4;
393+
? 2 : 4;
378394
} else {
379395
adrLen = 4;
380396
}
381397

382398
if (auto range = parseLocationField(index, type, item->text(), combo ? combo->currentText() : "")) {
383399
auto [begin, end] = *range;
384-
setTextField(type, row, LOCATION, QString("%1%2%3")
385-
.arg(hexValue(begin, adrLen))
386-
.arg(end ? ":" : "")
387-
.arg(end ? hexValue(*end, adrLen) : ""));
400+
QString address = QString("%1%2%3")
401+
.arg(hexValue(begin, adrLen))
402+
.arg(end ? ":" : "")
403+
.arg(end ? hexValue(*end, adrLen) : "");
404+
// Use a symbolic address in the location field if available
405+
QString location = debugSession.symbolTable().getAddressSymbol(item->text()) ? item->text() : address;
406+
setTextField(type, row, LOCATION, location, location != address ? address : "");
407+
setTextField(type, row, REAL_ADDRESS, address);
388408
} else {
389409
enabled = false;
390410
setTextField(type, row, LOCATION, "");
411+
setTextField(type, row, REAL_ADDRESS, "");
391412
setBreakpointChecked(type, row, Qt::Unchecked);
392413
}
393414
if (!enabled) return;
@@ -706,7 +727,7 @@ int BreakpointViewer::createTableRow(BreakpointRef::Type type, int row)
706727
createComboBox(row);
707728
}
708729

709-
// address
730+
// location
710731
auto* item2 = new QTableWidgetItem();
711732
item2->setTextAlignment(Qt::AlignCenter);
712733
table->setItem(row, LOCATION, item2);
@@ -742,6 +763,12 @@ int BreakpointViewer::createTableRow(BreakpointRef::Type type, int row)
742763
item6->setText("");
743764
table->setItem(row, ID, item6);
744765

766+
// real_address
767+
auto* item7 = new QTableWidgetItem();
768+
item7->setFlags(Qt::NoItemFlags);
769+
item7->setText("");
770+
table->setItem(row, REAL_ADDRESS, item7);
771+
745772
return row;
746773
}
747774

@@ -762,15 +789,24 @@ void BreakpointViewer::fillTableRow(int index, BreakpointRef::Type type, int row
762789
combo->setCurrentIndex(static_cast<int>(bp.type) - 1);
763790
}
764791

765-
// location
766-
int locLen = (bp.type == Breakpoint::WATCHPOINT_IOREAD
767-
|| bp.type == Breakpoint::WATCHPOINT_IOWRITE) ? 2 : 4;
768-
QString location = QString("%1%2%3").arg(hexValue(bp.range->start, locLen))
769-
.arg(bp.range->end ? ":" : "")
770-
.arg(bp.range->end ? hexValue(*bp.range->end, locLen) : "");
771-
772792
// location
773793
auto* item2 = table->item(row, LOCATION);
794+
QString location;
795+
796+
if (bp.type == Breakpoint::BREAKPOINT) {
797+
if (Symbol* s = debugSession.symbolTable().getAddressSymbol(item2->text())) {
798+
if (s->value() == bp.range->start) {
799+
location = s->text();
800+
}
801+
}
802+
}
803+
if (location.isEmpty()) {
804+
int locLen = (bp.type == Breakpoint::WATCHPOINT_IOREAD
805+
|| bp.type == Breakpoint::WATCHPOINT_IOWRITE) ? 2 : 4;
806+
location = QString("%1%2%3").arg(hexValue(bp.range->start, locLen))
807+
.arg(bp.range->end ? ":" : "")
808+
.arg(bp.range->end ? hexValue(*bp.range->end, locLen) : "");
809+
}
774810
item2->setText(location);
775811

776812
auto* item3 = table->item(row, T_CONDITION);
@@ -817,6 +853,27 @@ std::optional<Breakpoint> BreakpointViewer::parseTableRow(BreakpointRef::Type ty
817853
return bp;
818854
}
819855

856+
857+
void BreakpointViewer::onSymbolTableChanged()
858+
{
859+
for (int row = 0; row < bpTableWidget->rowCount(); ++row) {
860+
auto* item = bpTableWidget->item(row, REAL_ADDRESS);
861+
862+
// scan tooltip validity
863+
if (!item->text().isEmpty()) {
864+
Symbol* s = debugSession.symbolTable().getAddressSymbol(item->text());
865+
auto address = stringToValue<uint16_t>(item->text());
866+
assert(address);
867+
868+
if (!s || *address != s->value()) {
869+
setTextField(BreakpointRef::BREAKPOINT, row, LOCATION, item->text());
870+
setTextField(BreakpointRef::BREAKPOINT, row, REAL_ADDRESS, "");
871+
}
872+
}
873+
}
874+
}
875+
876+
820877
void BreakpointViewer::onAddBtnClicked(BreakpointRef::Type type)
821878
{
822879
auto sa = ScopedAssign(userMode, false);

src/BreakpointViewer.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
class QPaintEvent;
1212
class Breakpoints;
13+
class DebugSession;
1314

1415
struct BreakpointRef {
1516
enum Type { BREAKPOINT, WATCHPOINT, CONDITION, ALL } type;
@@ -24,9 +25,10 @@ class BreakpointViewer : public QTabWidget, private Ui::BreakpointViewer
2425
{
2526
Q_OBJECT
2627
public:
27-
BreakpointViewer(QWidget* parent = nullptr);
28+
BreakpointViewer(DebugSession& session, QWidget* parent = nullptr);
2829
void setBreakpoints(Breakpoints* bps);
2930

31+
void onSymbolTableChanged();
3032
void on_btnAddBp_clicked();
3133
void on_btnRemoveBp_clicked();
3234
void on_btnAddWp_clicked();
@@ -42,7 +44,10 @@ class BreakpointViewer : public QTabWidget, private Ui::BreakpointViewer
4244
void contentsUpdated(bool merge);
4345

4446
private:
45-
void setTextField(BreakpointRef::Type type, int row, int column, const QString& value);
47+
void setTextField(BreakpointRef::Type type, int row, int column, const QString& value, const QString& tooltip = {});
48+
49+
std::optional<AddressRange> parseSymbolOrValue(const QString& field) const;
50+
4651
std::optional<AddressRange> parseLocationField(std::optional<int> index,
4752
BreakpointRef::Type type,
4853
const QString& field,
@@ -86,6 +91,8 @@ class BreakpointViewer : public QTabWidget, private Ui::BreakpointViewer
8691

8792
private:
8893
Ui::BreakpointViewer* ui;
94+
DebugSession& debugSession;
95+
8996
QTableWidget* tables[BreakpointRef::ALL];
9097
std::map<QString, BreakpointRef> maps[BreakpointRef::ALL];
9198

src/BreakpointViewer.ui

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@
115115
<string>#</string>
116116
</property>
117117
</column>
118+
<column>
119+
<property name="text">
120+
<string>real_addr</string>
121+
</property>
122+
</column>
118123
</widget>
119124
</item>
120125
<item>
@@ -237,6 +242,11 @@
237242
<string>#</string>
238243
</property>
239244
</column>
245+
<column>
246+
<property name="text">
247+
<string>real_addr</string>
248+
</property>
249+
</column>
240250
</widget>
241251
</item>
242252
<item>

src/CPURegsViewer.cpp

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "CPURegs.h"
33
#include "CommClient.h"
44
#include "OpenMSXConnection.h"
5+
#include "ranges.h"
56
#include <QPainter>
67
#include <QPaintEvent>
78
#include <QMessageBox>
@@ -12,9 +13,9 @@ CPURegsViewer::CPURegsViewer(QWidget* parent)
1213
{
1314
setObjectName("CPURegsViewer");
1415
// avoid UMR
15-
memset(&regs, 0, sizeof(regs));
16-
memset(&regsChanged, 0, sizeof(regsChanged));
17-
memset(&regsModified, 0, sizeof(regsModified));
16+
regs.fill(0);
17+
regsChanged.fill(false);
18+
regsModified.fill(false);
1819

1920
setFrameStyle(WinPanel | Sunken);
2021
setFocusPolicy(Qt::StrongFocus);
@@ -174,8 +175,8 @@ void CPURegsViewer::setData(uint8_t* datPtr)
174175

175176
// reset modifications
176177
cursorLoc = -1;
177-
memset(&regsModified, 0, sizeof(regsModified));
178-
memcpy(&regsCopy, &regs, sizeof(regs));
178+
regsModified.fill(false);
179+
regsCopy = regs;
179180

180181
update();
181182

@@ -223,7 +224,7 @@ void CPURegsViewer::keyPressEvent(QKeyEvent* e)
223224
int move = e->key();
224225
if ((e->key() >= Qt::Key_0 && e->key() <= Qt::Key_9) ||
225226
(e->key() >= Qt::Key_A && e->key() <= Qt::Key_F)) {
226-
// calculate numercial value
227+
// calculate numerical value
227228
int v = e->key() - Qt::Key_0;
228229
if (v > 9) v -= Qt::Key_A - Qt::Key_0 - 10;
229230
// modify value
@@ -351,26 +352,36 @@ void CPURegsViewer::applyModifications()
351352
}
352353
// update screen
353354
update();
355+
356+
// update disasm window
357+
if (regsChanged[CpuRegs::REG_PC]) {
358+
emit pcChanged(regs[CpuRegs::REG_PC]);
359+
}
354360
}
355361

356362
void CPURegsViewer::cancelModifications()
357363
{
358-
bool mod = false;
359-
for (int i = 0; i < 14; ++i) mod |= regsModified[i];
360-
if (!mod) return;
361-
362-
int ret = QMessageBox::warning(
363-
this,
364-
tr("CPU registers changes"),
365-
tr("You made changes to the CPU registers.\n"
366-
"Do you want to apply your changes or ignore them?"),
367-
QMessageBox::Apply | QMessageBox::Ignore,
368-
QMessageBox::Ignore);
369-
if (ret == QMessageBox::Ignore) {
370-
memcpy(&regs, &regsCopy, sizeof(regs));
371-
memset(&regsModified, 0, sizeof(regsModified));
372-
} else {
373-
applyModifications();
364+
static bool isVisible = false;
365+
366+
if (!ranges::contains(regsModified, true)) return;
367+
368+
if (!isVisible) {
369+
isVisible = true;
370+
// this modal window blocks execution of next instruction
371+
int ret = QMessageBox::warning(
372+
this,
373+
tr("CPU registers changes"),
374+
tr("You made changes to the CPU registers.\n"
375+
"Do you want to apply your changes or ignore them?"),
376+
QMessageBox::Apply | QMessageBox::Ignore,
377+
QMessageBox::Ignore);
378+
isVisible = false;
379+
if (ret == QMessageBox::Ignore) {
380+
regs = regsCopy;
381+
regsModified.fill(false);
382+
} else {
383+
applyModifications();
384+
}
374385
}
375386
}
376387

src/CPURegsViewer.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define CPUREGSVIEWER_H
33

44
#include <QFrame>
5+
#include <array>
56

67
class QPaintEvent;
78

@@ -33,9 +34,10 @@ public slots:
3334
int leftRegPos, leftValuePos, rightRegPos, rightValuePos;
3435
int rowHeight;
3536

36-
int regs[16], regsCopy[16];
37-
bool regsModified[16];
38-
bool regsChanged[16];
37+
std::array<int, 16> regs;
38+
std::array<int, 16> regsCopy;
39+
std::array<bool, 16> regsModified;
40+
std::array<bool, 16> regsChanged;
3941
int cursorLoc;
4042

4143
void drawValue(QPainter& p, int id, int x, int y);

0 commit comments

Comments
 (0)