123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431 |
- #include "DebuggerForm.h"
- #include "BitMapViewer.h"
- #include "DockableWidgetArea.h"
- #include "DockableWidget.h"
- #include "DisasmViewer.h"
- #include "MainMemoryViewer.h"
- #include "CPURegsViewer.h"
- #include "FlagsViewer.h"
- #include "StackViewer.h"
- #include "SlotViewer.h"
- #include "CommClient.h"
- #include "ConnectDialog.h"
- #include "SymbolManager.h"
- #include "PreferencesDialog.h"
- #include "BreakpointDialog.h"
- #include "GotoDialog.h"
- #include "DebuggableViewer.h"
- #include "VDPRegViewer.h"
- #include "VDPStatusRegViewer.h"
- #include "VDPCommandRegViewer.h"
- #include "Settings.h"
- #include "Version.h"
- #include <QAction>
- #include <QMessageBox>
- #include <QMenu>
- #include <QMenuBar>
- #include <QToolBar>
- #include <QStatusBar>
- #include <QWidget>
- #include <QLabel>
- #include <QVBoxLayout>
- #include <QHBoxLayout>
- #include <QString>
- #include <QStringList>
- #include <QSplitter>
- #include <QPixmap>
- #include <QFileDialog>
- #include <QCloseEvent>
- #include <iostream>
- class QueryPauseHandler : public SimpleCommand
- {
- public:
- QueryPauseHandler(DebuggerForm& form_)
- : SimpleCommand("set pause")
- , form(form_)
- {
- }
- virtual void replyOk(const QString& message)
- {
- // old openmsx versions returned 'on','false'
- // new versions return 'true','false'
- // so check for 'false'
- bool checked = message.trimmed() != "false";
- form.systemPauseAction->setChecked(checked);
- delete this;
- }
- private:
- DebuggerForm& form;
- };
- class QueryBreakedHandler : public SimpleCommand
- {
- public:
- QueryBreakedHandler(DebuggerForm& form_)
- : SimpleCommand("debug breaked")
- , form(form_)
- {
- }
- virtual void replyOk(const QString& message)
- {
- form.finalizeConnection(message.trimmed() == "1");
- delete this;
- }
- private:
- DebuggerForm& form;
- };
- class ListBreakPointsHandler : public SimpleCommand
- {
- public:
- ListBreakPointsHandler(DebuggerForm& form_, bool merge_ = false)
- : SimpleCommand("debug_list_all_breaks")
- , form(form_), merge(merge_)
- {
- }
- virtual void replyOk(const QString& message)
- {
- if (merge) {
- QString bps = form.session.breakpoints().mergeBreakpoints(message);
- if (!bps.isEmpty()) {
- form.comm.sendCommand(new SimpleCommand(bps));
- form.comm.sendCommand(new ListBreakPointsHandler(form, false));
- } else {
- form.disasmView->update();
- form.session.sessionModified();
- form.updateWindowTitle();
- }
- } else {
- form.session.breakpoints().setBreakpoints(message);
- form.disasmView->update();
- form.session.sessionModified();
- form.updateWindowTitle();
- }
- delete this;
- }
- private:
- DebuggerForm& form;
- bool merge;
- };
- class CPURegRequest : public ReadDebugBlockCommand
- {
- public:
- CPURegRequest(DebuggerForm& form_)
- : ReadDebugBlockCommand("{CPU regs}", 0, 28, buf)
- , form(form_)
- {
- }
- virtual void replyOk(const QString& message)
- {
- copyData(message);
- form.regsView->setData(buf);
- delete this;
- }
- private:
- DebuggerForm& form;
- unsigned char buf[28];
- };
- class ListDebuggablesHandler : public SimpleCommand
- {
- public:
- ListDebuggablesHandler(DebuggerForm& form_)
- : SimpleCommand("debug list")
- , form(form_)
- {
- }
- virtual void replyOk(const QString& message)
- {
- form.setDebuggables(message);
- delete this;
- }
- private:
- DebuggerForm& form;
- };
- class DebuggableSizeHandler : public SimpleCommand
- {
- public:
- DebuggableSizeHandler(const QString& debuggable_, DebuggerForm& form_)
- : SimpleCommand(QString("debug size %1").arg(debuggable_))
- , debuggable(debuggable_)
- , form(form_)
- {
- }
- virtual void replyOk(const QString& message)
- {
- form.setDebuggableSize(debuggable, message.toInt());
- delete this;
- }
- private:
- QString debuggable;
- DebuggerForm& form;
- };
- DebuggerForm::DebuggerForm(QWidget* parent)
- : QMainWindow(parent)
- , comm(CommClient::instance())
- {
- VDPRegView = NULL;
- VDPStatusRegView = NULL;
- VDPCommandRegView = NULL;
- createActions();
- createMenus();
- createToolbars();
- createStatusbar();
- createForm();
- recentFiles = Settings::get().value("MainWindow/RecentFiles").toStringList();
- updateRecentFiles();
-
- connect(&session.symbolTable(), SIGNAL(symbolFileChanged()), this, SLOT(symbolFileChanged()));
- }
- void DebuggerForm::createActions()
- {
- fileNewSessionAction = new QAction(tr("&New Session"), this);
- fileNewSessionAction->setStatusTip(tr("Clear the current session."));
- fileOpenSessionAction = new QAction(tr("&Open Session ..."), this);
- fileOpenSessionAction->setShortcut(tr("Ctrl+O"));
- fileOpenSessionAction->setStatusTip(tr("Clear the current session."));
- fileSaveSessionAction = new QAction(tr("&Save Session"), this);
- fileSaveSessionAction->setShortcut(tr("Ctrl+S"));
- fileSaveSessionAction->setStatusTip(tr("Save the the current debug session"));
- fileSaveSessionAsAction = new QAction(tr("Save Session &As"), this);
- fileSaveSessionAsAction->setStatusTip(tr("Save the debug session in a selected file"));
- fileQuitAction = new QAction(tr("&Quit"), this);
- fileQuitAction->setShortcut(tr("Ctrl+Q"));
- fileQuitAction->setStatusTip(tr("Quit the openMSX debugger"));
- for (int i = 0; i < MaxRecentFiles; ++i) {
- recentFileActions[i] = new QAction(this);
- connect(recentFileActions[i], SIGNAL(triggered()), this, SLOT(fileRecentOpen()));
- }
- systemConnectAction = new QAction(tr("&Connect"), this);
- systemConnectAction->setShortcut(tr("Ctrl+C"));
- systemConnectAction->setStatusTip(tr("Connect to openMSX"));
- systemConnectAction->setIcon(QIcon(":/icons/connect.png"));
- systemDisconnectAction = new QAction(tr("&Disconnect"), this);
- systemDisconnectAction->setShortcut(tr(""));
- systemDisconnectAction->setStatusTip(tr("Disconnect from openMSX"));
- systemDisconnectAction->setIcon(QIcon(":/icons/disconnect.png"));
- systemDisconnectAction->setEnabled(false);
- systemPauseAction = new QAction(tr("&Pause emulator"), this);
- systemPauseAction->setShortcut(Qt::Key_Pause);
- systemPauseAction->setStatusTip(tr("Pause the emulation"));
- systemPauseAction->setIcon(QIcon(":/icons/pause.png"));
- systemPauseAction->setCheckable(true);
- systemPauseAction->setEnabled(false);
- systemRebootAction = new QAction(tr("&Reboot emulator"), this);
- systemRebootAction->setStatusTip(tr("Reboot the emulation and start if needed"));
- systemRebootAction->setEnabled(false);
- systemSymbolManagerAction = new QAction(tr("&Symbol manager ..."), this);
- systemSymbolManagerAction->setStatusTip(tr("Start the symbol manager"));
- systemSymbolManagerAction->setIcon(QIcon(":/icons/symmanager.png"));
- systemPreferencesAction = new QAction(tr("Pre&ferences ..."), this);
- systemPreferencesAction->setStatusTip(tr("Set the global debugger preferences"));
- searchGotoAction = new QAction(tr("&Goto ..."), this);
- searchGotoAction->setStatusTip(tr("Jump to a specific address or label in the disassembly view"));
- searchGotoAction->setShortcut(tr("Ctrl+G"));
- viewRegistersAction = new QAction(tr("CPU &Registers"), this);
- viewRegistersAction->setStatusTip(tr("Toggle the cpu registers display"));
- viewRegistersAction->setCheckable(true);
- viewFlagsAction = new QAction(tr("CPU &Flags"), this);
- viewFlagsAction->setStatusTip(tr("Toggle the cpu flags display"));
- viewFlagsAction->setCheckable(true);
- viewStackAction = new QAction(tr("Stack"), this);
- viewStackAction->setStatusTip(tr("Toggle the stack display"));
- viewStackAction->setCheckable(true);
- viewSlotsAction = new QAction(tr("Slots"), this);
- viewSlotsAction->setStatusTip(tr("Toggle the slots display"));
- viewSlotsAction->setCheckable(true);
- viewMemoryAction = new QAction(tr("Memory"), this);
- viewMemoryAction->setStatusTip(tr("Toggle the main memory display"));
- viewMemoryAction->setCheckable(true);
- viewDebuggableViewerAction = new QAction(tr("Add debuggable viewer"), this);
- viewDebuggableViewerAction->setStatusTip(tr("Add a hex viewer for debuggables"));
- viewVDPStatusRegsAction = new QAction(tr("Status Registers"), this);
- viewVDPStatusRegsAction->setStatusTip(tr("The VDP status registers interpreted"));
- viewVDPStatusRegsAction->setCheckable(true);
- viewVDPCommandRegsAction = new QAction(tr("Command Registers"), this);
- viewVDPCommandRegsAction->setStatusTip(tr("Interact with the VDP command registers"));
- viewVDPCommandRegsAction->setCheckable(true);
- viewVDPRegsAction = new QAction(tr("Registers"), this);
- viewVDPRegsAction->setStatusTip(tr("Interact with the VDP registers"));
- viewVDPRegsAction->setCheckable(true);
- viewBitMappedAction = new QAction(tr("Bitmapped VRAM"), this);
- viewBitMappedAction->setStatusTip(tr("Decode VRAM as screen 5/6/7/8 image"));
- //viewBitMappedAction->setCheckable(true);
- executeBreakAction = new QAction(tr("Break"), this);
- executeBreakAction->setShortcut(tr("CRTL+B"));
- executeBreakAction->setStatusTip(tr("Halt the execution and enter debug mode"));
- executeBreakAction->setIcon(QIcon(":/icons/break.png"));
- executeBreakAction->setEnabled(false);
- executeRunAction = new QAction(tr("Run"), this);
- executeRunAction->setShortcut(tr("F9"));
- executeRunAction->setStatusTip(tr("Leave debug mode and resume execution"));
- executeRunAction->setIcon(QIcon(":/icons/run.png"));
- executeRunAction->setEnabled(false);
- executeStepAction = new QAction(tr("Step into"), this);
- executeStepAction->setShortcut(tr("F7"));
- executeStepAction->setStatusTip(tr("Execute a single instruction"));
- executeStepAction->setIcon(QIcon(":/icons/stepinto.png"));
- executeStepAction->setEnabled(false);
- executeStepOverAction = new QAction(tr("Step over"), this);
- executeStepOverAction->setShortcut(tr("F8"));
- executeStepOverAction->setStatusTip(tr("Execute the next instruction including any called subroutines"));
- executeStepOverAction->setIcon(QIcon(":/icons/stepover.png"));
- executeStepOverAction->setEnabled(false);
- executeStepOutAction = new QAction(tr("Step out"), this);
- executeStepOutAction->setShortcut(tr("F11"));
- executeStepOutAction->setStatusTip(tr("Resume execution until the current routine has finished"));
- executeStepOutAction->setIcon(QIcon(":/icons/stepout.png"));
- executeStepOutAction->setEnabled(false);
- executeStepBackAction = new QAction(tr("Step back"), this);
- executeStepBackAction->setShortcut(tr("F12"));
- executeStepBackAction->setStatusTip(tr("Reverse the last instruction"));
- executeStepBackAction->setIcon(QIcon(":/icons/stepback.png"));
- executeStepBackAction->setEnabled(false);
- executeRunToAction = new QAction(tr("Run to"), this);
- executeRunToAction->setShortcut(tr("F4"));
- executeRunToAction->setStatusTip(tr("Resume execution until the selected line is reached"));
- executeRunToAction->setIcon(QIcon(":/icons/runto.png"));
- executeRunToAction->setEnabled(false);
- breakpointToggleAction = new QAction(tr("Toggle"), this);
- breakpointToggleAction->setShortcut(tr("F5"));
- breakpointToggleAction->setStatusTip(tr("Toggle breakpoint on/off at cursor"));
- breakpointToggleAction->setIcon(QIcon(":/icons/break.png"));
- breakpointToggleAction->setEnabled(false);
- breakpointAddAction = new QAction(tr("Add ..."), this);
- breakpointAddAction->setShortcut(tr("CTRL+B"));
- breakpointAddAction->setStatusTip(tr("Add a breakpoint at a location"));
- breakpointAddAction->setEnabled(false);
- helpAboutAction = new QAction(tr("&About"), this);
- executeRunToAction->setStatusTip(tr("Show the appliction information"));
- connect(fileNewSessionAction, SIGNAL(triggered()), this, SLOT(fileNewSession()));
- connect(fileOpenSessionAction, SIGNAL(triggered()), this, SLOT(fileOpenSession()));
- connect(fileSaveSessionAction, SIGNAL(triggered()), this, SLOT(fileSaveSession()));
- connect(fileSaveSessionAsAction, SIGNAL(triggered()), this, SLOT(fileSaveSessionAs()));
- connect(fileQuitAction, SIGNAL(triggered()), this, SLOT(close()));
- connect(systemConnectAction, SIGNAL(triggered()), this, SLOT(systemConnect()));
- connect(systemDisconnectAction, SIGNAL(triggered()), this, SLOT(systemDisconnect()));
- connect(systemPauseAction, SIGNAL(triggered()), this, SLOT(systemPause()));
- connect(systemRebootAction, SIGNAL(triggered()), this, SLOT(systemReboot()));
- connect(systemSymbolManagerAction, SIGNAL(triggered()), this, SLOT(systemSymbolManager()));
- connect(systemPreferencesAction, SIGNAL(triggered()), this, SLOT(systemPreferences()));
- connect(searchGotoAction, SIGNAL(triggered()), this, SLOT(searchGoto()));
- connect(viewRegistersAction, SIGNAL(triggered()), this, SLOT(toggleRegisterDisplay()));
- connect(viewFlagsAction, SIGNAL(triggered()), this, SLOT(toggleFlagsDisplay()));
- connect(viewStackAction, SIGNAL(triggered()), this, SLOT(toggleStackDisplay()));
- connect(viewSlotsAction, SIGNAL(triggered()), this, SLOT(toggleSlotsDisplay()));
- connect(viewMemoryAction, SIGNAL(triggered()), this, SLOT(toggleMemoryDisplay()));
- connect(viewDebuggableViewerAction, SIGNAL(triggered()), this, SLOT(addDebuggableViewer()));
- connect(viewBitMappedAction, SIGNAL(triggered()), this, SLOT(toggleBitMappedDisplay()));
- connect(viewVDPRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPRegsDisplay()));
- connect(viewVDPCommandRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPCommandRegsDisplay()));
- connect(viewVDPStatusRegsAction, SIGNAL(triggered()), this, SLOT(toggleVDPStatusRegsDisplay()));
- connect(executeBreakAction, SIGNAL(triggered()), this, SLOT(executeBreak()));
- connect(executeRunAction, SIGNAL(triggered()), this, SLOT(executeRun()));
- connect(executeStepAction, SIGNAL(triggered()), this, SLOT(executeStep()));
- connect(executeStepOverAction, SIGNAL(triggered()), this, SLOT(executeStepOver()));
- connect(executeRunToAction, SIGNAL(triggered()), this, SLOT(executeRunTo()));
- connect(executeStepOutAction, SIGNAL(triggered()), this, SLOT(executeStepOut()));
- connect(executeStepBackAction, SIGNAL(triggered()), this, SLOT(executeStepBack()));
- connect(breakpointToggleAction, SIGNAL(triggered()), this, SLOT(breakpointToggle()));
- connect(breakpointAddAction, SIGNAL(triggered()), this, SLOT(breakpointAdd()));
- connect(helpAboutAction, SIGNAL(triggered()), this, SLOT(showAbout()));
- }
- void DebuggerForm::createMenus()
- {
- // create file menu
- fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(fileNewSessionAction);
- fileMenu->addAction(fileOpenSessionAction);
- fileMenu->addAction(fileSaveSessionAction);
- fileMenu->addAction(fileSaveSessionAsAction);
- recentFileSeparator = fileMenu->addSeparator();
- for (int i = 0; i < MaxRecentFiles; ++i)
- fileMenu->addAction(recentFileActions[i]);
- fileMenu->addSeparator();
- fileMenu->addAction(fileQuitAction);
- // create system menu
- systemMenu = menuBar()->addMenu(tr("&System"));
- systemMenu->addAction(systemConnectAction);
- systemMenu->addAction(systemDisconnectAction);
- systemMenu->addSeparator();
- systemMenu->addAction(systemPauseAction);
- systemMenu->addSeparator();
- systemMenu->addAction(systemRebootAction);
- systemMenu->addSeparator();
- systemMenu->addAction(systemSymbolManagerAction);
- systemMenu->addSeparator();
- systemMenu->addAction(systemPreferencesAction);
- // create system menu
- searchMenu = menuBar()->addMenu(tr("Se&arch"));
- searchMenu->addAction(searchGotoAction);
- // create view menu
- viewMenu = menuBar()->addMenu(tr("&View"));
- viewMenu->addAction(viewRegistersAction);
- viewMenu->addAction(viewFlagsAction);
- viewMenu->addAction(viewStackAction);
- viewMenu->addAction(viewSlotsAction);
- viewMenu->addAction(viewMemoryAction);
- viewVDPDialogsMenu = viewMenu->addMenu("VDP");
- viewMenu->addSeparator();
- viewMenu->addAction(viewDebuggableViewerAction);
- connect(viewMenu, SIGNAL(aboutToShow()), this, SLOT(updateViewMenu()));
- // create VDP dialogs menu
- viewVDPDialogsMenu->addAction(viewVDPRegsAction);
- viewVDPDialogsMenu->addAction(viewVDPCommandRegsAction);
- viewVDPDialogsMenu->addAction(viewVDPStatusRegsAction);
- viewVDPDialogsMenu->addAction(viewBitMappedAction);
- connect(viewVDPDialogsMenu, SIGNAL(aboutToShow()), this, SLOT(updateVDPViewMenu()));
- // create execute menu
- executeMenu = menuBar()->addMenu(tr("&Execute"));
- executeMenu->addAction(executeBreakAction);
- executeMenu->addAction(executeRunAction);
- executeMenu->addSeparator();
- executeMenu->addAction(executeStepAction);
- executeMenu->addAction(executeStepOverAction);
- executeMenu->addAction(executeStepOutAction);
- executeMenu->addAction(executeStepBackAction);
- executeMenu->addAction(executeRunToAction);
- // create breakpoint menu
- breakpointMenu = menuBar()->addMenu(tr("&Breakpoint"));
- breakpointMenu->addAction(breakpointToggleAction);
- breakpointMenu->addAction(breakpointAddAction);
- // create help menu
- helpMenu = menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(helpAboutAction);
- }
- void DebuggerForm::createToolbars()
- {
- // create debug toolbar
- systemToolbar = addToolBar(tr("System"));
- systemToolbar->addAction(systemConnectAction);
- systemToolbar->addAction(systemDisconnectAction);
- systemToolbar->addSeparator();
- systemToolbar->addAction(systemPauseAction);
- systemToolbar->addSeparator();
- systemToolbar->addAction(systemSymbolManagerAction);
- // create debug toolbar
- executeToolbar = addToolBar(tr("Execution"));
- executeToolbar->addAction(executeBreakAction);
- executeToolbar->addAction(executeRunAction);
- executeToolbar->addSeparator();
- executeToolbar->addAction(executeStepAction);
- executeToolbar->addAction(executeStepOverAction);
- executeToolbar->addAction(executeStepOutAction);
- executeToolbar->addAction(executeStepBackAction);
- executeToolbar->addAction(executeRunToAction);
- }
- void DebuggerForm::createStatusbar()
- {
- // create the statusbar
- statusBar()->showMessage("No emulation running.");
- }
- void DebuggerForm::createForm()
- {
- updateWindowTitle();
- mainArea = new DockableWidgetArea();
- dockMan.addDockArea(mainArea);
- setCentralWidget(mainArea);
- // Create main widgets and append them to the list first
- DockableWidget* dw = new DockableWidget(dockMan);
- // create the disasm viewer widget
- disasmView = new DisasmViewer();
- dw->setWidget(disasmView);
- dw->setTitle(tr("Code view"));
- dw->setId("CODEVIEW");
- dw->setFloating(false);
- dw->setDestroyable(false);
- dw->setMovable(false);
- dw->setClosable(false);
- connect(this, SIGNAL(settingsChanged()),
- disasmView, SLOT(settingsChanged()));
- connect(this, SIGNAL(symbolsChanged()),
- disasmView, SLOT(symbolsChanged()));
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- // create the memory view widget
- mainMemoryView = new MainMemoryViewer();
- dw = new DockableWidget(dockMan);
- dw->setWidget(mainMemoryView);
- dw->setTitle(tr("Main memory"));
- dw->setId("MEMORY");
- dw->setFloating(false);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- mainMemoryView->setSymbolTable(&session.symbolTable());
- // create register viewer
- regsView = new CPURegsViewer();
- dw = new DockableWidget(dockMan);
- dw->setWidget(regsView);
- dw->setTitle(tr("CPU registers"));
- dw->setId("REGISTERS");
- dw->setFloating(false);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- // Hook up the register viewer with the MainMemory viewer
- connect(regsView, SIGNAL(registerChanged(int,int)),
- mainMemoryView, SLOT(registerChanged(int,int)));
- mainMemoryView->setRegsView(regsView);
- // create flags viewer
- flagsView = new FlagsViewer();
- dw = new DockableWidget(dockMan);
- dw->setWidget(flagsView);
- dw->setTitle(tr("Flags"));
- dw->setId("FLAGS");
- dw->setFloating(false);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- // create stack viewer
- stackView = new StackViewer();
- dw = new DockableWidget(dockMan);
- dw->setWidget(stackView);
- dw->setTitle(tr("Stack"));
- dw->setId("STACK");
- dw->setFloating(false);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- // create slot viewer
- slotView = new SlotViewer();
- dw = new DockableWidget(dockMan);
- dw->setWidget(slotView);
- dw->setTitle(tr("Memory layout"));
- dw->setId("SLOTS");
- dw->setFloating(false);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- // restore layout
- restoreGeometry(Settings::get().value("Layout/WindowGeometry", saveGeometry()).toByteArray());
- QStringList list = Settings::get().value("Layout/WidgetLayout").toStringList();
- // defaults needed?
- if (list.empty() || !list.at(0).startsWith("CODEVIEW ")) {
- list.clear();
- list.append("CODEVIEW D V R 0 -1 -1");
- list.append("REGISTERS D V R 0 -1 -1");
- list.append("FLAGS D V R 0 -1 -1");
- int regW = dockMan.findDockableWidget("REGISTERS")->sizeHint().width();
- int regH = dockMan.findDockableWidget("REGISTERS")->sizeHint().height();
- int codeW = dockMan.findDockableWidget("CODEVIEW")->sizeHint().width();
- int codeH = dockMan.findDockableWidget("CODEVIEW")->sizeHint().height();
- int flagW = dockMan.findDockableWidget("FLAGS")->sizeHint().width();
- int slotW = dockMan.findDockableWidget("SLOTS")->sizeHint().width();
- list.append(QString("SLOTS D V R 0 -1 %1").arg(regH));
- list.append(QString("STACK D V R 0 -1 %1").arg(codeH));
- list.append(QString("MEMORY D V B %1 %2 %3").arg(codeW)
- .arg(regW + flagW + slotW)
- .arg(codeH - regH));
- }
- // add widgets
- for (int i = 0; i < list.size(); ++i) {
- QStringList s = list.at(i).split(" ", QString::SkipEmptyParts);
- // get widget
- if ((dw = dockMan.findDockableWidget(s.at(0)))) {
- if (s.at(1) == "D") {
- // dock widget
- DockableWidgetLayout::DockSide side;
- if (s.at(3) == "T") {
- side = DockableWidgetLayout::TOP;
- } else if (s.at(3) == "L") {
- side = DockableWidgetLayout::LEFT;
- } else if (s.at(3) == "R") {
- side = DockableWidgetLayout::RIGHT;
- } else {
- side = DockableWidgetLayout::BOTTOM;
- }
- dockMan.insertWidget(dw, 0, side, s.at(4).toInt(),
- s.at(5).toInt(), s.at(6).toInt());
- if (s.at(2) == "H") dw->hide();
- } else if (s.at(1) == "F") {
- // float widget
- dw->setFloating(true, s.at(2) == "V");
- dw->resize(s.at(5).toInt(), s.at(6).toInt());
- dw->move (s.at(3).toInt(), s.at(4).toInt());
- }
- }
- }
- // disable all widgets
- connectionClosed();
- connect(regsView, SIGNAL(pcChanged(quint16)),
- disasmView, SLOT(setProgramCounter(quint16)));
- connect(regsView, SIGNAL(flagsChanged(quint8)),
- flagsView, SLOT(setFlags(quint8)));
- connect(regsView, SIGNAL(spChanged(quint16)),
- stackView, SLOT(setStackPointer(quint16)));
- connect(disasmView, SIGNAL(toggleBreakpoint(int)),
- SLOT(breakpointToggle(int)));
- connect(&comm, SIGNAL(connectionReady()),
- SLOT(initConnection()));
- connect(&comm, SIGNAL(updateParsed(const QString&, const QString&, const QString&)),
- SLOT(handleUpdate(const QString&, const QString&, const QString&)));
- connect(&comm, SIGNAL(connectionTerminated()),
- SLOT(connectionClosed()));
- // init main memory
- // added four bytes as runover buffer for dasm
- // otherwise dasm would need to check the buffer end continously.
- session.breakpoints().setMemoryLayout(&memLayout);
- mainMemory = new unsigned char[65536 + 4];
- memset(mainMemory, 0, 65536 + 4);
- disasmView->setMemory(mainMemory);
- disasmView->setBreakpoints(&session.breakpoints());
- disasmView->setMemoryLayout(&memLayout);
- disasmView->setSymbolTable(&session.symbolTable());
- mainMemoryView->setDebuggable("memory", 65536);
- stackView->setData(mainMemory, 65536);
- slotView->setMemoryLayout(&memLayout);
- }
- DebuggerForm::~DebuggerForm()
- {
- delete[] mainMemory;
- delete mainArea;
- }
- void DebuggerForm::closeEvent(QCloseEvent* e)
- {
- // handle unsaved session
- fileNewSession();
- // cancel if session is still modified
- if (session.isModified()) {
- e->ignore();
- return;
- }
- // store layout
- Settings::get().setValue("Layout/WindowGeometry", saveGeometry());
- QStringList layoutList;
- // fill layout list with docked widgets
- dockMan.getConfig(0, layoutList);
- // append floating widgets
- for (QList<DockableWidget*>::const_iterator it = dockMan.managedWidgets().begin();
- it != dockMan.managedWidgets().end(); ++it) {
- if ((*it)->isFloating()) {
- QString s("%1 F %2 %3 %4 %5 %6");
- s = s.arg((*it)->id());
- if ((*it)->isHidden()) {
- s = s.arg("H");
- } else {
- s = s.arg("V");
- }
- s = s.arg((*it)->x()).arg((*it)->y())
- .arg((*it)->width()).arg((*it)->height());
- layoutList.append(s);
- }
- }
- Settings::get().setValue("Layout/WidgetLayout", layoutList);
- QMainWindow::closeEvent(e);
- }
- void DebuggerForm::updateRecentFiles()
- {
- // store settings
- Settings::get().setValue("MainWindow/RecentFiles", recentFiles);
- // update actions
- for(int i = 0; i < MaxRecentFiles; i++)
- if(i < recentFiles.size()) {
- recentFileActions[i]->setVisible(true);
- QString text = QString("&%1 %2").arg(i + 1).arg(QFileInfo(recentFiles[i]).fileName());
- recentFileActions[i]->setText(text);
- recentFileActions[i]->setData(recentFiles[i]);
- } else
- recentFileActions[i]->setVisible(false);
- // show separator only when recent files exist
- recentFileSeparator->setVisible(recentFiles.size());
- }
- void DebuggerForm::addRecentFile(const QString& file)
- {
- recentFiles.removeAll(file);
- recentFiles.prepend(file);
- while (recentFiles.size() > MaxRecentFiles)
- recentFiles.removeLast();
- updateRecentFiles();
- }
- void DebuggerForm::removeRecentFile(const QString& file)
- {
- recentFiles.removeAll(file);
- updateRecentFiles();
- }
- void DebuggerForm::updateWindowTitle()
- {
- QString title = "openMSX debugger [%1%2]";
- if (session.existsAsFile()) {
- title = title.arg(session.filename());
- } else {
- title = title.arg("unnamed session");
- }
- if (session.isModified()) {
- title = title.arg('*');
- } else {
- title = title.arg("");
- }
- setWindowTitle(title);
- }
- void DebuggerForm::initConnection()
- {
- systemConnectAction->setEnabled(false);
- systemDisconnectAction->setEnabled(true);
- comm.sendCommand(new QueryPauseHandler(*this));
- comm.sendCommand(new QueryBreakedHandler(*this));
- comm.sendCommand(new SimpleCommand("openmsx_update enable status"));
- comm.sendCommand(new ListDebuggablesHandler(*this));
- // define 'debug_bin2hex' proc for internal use
- comm.sendCommand(new SimpleCommand(
- "proc debug_bin2hex { input } {\n"
- " set result \"\"\n"
- " foreach i [split $input {}] {\n"
- " append result [format %02X [scan $i %c]] \"\"\n"
- " }\n"
- " return $result\n"
- "}\n"));
- // define 'debug_hex2bin' proc for internal use
- comm.sendCommand(new SimpleCommand(
- "proc debug_hex2bin { input } {\n"
- " set result \"\"\n"
- " foreach {h l} [split $input {}] {\n"
- " append result [binary format H2 $h$l] \"\"\n"
- " }\n"
- " return $result\n"
- "}\n"));
- // define 'debug_memmapper' proc for internal use
- comm.sendCommand(new SimpleCommand(
- "proc debug_memmapper { } {\n"
- " set result \"\"\n"
- " for { set page 0 } { $page < 4 } { incr page } {\n"
- " set tmp [get_selected_slot $page]\n"
- " append result [lindex $tmp 0] [lindex $tmp 1] \"\\n\"\n"
- " if { [lsearch [debug list] \"MapperIO\"] != -1} {\n"
- " append result [debug read \"MapperIO\" $page] \"\\n\"\n"
- " } else {\n"
- " append result \"0\\n\"\n"
- " }\n"
- " }\n"
- " for { set ps 0 } { $ps < 4 } { incr ps } {\n"
- " if [machine_info issubslotted $ps] {\n"
- " append result \"1\\n\"\n"
- " for { set ss 0 } { $ss < 4 } { incr ss } {\n"
- " append result [get_mapper_size $ps $ss] \"\\n\"\n"
- " }\n"
- " } else {\n"
- " append result \"0\\n\"\n"
- " append result [get_mapper_size $ps 0] \"\\n\"\n"
- " }\n"
- " }\n"
- " for { set page 0 } { $page < 4 } { incr page } {\n"
- " set tmp [get_selected_slot $page]\n"
- " set ss [lindex $tmp 1]\n"
- " if { $ss == \"X\" } { set ss 0 }\n"
- " set device_list [machine_info slot [lindex $tmp 0] $ss $page]\n"
- " set name \"[lindex $device_list 0] romblocks\"\n"
- " if { [lsearch [debug list] $name] != -1} {\n"
- " append result \"[debug read $name [expr {$page * 0x4000}] ]\\n\"\n"
- " append result \"[debug read $name [expr {$page * 0x4000 + 0x2000}] ]\\n\"\n"
- " } else {\n"
- " append result \"X\\nX\\n\"\n"
- " }\n"
- " }\n"
- " return $result\n"
- "}\n"));
- // define 'debug_list_all_breaks' proc for internal use
- comm.sendCommand(new SimpleCommand(
- "proc debug_list_all_breaks { } {\n"
- " set result [debug list_bp]\n"
- " append result [debug list_watchpoints]\n"
- " append result [debug list_conditions]\n"
- " return $result\n"
- "}\n"));
-
- }
- void DebuggerForm::connectionClosed()
- {
- systemPauseAction->setEnabled(false);
- systemRebootAction->setEnabled(false);
- executeBreakAction->setEnabled(false);
- executeRunAction->setEnabled(false);
- executeStepAction->setEnabled(false);
- executeStepOverAction->setEnabled(false);
- executeStepOutAction->setEnabled(false);
- executeStepBackAction->setEnabled(false);
- executeRunToAction->setEnabled(false);
- systemDisconnectAction->setEnabled(false);
- systemConnectAction->setEnabled(true);
- breakpointToggleAction->setEnabled(false);
- breakpointAddAction->setEnabled(false);
- for (QList<DockableWidget*>::const_iterator it = dockMan.managedWidgets().begin();
- it != dockMan.managedWidgets().end(); ++it) {
- (*it)->widget()->setEnabled(false);
- }
- }
- void DebuggerForm::finalizeConnection(bool halted)
- {
- systemPauseAction->setEnabled(true);
- systemRebootAction->setEnabled(true);
- breakpointToggleAction->setEnabled(true);
- breakpointAddAction->setEnabled(true);
- // merge breakpoints on connect
- mergeBreakpoints = true;
- if (halted) {
- setBreakMode();
- breakOccured();
- } else {
- setRunMode();
- updateData();
- }
- for (QList<DockableWidget*>::const_iterator it = dockMan.managedWidgets().begin();
- it != dockMan.managedWidgets().end(); ++it) {
- (*it)->widget()->setEnabled(true);
- }
- }
- void DebuggerForm::handleUpdate(const QString& type, const QString& name,
- const QString& message)
- {
- if (type == "status") {
- if (name == "cpu") {
- if (message == "suspended") {
- breakOccured();
- } else {
- setRunMode();
- }
- } else if (name == "paused") {
- pauseStatusChanged(message == "true");
- }
- }
- }
- void DebuggerForm::pauseStatusChanged(bool isPaused)
- {
- systemPauseAction->setChecked(isPaused);
- }
- void DebuggerForm::breakOccured()
- {
- setBreakMode();
- updateData();
- }
- void DebuggerForm::updateData()
- {
- comm.sendCommand(new ListBreakPointsHandler(*this, mergeBreakpoints));
- // only merge the first time after connect
- mergeBreakpoints = false;
- // refresh memory viewer
- mainMemoryView->refresh();
- // update registers
- // note that a register update is processed, a signal is sent to other
- // widgets as well. Any dependent updates shoud be called before this one.
- CPURegRequest* regs = new CPURegRequest(*this);
- comm.sendCommand(regs);
- // refresh slot viewer
- slotView->refresh();
- emit emulationChanged();
- }
- void DebuggerForm::setBreakMode()
- {
- executeBreakAction->setEnabled(false);
- executeRunAction->setEnabled(true);
- executeStepAction->setEnabled(true);
- executeStepOverAction->setEnabled(true);
- executeStepOutAction->setEnabled(true);
- executeStepBackAction->setEnabled(true);
- executeRunToAction->setEnabled(true);
- }
- void DebuggerForm::setRunMode()
- {
- executeBreakAction->setEnabled(true);
- executeRunAction->setEnabled(false);
- executeStepAction->setEnabled(false);
- executeStepOverAction->setEnabled(false);
- executeStepOutAction->setEnabled(false);
- executeStepBackAction->setEnabled(false);
- executeRunToAction->setEnabled(false);
- }
- void DebuggerForm::fileNewSession()
- {
- if (session.isModified()) {
- // save current session?
- int choice = QMessageBox::warning(this, tr("Unsaved session"),
- tr("The current session has unsaved data.\n"
- "Do you want to save your changes?"),
- QMessageBox::Save | QMessageBox::Discard |
- QMessageBox::Cancel, QMessageBox::Save);
- if (choice == QMessageBox::Cancel) {
- return;
- } else if (choice == QMessageBox::Save) {
- fileSaveSession();
- // skip new if session is still modified (save was cancelled)
- if (session.isModified()) return;
- }
- }
- session.clear();
- updateWindowTitle();
- }
- void DebuggerForm::fileOpenSession()
- {
- QString fileName = QFileDialog::getOpenFileName(
- this, tr("Open debug session"),
- QDir::currentPath(), tr("Debug Session Files (*.omds)"));
- if (!fileName.isEmpty())
- openSession(fileName);
- }
- void DebuggerForm::openSession(const QString& file)
- {
- fileNewSession();
- session.open(file);
- if (systemDisconnectAction->isEnabled()) {
- // active connection, merge loaded breakpoints
- comm.sendCommand(new ListBreakPointsHandler(*this, true));
- }
- // update recent
- if(session.existsAsFile())
- addRecentFile(file);
- else
- removeRecentFile(file);
- updateWindowTitle();
- }
- void DebuggerForm::fileSaveSession()
- {
- if (session.existsAsFile()) {
- session.save();
- } else {
- fileSaveSessionAs();
- }
- updateWindowTitle();
- }
- void DebuggerForm::fileSaveSessionAs()
- {
- QFileDialog d(this, tr("Save debug session"));
- d.setNameFilter(tr("Debug Session Files (*.omds)"));
- d.setDefaultSuffix("omds");
- d.setDirectory(QDir::currentPath());
- d.setAcceptMode(QFileDialog::AcceptSave);
- d.setFileMode(QFileDialog::AnyFile);
- if (d.exec()) {
- session.saveAs(d.selectedFiles().at(0));
- // update recent
- if(session.existsAsFile())
- addRecentFile(session.filename());
- }
- updateWindowTitle();
- }
- void DebuggerForm::fileRecentOpen()
- {
- QAction *action = qobject_cast<QAction *>(sender());
- if (action)
- openSession(action->data().toString());
- }
- void DebuggerForm::systemConnect()
- {
- if (OpenMSXConnection* connection = ConnectDialog::getConnection(this)) {
- comm.connectToOpenMSX(connection);
- }
- }
- void DebuggerForm::systemDisconnect()
- {
- comm.closeConnection();
- }
- void DebuggerForm::systemPause()
- {
- comm.sendCommand(new SimpleCommand(QString("set pause ") +
- (systemPauseAction->isChecked() ? "true" : "false")));
- }
- void DebuggerForm::systemReboot()
- {
- if (systemPauseAction->isChecked()) {
- systemPauseAction->trigger();
- }
- if (executeRunAction->isEnabled()) {
- executeRun();
- }
- comm.sendCommand(new SimpleCommand("reset"));
- }
- void DebuggerForm::systemSymbolManager()
- {
- SymbolManager symManager(session.symbolTable(), this);
- connect(&symManager, SIGNAL(symbolTableChanged()),
- &session, SLOT(sessionModified()));
- symManager.exec();
- emit symbolsChanged();
- updateWindowTitle();
- }
- void DebuggerForm::systemPreferences()
- {
- PreferencesDialog prefs(this);
- prefs.exec();
- emit settingsChanged();
- }
- void DebuggerForm::searchGoto()
- {
- GotoDialog gtd(memLayout, &session, this);
- if (gtd.exec()) {
- int addr = gtd.address();
- if ( addr >= 0) {
- disasmView->setCursorAddress(addr, 0, DisasmViewer::MiddleAlways);
- }
- }
- }
- void DebuggerForm::executeBreak()
- {
- comm.sendCommand(new SimpleCommand("debug break"));
- }
- void DebuggerForm::executeRun()
- {
- comm.sendCommand(new SimpleCommand("debug cont"));
- setRunMode();
- }
- void DebuggerForm::executeStep()
- {
- comm.sendCommand(new SimpleCommand("debug step"));
- setRunMode();
- }
- void DebuggerForm::executeStepOver()
- {
- SimpleCommand *sc = new SimpleCommand("step_over");
- connect(sc, SIGNAL(replyStatusOk(bool)), this, SLOT(handleCommandReplyStatus(bool)));
- comm.sendCommand(sc);
- setRunMode();
- }
- void DebuggerForm::executeRunTo()
- {
- comm.sendCommand(new SimpleCommand(
- "run_to " + QString::number(disasmView->cursorAddress())));
- setRunMode();
- }
- void DebuggerForm::executeStepOut()
- {
- comm.sendCommand(new SimpleCommand("step_out"));
- setRunMode();
- }
- void DebuggerForm::executeStepBack()
- {
- SimpleCommand *sc = new SimpleCommand("step_back");
- connect(sc, SIGNAL(replyStatusOk(bool)), this, SLOT(handleCommandReplyStatus(bool)));
- comm.sendCommand(sc);
- setRunMode();
- }
- void DebuggerForm::handleCommandReplyStatus(bool status)
- {
- if(status) {
- finalizeConnection(true);
- }
- }
- void DebuggerForm::breakpointToggle(int addr)
- {
- // toggle address unspecified, use cursor address
- if (addr < 0) addr = disasmView->cursorAddress();
- QString cmd, id;
- if (session.breakpoints().isBreakpoint(addr, &id)) {
- cmd = Breakpoints::createRemoveCommand(id);
- } else {
- // get slot
- int ps, ss, seg;
- addressSlot(addr, ps, ss, seg);
- // create command
- cmd = Breakpoints::createSetCommand(Breakpoints::BREAKPOINT, addr, ps, ss, seg);
- }
- comm.sendCommand(new SimpleCommand(cmd));
- comm.sendCommand(new ListBreakPointsHandler(*this));
- }
- void DebuggerForm::breakpointAdd()
- {
- BreakpointDialog bpd(memLayout, &session, this);
- int addr = disasmView->cursorAddress();
- int ps, ss, seg;
- addressSlot(addr, ps, ss, seg);
- bpd.setData(Breakpoints::BREAKPOINT, addr, ps, ss, seg);
- if (bpd.exec()) {
- if (bpd.address() >= 0) {
- QString cmd = Breakpoints::createSetCommand(
- bpd.type(), bpd.address(), bpd.slot(), bpd.subslot(), bpd.segment(),
- bpd.addressEndRange(), bpd.condition() );
- comm.sendCommand(new SimpleCommand(cmd));
- comm.sendCommand(new ListBreakPointsHandler(*this));
- }
- }
- }
- void DebuggerForm::showAbout()
- {
- QMessageBox::about(
- this, "openMSX Debugger", QString(Version::full().c_str()));
- }
- void DebuggerForm::toggleRegisterDisplay()
- {
- toggleView(qobject_cast<DockableWidget*>(regsView->parentWidget()));
- }
- void DebuggerForm::toggleFlagsDisplay()
- {
- toggleView(qobject_cast<DockableWidget*>(flagsView->parentWidget()));
- }
- void DebuggerForm::toggleStackDisplay()
- {
- toggleView(qobject_cast<DockableWidget*>(stackView->parentWidget()));
- }
- void DebuggerForm::toggleSlotsDisplay()
- {
- toggleView(qobject_cast<DockableWidget*>(slotView->parentWidget()));
- }
- void DebuggerForm::toggleBitMappedDisplay()
- {
- //toggleView( qobject_cast<DockableWidget*>(slotView->parentWidget()));
- // not sure if this a good idea for a docable widget
- // create new debuggable viewer window
- BitMapViewer* viewer = new BitMapViewer();
- DockableWidget* dw = new DockableWidget(dockMan);
- dw->setWidget(viewer);
- dw->setTitle(tr("Bitmapped VRAM View"));
- dw->setId("BITMAPVRAMVIEW");
- dw->setFloating(true);
- dw->setDestroyable(true);
- dw->setMovable(true);
- dw->setClosable(true);
- /*
- connect( dw, SIGNAL( visibilityChanged(DockableWidget*) ),
- this, SLOT( dockWidgetVisibilityChanged(DockableWidget*) ) );
- connect( this, SIGNAL( debuggablesChanged(const QMap<QString,int>&) ),
- viewer, SLOT( setDebuggables(const QMap<QString,int>&) ) );
- */
- // TODO: refresh should be being hanled by VDPDataStore...
- connect(this, SIGNAL(emulationChanged()), viewer, SLOT(refresh()));
- /*
- viewer->setDebuggables( debuggables );
- viewer->setEnabled( disasmView->isEnabled() );
- */
- }
- void DebuggerForm::toggleVDPCommandRegsDisplay()
- {
- if (VDPCommandRegView == NULL) {
- VDPCommandRegView = new VDPCommandRegViewer();
- DockableWidget* dw = new DockableWidget(dockMan);
- dw->setWidget(VDPCommandRegView);
- dw->setTitle(tr("VDP registers view"));
- dw->setId("VDPCommandRegView");
- dw->setFloating(true);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(this, SIGNAL(emulationChanged()),
- VDPCommandRegView, SLOT(refresh()));
- } else {
- toggleView(qobject_cast<DockableWidget*>(VDPCommandRegView->parentWidget()));
- }
- }
- void DebuggerForm::toggleVDPRegsDisplay()
- {
- if (VDPRegView == NULL) {
- VDPRegView = new VDPRegViewer();
- DockableWidget *dw = new DockableWidget(dockMan);
- dw->setWidget(VDPRegView);
- dw->setTitle(tr("VDP registers view"));
- dw->setId("VDPREGVIEW");
- dw->setFloating(true);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(this, SIGNAL(emulationChanged()),
- VDPRegView, SLOT(refresh()));
- } else {
- toggleView(qobject_cast<DockableWidget*>(VDPRegView->parentWidget()));
- }
- }
- void DebuggerForm::toggleVDPStatusRegsDisplay()
- {
- if (VDPStatusRegView == NULL) {
- VDPStatusRegView = new VDPStatusRegViewer();
- DockableWidget* dw = new DockableWidget(dockMan);
- dw->setWidget(VDPStatusRegView);
- dw->setTitle(tr("VDP status registers view"));
- dw->setId("VDPSTATUSREGVIEW");
- dw->setFloating(true);
- dw->setDestroyable(false);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(this, SIGNAL(emulationChanged()),
- VDPStatusRegView, SLOT(refresh()));
- } else {
- toggleView(qobject_cast<DockableWidget*>(VDPStatusRegView->parentWidget()));
- }
- }
- void DebuggerForm::toggleMemoryDisplay()
- {
- toggleView(qobject_cast<DockableWidget*>(mainMemoryView->parentWidget()));
- }
- void DebuggerForm::toggleView(DockableWidget* widget)
- {
- if (widget->isHidden()) {
- widget->show();
- } else {
- widget->hide();
- }
- dockMan.visibilityChanged(widget);
- }
- void DebuggerForm::addDebuggableViewer()
- {
- // create new debuggable viewer window
- DebuggableViewer* viewer = new DebuggableViewer();
- DockableWidget* dw = new DockableWidget(dockMan);
- dw->setWidget(viewer);
- dw->setTitle(tr("Debuggable hex view"));
- dw->setId("DEBUGVIEW");
- dw->setFloating(true);
- dw->setDestroyable(true);
- dw->setMovable(true);
- dw->setClosable(true);
- connect(dw, SIGNAL(visibilityChanged(DockableWidget*)),
- this, SLOT(dockWidgetVisibilityChanged(DockableWidget*)));
- connect(this, SIGNAL(debuggablesChanged(const QMap<QString,int>&)),
- viewer, SLOT(setDebuggables(const QMap<QString,int>&)));
- connect(this, SIGNAL(emulationChanged()),
- viewer, SLOT(refresh()));
- viewer->setDebuggables(debuggables);
- viewer->setEnabled(disasmView->isEnabled());
- }
- void DebuggerForm::dockWidgetVisibilityChanged(DockableWidget* w)
- {
- dockMan.visibilityChanged(w);
- updateViewMenu();
- }
- void DebuggerForm::updateViewMenu()
- {
- viewRegistersAction->setChecked(regsView->parentWidget()->isVisible());
- viewFlagsAction->setChecked(flagsView->isVisible());
- viewStackAction->setChecked(stackView->isVisible());
- viewSlotsAction->setChecked(slotView->isVisible());
- viewMemoryAction->setChecked(mainMemoryView->isVisible());
- }
- void DebuggerForm::updateVDPViewMenu()
- {
- if (VDPCommandRegView) {
- viewVDPCommandRegsAction->setChecked(VDPCommandRegView->isVisible());
- }
- if (VDPRegView) {
- viewVDPRegsAction->setChecked(VDPRegView->isVisible());
- }
- if (VDPStatusRegView) {
- viewVDPStatusRegsAction->setChecked(VDPStatusRegView->isVisible());
- }
- }
- void DebuggerForm::setDebuggables(const QString& list)
- {
- debuggables.clear();
- // process result string
- QStringList l = list.split(" ", QString::SkipEmptyParts);
- for (int i = 0; i < l.size(); ++i) {
- QString d = l[i];
- // combine multiple words
- if (d[0] == '{') {
- while (!d.endsWith("}")) {
- d.push_back(' ');
- d.append(l[++i]);
- }
- }
- // set initial size to zero
- debuggables[d] = 0;
- }
- // find the size for all debuggables
- for (QMap<QString, int>::iterator it = debuggables.begin();
- it != debuggables.end(); ++it) {
- comm.sendCommand(new DebuggableSizeHandler(it.key(), *this));
- }
- }
- void DebuggerForm::setDebuggableSize(const QString& debuggable, int size)
- {
- debuggables[debuggable] = size;
- // emit update if size of last debuggable was set
- if (debuggable == debuggables.keys().last()) {
- emit debuggablesChanged(debuggables);
- }
- }
- void DebuggerForm::symbolFileChanged()
- {
- static bool shown(false);
- if(shown) return;
- shown = true;
- int choice = QMessageBox::question(this, tr("Symbol file changed"),
- tr("One or more symbol file have changed.\n"
- "Reload now?"),
- QMessageBox::Yes | QMessageBox::No);
- shown = false;
- if (choice == QMessageBox::Yes)
- session.symbolTable().reloadFiles();
- }
- void DebuggerForm::addressSlot(int addr, int& ps, int& ss, int& segment)
- {
- int p = (addr & 0xC000) >> 14;
- ps = memLayout.primarySlot[p];
- // figure out secondary slot
- ss = memLayout.isSubslotted[ps] ? memLayout.secondarySlot[p] : -1;
- // figure out (rom) mapper segment
- segment = -1;
- if (memLayout.mapperSize[ps][ss==-1 ? 0 : ss] > 0)
- segment = memLayout.mapperSegment[p];
- else {
- int q = 2*p + ((addr & 0x2000) >> 13);
- if (memLayout.romBlock[q] >= 0)
- segment = memLayout.romBlock[q];
- }
- }
|