-//\r
-// allwatch.cpp - All Watch\r
-//\r
-// by Jean-Paul Mari\r
-//\r
-// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
-//\r
-// Who When What\r
-// --- ---------- -----------------------------------------------------------\r
-// JPM 01/08/2017 Created this file\r
-//\r
-\r
-// STILL TO DO:\r
-//\r
-\r
-#include "debugger/heapallocatorbrowser.h"\r
-#include "memory.h"\r
-#include "debugger/DBGManager.h"\r
-#include "m68000/m68kinterface.h"\r
-\r
-\r
-HeapAllocatorBrowserWindow::HeapAllocatorBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
-layout(new QVBoxLayout), text(new QTextBrowser),\r
-// layout(new QVBoxLayout), text(new QLabel),\r
-// refresh(new QPushButton(tr("Refresh"))),\r
-// address(new QLineEdit),\r
-// go(new QPushButton(tr("Go"))),\r
-// memBase(0),\r
-// NbWatch(0),\r
-// PtrWatchInfo(NULL)\r
-Adr(0)\r
-//PtrAdr(NULL)\r
-{\r
- setWindowTitle(tr("Heap Allocation"));\r
-\r
-// address->setInputMask("hhhhhh");\r
-// QHBoxLayout * hbox1 = new QHBoxLayout;\r
-// hbox1->addWidget(refresh);\r
-// hbox1->addWidget(address);\r
-// hbox1->addWidget(go);\r
-\r
- // Need to set the size as well...\r
-// resize(560, 480);\r
-\r
- QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
-// QFont fixedFont("", 8, QFont::Normal);\r
- fixedFont.setStyleHint(QFont::TypeWriter);\r
- text->setFont(fixedFont);\r
-//// layout->setSizeConstraint(QLayout::SetFixedSize);\r
- setLayout(layout);\r
-\r
- layout->addWidget(text);\r
-// layout->addWidget(refresh);\r
-// layout->addLayout(hbox1);\r
-\r
-// connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents()));\r
-// connect(go, SIGNAL(clicked()), this, SLOT(GoToAddress()));\r
-}\r
-\r
-\r
-//\r
-HeapAllocatorBrowserWindow::~HeapAllocatorBrowserWindow(void)\r
-{\r
-// NbWatch = 0;\r
-// free(PtrAdr);\r
-}\r
-\r
-\r
-//\r
-void HeapAllocatorBrowserWindow::RefreshContents(void)\r
-{\r
- char string[1024];\r
-// char buf[64];\r
- QString HA;\r
- size_t Adr68K;\r
- size_t Error = 0;\r
- HeapAllocation HeapAllocation;\r
-\r
- if (isVisible())\r
- {\r
- if (Adr68K = Adr)\r
- {\r
- do\r
- {\r
- if ((Adr68K >= 0x4000) && (Adr68K < 0x200000))\r
- {\r
- memcpy(&HeapAllocation, &jaguarMainRAM[Adr68K], sizeof(HeapAllocation));\r
-\r
- if (HeapAllocation.size = ((HeapAllocation.size & 0xff) << 24) + ((HeapAllocation.size & 0xff00) << 8) + ((HeapAllocation.size & 0xff0000) >> 8) + ((HeapAllocation.size & 0xff000000) >> 24))\r
- {\r
- if (HeapAllocation.size <= (0x200000 - 0x4000))\r
- {\r
- if ((HeapAllocation.used = ((HeapAllocation.used & 0xff) << 8) + ((HeapAllocation.used & 0xff00) >> 8)) <= 1)\r
- {\r
- HeapAllocation.nextalloc = ((HeapAllocation.nextalloc & 0xff) << 24) + ((HeapAllocation.nextalloc & 0xff00) << 8) + ((HeapAllocation.nextalloc & 0xff0000) >> 8) + ((HeapAllocation.nextalloc & 0xff000000) >> 24);\r
-\r
- if ((HeapAllocation.nextalloc >= 0x4000) && (HeapAllocation.nextalloc < 0x200000))\r
- {\r
- sprintf(string, "0x%06x | 0x%06x (%i) | %s | 0x%06x<br>", Adr68K, HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.used ? "Allocated" : "Free", HeapAllocation.nextalloc);\r
- Adr68K = HeapAllocation.nextalloc;\r
- }\r
- else\r
- {\r
- sprintf(string, "<br><font color='#ff0000'><b>Unable to determine the next memory allocation</b></font>");\r
- Error = 1;\r
- }\r
- }\r
- else\r
- {\r
- sprintf(string, "<br><font color='#ff0000'><b>Unable to determine if the allocated memory is used or not</b></font>");\r
- Error = 2;\r
- }\r
- }\r
- else\r
- {\r
- sprintf(string, "<br><font color='#ff0000'><b>Memory bloc size has a problem</b></font>");\r
- Error = 3;\r
- }\r
- }\r
- else\r
- {\r
- sprintf(string, "<br><font color='#0000ff'><b>Memory allocations browsing successfully completed</b></font>");\r
- }\r
- }\r
- else\r
- {\r
- sprintf(string, "<br><font color='#ff0000'><b>Memory allocations may have a problem</b></font>");\r
- Error = 4;\r
- }\r
-\r
- HA += QString(string);\r
-\r
- } while (HeapAllocation.size && !Error);\r
- }\r
- else\r
- {\r
- if (Adr = DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
- {\r
- if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
- {\r
- if (!(Adr68K = (jaguarMainRAM[Adr68K] << 24) + (jaguarMainRAM[Adr68K + 1] << 16) + (jaguarMainRAM[Adr68K + 2] << 8) + (jaguarMainRAM[Adr68K + 3])) || ((Adr68K < 0x4000) || (Adr68K >= 0x200000)))\r
- {\r
- sprintf(string, "<font color='#ff0000'><b>Memory allocator not yet initialised</b></font>");\r
- Adr = 0;\r
- }\r
- else\r
- {\r
- return RefreshContents();\r
- //sprintf(string, "<font color='#0000ff'><b>Memory allocator has been initialised</b></font>");\r
- }\r
- }\r
- else\r
- {\r
- sprintf(string, "<font color='#ff0000'><b>Memory allocator is not compatible</b></font>");\r
- Adr = 0;\r
- }\r
- }\r
- else\r
- {\r
- sprintf(string, "<font color='#ff0000'><b>Memory allocator doesn't exist</b></font>");\r
- }\r
-\r
- HA += QString(string);\r
- }\r
-\r
- text->clear();\r
- text->setText(HA);\r
- }\r
-}\r
-\r
-\r
-#if 0\r
-void HeapAllocatorBrowserWindow::keyPressEvent(QKeyEvent * e)\r
-{\r
- if (e->key() == Qt::Key_Escape)\r
- hide();\r
- else if (e->key() == Qt::Key_PageUp)\r
- {\r
- memBase -= 480;\r
-\r
- if (memBase < 0)\r
- memBase = 0;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_PageDown)\r
- {\r
- memBase += 480;\r
-\r
- if (memBase > (0x200000 - 480))\r
- memBase = 0x200000 - 480;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_Up || e->key() == Qt::Key_Minus)\r
- {\r
- memBase -= 16;\r
-\r
- if (memBase < 0)\r
- memBase = 0;\r
-\r
- RefreshContents();\r
- }\r
- else if (e->key() == Qt::Key_Down || e->key() == Qt::Key_Equal)\r
- {\r
- memBase += 16;\r
-\r
- if (memBase > (0x200000 - 480))\r
- memBase = 0x200000 - 480;\r
-\r
- RefreshContents();\r
- }\r
-}\r
-#endif\r
-\r
-\r
-#if 0\r
-void HeapAllocatorBrowserWindow::GoToAddress(void)\r
-{\r
- bool ok;\r
- QString newAddress = address->text();\r
- memBase = newAddress.toUInt(&ok, 16);\r
- RefreshContents();\r
-}\r
-#endif\r
-\r
+//\r
+// heapallocatorbrowser.cpp: Memory heap allocation\r
+//\r
+// by Jean-Paul Mari\r
+//\r
+// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
+//\r
+// Who When (MM/DD/YY) What\r
+// --- --------------- -----------------------------------------------------------\r
+// JPM 01/08/2017 Created this file\r
+// JPM Sept./2018 Support of the DRAM size limit option, use definitions for error instead of hard values, detect if heap allocation shares space with SP (Stack), added a status bar and better status report, and set information values in a tab\r
+// JPM 07/04/2019 Fix the support of the DRAM size limit option\r
+//\r
+\r
+// STILL TO DO:\r
+// To have filters\r
+// To set the information display at the right\r
+// Feature to list the pointer(s) in the code using the allocation\r
+//\r
+\r
+\r
+#include "settings.h"\r
+#include "debugger/heapallocatorbrowser.h"\r
+#include "memory.h"\r
+#include "debugger/DBGManager.h"\r
+#include "m68000/m68kinterface.h"\r
+\r
+\r
+// \r
+HeapAllocatorBrowserWindow::HeapAllocatorBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
+layout(new QVBoxLayout),\r
+#ifdef HA_LAYOUTTEXTS\r
+text(new QTextBrowser),\r
+#else\r
+TableView(new QTableView),\r
+model(new QStandardItemModel),\r
+proxyModel(new QSortFilterProxyModel),\r
+#endif\r
+statusbar(new QStatusBar),\r
+Adr(0)\r
+{\r
+ setWindowTitle(tr("Heap Allocation"));\r
+\r
+ // Set the font\r
+ QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
+ fixedFont.setStyleHint(QFont::TypeWriter);\r
+\r
+#ifdef HA_LAYOUTTEXTS\r
+ // Set original layout\r
+ text->setFont(fixedFont);\r
+ layout->addWidget(text);\r
+#else\r
+ // Set the new layout with proper identation and readibility\r
+ model->setColumnCount(3);\r
+ model->setHeaderData(0, Qt::Horizontal, QObject::tr("Pointer"));\r
+ model->setHeaderData(1, Qt::Horizontal, QObject::tr("Size"));\r
+ model->setHeaderData(2, Qt::Horizontal, QObject::tr("Use"));\r
+ // Information table\r
+ TableView->setModel(model);\r
+ TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r
+ TableView->setShowGrid(0);\r
+ TableView->setFont(fixedFont);\r
+ TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r
+ TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r
+ layout->addWidget(TableView);\r
+ // Set filter\r
+ proxyModel->setSourceModel(model);\r
+ QRegExp regExp("*", Qt::CaseInsensitive, QRegExp::Wildcard);\r
+ proxyModel->setFilterRegExp(regExp);\r
+#endif\r
+\r
+ // Status bar\r
+ layout->addWidget(statusbar);\r
+ setLayout(layout);\r
+}\r
+\r
+\r
+//\r
+HeapAllocatorBrowserWindow::~HeapAllocatorBrowserWindow(void)\r
+{\r
+}\r
+\r
+\r
+//\r
+void HeapAllocatorBrowserWindow::RefreshContents(void)\r
+{\r
+#ifdef HA_LAYOUTTEXTS\r
+ char string[1024] = { 0 };\r
+ QString HA;\r
+#endif\r
+ char msg[1024];\r
+ QString MSG;\r
+ size_t Adr68K, Adr68KHigh;\r
+ size_t Error = HA_NOERROR;\r
+ size_t NbBlocks, TotalBytesUsed;\r
+ HeapAllocation HeapAllocation;\r
+\r
+ if (isVisible())\r
+ {\r
+ if (Adr68K = Adr)\r
+ {\r
+ Adr68KHigh = TotalBytesUsed = NbBlocks = 0;\r
+#ifndef HA_LAYOUTTEXTS\r
+ model->setRowCount(0);\r
+#endif\r
+ do\r
+ {\r
+ if ((Adr68K >= 0x4000) && (Adr68K < vjs.DRAM_size))\r
+ {\r
+ if (Adr68K < m68k_get_reg(NULL, M68K_REG_SP))\r
+ {\r
+ memcpy(&HeapAllocation, &jaguarMainRAM[Adr68K], sizeof(HeapAllocation));\r
+\r
+ if (HeapAllocation.size = ((HeapAllocation.size & 0xff) << 24) + ((HeapAllocation.size & 0xff00) << 8) + ((HeapAllocation.size & 0xff0000) >> 8) + ((HeapAllocation.size & 0xff000000) >> 24))\r
+ {\r
+ if (HeapAllocation.size <= (vjs.DRAM_size - 0x4000))\r
+ {\r
+ if ((HeapAllocation.used = ((HeapAllocation.used & 0xff) << 8) + ((HeapAllocation.used & 0xff00) >> 8)) <= 1)\r
+ {\r
+ HeapAllocation.nextalloc = ((HeapAllocation.nextalloc & 0xff) << 24) + ((HeapAllocation.nextalloc & 0xff00) << 8) + ((HeapAllocation.nextalloc & 0xff0000) >> 8) + ((HeapAllocation.nextalloc & 0xff000000) >> 24);\r
+\r
+ if ((HeapAllocation.nextalloc >= 0x4000) && (HeapAllocation.nextalloc < vjs.DRAM_size))\r
+ {\r
+#ifdef HA_LAYOUTTEXTS\r
+ if (NbBlocks++)\r
+ {\r
+ HA += QString("<br>");\r
+ }\r
+ sprintf(string, "0x%06x | 0x%0x (%zi) | %s | 0x%06x", Adr68K, HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.used ? "Allocated" : "Free", HeapAllocation.nextalloc);\r
+ HA += QString(string);\r
+#else\r
+ model->insertRow(NbBlocks);\r
+ model->setItem(NbBlocks, 0, new QStandardItem(QString("0x%1").arg(Adr68K, 6, 16, QChar('0'))));\r
+ model->setItem(NbBlocks, 1, new QStandardItem(QString("%1").arg((HeapAllocation.size - sizeof(HeapAllocation)))));\r
+ model->setItem(NbBlocks++, 2, new QStandardItem(QString("%1").arg(HeapAllocation.used ? "Allocated" : "Free")));\r
+#endif\r
+ TotalBytesUsed += HeapAllocation.size;\r
+\r
+ if ((Adr68K = HeapAllocation.nextalloc) > Adr68KHigh)\r
+ {\r
+ Adr68KHigh = Adr68K;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Unable to determine the next memory allocation");\r
+ Error = HA_UNABLENEXTMEMORYALLOC;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Unable to determine if the allocated memory is used or not");\r
+ Error = HA_UNABLEALLOCATEMEMORYUSAGE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Memory bloc size has a problem");\r
+ Error = HA_MEMORYBLOCKSIZEPROBLEM;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "%i blocks | %i bytes in blocks | %i contiguous bytes free", NbBlocks, TotalBytesUsed, (m68k_get_reg(NULL, M68K_REG_SP) - Adr68KHigh));\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Memory allocations and Stack have reached the same space");\r
+ Error = HA_HAANDSPSHARESPACE;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Memory allocations may have a problem");\r
+ Error = HA_MEMORYALLOCATIONPROBLEM;\r
+ }\r
+ }\r
+ while (HeapAllocation.size && !Error);\r
+\r
+ MSG += QString(msg);\r
+ }\r
+ else\r
+ {\r
+ if (Adr = DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
+ {\r
+ if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
+ {\r
+ if (!(Adr68K = (jaguarMainRAM[Adr68K] << 24) + (jaguarMainRAM[Adr68K + 1] << 16) + (jaguarMainRAM[Adr68K + 2] << 8) + (jaguarMainRAM[Adr68K + 3])) || ((Adr68K < 0x4000) || (Adr68K >= vjs.DRAM_size)))\r
+ {\r
+ sprintf(msg, "Memory allocator not yet initialised");\r
+ Error = HA_MEMORYALLOCATORNOTINITIALIZED;\r
+ Adr = 0;\r
+ }\r
+ else\r
+ {\r
+ return RefreshContents();\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Memory allocator is not compatible");\r
+ Error = HA_MEMORYALLOCATORNOTCOMPATIBLE;\r
+ Adr = 0;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ sprintf(msg, "Memory allocator doesn't exist");\r
+ Error = HA_MEMORYALLOCATORNOTEXIST;\r
+ }\r
+#ifdef HA_LAYOUTTEXTS\r
+ HA += QString("");\r
+#else\r
+ model->setRowCount(0);\r
+#endif\r
+ MSG += QString(msg);\r
+ }\r
+\r
+ // Display status bar\r
+ if (Error)\r
+ {\r
+ if ((Error & HA_WARNING))\r
+ {\r
+ statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r
+ }\r
+ else\r
+ {\r
+ statusbar->setStyleSheet("background-color: tomato; font: bold");\r
+ }\r
+ }\r
+ else\r
+ {\r
+ statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r
+ }\r
+ statusbar->showMessage(MSG);\r
+\r
+#ifdef HA_LAYOUTTEXTS\r
+ // Display values\r
+ text->clear();\r
+ text->setText(HA);\r
+#endif\r
+ }\r
+}\r
+\r
+\r
+// \r
+void HeapAllocatorBrowserWindow::Reset(void)\r
+{\r
+ size_t Adr68K;\r
+\r
+ if (DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
+ {\r
+ if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
+ {\r
+ jaguarMainRAM[Adr68K] = jaguarMainRAM[Adr68K + 1] = jaguarMainRAM[Adr68K + 2] = jaguarMainRAM[Adr68K + 3] = 0;\r
+ Adr = 0;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+// \r
+void HeapAllocatorBrowserWindow::keyPressEvent(QKeyEvent * e)\r
+{\r
+ if (e->key() == Qt::Key_Escape)\r
+ {\r
+ hide();\r
+ }\r
+}\r
+\r