From: Jean-Paul Mari Date: Sun, 16 Sep 2018 10:34:12 +0000 (-0400) Subject: UI modifications X-Git-Tag: v2.1.3-R4~31 X-Git-Url: http://git.hcoop.net/clinton/Virtual-Jaguar-Rx.git/commitdiff_plain/2b91c43522db268bedd2c49ec7094d2d635ea90d UI modifications --- diff --git a/docs/vj_ReleaseNotes.txt b/docs/vj_ReleaseNotes.txt index 41643b4..5ad331e 100644 --- a/docs/vj_ReleaseNotes.txt +++ b/docs/vj_ReleaseNotes.txt @@ -1,5 +1,7 @@ Release 4 (TBD) --------------- +Git commit: TBD +- 0) The zoom value setting has been fixed in the registry 1) Debugger mode now shares the same alpine rom path setting 2) Local variables window displays register name now @@ -13,28 +15,43 @@ Release 4 (TBD) 8) Local variables window detects now if a variable is used or not by the code 9) The address provided in the memory window is now verified to prevent crash -- Wrong address will be displayed in red -10) UI cosmetic changes +10) UI changes -- Added new icons for the exit and status features -- Modified icons for the SP (Stack) browser -- Unified icons sizes depend on their usage (drop down menu and main menu) -- Underline the active M68K line in the disassembly window -- Allow the up/down navigation on the SP (Stack) browser -- Restart function cleans-up the SP (Stack) browser and the heap allocator system -11) Fixed the up navigation on the memory window -12) Added some log information for the emulator initialisations -13) Breakpoint will happen in case of writing at unknown memory location --- Alert box will display a message and then code will stop -14) Added the DRAM size in the emulator status window -15) Debugger sources code clean-up -16) Added a call stack feature -17) Prevent source file reading issue on no-Windows system -18) UI modifications +-- Fixed the up navigation on the memory window +11) Added some log information for the emulator initialisations +12) Breakpoint will happen in case of writing at unknown memory location +-- Alert box will display a message and then the code will stop +13) Added the DRAM size in the emulator status window +14) Debugger sources code clean-up +15) Added a call stack feature +16) Follow platform requirement to prevent source file reading issue +17) UI modifications -- Modified icon for the memory window to make a distinction with the memory browser -- The all watch, and Exception Vector Table windows, can be closed using keyboard -- Renamed the debugger dedicated icons to make a distinction -- Added the call stack window -19) Fixed a crash in the all watch window after loading a new binary without ELF/DWARF information +18) Fixed a crash in the all watch window after loading a new binary without ELF/DWARF information -- Previously used ELF/DWARF information was still accessible +19) Fixed slash/backslash issue, in the Alpine tab, to follow platform requirement +20) Heap allocation window uses the DRAM size limit option and detect if heap allocation shares space with SP (Stack) +21) Added a Jaguar model and BIOS configuration tab +22) Jaguar model and BIOS configuration integration +23) Added LEB128 decoding functions +-- It is used for the DWARF decoding information +24) Debugger support improvement +-- DWARF support for the enum type (partial), and subroutine type +-- Debugger can report variable's unsigned char value +25) UI modifications +-- Added a status bar, better status report & information display for the heap allocation window +-- Added a status bar, better status report & information display for the local variables window +-- Added better information display for the exception vectors table window, and added some missing vectors +-- Added a status bar, better status report & information display for the call stack window +-- Added a status bar, better status report & information display for the all watches window Release 3 (13th November 2017) ------------------------------ @@ -133,8 +150,9 @@ Known issues -- Need to trace over the BPM or unset the BPM -- The issue can be prevented if the code doesn't set IRQ, otherwise the IRQ will need to be traced to get back control 3) To support DWARF 2 with GCC, the code must be compiled with the -gdwarf-2 option -4) The Local and Watch variables window may display not available (N/A) type information +4) The Local and Watch variables window may display not available type information or empty information -- Such missing information may be included in future release +-- The 'const' type may not be reported correctly in the DWARF information 5) The 2MB mirroring is no longer applied in case of --dram-max option usage 6) Stack must reflect the --dram-max option usage otherwise the stack may be corrupted -- The application needs to set the SP (Stack) in accordance @@ -142,7 +160,9 @@ Known issues -- Missing vectors may be added in future release 8) User needs to manualy check if the Atari Jaguar executable match his source code files -- Otherwise, source code and assembly may not match or leads to instabilities -9) The emulator needs to be restarted in case of keybindings changes +9) The emulator needs to be restarted in case of the following actions occur +-- Keybindings changes +-- BIOS selection changes and without new executable load 10) In the case of a ROM cartridge writing, and with occuring breakpoint, the PC pointer will point at the next instruction and not at the instruction causing the breakpoint 11) Emulator will crash in case of wrong address value provided in the memory browser 12) The RAM access log is limited to the 2MB diff --git a/src/debugger/allwatchbrowser.cpp b/src/debugger/allwatchbrowser.cpp index c7430d7..8021b7e 100644 --- a/src/debugger/allwatchbrowser.cpp +++ b/src/debugger/allwatchbrowser.cpp @@ -8,12 +8,23 @@ // Who When What // --- ---------- ----------------------------------------------------------- // JPM 12/07/2017 Created this file +// JPM 09/14/2018 Added a status bar and better status report +// JPM 09/14/2018 Set information values in a tab // // STILL TO DO: // Better presentation +// To set the information display at the right // +//#define AW_DEBUGNUMVARIABLE 177 // Set the global variable number to debug +#ifndef AW_DEBUGNUMVARIABLE +#define AW_STARTNUMVARIABLE 0 // Must be kept to 0 in case of no debug is required +#else +#define AW_STARTNUMVARIABLE AW_DEBUGNUMVARIABLE - 1 +#endif + + #include "debugger/allwatchbrowser.h" #include "memory.h" #include "debugger/DBGManager.h" @@ -21,18 +32,46 @@ // AllWatchBrowserWindow::AllWatchBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog), - layout(new QVBoxLayout), text(new QTextBrowser), - NbWatch(0), - PtrWatchInfo(NULL) +layout(new QVBoxLayout), +#ifdef AW_LAYOUTTEXTS +text(new QTextBrowser), +#else +TableView(new QTableView), +model(new QStandardItemModel), +#endif +NbWatch(0), +statusbar(new QStatusBar), +PtrWatchInfo(NULL) { setWindowTitle(tr("All Watch")); + // Set the font QFont fixedFont("Lucida Console", 8, QFont::Normal); fixedFont.setStyleHint(QFont::TypeWriter); - text->setFont(fixedFont); - setLayout(layout); +#ifdef AW_LAYOUTTEXTS + // Set original layout + text->setFont(fixedFont); layout->addWidget(text); +#else + // Set the new layout with proper identation and readibility + model->setColumnCount(3); + model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); + model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value")); + model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type")); + // Information table + TableView->setModel(model); + TableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + TableView->setShowGrid(0); + TableView->setFont(fixedFont); + TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize()); + TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight); + layout->addWidget(TableView); +#endif + + // Status bar + layout->addWidget(statusbar); + setLayout(layout); } @@ -55,44 +94,102 @@ void AllWatchBrowserWindow::Reset(void) // void AllWatchBrowserWindow::RefreshContents(void) { + char msg[100]; +#ifdef AW_LAYOUTTEXTS char string[1024]; +#endif QString WatchAll; + size_t Error = AW_NOERROR; + char *PtrValue; if (isVisible()) { - text->clear(); - if (!NbWatch) { + // Pre-catch the information for each global variables if (NbWatch = DBGManager_GetNbGlobalVariables()) { PtrWatchInfo = (WatchInfo *)calloc(NbWatch, sizeof(WatchInfo)); - for (uint32_t i = 0; i < NbWatch; i++) + for (uint32_t i = AW_STARTNUMVARIABLE; i < NbWatch; i++) { PtrWatchInfo[i].PtrVariableName = DBGManager_GetGlobalVariableName(i + 1); - PtrWatchInfo[i].addr = DBGManager_GetGlobalVariableAdr(i + 1); PtrWatchInfo[i].TypeTag = DBGManager_GetGlobalVariableTypeTag(i + 1); +#ifdef AW_LAYOUTTEXTS + PtrWatchInfo[i].addr = DBGManager_GetGlobalVariableAdr(i + 1); if (!strlen(PtrWatchInfo[i].PtrVariableBaseTypeName = DBGManager_GetGlobalVariableTypeName(i + 1))) { PtrWatchInfo[i].PtrVariableBaseTypeName = (char *)"N/A"; } +#else + PtrWatchInfo[i].PtrVariableBaseTypeName = DBGManager_GetGlobalVariableTypeName(i + 1); +#endif } } } - - for (uint32_t i = 0; i < NbWatch; i++) +#ifndef AW_LAYOUTTEXTS + model->setRowCount(0); +#endif + if (NbWatch) { - if (PtrWatchInfo[i].PtrVariableName && PtrWatchInfo[i].PtrVariableBaseTypeName) + for (uint32_t i = AW_STARTNUMVARIABLE; i < NbWatch; i++) { - sprintf(string, "%i : %s | %s | 0x%06X | %s", (i + 1), PtrWatchInfo[i].PtrVariableBaseTypeName, PtrWatchInfo[i].PtrVariableName, (unsigned int)PtrWatchInfo[i].addr, (PtrWatchInfo[i].TypeTag & 0x8) ? "" : DBGManager_GetGlobalVariableValue(i + 1)); - WatchAll += QString(string); - sprintf(string, "
"); + if ((PtrWatchInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure))) + { +#if defined(AW_SUPPORTARRAY) || defined(AW_SUPPORTSTRUCTURE) + //PtrValue = (char *)memcpy(Value, &jaguarMainRAM[PtrWatchInfo[i].addr], 20); + PtrValue = NULL; +#else + PtrValue = NULL; +#endif + } + else + { + PtrValue = DBGManager_GetGlobalVariableValue(i + 1); + } +#ifdef AW_LAYOUTTEXTS + if (i) + { + WatchAll += QString("
"); + } + sprintf(string, "%i : %s | %s | 0x%06X | %s", (i + 1), PtrWatchInfo[i].PtrVariableBaseTypeName, PtrWatchInfo[i].PtrVariableName, (unsigned int)PtrWatchInfo[i].addr, PtrValue ? PtrValue : (char *)"N/A"); WatchAll += QString(string); +#else + model->insertRow(i); + model->setItem(i, 0, new QStandardItem(QString("%1").arg(PtrWatchInfo[i].PtrVariableName))); + model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue))); + model->setItem(i, 2, new QStandardItem(QString("%1").arg(PtrWatchInfo[i].PtrVariableBaseTypeName))); +#endif } +#ifdef AW_LAYOUTTEXTS + text->clear(); + text->setText(WatchAll); +#endif + sprintf(msg, "Ready"); + } + else + { + sprintf(msg, "No watches"); + Error = AW_NOALLWATCH; } - text->setText(WatchAll); + // Display status bar + if (Error) + { + if ((Error & AW_WARNING)) + { + statusbar->setStyleSheet("background-color: lightyellow; font: bold"); + } + else + { + statusbar->setStyleSheet("background-color: tomato; font: bold"); + } + } + else + { + statusbar->setStyleSheet("background-color: lightgreen; font: bold"); + } + statusbar->showMessage(QString(msg)); } } diff --git a/src/debugger/allwatchbrowser.h b/src/debugger/allwatchbrowser.h index e477409..63107f4 100644 --- a/src/debugger/allwatchbrowser.h +++ b/src/debugger/allwatchbrowser.h @@ -7,9 +7,21 @@ #ifndef __ALLWATCHBROWSER_H__ #define __ALLWATCHBROWSER_H__ +//#define AW_LAYOUTTEXTS // Use a layout with just texts +//#define AW_SUPPORTARRAY // Support array +//#define AW_SUPPORTSTRUCTURE // Support structure + #include #include + +// Error code definitions +#define AW_NOERROR 0x00 +#define AW_ERROR 0x80 +#define AW_WARNING 0x40 +#define AW_NOALLWATCH (0x01 | AW_WARNING) + +// class AllWatchBrowserWindow: public QWidget { Q_OBJECT @@ -17,7 +29,9 @@ class AllWatchBrowserWindow: public QWidget // typedef struct WatchInfo { +#ifdef AW_LAYOUTTEXTS size_t addr; +#endif size_t TypeTag; char *PtrVariableName; char *PtrVariableBaseTypeName; @@ -36,7 +50,13 @@ class AllWatchBrowserWindow: public QWidget private: QVBoxLayout *layout; +#ifdef AW_LAYOUTTEXTS QTextBrowser *text; +#else + QTableView *TableView; + QStandardItemModel *model; +#endif + QStatusBar *statusbar; WatchInfo *PtrWatchInfo; size_t NbWatch; }; diff --git a/src/debugger/callstackbrowser.cpp b/src/debugger/callstackbrowser.cpp index 77fe154..c2d349e 100644 --- a/src/debugger/callstackbrowser.cpp +++ b/src/debugger/callstackbrowser.cpp @@ -8,11 +8,11 @@ // Who When What // --- ---------- ----------------------------------------------------------- // JPM 08/31/2018 Created this file +// JPM 09/12/2018 Added a status bar and better status report // // STILL TO DO: -// Better display presentation -// To display call function +// To set the information display at the right // To use DWARF frame information // @@ -22,65 +22,133 @@ #include "m68000/m68kinterface.h" -// +// CallStackBrowserWindow::CallStackBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog), - layout(new QVBoxLayout), text(new QTextBrowser) +#ifdef CS_LAYOUTTEXTS +text(new QTextBrowser), +#else +TableView(new QTableView), +model(new QStandardItemModel), +#endif +statusbar(new QStatusBar), +layout(new QVBoxLayout) { setWindowTitle(tr("Call Stack")); + // Set the font QFont fixedFont("Lucida Console", 8, QFont::Normal); fixedFont.setStyleHint(QFont::TypeWriter); - text->setFont(fixedFont); - setLayout(layout); +#ifdef CS_LAYOUTTEXTS + // Set original layout + text->setFont(fixedFont); layout->addWidget(text); +#else + // Set the new layout with proper identation and readibility + model->setColumnCount(2); + model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); + model->setHeaderData(1, Qt::Horizontal, QObject::tr("Line")); + // Information table + TableView->setModel(model); + TableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + TableView->setShowGrid(0); + TableView->setFont(fixedFont); + TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize()); + TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight); + layout->addWidget(TableView); +#endif + + // Status bar + layout->addWidget(statusbar); + setLayout(layout); } -// +// CallStackBrowserWindow::~CallStackBrowserWindow(void) { } -// +// void CallStackBrowserWindow::RefreshContents(void) { + char msg[1024]; + size_t Error = CS_NOERROR; unsigned int a6, Sa6, ret; char *FuncName; +#ifdef CS_LAYOUTTEXTS QString CallStack; char string[1024]; +#else + size_t NbRaw = 0; + QString FunctionName; +#endif if (isVisible()) { +#ifndef CS_LAYOUTTEXTS + model->setRowCount(0); +#endif if ((a6 = m68k_get_reg(NULL, M68K_REG_A6)) && DBGManager_GetType()) { while ((Sa6 = a6)) { a6 = GET32(jaguarMainRAM, Sa6); ret = GET32(jaguarMainRAM, Sa6 + 4); - - sprintf(string, "0x%06X | Ret: 0x%06X | From: %s - 0x%06X", Sa6, ret, (FuncName = DBGManager_GetFunctionName(ret)), (unsigned int)DBGManager_GetAdrFromSymbolName(FuncName)); +#ifdef CS_LAYOUTTEXTS + sprintf(string, "0x%06X | Ret: 0x%06X | From: %s - 0x%06X | Line: %s", Sa6, ret, (FuncName = DBGManager_GetFunctionName(ret)), (unsigned int)DBGManager_GetAdrFromSymbolName(FuncName), DBGManager_GetLineSrcFromAdr(ret, DBG_NO_TAG)); CallStack += QString(string); if (a6) { - sprintf(string, "
"); - CallStack += QString(string); + CallStack += QString("
"); } +#else + model->insertRow(NbRaw); + model->setItem(NbRaw, 0, new QStandardItem(QString("%1").arg((FuncName = DBGManager_GetFunctionName(ret)) ? FuncName : "(null)"))); + FunctionName = QString(FuncName = DBGManager_GetLineSrcFromAdr(ret, DBG_NO_TAG)); + FunctionName.replace(" ", " "); + model->setItem(NbRaw++, 1, new QStandardItem(QString("%1").arg(FuncName ? FunctionName : "(null)"))); +#endif } - +#ifdef CS_LAYOUTTEXTS text->clear(); text->setText(CallStack); +#endif + sprintf(msg, "Ready"); + Error = CS_NOERROR; } else { + sprintf(msg, "Call Stack not available"); + Error = CS_NOCALLSTACK; +#ifdef CS_LAYOUTTEXTS text->clear(); +#endif + } + + // Display status bar + if (Error) + { + if ((Error & CS_WARNING)) + { + statusbar->setStyleSheet("background-color: lightyellow; font: bold"); + } + else + { + statusbar->setStyleSheet("background-color: tomato; font: bold"); + } } + else + { + statusbar->setStyleSheet("background-color: lightgreen; font: bold"); + } + statusbar->showMessage(QString(msg)); } } -// +// void CallStackBrowserWindow::keyPressEvent(QKeyEvent * e) { if (e->key() == Qt::Key_Escape) diff --git a/src/debugger/callstackbrowser.h b/src/debugger/callstackbrowser.h index 8ae56f1..91223f1 100644 --- a/src/debugger/callstackbrowser.h +++ b/src/debugger/callstackbrowser.h @@ -7,9 +7,19 @@ #ifndef __CALLSTACKBROWSER_H__ #define __CALLSTACKBROWSER_H__ +//#define CS_LAYOUTTEXTS // Use a layout with just texts + #include #include +// Error code definitions +#define CS_NOERROR 0x00 +#define CS_ERROR 0x80 +#define CS_WARNING 0x40 +#define CS_NOCALLSTACK (0x01 | CS_WARNING) + + +// class CallStackBrowserWindow : public QWidget { Q_OBJECT @@ -26,7 +36,13 @@ class CallStackBrowserWindow : public QWidget private: QVBoxLayout *layout; + QStatusBar *statusbar; +#ifdef CS_LAYOUTTEXTS QTextBrowser * text; +#else + QTableView *TableView; + QStandardItemModel *model; +#endif }; #endif // __CALLSTACKBROWSER_H__ diff --git a/src/debugger/exceptionvectortablebrowser.cpp b/src/debugger/exceptionvectortablebrowser.cpp dissimilarity index 72% index e7fd51b..2324ac7 100644 --- a/src/debugger/exceptionvectortablebrowser.cpp +++ b/src/debugger/exceptionvectortablebrowser.cpp @@ -1,155 +1,219 @@ -// -// exceptionvectortable.cpp - Exception Vector Table -// -// by Jean-Paul Mari -// -// JPM = Jean-Paul Mari -// -// Who When What -// --- ---------- ----------------------------------------------------------- -// JPM 05/09/2017 Created this file -// - -// STILL TO DO: -// Better display presentation -// - -#include "debugger/exceptionvectortablebrowser.h" -#include "memory.h" -#include "debugger/DBGManager.h" - - -// -struct ExceptionVectorTable -{ - size_t VectorNumber; - size_t Address; - const char *ExceptionName; -}S_ExceptionVectorTable; - - -ExceptionVectorTable TabExceptionVectorTable[] = { - { 0, 0x000000, "RESET - Initial SSP" }, - { 1, 0x000004, "RESET - Initial PC" }, - { 2, 0x000008, "Bus error" }, - { 3, 0x00000C, "Address error" }, - { 4, 0x000010, "Illegal instruction" }, - { 5, 0x000014, "Division by zero" }, - { 6, 0x000018, "CHK instruction" }, - { 7, 0x00001C, "TRAPV instruction" }, - { 8, 0x000020, "Privilege violation" }, - { 9, 0x000024, "Trace" }, - { 10, 0x000028, "Unimplemented instruction" }, - { 11, 0x00002C, "Unimplemented instruction" }, - { 12, 0x000030, "Reserved by Motorola" }, - { 13, 0x000034, "Reserved by Motorola" }, - { 14, 0x000038, "Reserved by Motorola" }, - { 15, 0x00003C, "Uninitialised interrupt vector" }, - { 16, 0x000040, "Reserved by Motorola" }, - { 17, 0x000044, "Reserved by Motorola" }, - { 18, 0x000048, "Reserved by Motorola" }, - { 19, 0x00004C, "Reserved by Motorola" }, - { 20, 0x000050, "Reserved by Motorola" }, - { 21, 0x000054, "Reserved by Motorola" }, - { 22, 0x000058, "Reserved by Motorola" }, - { 23, 0x00005C, "Reserved by Motorola" }, - { 24, 0x000060, "Spurious interrupt" }, - { 25, 0x000064, "Level 1 interrupt autovector" }, - { 26, 0x000068, "Level 2 interrupt autovector" }, - { 27, 0x00006C, "Level 3 interrupt autovector" }, - { 28, 0x000070, "Level 4 interrupt autovector" }, - { 29, 0x000074, "Level 5 interrupt autovector" }, - { 30, 0x000078, "Level 6 interrupt autovector" }, - { 31, 0x00007C, "Level 7 interrupt autovector" }, - { 32, 0x000080, "TRAP #0 instruction" }, - { 33, 0x000084, "TRAP #1 instruction" }, - { 34, 0x000088, "TRAP #2 instruction" }, - { 35, 0x00008C, "TRAP #3 instruction" }, - { 36, 0x000090, "TRAP #4 instruction" }, - { 37, 0x000094, "TRAP #5 instruction" }, - { 38, 0x000098, "TRAP #6 instruction" }, - { 39, 0x00009C, "TRAP #7 instruction" }, - { 40, 0x0000A0, "TRAP #8 instruction" }, - { 41, 0x0000A4, "TRAP #9 instruction" }, - { 42, 0x0000A8, "TRAP #10 instruction" }, - { 43, 0x0000AC, "TRAP #11 instruction" }, - { 44, 0x0000B0, "TRAP #12 instruction" }, - { 45, 0x0000B4, "TRAP #13 instruction" }, - { 46, 0x0000B8, "TRAP #14 instruction" }, - { 47, 0x0000BC, "TRAP #15 instruction" }, - { 48, 0x0000C0, "Reserved by Motorola" }, - { 49, 0x0000C4, "Reserved by Motorola" }, - { 50, 0x0000C8, "Reserved by Motorola" }, - { 51, 0x0000CC, "Reserved by Motorola" }, - { 52, 0x0000D0, "Reserved by Motorola" }, - { 53, 0x0000D4, "Reserved by Motorola" }, - { 54, 0x0000D8, "Reserved by Motorola" }, - { 55, 0x0000DC, "Reserved by Motorola" }, - { 56, 0x0000E0, "Reserved by Motorola" }, - { 57, 0x0000E4, "Reserved by Motorola" }, - { 58, 0x0000E8, "Reserved by Motorola" }, - { 59, 0x0000EC, "Reserved by Motorola" }, - { 60, 0x0000F0, "Reserved by Motorola" }, - { 61, 0x0000F4, "Reserved by Motorola" }, - { 62, 0x0000F8, "Reserved by Motorola" }, - { 63, 0x0000FC, "Reserved by Motorola" }, - { 64, 0x000100, "User interrupt vectors" }, - { 255, 0x0003FC, "User interrupt vectors" } - }; - - -ExceptionVectorTableBrowserWindow::ExceptionVectorTableBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog), - layout(new QVBoxLayout), text(new QTextBrowser), - refresh(new QPushButton(tr("Refresh"))) -{ - setWindowTitle(tr("Exception Vector Table")); - - QHBoxLayout *hbox1 = new QHBoxLayout; - hbox1->addWidget(refresh); - - QFont fixedFont("Lucida Console", 8, QFont::Normal); - fixedFont.setStyleHint(QFont::TypeWriter); - text->setFont(fixedFont); - setLayout(layout); - - layout->addWidget(text); - layout->addWidget(refresh); - - connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents())); -} - - -// -ExceptionVectorTableBrowserWindow::~ExceptionVectorTableBrowserWindow(void) -{ -} - - -// -void ExceptionVectorTableBrowserWindow::RefreshContents(void) -{ - char string[1024]; - QString ExceptionVector; - size_t i; - - if (isVisible()) - { - for (i = 0; i < (sizeof(TabExceptionVectorTable) / sizeof(ExceptionVectorTable)); i++) - { - sprintf(string, "%03i : 0x%06X | 0x%06X | %s
", (unsigned int)TabExceptionVectorTable[i].VectorNumber, (unsigned int)TabExceptionVectorTable[i].Address, GET32(jaguarMainRAM, TabExceptionVectorTable[i].Address), TabExceptionVectorTable[i].ExceptionName); - ExceptionVector += QString(string); - } - - text->clear(); - text->setText(ExceptionVector); - } -} - - -void ExceptionVectorTableBrowserWindow::keyPressEvent(QKeyEvent * e) -{ - if (e->key() == Qt::Key_Escape) - { - hide(); - } -} +// +// exceptionvectortable.cpp - Exception Vector Table +// +// by Jean-Paul Mari +// +// JPM = Jean-Paul Mari +// +// Who When What +// --- ---------- ----------------------------------------------------------- +// JPM 05/09/2017 Created this file +// JPM 09/09/2018 Set information values in a tab +// JPM 09/09/2018 Added vectors in the table +// + +// STILL TO DO: +// To set the information display at the right +// + + +#include "debugger/exceptionvectortablebrowser.h" +#include "memory.h" +#include "debugger/DBGManager.h" + + +// +struct ExceptionVectorTable +{ + size_t VectorNumber; + size_t Address; + const char *ExceptionName; +} +S_ExceptionVectorTable; + +// +ExceptionVectorTable TabExceptionVectorTable[] = { + { 0, 0x000000, "RESET - Initial SSP" }, + { 1, 0x000004, "RESET - Initial PC" }, + { 2, 0x000008, "Bus error" }, + { 3, 0x00000C, "Address error" }, + { 4, 0x000010, "Illegal instruction" }, + { 5, 0x000014, "Division by zero" }, + { 6, 0x000018, "CHK instruction" }, + { 7, 0x00001C, "TRAPV instruction" }, + { 8, 0x000020, "Privilege violation" }, + { 9, 0x000024, "Trace" }, + { 10, 0x000028, "Unimplemented instruction" }, + { 11, 0x00002C, "Unimplemented instruction" }, + { 12, 0x000030, "Reserved by Motorola" }, + { 13, 0x000034, "Reserved by Motorola" }, + { 14, 0x000038, "Reserved by Motorola" }, + { 15, 0x00003C, "Uninitialised interrupt vector" }, + { 16, 0x000040, "Reserved by Motorola" }, + { 17, 0x000044, "Reserved by Motorola" }, + { 18, 0x000048, "Reserved by Motorola" }, + { 19, 0x00004C, "Reserved by Motorola" }, + { 20, 0x000050, "Reserved by Motorola" }, + { 21, 0x000054, "Reserved by Motorola" }, + { 22, 0x000058, "Reserved by Motorola" }, + { 23, 0x00005C, "Reserved by Motorola" }, + { 24, 0x000060, "Spurious interrupt" }, + { 25, 0x000064, "Level 1 interrupt autovector" }, + { 26, 0x000068, "Level 2 interrupt autovector" }, + { 27, 0x00006C, "Level 3 interrupt autovector" }, + { 28, 0x000070, "Level 4 interrupt autovector" }, + { 29, 0x000074, "Level 5 interrupt autovector" }, + { 30, 0x000078, "Level 6 interrupt autovector" }, + { 31, 0x00007C, "Level 7 interrupt autovector" }, + { 32, 0x000080, "TRAP #0 instruction" }, + { 33, 0x000084, "TRAP #1 instruction" }, + { 34, 0x000088, "TRAP #2 instruction" }, + { 35, 0x00008C, "TRAP #3 instruction" }, + { 36, 0x000090, "TRAP #4 instruction" }, + { 37, 0x000094, "TRAP #5 instruction" }, + { 38, 0x000098, "TRAP #6 instruction" }, + { 39, 0x00009C, "TRAP #7 instruction" }, + { 40, 0x0000A0, "TRAP #8 instruction" }, + { 41, 0x0000A4, "TRAP #9 instruction" }, + { 42, 0x0000A8, "TRAP #10 instruction" }, + { 43, 0x0000AC, "TRAP #11 instruction" }, + { 44, 0x0000B0, "TRAP #12 instruction" }, + { 45, 0x0000B4, "TRAP #13 instruction" }, + { 46, 0x0000B8, "TRAP #14 instruction" }, + { 47, 0x0000BC, "TRAP #15 instruction" }, + { 48, 0x0000C0, "Reserved by Motorola" }, + { 49, 0x0000C4, "Reserved by Motorola" }, + { 50, 0x0000C8, "Reserved by Motorola" }, + { 51, 0x0000CC, "Reserved by Motorola" }, + { 52, 0x0000D0, "Reserved by Motorola" }, + { 53, 0x0000D4, "Reserved by Motorola" }, + { 54, 0x0000D8, "Reserved by Motorola" }, + { 55, 0x0000DC, "Reserved by Motorola" }, + { 56, 0x0000E0, "Reserved by Motorola" }, + { 57, 0x0000E4, "Reserved by Motorola" }, + { 58, 0x0000E8, "Reserved by Motorola" }, + { 59, 0x0000EC, "Reserved by Motorola" }, + { 60, 0x0000F0, "Reserved by Motorola" }, + { 61, 0x0000F4, "Reserved by Motorola" }, + { 62, 0x0000F8, "Reserved by Motorola" }, + { 63, 0x0000FC, "Reserved by Motorola" }, + { 64, 0x000100, "User interrupt vectors" }, + { 65, 0x000104, "User interrupt vectors" }, + { 66, 0x000108, "User interrupt vectors" }, + { 67, 0x00010C, "User interrupt vectors" }, + { 68, 0x000200, "User interrupt vectors" }, + { 69, 0x000204, "User interrupt vectors" }, + { 70, 0x000208, "User interrupt vectors" }, + { 71, 0x00020C, "User interrupt vectors" }, + { 72, 0x000210, "User interrupt vectors" }, + { 73, 0x000214, "User interrupt vectors" }, + { 74, 0x000218, "User interrupt vectors" }, + { 75, 0x00021C, "User interrupt vectors" }, + { 252, 0x0003F0, "User interrupt vectors" }, + { 253, 0x0003F4, "User interrupt vectors" }, + { 254, 0x0003F8, "User interrupt vectors" }, + { 255, 0x0003FC, "User interrupt vectors" } + }; + + +// +ExceptionVectorTableBrowserWindow::ExceptionVectorTableBrowserWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog), +layout(new QVBoxLayout), +#ifdef EV_LAYOUTTEXTS +text(new QTextBrowser), +#else +TableView (new QTableView), +model (new QStandardItemModel), +#endif +refresh(new QPushButton(tr("Refresh"))) +{ + setWindowTitle(tr("Exception Vector Table")); + + // Refresh feature + QHBoxLayout *hbox1 = new QHBoxLayout; + hbox1->addWidget(refresh); + + // Setup font + QFont fixedFont("Lucida Console", 8, QFont::Normal); + fixedFont.setStyleHint(QFont::TypeWriter); + +#ifdef EV_LAYOUTTEXTS + text->setFont(fixedFont); + layout->addWidget(text); +#else + // Set the new layout with proper identation and readibility + model->setColumnCount(3); + model->setHeaderData(0, Qt::Horizontal, QObject::tr("Vector")); + model->setHeaderData(1, Qt::Horizontal, QObject::tr("Pointer")); + model->setHeaderData(2, Qt::Horizontal, QObject::tr("Use")); + // Information table + TableView->setModel(model); + TableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + TableView->setShowGrid(0); + TableView->setFont(fixedFont); + TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize()); + TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight); + layout->addWidget(TableView); +#endif + + layout->addWidget(refresh); + setLayout(layout); + + // Event setup + connect(refresh, SIGNAL(clicked()), this, SLOT(RefreshContents())); +} + + +// +ExceptionVectorTableBrowserWindow::~ExceptionVectorTableBrowserWindow(void) +{ +} + + +// +void ExceptionVectorTableBrowserWindow::RefreshContents(void) +{ + char string[1024]; +#ifdef EV_LAYOUTTEXTS + QString ExceptionVector; +#endif + size_t i; + + if (isVisible()) + { +#ifndef HA_LAYOUTTEXTS + model->setRowCount(0); +#endif + for (i = 0; i < (sizeof(TabExceptionVectorTable) / sizeof(ExceptionVectorTable)); i++) + { +#ifdef EV_LAYOUTTEXTS + if (i) + { + ExceptionVector += QString("
"); + } + sprintf(string, "%03i : 0x%06X | 0x%06X | %s", (unsigned int)TabExceptionVectorTable[i].VectorNumber, (unsigned int)TabExceptionVectorTable[i].Address, GET32(jaguarMainRAM, TabExceptionVectorTable[i].Address), TabExceptionVectorTable[i].ExceptionName); + ExceptionVector += QString(string); +#else + model->insertRow(i); + model->setItem(i, 0, new QStandardItem(QString("0x%1").arg(TabExceptionVectorTable[i].Address, 4, 16, QChar('0')))); + sprintf(string, "0x%06x", (unsigned int)GET32(jaguarMainRAM, TabExceptionVectorTable[i].Address)); + model->setItem(i, 1, new QStandardItem(QString("%1").arg(string))); + model->setItem(i, 2, new QStandardItem(QString("%1").arg(TabExceptionVectorTable[i].ExceptionName))); +#endif + } +#ifdef EV_LAYOUTTEXTS + text->clear(); + text->setText(ExceptionVector); +#endif + } +} + + +// +void ExceptionVectorTableBrowserWindow::keyPressEvent(QKeyEvent * e) +{ + if (e->key() == Qt::Key_Escape) + { + hide(); + } +} diff --git a/src/debugger/exceptionvectortablebrowser.h b/src/debugger/exceptionvectortablebrowser.h index 12bf882..aaccda0 100644 --- a/src/debugger/exceptionvectortablebrowser.h +++ b/src/debugger/exceptionvectortablebrowser.h @@ -7,10 +7,13 @@ #ifndef __EXCEPTIONVECTORTABLEBROWSER_H__ #define __EXCEPTIONVECTORTABLEBROWSER_H__ +//#define EV_LAYOUTTEXTS // Use a layout with just texts + #include #include +// class ExceptionVectorTableBrowserWindow: public QWidget { Q_OBJECT @@ -27,7 +30,12 @@ class ExceptionVectorTableBrowserWindow: public QWidget private: QVBoxLayout *layout; +#ifdef EV_LAYOUTTEXTS QTextBrowser *text; +#else + QTableView *TableView; + QStandardItemModel *model; +#endif QPushButton *refresh; }; diff --git a/src/debugger/heapallocatorbrowser.cpp b/src/debugger/heapallocatorbrowser.cpp index b65587b..024a9cf 100644 --- a/src/debugger/heapallocatorbrowser.cpp +++ b/src/debugger/heapallocatorbrowser.cpp @@ -11,12 +11,17 @@ // JPM 09/05/2018 Support of the DRAM size limit option // JPM 09/05/2018 Use definitions for error instead of hard values // JPM 09/05/2018 Detect if heap allocation shares space with SP (Stack) +// JPM 09/06/2018 Added a status bar and better status report +// JPM 09/07/2018 Set information values in a tab // // STILL TO DO: -// Better information display +// To have filters +// To set the information display at the right +// Feature to list the pointer(s) in the code using the allocation // + #include "settings.h" #include "debugger/heapallocatorbrowser.h" #include "memory.h" @@ -24,18 +29,52 @@ #include "m68000/m68kinterface.h" +// HeapAllocatorBrowserWindow::HeapAllocatorBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog), -layout(new QVBoxLayout), text(new QTextBrowser), +layout(new QVBoxLayout), +#ifdef HA_LAYOUTTEXTS +text(new QTextBrowser), +#else +TableView(new QTableView), +model(new QStandardItemModel), +proxyModel(new QSortFilterProxyModel), +#endif +statusbar(new QStatusBar), Adr(0) { setWindowTitle(tr("Heap Allocation")); + // Set the font QFont fixedFont("Lucida Console", 8, QFont::Normal); fixedFont.setStyleHint(QFont::TypeWriter); - text->setFont(fixedFont); - setLayout(layout); +#ifdef HA_LAYOUTTEXTS + // Set original layout + text->setFont(fixedFont); layout->addWidget(text); +#else + // Set the new layout with proper identation and readibility + model->setColumnCount(3); + model->setHeaderData(0, Qt::Horizontal, QObject::tr("Pointer")); + model->setHeaderData(1, Qt::Horizontal, QObject::tr("Size")); + model->setHeaderData(2, Qt::Horizontal, QObject::tr("Use")); + // Information table + TableView->setModel(model); + TableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + TableView->setShowGrid(0); + TableView->setFont(fixedFont); + TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize()); + TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight); + layout->addWidget(TableView); + // Set filter + proxyModel->setSourceModel(model); + QRegExp regExp("*", Qt::CaseInsensitive, QRegExp::Wildcard); + proxyModel->setFilterRegExp(regExp); +#endif + + // Status bar + layout->addWidget(statusbar); + setLayout(layout); } @@ -48,16 +87,25 @@ HeapAllocatorBrowserWindow::~HeapAllocatorBrowserWindow(void) // void HeapAllocatorBrowserWindow::RefreshContents(void) { - char string[1024]; +#ifdef HA_LAYOUTTEXTS + char string[1024] = { 0 }; QString HA; - size_t Adr68K; +#endif + char msg[1024]; + QString MSG; + size_t Adr68K, Adr68KHigh; size_t Error = HA_NOERROR; + size_t NbBlocks, TotalBytesUsed; HeapAllocation HeapAllocation; if (isVisible()) { if (Adr68K = Adr) { + Adr68KHigh = TotalBytesUsed = NbBlocks = 0; +#ifndef HA_LAYOUTTEXTS + model->setRowCount(0); +#endif do { if ((Adr68K >= 0x4000) && (Adr68K < vjs.DRAM_size)) @@ -76,48 +124,64 @@ void HeapAllocatorBrowserWindow::RefreshContents(void) if ((HeapAllocation.nextalloc >= 0x4000) && (HeapAllocation.nextalloc < vjs.DRAM_size)) { - sprintf(string, "0x%06x | 0x%06x (%zi) | %s | 0x%06x
", Adr68K, HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.used ? "Allocated" : "Free", HeapAllocation.nextalloc); - Adr68K = HeapAllocation.nextalloc; +#ifdef HA_LAYOUTTEXTS + if (NbBlocks++) + { + HA += QString("
"); + } + 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); + HA += QString(string); +#else + model->insertRow(NbBlocks); + model->setItem(NbBlocks, 0, new QStandardItem(QString("0x%1").arg(Adr68K, 6, 16, QChar('0')))); + model->setItem(NbBlocks, 1, new QStandardItem(QString("%1").arg((HeapAllocation.size - sizeof(HeapAllocation))))); + model->setItem(NbBlocks++, 2, new QStandardItem(QString("%1").arg(HeapAllocation.used ? "Allocated" : "Free"))); +#endif + TotalBytesUsed += HeapAllocation.size; + + if ((Adr68K = HeapAllocation.nextalloc) > Adr68KHigh) + { + Adr68KHigh = Adr68K; + } } else { - sprintf(string, "
Unable to determine the next memory allocation"); + sprintf(msg, "Unable to determine the next memory allocation"); Error = HA_UNABLENEXTMEMORYALLOC; } } else { - sprintf(string, "
Unable to determine if the allocated memory is used or not"); + sprintf(msg, "Unable to determine if the allocated memory is used or not"); Error = HA_UNABLEALLOCATEMEMORYUSAGE; } } else { - sprintf(string, "
Memory bloc size has a problem"); + sprintf(msg, "Memory bloc size has a problem"); Error = HA_MEMORYBLOCKSIZEPROBLEM; } } else { - sprintf(string, "
Memory allocations browsing successfully completed"); + sprintf(msg, "%i blocks | %i bytes in blocks | %i contiguous bytes free", NbBlocks, TotalBytesUsed, (m68k_get_reg(NULL, M68K_REG_SP) - Adr68KHigh)); } } else { - sprintf(string, "
Memory allocations and Stack are sharing the same space"); + sprintf(msg, "Memory allocations and Stack have reached the same space"); Error = HA_HAANDSPSHARESPACE; } } else { - sprintf(string, "
Memory allocations may have a problem"); + sprintf(msg, "Memory allocations may have a problem"); Error = HA_MEMORYALLOCATIONPROBLEM; } - - HA += QString(string); - } while (HeapAllocation.size && !Error); + + MSG += QString(msg); } else { @@ -127,7 +191,8 @@ void HeapAllocatorBrowserWindow::RefreshContents(void) { if (!(Adr68K = (jaguarMainRAM[Adr68K] << 24) + (jaguarMainRAM[Adr68K + 1] << 16) + (jaguarMainRAM[Adr68K + 2] << 8) + (jaguarMainRAM[Adr68K + 3])) || ((Adr68K < 0x4000) || (Adr68K >= 0x200000))) { - sprintf(string, "Memory allocator not yet initialised"); + sprintf(msg, "Memory allocator not yet initialised"); + Error = HA_MEMORYALLOCATORNOTINITIALIZED; Adr = 0; } else @@ -137,20 +202,47 @@ void HeapAllocatorBrowserWindow::RefreshContents(void) } else { - sprintf(string, "Memory allocator is not compatible"); + sprintf(msg, "Memory allocator is not compatible"); + Error = HA_MEMORYALLOCATORNOTCOMPATIBLE; Adr = 0; } } else { - sprintf(string, "Memory allocator doesn't exist"); + sprintf(msg, "Memory allocator doesn't exist"); + Error = HA_MEMORYALLOCATORNOTEXIST; } +#ifdef HA_LAYOUTTEXTS + HA += QString(""); +#else + model->setRowCount(0); +#endif + MSG += QString(msg); + } - HA += QString(string); + // Display status bar + if (Error) + { + if ((Error & HA_WARNING)) + { + statusbar->setStyleSheet("background-color: lightyellow; font: bold"); + } + else + { + statusbar->setStyleSheet("background-color: tomato; font: bold"); + } + } + else + { + statusbar->setStyleSheet("background-color: lightgreen; font: bold"); } + statusbar->showMessage(MSG); +#ifdef HA_LAYOUTTEXTS + // Display values text->clear(); text->setText(HA); +#endif } } diff --git a/src/debugger/heapallocatorbrowser.h b/src/debugger/heapallocatorbrowser.h index b3521f0..bbc2a4e 100644 --- a/src/debugger/heapallocatorbrowser.h +++ b/src/debugger/heapallocatorbrowser.h @@ -7,18 +7,24 @@ #ifndef __HEAPALLOCATORBROWSER_H__ #define __HEAPALLOCATORBROWSER_H__ +//#define HA_LAYOUTTEXTS // Use a layout with just texts #include #include - // Error code definitions -#define HA_NOERROR 0 -#define HA_UNABLENEXTMEMORYALLOC 1 -#define HA_UNABLEALLOCATEMEMORYUSAGE 2 -#define HA_MEMORYBLOCKSIZEPROBLEM 3 -#define HA_MEMORYALLOCATIONPROBLEM 4 -#define HA_HAANDSPSHARESPACE 5 +#define HA_NOERROR 0x00 +#define HA_ERROR 0x80 +#define HA_WARNING 0x40 +#define HA_UNABLENEXTMEMORYALLOC (0x01 | HA_ERROR) +#define HA_UNABLEALLOCATEMEMORYUSAGE (0x02 | HA_ERROR) +#define HA_MEMORYBLOCKSIZEPROBLEM (0x03 | HA_ERROR) +#define HA_MEMORYALLOCATIONPROBLEM (0x04 | HA_ERROR) +#define HA_HAANDSPSHARESPACE (0x05 | HA_ERROR) +#define HA_MEMORYALLOCATORNOTEXIST (0x06 | HA_WARNING) +#define HA_MEMORYALLOCATORNOTCOMPATIBLE (0x07 | HA_WARNING) +#define HA_MEMORYALLOCATORNOTINITIALIZED (0x08 | HA_WARNING) + // class HeapAllocatorBrowserWindow: public QWidget @@ -30,7 +36,8 @@ class HeapAllocatorBrowserWindow: public QWidget uint32_t nextalloc; uint32_t size; uint16_t used; - }S_HeapAllocation; + } + S_HeapAllocation; public: HeapAllocatorBrowserWindow(QWidget *parent = 0); @@ -45,7 +52,14 @@ class HeapAllocatorBrowserWindow: public QWidget private: QVBoxLayout *layout; +#ifdef HA_LAYOUTTEXTS QTextBrowser *text; +#else + QTableView *TableView; + QStandardItemModel *model; + QSortFilterProxyModel *proxyModel; +#endif + QStatusBar *statusbar; size_t Adr; }; diff --git a/src/debugger/localbrowser.cpp b/src/debugger/localbrowser.cpp index 35b858d..9c59b43 100644 --- a/src/debugger/localbrowser.cpp +++ b/src/debugger/localbrowser.cpp @@ -8,6 +8,14 @@ // Who When What // --- ---------- ----------------------------------------------------------- // JPM 11/03/2017 Created this file +// JPM 09/08/2018 Added a status bar and better status report +// JPM 09/08/2018 Set information values in a tab +// + +// STILL TO DO: +// Feature to list the pointer(s) in the code using the allocation +// To set the information display at the right +// To support the array // @@ -20,19 +28,47 @@ // LocalBrowserWindow::LocalBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog), - layout(new QVBoxLayout), text(new QTextBrowser), - NbLocal(0), - FuncName((char *)calloc(1, 1)), - LocalInfo(NULL) +layout(new QVBoxLayout), +#ifdef LOCAL_LAYOUTTEXTS +text(new QTextBrowser), +#else +TableView(new QTableView), +model(new QStandardItemModel), +#endif +NbLocal(0), +FuncName((char *)calloc(1, 1)), +LocalInfo(NULL), +statusbar(new QStatusBar) { - setWindowTitle(tr("Local")); + setWindowTitle(tr("Locals")); + // Set the font QFont fixedFont("Lucida Console", 8, QFont::Normal); fixedFont.setStyleHint(QFont::TypeWriter); - text->setFont(fixedFont); - setLayout(layout); +#ifdef LOCAL_LAYOUTTEXTS + // Set original layout + text->setFont(fixedFont); layout->addWidget(text); +#else + // Set the new layout with proper identation and readibility + model->setColumnCount(3); + model->setHeaderData(0, Qt::Horizontal, QObject::tr("Name")); + model->setHeaderData(1, Qt::Horizontal, QObject::tr("Value")); + model->setHeaderData(2, Qt::Horizontal, QObject::tr("Type")); + // Information table + TableView->setModel(model); + TableView->setEditTriggers(QAbstractItemView::NoEditTriggers); + TableView->setShowGrid(0); + TableView->setFont(fixedFont); + TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize()); + TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight); + layout->addWidget(TableView); +#endif + + // Status bar + layout->addWidget(statusbar); + setLayout(layout); } @@ -94,21 +130,40 @@ bool LocalBrowserWindow::UpdateInfos(void) // void LocalBrowserWindow::RefreshContents(void) { +#ifdef LOCAL_LAYOUTTEXTS char string[1024]; +#endif + size_t Error = LOCAL_NOERROR; QString Local; + QString MSG; + char Value1[100]; +#ifdef LOCAL_SUPPORTARRAY char Value[100]; +#endif char *PtrValue; const char *CPURegName[] = { "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7" }; if (isVisible()) { +#ifndef LOCAL_LAYOUTTEXTS + model->setRowCount(0); +#endif if (UpdateInfos()) { for (size_t i = 0; i < NbLocal; i++) { if (LocalInfo[i].PtrVariableName) { + memset(Value1, 0, sizeof(Value1)); +#ifdef LOCAL_LAYOUTTEXTS + if (i) + { + Local += QString("
"); + } +#else + model->insertRow(i); +#endif // Local or parameters variables if (((LocalInfo[i].Op >= DBG_OP_breg0) && (LocalInfo[i].Op <= DBG_OP_breg31)) || (LocalInfo[i].Op == DBG_OP_fbreg)) { @@ -121,7 +176,25 @@ void LocalBrowserWindow::RefreshContents(void) if ((LocalInfo[i].Adr >= 0) && (LocalInfo[i].Adr < vjs.DRAM_size)) { - PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, LocalInfo[i].TypeEncoding, LocalInfo[i].TypeByteSize); + if ((LocalInfo[i].TypeTag & (DBG_TAG_TYPE_array | DBG_TAG_TYPE_structure))) + { +#if defined(LOCAL_SUPPORTARRAY) || defined(LOCAL_SUPPORTSTRUCTURE) + //memcpy(Value1, &jaguarMainRAM[LocalInfo[i].Adr], 20); +#ifdef LOCAL_LAYOUTTEXTS + //sprintf(Value, "\"%s\"", Value1); +#else + //sprintf(Value, "0x%06X, \"%s\"", LocalInfo[i].Adr, Value1); +#endif + //PtrValue = Value; + PtrValue = NULL; +#else + PtrValue = NULL; +#endif + } + else + { + PtrValue = DBGManager_GetVariableValueFromAdr(LocalInfo[i].Adr, LocalInfo[i].TypeEncoding, LocalInfo[i].TypeByteSize); + } } else { @@ -134,7 +207,7 @@ void LocalBrowserWindow::RefreshContents(void) if ((LocalInfo[i].Op >= DBG_OP_reg0) && (LocalInfo[i].Op <= DBG_OP_reg31)) { LocalInfo[i].PtrCPURegisterName = (char *)CPURegName[(LocalInfo[i].Op - DBG_OP_reg0)]; - PtrValue = itoa(m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))), Value, 10); + PtrValue = itoa(m68k_get_reg(NULL, (m68k_register_t)((size_t)M68K_REG_D0 + (LocalInfo[i].Op - DBG_OP_reg0))), Value1, 10); } else { @@ -142,14 +215,25 @@ void LocalBrowserWindow::RefreshContents(void) } } +#ifndef LOCAL_LAYOUTTEXTS + model->setItem(i, 0, new QStandardItem(QString("%1").arg(LocalInfo[i].PtrVariableName))); +#endif + // Check if the local variable is use by the code if (!LocalInfo[i].Op) { +#ifdef LOCAL_LAYOUTTEXTS sprintf(string, "%i : %s | %s | [Not used]", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"N/A"), LocalInfo[i].PtrVariableName); +#else +#endif } else { +#ifndef LOCAL_LAYOUTTEXTS + model->setItem(i, 1, new QStandardItem(QString("%1").arg(PtrValue))); +#else sprintf(string, "%i : %s | %s | ", (i + 1), (LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"N/A"), LocalInfo[i].PtrVariableName); Local += QString(string); + if ((unsigned int)LocalInfo[i].Adr) { sprintf(string, "0x%06X", (unsigned int)LocalInfo[i].Adr); @@ -165,22 +249,52 @@ void LocalBrowserWindow::RefreshContents(void) sprintf(string, "%s", (char *)"N/A"); } } + Local += QString(string); sprintf(string, " | %s", (!PtrValue ? (char *)"N/A" : PtrValue)); +#endif } +#ifndef LOCAL_LAYOUTTEXTS + model->setItem(i, 2, new QStandardItem(QString("%1").arg((LocalInfo[i].PtrVariableBaseTypeName ? LocalInfo[i].PtrVariableBaseTypeName : (char *)"N/A")))); +#else Local += QString(string); - sprintf(string, "
"); - Local += QString(string); +#endif } } + MSG += QString("Ready"); +#ifdef LOCAL_LAYOUTTEXTS text->clear(); text->setText(Local); +#endif } else { + // No locals + MSG += QString("No locals"); + Error = LOCAL_NOLOCALS; +#ifdef LOCAL_LAYOUTTEXTS text->clear(); +#endif + } + + // Display status bar + if (Error) + { + if ((Error & LOCAL_WARNING)) + { + statusbar->setStyleSheet("background-color: lightyellow; font: bold"); + } + else + { + statusbar->setStyleSheet("background-color: tomato; font: bold"); + } + } + else + { + statusbar->setStyleSheet("background-color: lightgreen; font: bold"); } + statusbar->showMessage(MSG); } } diff --git a/src/debugger/localbrowser.h b/src/debugger/localbrowser.h index 544957a..056fd73 100644 --- a/src/debugger/localbrowser.h +++ b/src/debugger/localbrowser.h @@ -7,9 +7,21 @@ #ifndef __LOCALBROWSER_H__ #define __LOCALBROWSER_H__ +//#define LOCAL_LAYOUTTEXTS // Use a layout with just texts +//#define LOCAL_SUPPORTARRAY // Support array +//#define LOCAL_SUPPORTSTRUCTURE // Support structure + #include #include + +// Error code definitions +#define LOCAL_NOERROR 0x00 +#define LOCAL_ERROR 0x80 +#define LOCAL_WARNING 0x40 +#define LOCAL_NOLOCALS (0x01 | LOCAL_WARNING) + +// class LocalBrowserWindow: public QWidget { Q_OBJECT @@ -26,7 +38,8 @@ class LocalBrowserWindow: public QWidget char *PtrVariableName; char *PtrVariableBaseTypeName; char *PtrCPURegisterName; - }S_WatchInfo; + } + S_WatchInfo; public: LocalBrowserWindow(QWidget *parent = 0); @@ -41,8 +54,14 @@ class LocalBrowserWindow: public QWidget private: QVBoxLayout *layout; +#ifdef LOCAL_LAYOUTTEXTS QTextBrowser *text; +#else + QTableView *TableView; + QStandardItemModel *model; +#endif WatchInfo *LocalInfo; + QStatusBar *statusbar; size_t NbLocal; char *FuncName; };