From 3323d78b32c62b83dfbb32b57f2bd718fd2b62c4 Mon Sep 17 00:00:00 2001 From: Jean-Paul Mari Date: Sun, 21 Apr 2019 21:03:43 -0400 Subject: [PATCH] Added a Save Dump As... feature to save a memory zone to a file --- .gitignore | 1 + Win-VS2017/virtualjaguar.vcxproj | 27 ++++ Win-VS2017/virtualjaguar.vcxproj.filters | 12 ++ docs/vj_HistoryNotes.txt | 1 + src/debugger/SaveDumpAsWin.cpp | 190 +++++++++++++++++++++++ src/debugger/SaveDumpAsWin.h | 46 ++++++ src/gui/mainwin.cpp | 33 +++- src/gui/mainwin.h | 4 + virtualjaguar.pro | 2 + 9 files changed, 313 insertions(+), 3 deletions(-) create mode 100644 src/debugger/SaveDumpAsWin.cpp create mode 100644 src/debugger/SaveDumpAsWin.h diff --git a/.gitignore b/.gitignore index 05baa39..ffc38f5 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ Win-VS2017/virtualjaguar.sdf Win-VS2017/virtualjaguar.vcxproj.user Win-VS2017/GeneratedFiles/ Win-VS2015/ +Win-VS2019/ diff --git a/Win-VS2017/virtualjaguar.vcxproj b/Win-VS2017/virtualjaguar.vcxproj index 08f1e70..52a6b6d 100644 --- a/Win-VS2017/virtualjaguar.vcxproj +++ b/Win-VS2017/virtualjaguar.vcxproj @@ -285,6 +285,7 @@ + @@ -425,6 +426,10 @@ true true + + true + true + true true @@ -608,6 +613,10 @@ true true + + true + true + true true @@ -741,6 +750,24 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -D__GCCWIN32__ -DQT_NO_DEBUG -DQT_OPENGL_LIB -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -D_UNICODE "-I." "-I.\..\src" "-I.\..\src\gui" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtOpenGL" "-IC:\SDK\OpenGL\include" "-IC:\SDK\SDL\SDL-1.2.15\include" "-IC:\SDK\DWARF\libdwarf-VS2015\include" "-IC:\SDK\Elf\libelf-0.8.13\include" "-IC:\SDK\zlib\zlib-1.2.11\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I.\GeneratedFiles" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -D__GCCWIN32__ -DQT_OPENGL_ES_2 -DQT_OPENGL_ES_2_ANGLE -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_OPENGL_LIB -D%(PreprocessorDefinitions) "-I." "-I.\..\src" "-I.\..\src\gui" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtOpenGL" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtWidgets" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtGui" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtANGLE" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtCore" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\mkspecs\win32-msvc2015" "-IC:\SDK\SDL-1.2.15\include" "-IC:\SDK\mesa-11.2.0-rc4\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtOpenGL" "-I.\GeneratedFiles\$(ConfigurationName)" "-I.\GeneratedFiles" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -D__GCCWIN32__ -DQT_OPENGL_LIB -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -D%(PreprocessorDefinitions) "-I." "-I.\..\src" "-I.\..\src\gui" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtOpenGL" "-IC:\SDK\SDL\SDL-1.2.15\include" "-IC:\SDK\DWARF\libdwarf-VS2015\include" "-IC:\SDK\Elf\libelf-0.8.13\include" "-IC:\SDK\zlib\zlib-1.2.8\include" "-I.\GeneratedFiles\$(ConfigurationName)" "-IC:\SDK\OpenGL\include" "-I.\GeneratedFiles" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -D__GCCWIN32__ -DQT_NO_DEBUG -DQT_OPENGL_ES_2 -DQT_OPENGL_ES_2_ANGLE -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_OPENGL_LIB -D%(PreprocessorDefinitions) "-I." "-I.\..\src" "-I.\..\src\gui" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtOpenGL" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtWidgets" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtGui" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtANGLE" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\include\QtCore" "-I.\..\..\..\Qt\Qt5.5.1\msvc2015_64\mkspecs\win32-msvc2015" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtOpenGL" "-I.\GeneratedFiles\$(ConfigurationName)" "-I.\GeneratedFiles" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_CRT_SECURE_NO_WARNINGS -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -D__GCCWIN32__ -DQT_NO_DEBUG -DQT_OPENGL_LIB -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -D%(PreprocessorDefinitions) "-I." "-I.\..\src" "-I.\..\src\gui" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtOpenGL" "-IC:\SDK\OpenGL\include" "-IC:\SDK\SDL\SDL-1.2.15\include" "-IC:\SDK\DWARF\libdwarf-VS2015\include" "-IC:\SDK\Elf\libelf-0.8.13\include" "-IC:\SDK\zlib\zlib-1.2.11\include" "-I.\GeneratedFiles\$(ConfigurationName)" "-I.\GeneratedFiles" + Moc%27ing keybindingstab.h... diff --git a/Win-VS2017/virtualjaguar.vcxproj.filters b/Win-VS2017/virtualjaguar.vcxproj.filters index 75e8af3..530696e 100644 --- a/Win-VS2017/virtualjaguar.vcxproj.filters +++ b/Win-VS2017/virtualjaguar.vcxproj.filters @@ -436,6 +436,15 @@ Generated Files + + Generated Files + + + Generated Files + + + Source Files\debugger + @@ -748,6 +757,9 @@ Header Files\debugger\View + + Header Files\debugger + diff --git a/docs/vj_HistoryNotes.txt b/docs/vj_HistoryNotes.txt index ba62d4b..c9756bb 100644 --- a/docs/vj_HistoryNotes.txt +++ b/docs/vj_HistoryNotes.txt @@ -84,6 +84,7 @@ Git commit: TBD 46) Fix crash with potential missing DWARF structure tag's type name 47) Added ELF sections check so a potential unknown section will stop, or not stop, the decoding 48) Project has switched to QT 5.12.0 library 64bits for VS 2017 +49) Added a Save Dump As... feature to save a memory zone to a file Release 3 (13th November 2017) ------------------------------ diff --git a/src/debugger/SaveDumpAsWin.cpp b/src/debugger/SaveDumpAsWin.cpp new file mode 100644 index 0000000..abf7cbd --- /dev/null +++ b/src/debugger/SaveDumpAsWin.cpp @@ -0,0 +1,190 @@ +// +// SaveDumpAsWin.cpp - Save Dump function +// +// by Jean-Paul Mari +// +// JPM = Jean-Paul Mari +// +// Who When What +// --- ---------- ----------------------------------------------------------- +// JPM 04/10/2019 Created this file +// + +// STILL TO DO: +// + +#include "debugger/SaveDumpAsWin.h" +#include "jaguar.h" +#include "debugger/DBGManager.h" +#include "m68000/m68kinterface.h" +#include "settings.h" + + +// +SaveDumpAsWindow::SaveDumpAsWindow(QWidget * parent/*= 0*/): QWidget(parent, Qt::Dialog), +layout(new QVBoxLayout), +maddress(new QLineEdit), +msize(new QLineEdit), +savedump(new SaveDumpAsInfo), +save(new QPushButton(tr("Save"))) +{ + setWindowTitle(tr("Save Dump As...")); + + maddress->setPlaceholderText("0x, decimal value or symbol name"); + msize->setPlaceholderText("0x, or decimal value"); + + QHBoxLayout * hbox1 = new QHBoxLayout; + hbox1->addWidget(maddress); + hbox1->addWidget(msize); + hbox1->addWidget(save); + + layout->addLayout(hbox1); + setLayout(layout); + + connect(save, SIGNAL(clicked()), this, SLOT(SaveDumpAs())); +} + + +// +SaveDumpAsWindow::~SaveDumpAsWindow(void) +{ +} + + +// +void SaveDumpAsWindow::keyPressEvent(QKeyEvent * e) +{ + if (e->key() == Qt::Key_Escape) + { + hide(); + } + else + { + if (e->key() == Qt::Key_Return) + { + SaveDumpAs(); + } + } +} + + +// Save Dump +void SaveDumpAsWindow::SaveDumpAs(void) +{ + if (SelectAddress() && SelectSize()) + { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save dump"), "", tr("Save dump files (*.bin)")); + + if (fileName.size()) + { + if (FILE *File = fopen((char *)fileName.toUtf8().data(), "wb")) + { + if (fwrite((void *)&jagMemSpace[savedump->Adr], savedump->Size, 1, File) == 1) + { + fclose(File); + } + } + } + } +} + + +// Select size +bool SaveDumpAsWindow::SelectSize(void) +{ + bool ok = false; + size_t len; + QString newSize; + size_t s; + + QPalette p = msize->palette(); + newSize = msize->text(); + + if ((len = newSize.size())) + { + if ((len > 1) && (newSize.at(0) == QChar('0')) && (newSize.at(1) == QChar('x'))) + { + s = newSize.toUInt(&ok, 16); + } + else + { + s = newSize.toUInt(&ok, 10); + } + + // Check validity size + if (ok && s && (s < 0xffffff)) + { + // In all cases, consider size as valid + savedump->Size = s; + p.setColor(QPalette::Text, Qt::darkYellow); + } + else + { + // Size is not valid + ok = false; + p.setColor(QPalette::Text, Qt::red); + } + } + else + { + // Size has not be set + p.setColor(QPalette::Text, Qt::darkRed); + } + + msize->setPalette(p); + return ok ? true : false; +} + + +// Select address +// Address can be an hexa, decimal or a symbol name +bool SaveDumpAsWindow::SelectAddress(void) +{ + bool ok = false; + size_t len; + QString newAddress; + size_t adr; + + QPalette p = maddress->palette(); + newAddress = maddress->text(); + + if ((len = newAddress.size())) + { + if ((len > 1) && (newAddress.at(0) == QChar('0')) && (newAddress.at(1) == QChar('x'))) + { + adr = newAddress.toUInt(&ok, 16); + } + else + { + if (!(adr = DBGManager_GetAdrFromSymbolName(newAddress.toLatin1().data()))) + { + adr = newAddress.toUInt(&ok, 10); + } + else + { + ok = true; + } + } + + // Check validity address + if (ok && (adr < 0xffffff)) + { + // In all cases, consider address as valid + savedump->Adr = adr; + p.setColor(QPalette::Text, Qt::darkYellow); + } + else + { + // Address is not valid + p.setColor(QPalette::Text, Qt::red); + } + } + else + { + // Address has not be set + p.setColor(QPalette::Text, Qt::darkRed); + } + + maddress->setPalette(p); + return ok ? true : false; +} diff --git a/src/debugger/SaveDumpAsWin.h b/src/debugger/SaveDumpAsWin.h new file mode 100644 index 0000000..3a755ed --- /dev/null +++ b/src/debugger/SaveDumpAsWin.h @@ -0,0 +1,46 @@ +// +// SaveDumpAsWin.h: Save Dump function +// +// by Jean-Paul Mari +// + +#ifndef __SAVEDUMPASWIN_H__ +#define __SAVEDUMPASWIN_H__ + +#include +#include + +class SaveDumpAsWindow : public QWidget +{ + Q_OBJECT + + typedef struct SaveDumpAsInfo + { + size_t Size; + size_t Adr; + } + S_SaveDumpAsInfo; + + public: + SaveDumpAsWindow(QWidget * parent = 0); + ~SaveDumpAsWindow(void); + + protected: + void keyPressEvent(QKeyEvent *); + + protected slots: + void SaveDumpAs(void); + + private: + bool SelectAddress(void); + bool SelectSize(void); + + private: + QVBoxLayout *layout; + QLineEdit *maddress; + QLineEdit *msize; + QPushButton *save; + SaveDumpAsInfo *savedump; +}; + +#endif // __SAVEDUMPASWIN_H__ diff --git a/src/gui/mainwin.cpp b/src/gui/mainwin.cpp index 1b547e2..0c3ec45 100644 --- a/src/gui/mainwin.cpp +++ b/src/gui/mainwin.cpp @@ -22,7 +22,7 @@ // JPM Sept./2018 Added the new Models and BIOS handler, a screenshot feature and source code files browsing // JPM Oct./2018 Added search paths in the settings, breakpoints feature, cartdridge view menu // JPM 11/18/2018 Fix crash with non-debugger mode -// JPM 04/06/2019 Added ELF sections check +// JPM April/2019 Added ELF sections check, added a save memory dump // // FIXED: @@ -102,6 +102,7 @@ #include "debugger/heapallocatorbrowser.h" #include "debugger/callstackbrowser.h" #include "debugger/CartFilesListWin.h" +#include "debugger/SaveDumpAsWin.h" // According to SebRmv, this header isn't seen on Arch Linux either... :-/ @@ -200,6 +201,7 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), heapallocatorBrowseWin = new HeapAllocatorBrowserWindow(this); BreakpointsWin = new BreakpointsWindow(this); NewFunctionBreakpointWin = new NewFnctBreakpointWindow(this); + SaveDumpAsWin = new SaveDumpAsWindow(this); exceptionvectortableBrowseWin = new ExceptionVectorTableBrowserWindow(this); CallStackBrowseWin = new CallStackBrowserWindow(this); CartFilesListWin = new CartFilesListWindow(this); @@ -418,6 +420,12 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), disableAllBreakpointsAct = new QAction(QIcon(":/res/debug-disableallbreakpoints.png"), tr("&Disable All Breakpoints"), this); connect(disableAllBreakpointsAct, SIGNAL(triggered()), this, SLOT(DisableAllBreakpoints())); + // Save dump + saveDumpAsAct = new QAction(tr("&Save Dump As..."), this); + saveDumpAsAct->setCheckable(false); + saveDumpAsAct->setDisabled(false); + connect(saveDumpAsAct, SIGNAL(triggered()), this, SLOT(ShowSaveDumpAsWin())); + //VideoOutputAct = new QAction(tr("Output Video"), this); //VideoOutputAct->setStatusTip(tr("Shows the output video window")); //connect(VideoOutputAct, SIGNAL(triggered()), this, SLOT(ShowVideoOutputWin())); @@ -588,6 +596,8 @@ MainWin::MainWin(bool autoRun): running(true), powerButtonOn(false), debugNewBreakpointMenu->addAction(newFunctionBreakpointAct); debugMenu->addAction(deleteAllBreakpointsAct); debugMenu->addAction(disableAllBreakpointsAct); + debugMenu->addSeparator(); + debugMenu->addAction(saveDumpAsAct); #if 0 debugMenu->addSeparator(); debugMenu->addAction(DasmAct); @@ -1515,7 +1525,7 @@ void MainWin::ShowNewFunctionBreakpointWin(void) } -// +// Display list of files found in cartdridge void MainWin::ShowCartFilesListWin(void) { CartFilesListWin->show(); @@ -1523,6 +1533,13 @@ void MainWin::ShowCartFilesListWin(void) } +// +void MainWin::ShowSaveDumpAsWin(void) +{ + SaveDumpAsWin->show(); +} + + // Step Into trace void MainWin::DebuggerTraceStepInto(void) { @@ -2058,13 +2075,20 @@ void MainWin::ReadUISettings(void) size = settings.value("CallStackBrowseWinSize", QSize(400, 400)).toSize(); CallStackBrowseWin->resize(size); - // Cartdridge directory and files + // Cartdridge directory and files UI information pos = settings.value("CartFilesListWinPos", QPoint(200, 200)).toPoint(); CartFilesListWin->move(pos); settings.value("CartFilesListWinIsVisible", false).toBool() ? ShowCartFilesListWin() : void(); size = settings.value("CartFilesListWinSize", QSize(400, 400)).toSize(); CartFilesListWin->resize(size); + // Save dump UI information + pos = settings.value("SaveDumpAsWinPos", QPoint(200, 200)).toPoint(); + SaveDumpAsWin->move(pos); + settings.value("SaveDumpAsWinIsVisible", false).toBool() ? ShowSaveDumpAsWin() : void(); + size = settings.value("SaveDumpAsWinSize", QSize(400, 400)).toSize(); + SaveDumpAsWin->resize(size); + // Breakpoints UI information pos = settings.value("BreakpointsWinPos", QPoint(200, 200)).toPoint(); BreakpointsWin->move(pos); @@ -2288,6 +2312,9 @@ void MainWin::WriteUISettings(void) settings.setValue("CartFilesListWinPos", CartFilesListWin->pos()); settings.setValue("CartFilesListWinIsVisible", CartFilesListWin->isVisible()); settings.setValue("CartFilesListWinSize", CartFilesListWin->size()); + settings.setValue("SaveDumpAsWinPos", SaveDumpAsWin->pos()); + settings.setValue("SaveDumpAsWinIsVisible", SaveDumpAsWin->isVisible()); + settings.setValue("SaveDumpAsWinSize", SaveDumpAsWin->size()); for (i = 0; i < vjs.nbrmemory1browserwindow; i++) { diff --git a/src/gui/mainwin.h b/src/gui/mainwin.h index e0aa8d1..849b0cc 100644 --- a/src/gui/mainwin.h +++ b/src/gui/mainwin.h @@ -48,6 +48,7 @@ class NewFnctBreakpointWindow; class ExceptionVectorTableBrowserWindow; class FilesrcListWindow; class CartFilesListWindow; +class SaveDumpAsWindow; // @@ -108,6 +109,7 @@ class MainWin: public QMainWindow void ShowBreakpointsWin(void); void DeleteAllBreakpoints(void); void DisableAllBreakpoints(void); + void ShowSaveDumpAsWin(void); #if 0 void ShowVideoOutputWin(void); void ShowDasmWin(void); @@ -162,6 +164,7 @@ class MainWin: public QMainWindow BreakpointsWindow *BreakpointsWin; NewFnctBreakpointWindow *NewFunctionBreakpointWin; CartFilesListWindow *CartFilesListWin; + SaveDumpAsWindow *SaveDumpAsWin; QTimer *timer; bool running; int zoomLevel; @@ -244,6 +247,7 @@ class MainWin: public QMainWindow QAction *BreakpointsAct; QAction *deleteAllBreakpointsAct; QAction *disableAllBreakpointsAct; + QAction *saveDumpAsAct; QAction *exceptionVectorTableBrowseAct; QAction *CartFilesListAct; diff --git a/virtualjaguar.pro b/virtualjaguar.pro index d7e70de..19bd96a 100644 --- a/virtualjaguar.pro +++ b/virtualjaguar.pro @@ -127,6 +127,7 @@ HEADERS = \ src/debugger/exceptionvectortablebrowser.h \ src/debugger/NewFnctBreakpointWin.h \ src/debugger/CartFilesListWin.h \ + src/debugger/SaveDumpAsWin.h \ src/log.h \ src/unzip.h \ src/crc32.h \ @@ -181,6 +182,7 @@ SOURCES = \ src/debugger/callstackbrowser.cpp \ src/debugger/NewFnctBreakpointWin.cpp \ src/debugger/CartFilesListWin.cpp \ + src/debugger/SaveDumpAsWin.cpp \ src/log.cpp \ src/unzip.cpp \ src/crc32.cpp \ -- 2.20.1