|
26 | 26 |
|
27 | 27 | #include <QtWidgets/QToolTip> |
28 | 28 | #include <QtCore/QFileInfo> |
| 29 | +#include <QtCore/QStringList> |
29 | 30 | #include <QtCore/QRegularExpression> |
30 | 31 | #include <QtWidgets/QMessageBox> |
31 | 32 | #include <QtWidgets/QInputDialog> |
|
41 | 42 | #include <QtGui/QScreen> |
42 | 43 | #include <algorithm> |
43 | 44 | #include <array> |
| 45 | +#include <ranges> |
44 | 46 |
|
45 | 47 | #ifdef _MSC_VER |
46 | 48 | #include <direct.h> |
@@ -222,6 +224,7 @@ void MainWindow::debugImportFile(const QString &file) { |
222 | 224 |
|
223 | 225 | disasm.map.clear(); |
224 | 226 | disasm.reverse.clear(); |
| 227 | + markDisasmGotoCompletionsDirty(); |
225 | 228 | for (QString &equFile : m_equateFiles) { |
226 | 229 | equatesAddFile(equFile); |
227 | 230 | } |
@@ -1887,6 +1890,7 @@ void MainWindow::updateLabels() { |
1887 | 1890 | void MainWindow::equatesRefresh() { |
1888 | 1891 | disasm.map.clear(); |
1889 | 1892 | disasm.reverse.clear(); |
| 1893 | + markDisasmGotoCompletionsDirty(); |
1890 | 1894 | for (QString &file : m_equateFiles) { |
1891 | 1895 | equatesAddFile(file); |
1892 | 1896 | } |
@@ -1984,11 +1988,14 @@ void MainWindow::equatesAddEquate(const QString &name, uint32_t address) { |
1984 | 1988 | if (!equatesAddEquateInternal(name, address)) { |
1985 | 1989 | return; |
1986 | 1990 | } |
| 1991 | + markDisasmGotoCompletionsDirty(); |
1987 | 1992 | uint8_t *ptr = static_cast<uint8_t *>(phys_mem_ptr(address - 4, 9)); |
1988 | 1993 | if (ptr && ptr[4] == 0xC3 && (ptr[0] == 0xC3 || ptr[8] == 0xC3)) { // jump table? |
1989 | 1994 | uint32_t address2 = ptr[5] | ptr[6] << 8 | ptr[7] << 16; |
1990 | 1995 | if (phys_mem_ptr(address2, 1)) { |
1991 | | - equatesAddEquateInternal(QStringLiteral("_") + name, address2); |
| 1996 | + if (equatesAddEquateInternal(QStringLiteral("_") + name, address2)) { |
| 1997 | + markDisasmGotoCompletionsDirty(); |
| 1998 | + } |
1992 | 1999 | } |
1993 | 2000 | } |
1994 | 2001 | } |
@@ -2148,14 +2155,15 @@ void MainWindow::gotoPressed() { |
2148 | 2155 | m_gotoAddr = m_disasm->getSelectedAddr(); |
2149 | 2156 | } |
2150 | 2157 |
|
2151 | | - GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, this); |
| 2158 | + GotoDialog dlg(m_gotoAddr, m_disasmGotoHistory, disasmGotoCompletions(), this); |
2152 | 2159 | if (dlg.exec() == QDialog::Accepted) { |
2153 | 2160 | QString typed = dlg.text().trimmed(); |
2154 | 2161 | bool ok = false; |
2155 | 2162 | QString resolved = resolveAddressOrEquate(typed, &ok); |
2156 | 2163 | if (ok) { |
2157 | 2164 | m_gotoAddr = typed; |
2158 | | - disasmUpdateAddr(hex2int(resolved), false); |
| 2165 | + // changes are routed through here to make sure history is updated for fwd and back |
| 2166 | + gotoDisasmAddr(static_cast<uint32_t>(hex2int(resolved))); |
2159 | 2167 |
|
2160 | 2168 | auto &hist = m_disasmGotoHistory; |
2161 | 2169 | std::erase_if(hist, [&](const QString &s){ return s.compare(typed, Qt::CaseInsensitive) == 0; }); |
@@ -2226,6 +2234,43 @@ QAction *MainWindow::gotoMemAction(QMenu *menu, bool vat) const { |
2226 | 2234 | return gotoMem; |
2227 | 2235 | } |
2228 | 2236 |
|
| 2237 | +const QStringList &MainWindow::disasmGotoCompletions() { |
| 2238 | + if (!m_disasmGotoCompletionsDirty) { |
| 2239 | + return m_disasmGotoCompletions; |
| 2240 | + } |
| 2241 | + |
| 2242 | + m_disasmGotoCompletionsDirty = false; |
| 2243 | + |
| 2244 | + QStringList completions; |
| 2245 | + static constexpr std::array kRegisterAliases = { |
| 2246 | + "AF"_L1, "HL"_L1, "DE"_L1, "BC"_L1, "IX"_L1, "IY"_L1, |
| 2247 | + "AF'"_L1, "HL'"_L1, "DE'"_L1, "BC'"_L1, "SPL"_L1, "SPS"_L1, "PC"_L1 |
| 2248 | + }; |
| 2249 | + |
| 2250 | + completions.reserve(static_cast<int>(disasm.reverse.size() + kRegisterAliases.size())); |
| 2251 | + |
| 2252 | + for (const auto &name : disasm.reverse | std::views::keys) { |
| 2253 | + completions.append(QString::fromStdString(name)); |
| 2254 | + } |
| 2255 | + |
| 2256 | + for (const auto alias : kRegisterAliases) { |
| 2257 | + if (!completions.contains(alias)) { |
| 2258 | + completions.append(QString(alias)); |
| 2259 | + } |
| 2260 | + } |
| 2261 | + |
| 2262 | + std::ranges::sort(completions, [](const QString &lhs, const QString &rhs) { |
| 2263 | + return lhs.localeAwareCompare(rhs) < 0; |
| 2264 | + }); |
| 2265 | + |
| 2266 | + m_disasmGotoCompletions = std::move(completions); |
| 2267 | + return m_disasmGotoCompletions; |
| 2268 | +} |
| 2269 | + |
| 2270 | +void MainWindow::markDisasmGotoCompletionsDirty() { |
| 2271 | + m_disasmGotoCompletionsDirty = true; |
| 2272 | +} |
| 2273 | + |
2229 | 2274 | void MainWindow::handleCtrlClickText(QPlainTextEdit *edit) { |
2230 | 2275 | if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) { |
2231 | 2276 | bool ok = true; |
@@ -2352,7 +2397,7 @@ bool MainWindow::eventFilter(QObject *obj, QEvent *e) { |
2352 | 2397 | return true; |
2353 | 2398 | } |
2354 | 2399 | } |
2355 | | - |
| 2400 | + |
2356 | 2401 | // Mouse back/forward in Disassembly view |
2357 | 2402 | if (obj == m_disasm && e->type() == QEvent::MouseButtonPress) { |
2358 | 2403 | auto *me = static_cast<QMouseEvent*>(e); |
|
0 commit comments