summaryrefslogtreecommitdiffstats
path: root/src/devices/pic/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/pic/gui')
-rw-r--r--src/devices/pic/gui/Makefile.am9
-rw-r--r--src/devices/pic/gui/pic_config_editor.cpp68
-rw-r--r--src/devices/pic/gui/pic_config_editor.h37
-rw-r--r--src/devices/pic/gui/pic_config_word_editor.cpp196
-rw-r--r--src/devices/pic/gui/pic_config_word_editor.h70
-rw-r--r--src/devices/pic/gui/pic_group_ui.cpp87
-rw-r--r--src/devices/pic/gui/pic_group_ui.h29
-rw-r--r--src/devices/pic/gui/pic_hex_view.cpp60
-rw-r--r--src/devices/pic/gui/pic_hex_view.h39
-rw-r--r--src/devices/pic/gui/pic_memory_editor.cpp404
-rw-r--r--src/devices/pic/gui/pic_memory_editor.h189
-rw-r--r--src/devices/pic/gui/pic_prog_group_ui.cpp41
-rw-r--r--src/devices/pic/gui/pic_prog_group_ui.h31
-rw-r--r--src/devices/pic/gui/pic_register_view.cpp329
-rw-r--r--src/devices/pic/gui/pic_register_view.h88
15 files changed, 1677 insertions, 0 deletions
diff --git a/src/devices/pic/gui/Makefile.am b/src/devices/pic/gui/Makefile.am
new file mode 100644
index 0000000..72f3165
--- /dev/null
+++ b/src/devices/pic/gui/Makefile.am
@@ -0,0 +1,9 @@
+INCLUDES = -I$(top_srcdir)/src $(all_includes)
+METASOURCES = AUTO
+libpicui_la_LDFLAGS = $(all_libraries)
+noinst_LTLIBRARIES = libpicui.la
+
+
+libpicui_la_SOURCES = pic_config_editor.cpp \
+ pic_config_word_editor.cpp pic_hex_view.cpp pic_memory_editor.cpp pic_register_view.cpp pic_group_ui.cpp \
+ pic_prog_group_ui.cpp
diff --git a/src/devices/pic/gui/pic_config_editor.cpp b/src/devices/pic/gui/pic_config_editor.cpp
new file mode 100644
index 0000000..1812bbf
--- /dev/null
+++ b/src/devices/pic/gui/pic_config_editor.cpp
@@ -0,0 +1,68 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_config_editor.h"
+
+#include <qlayout.h>
+#include <qvgroupbox.h>
+#include <qapplication.h>
+
+#include "pic_config_word_editor.h"
+#include "common/common/misc.h"
+#include "common/gui/misc_gui.h"
+
+//----------------------------------------------------------------------------
+Pic::MemoryConfigEditorWidget::MemoryConfigEditorWidget(Memory &memory, bool withWordEditor, QWidget *parent)
+ : Device::MemoryEditorGroup(&memory, parent, "pic_config_editor_widget"),
+ MemoryCaster(MemoryRangeType::Config, memory)
+{
+ QHBoxLayout *hb = new QHBoxLayout(_top);
+
+ TabWidget *tabw = 0;
+ uint nbWords = device().nbWords(MemoryRangeType::Config);
+ if ( nbWords>1 ) {
+ tabw = new TabWidget(this);
+ tabw->setIgnoreWheelEvent(true);
+ hb->addWidget(tabw);
+ }
+
+ for(uint i=0; i<nbWords; ++i) {
+ //qDebug("BinWordsEditor for config word #%i", i);
+ //uint address = device().range(Device::MemoryConfig).start + device().addressIncrement(Device::MemoryConfig) * i;
+ //qDebug("address: %s %s nb: %i", toHex(address, 8).data(), device().configWord(i).name.latin1(), device().configWord(i).masks.count());
+ if ( device().config()._words[i].masks.count()==0 ) continue;
+ QWidget *page = 0;
+ if ( nbWords>1 ) {
+ page = new QWidget(tabw);
+ tabw->addTab(page, device().config()._words[i].name);
+ } else {
+ page = new QGroupBox(this);
+ hb->addWidget(page);
+ }
+ QVBoxLayout *vbox = new QVBoxLayout(page, 10, 10);
+ QHBoxLayout *hbox = new QHBoxLayout(vbox);
+ ConfigWordEditor *we = new ConfigWordEditor(memory, i, withWordEditor, page);
+ addEditor(we);
+ hbox->addWidget(we);
+ hbox->addStretch(1);
+ vbox->addStretch(1);
+ }
+}
+
+//----------------------------------------------------------------------------
+Pic::MemoryConfigEditor::MemoryConfigEditor(const HexView *hexview, Memory &memory, QWidget *parent)
+ : MemoryTypeEditor(hexview, MemoryRangeType::Config, memory, parent, "pic_config_editor")
+{}
+
+void Pic::MemoryConfigEditor::init(bool first)
+{
+ MemoryTypeEditor::init(first);
+ MemoryConfigEditorWidget *w = new MemoryConfigEditorWidget(memory(), true, this);
+ addEditor(w);
+ _top->addWidget(w);
+}
diff --git a/src/devices/pic/gui/pic_config_editor.h b/src/devices/pic/gui/pic_config_editor.h
new file mode 100644
index 0000000..888debf
--- /dev/null
+++ b/src/devices/pic/gui/pic_config_editor.h
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_CONFIG_EDITOR_H
+#define PIC_CONFIG_EDITOR_H
+
+#include "pic_memory_editor.h"
+
+//----------------------------------------------------------------------------
+namespace Pic
+{
+class HexView;
+
+class MemoryConfigEditorWidget : public Device::MemoryEditorGroup, public MemoryCaster
+{
+Q_OBJECT
+public:
+ MemoryConfigEditorWidget(Memory &memory, bool withWordEditor, QWidget *parent);
+};
+
+//----------------------------------------------------------------------------
+class MemoryConfigEditor : public MemoryTypeEditor
+{
+Q_OBJECT
+public:
+ MemoryConfigEditor(const HexView *hexview, Memory &memory, QWidget *parent);
+ virtual void init(bool first);
+};
+
+} // namespace
+
+#endif
diff --git a/src/devices/pic/gui/pic_config_word_editor.cpp b/src/devices/pic/gui/pic_config_word_editor.cpp
new file mode 100644
index 0000000..23e4bce
--- /dev/null
+++ b/src/devices/pic/gui/pic_config_word_editor.cpp
@@ -0,0 +1,196 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_config_word_editor.h"
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qcombobox.h>
+#include <klocale.h>
+
+#include "common/common/misc.h"
+#include "common/gui/misc_gui.h"
+
+//----------------------------------------------------------------------------
+Pic::ConfigWordComboBox::ConfigWordComboBox(QWidget *parent)
+ : ComboBox(parent)
+{
+ setIgnoreWheelEvent(true);
+}
+
+uint Pic::ConfigWordComboBox::index() const
+{
+ if ( isValid() ) return _map[currentItem()];
+ if ( currentItem()==0 ) return _invalidIndex;
+ return _map[currentItem()-1];
+}
+
+void Pic::ConfigWordComboBox::setItem(uint i)
+{
+ if ( !isValid() ) removeItem(0);
+ for (uint l=0; l<_map.count(); l++)
+ if ( _map[l]==i ) setCurrentItem(l);
+}
+
+void Pic::ConfigWordComboBox::setInvalidItem(uint i, const QString &label)
+{
+ if ( !isValid() ) changeItem(label, 0);
+ else insertItem(label, 0);
+ setCurrentItem(0);
+ _invalidIndex = i;
+}
+
+//----------------------------------------------------------------------------
+Pic::ConfigWordDialog::ConfigWordDialog(const Memory &memory, uint ci, QWidget *parent)
+ : Dialog(parent, "config_word_dialog", true, i18n("Config Word Details"), Close, Close, false)
+{
+ uint nbChars = memory.device().nbCharsWord(MemoryRangeType::Config);
+ const Config::Word &cword = memory.device().config()._words[ci];
+
+ QGridLayout *grid = new QGridLayout(mainWidget(), 0, 0, 10, 10);
+ uint row = 0;
+ QLabel *label = new QLabel(i18n("Name:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(cword.name, mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Index:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(QString::number(ci), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Raw Value:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(memory.word(MemoryRangeType::Config, ci), nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Value:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(memory.normalizedWord(MemoryRangeType::Config, ci), nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Raw Blank Value:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(cword.bvalue, nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Used Mask:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(cword.usedMask(), nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Write Mask:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(cword.wmask, nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Protected Mask:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(cword.pmask, nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+ label = new QLabel(i18n("Checksum Mask:"), mainWidget());
+ grid->addWidget(label, row, 0);
+ label = new QLabel(toHexLabel(cword.cmask, nbChars), mainWidget());
+ grid->addWidget(label, row, 1);
+ row++;
+}
+
+//----------------------------------------------------------------------------
+Pic::ConfigWordEditor::ConfigWordEditor(Memory &memory, uint ci, bool withWordEditor, QWidget *parent)
+ : MemoryEditor(MemoryRangeType::Config, memory, parent, "pic_config_word_editor"), _configIndex(ci)
+{
+ if (withWordEditor) {
+ QHBoxLayout *hbox = new QHBoxLayout(_top);
+ _mdb = new MemoryRangeEditor(MemoryRangeType::Config, memory, 1, 1, ci, 1, this);
+ _mdb->init();
+ connect(_mdb, SIGNAL(modified()), SIGNAL(modified()));
+ connect(_mdb, SIGNAL(modified()), SLOT(updateDisplay()));
+ hbox->addWidget(_mdb);
+ KPushButton *button = new KPushButton(i18n("Details..."), this);
+ button->setFixedHeight(button->sizeHint().height());
+ connect(button, SIGNAL(clicked()), SLOT(showDialog()));
+ hbox->addWidget(button);
+ hbox->addStretch(1);
+ } else _mdb = 0;
+
+ QGridLayout *grid = new QGridLayout(_top);
+ grid->setColStretch(2, 1);
+ const Config::Word &cword = device().config()._words[ci];
+ _combos.resize(cword.masks.count());
+ uint nbChars = device().nbCharsWord(MemoryRangeType::Config);
+ for (uint k=0; k<_combos.count(); k++) {
+ const Config::Mask &cmask = cword.masks[k];
+ QLabel *label = new QLabel(Config::maskLabel(cmask.name) + ":", this);
+ grid->addWidget(label, k, 0);
+ label = new QLabel(cmask.name, this);
+ grid->addWidget(label, k, 1);
+ _combos[k] = new ConfigWordComboBox(this);
+ for (uint i=0; i<cmask.values.count(); i++) {
+ if ( !cmask.values[i].isValid() ) continue;
+ QString label = Config::valueLabel(cmask.name, cmask.values[i].name);
+ label += " (" + toHexLabel(cmask.values[i].value, nbChars) + ")";
+ _combos[k]->appendItem(label, i);
+ }
+ connect(_combos[k], SIGNAL(activated(int)), SLOT(slotModified()));
+ grid->addWidget(_combos[k], k, 2);
+ }
+}
+
+void Pic::ConfigWordEditor::setReadOnly(bool readOnly)
+{
+ if (_mdb) _mdb->setReadOnly(readOnly);
+ const Config::Word &cword = device().config()._words[_configIndex];
+ for (uint k=0; k<_combos.count(); k++) {
+ const Config::Mask &cmask = cword.masks[k];
+ _combos[k]->setEnabled(!readOnly && !cmask.value.isOverlapping(cword.pmask) && cmask.values.count()!=1);
+ }
+}
+
+void Pic::ConfigWordEditor::slotModified()
+{
+ BitValue v = memory().word(MemoryRangeType::Config, _configIndex);
+ //qDebug("BinWordEditor::slotModified %i: %s", _configIndex, toHex(v, 4).data());
+ for (uint k=0; k<_combos.count(); k++) {
+ const Config::Mask &cmask = device().config()._words[_configIndex].masks[k];
+ v = v.clearMaskBits(cmask.value);
+ v |= cmask.values[_combos[k]->index()].value; // set value
+ }
+ memory().setWord(MemoryRangeType::Config, _configIndex, v);
+ //qDebug(" now: %s", toHex(v, 4).data());
+ if (_mdb) _mdb->updateDisplay();
+ emit modified();
+}
+
+void Pic::ConfigWordEditor::updateDisplay()
+{
+ BitValue v = memory().word(MemoryRangeType::Config, _configIndex);
+ uint nbChars = device().nbCharsWord(MemoryRangeType::Config);
+ //qDebug("BinWordEditor::updateDisplay %i: %s", _configIndex, toHex(v, 4).data());
+ for (uint k=0; k<_combos.count(); k++) {
+ const Config::Mask &cmask = device().config()._words[_configIndex].masks[k];
+ for (int i=cmask.values.count()-1; i>=0; i--) {
+ if ( cmask.values[i].value.isInside(v) ) {
+ if ( cmask.values[i].isValid() ) _combos[k]->setItem(i);
+ else {
+ QString label = i18n("<invalid>") + " (" + toHexLabel(cmask.values[i].value, nbChars) + ")";
+ _combos[k]->setInvalidItem(i, label);
+ }
+ break;
+ }
+ }
+ }
+ if (_mdb) _mdb->updateDisplay();
+}
+
+void Pic::ConfigWordEditor::showDialog()
+{
+ ConfigWordDialog dialog(memory(), _configIndex, this);
+ dialog.exec();
+}
diff --git a/src/devices/pic/gui/pic_config_word_editor.h b/src/devices/pic/gui/pic_config_word_editor.h
new file mode 100644
index 0000000..8f483c7
--- /dev/null
+++ b/src/devices/pic/gui/pic_config_word_editor.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_CONFIG_WORD_EDITOR_H
+#define PIC_CONFIG_WORD_EDITOR_H
+
+#include <qcombobox.h>
+
+#include "common/gui/dialog.h"
+#include "common/gui/misc_gui.h"
+#include "pic_memory_editor.h"
+
+namespace Pic
+{
+//----------------------------------------------------------------------------
+class ConfigWordDialog : public Dialog
+{
+Q_OBJECT
+public:
+ ConfigWordDialog(const Memory &memory, uint index, QWidget *parent);
+};
+
+//----------------------------------------------------------------------------
+class ConfigWordComboBox : public ComboBox
+{
+Q_OBJECT
+public:
+ ConfigWordComboBox(QWidget *parent);
+ void appendItem(const QString &text, uint index) { insertItem(text); _map.append(index); }
+ uint index() const;
+ void setItem(uint index);
+ void setInvalidItem(uint index, const QString &label);
+
+private:
+ QValueVector<uint> _map; // item index -> value index
+ uint _invalidIndex; // if invalid -> value index
+
+ bool isValid() const { return uint(count())==_map.count(); }
+};
+
+//----------------------------------------------------------------------------
+class ConfigWordEditor : public MemoryEditor
+{
+Q_OBJECT
+public:
+ ConfigWordEditor(Memory &memory, uint index, bool withWordEditor, QWidget *parent);
+ virtual void setReadOnly(bool readOnly);
+
+public slots:
+ virtual void updateDisplay();
+
+private slots:
+ void slotModified();
+ void showDialog();
+
+private:
+ uint _configIndex;
+ MemoryRangeEditor *_mdb;
+ QValueVector<ConfigWordComboBox *> _combos;
+};
+
+} // namespace
+
+#endif
diff --git a/src/devices/pic/gui/pic_group_ui.cpp b/src/devices/pic/gui/pic_group_ui.cpp
new file mode 100644
index 0000000..3f7a84c
--- /dev/null
+++ b/src/devices/pic/gui/pic_group_ui.cpp
@@ -0,0 +1,87 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_group_ui.h"
+
+#include <kaction.h>
+
+#include "libgui/main_global.h"
+#include "pic_hex_view.h"
+#include "pic_register_view.h"
+#include "pic_config_editor.h"
+#include "coff/base/text_coff.h"
+#include "libgui/gui_debug_manager.h"
+#include "common/gui/list_container.h"
+
+Device::HexView *Pic::GroupUI::createHexView(const HexEditor &editor, QWidget *parent) const
+{
+ return new HexView(editor, parent);
+}
+
+Register::View *Pic::GroupUI::createRegisterView(QWidget *parent) const
+{
+ return new RegisterView(parent);
+}
+
+Device::MemoryEditor *Pic::GroupUI::createConfigEditor(Device::Memory &memory, QWidget *parent) const
+{
+ return new MemoryConfigEditorWidget(static_cast<Memory &>(memory), false, parent);
+}
+
+void Pic::GroupUI::fillWatchListContainer(ListContainer *container, QValueVector<Register::TypeData> &ids) const
+{
+ ids.clear();
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ ListContainer *branch = container->appendBranch(i18n("SFRs"));
+ QValueVector<Pic::RegisterNameData> list = Pic::sfrList(data);
+ for (uint i=0; i<list.count(); i++) {
+ branch->appendItem(list[i].label(), ids.count(), ListContainer::UnChecked);
+ ids.append(list[i].data());
+ }
+ branch = container->appendBranch(i18n("I/Os"));
+ for (uint i=0; i<Device::MAX_NB_PORTS; i++) {
+ if ( !rdata.hasPort(i) ) continue;
+ QString name = rdata.portName(i);
+ branch->appendItem(name, ids.count(), ListContainer::UnChecked);
+ ids.append(Register::TypeData(rdata.sfrs[name].address, rdata.nbChars()));
+ }
+ branch = container->appendBranch(i18n("GPRs"));
+ const Coff::Object *coff = Debugger::manager->coff();
+ list = Pic::gprList(data, coff);
+ for (uint k=0; k<rdata.nbBanks; k++) {
+ if ( !rdata.isBankUsed(k) ) continue;
+ ListContainer *bbranch = (rdata.nbBanks==1 ? branch : branch->appendBranch(i18n("Bank %1").arg(k)));
+ uint nb = 0;
+ for (uint i=0; i<list.count(); i++) {
+ if ( rdata.bankFromAddress(list[i].data().address())!=k ) continue;
+ bbranch->appendItem(list[i].label(), ids.count(), ListContainer::UnChecked);
+ ids.append(list[i].data());
+ nb++;
+ }
+ }
+ branch = container->appendBranch(i18n("Variables"));
+ if (coff) {
+ list = Pic::variableList(data, *coff);
+ if ( list.count()==0 ) {
+ branch->appendItem(i18n("No variable"), ids.count(), ListContainer::Disabled);
+ ids.append(Register::TypeData());
+ } else for (uint i=0; i<list.count(); i++) {
+ branch->appendItem(list[i].label(), ids.count(), ListContainer::UnChecked);
+ ids.append(list[i].data());
+ }
+ } else {
+ branch->appendItem(i18n("Please compile the current project"), ids.count(), ListContainer::Disabled);
+ ids.append(Register::TypeData());
+ }
+}
+
+Register::ListViewItem *Pic::GroupUI::createWatchItem(const Register::TypeData &data, KListViewItem *parent) const
+{
+ return new Pic::RegisterListViewItem(data, parent);
+}
diff --git a/src/devices/pic/gui/pic_group_ui.h b/src/devices/pic/gui/pic_group_ui.h
new file mode 100644
index 0000000..a8bee66
--- /dev/null
+++ b/src/devices/pic/gui/pic_group_ui.h
@@ -0,0 +1,29 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_GROUP_UI_H
+#define PIC_GROUP_UI_H
+
+#include "devices/gui/device_group_ui.h"
+
+namespace Pic
+{
+
+class GroupUI : public Device::GroupUI
+{
+public:
+ virtual Device::HexView *createHexView(const HexEditor &editor, QWidget *parent) const;
+ virtual Register::View *createRegisterView(QWidget *parent) const;
+ virtual Device::MemoryEditor *createConfigEditor(Device::Memory &memory, QWidget *parent) const;
+ virtual void fillWatchListContainer(ListContainer *container, QValueVector<Register::TypeData> &ids) const;
+ virtual Register::ListViewItem *createWatchItem(const Register::TypeData &data, KListViewItem *parent) const;
+};
+
+} // namespace
+
+#endif
diff --git a/src/devices/pic/gui/pic_hex_view.cpp b/src/devices/pic/gui/pic_hex_view.cpp
new file mode 100644
index 0000000..07a1938
--- /dev/null
+++ b/src/devices/pic/gui/pic_hex_view.cpp
@@ -0,0 +1,60 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_hex_view.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+
+#include <klocale.h>
+
+#include "pic_memory_editor.h"
+#include "pic_config_editor.h"
+
+Pic::HexView::HexView(const HexEditor &editor, QWidget *parent)
+ : Device::HexView(editor, parent, "pic_hex_view")
+{}
+
+const Pic::MemoryRangeType::Type Pic::HexView::MEMORY_DATA[] = {
+ MemoryRangeType::Code, MemoryRangeType::Config, MemoryRangeType::Eeprom, MemoryRangeType::UserId,
+ MemoryRangeType::Cal, MemoryRangeType::Nb_Types
+};
+
+void Pic::HexView::display()
+{
+ bool first = true;
+ for (uint i=0; MEMORY_DATA[i]!=MemoryRangeType::Nb_Types; i++) {
+ Pic::MemoryRangeType type = MEMORY_DATA[i];
+ if ( !memory()->device().isReadable(type) ) continue;
+ Device::MemoryTypeEditor *e = 0;
+ switch (type.type()) {
+ case MemoryRangeType::Config: e = new MemoryConfigEditor(this, *memory(), this); break;
+ case MemoryRangeType::Cal: e = new MemoryCalibrationEditor(this, *memory(), this); break;
+ case MemoryRangeType::Code:
+ case MemoryRangeType::Eeprom: e = new MemoryTypeRangeEditor(this, type, *memory(), this); break;
+ case MemoryRangeType::UserId: e = new MemoryUserIdEditor(this, *memory(), this); break;
+ case MemoryRangeType::DeviceId:
+ case MemoryRangeType::HardwareStack:
+ case MemoryRangeType::ProgramExecutive:
+ case MemoryRangeType::DebugVector:
+ case MemoryRangeType::CalBackup:
+ case MemoryRangeType::Nb_Types: Q_ASSERT(false); break;
+ }
+ e->init(first);
+ e->show();
+ _top->addWidget(e);
+ addEditor(e);
+ first = false;
+ }
+}
+
+BitValue Pic::HexView::checksum() const
+{
+ return (_memory ? memory()->checksum() : 0x0000);
+}
diff --git a/src/devices/pic/gui/pic_hex_view.h b/src/devices/pic/gui/pic_hex_view.h
new file mode 100644
index 0000000..2086ccb
--- /dev/null
+++ b/src/devices/pic/gui/pic_hex_view.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_HEX_VIEW_H
+#define PIC_HEX_VIEW_H
+
+class QVBoxLayout;
+
+#include "devices/gui/hex_view.h"
+#include "devices/pic/pic/pic_memory.h"
+
+namespace Pic
+{
+
+class HexView : public Device::HexView
+{
+Q_OBJECT
+public:
+ HexView(const HexEditor &editor, QWidget *parent);
+ Memory *memory() { return static_cast<Memory *>(_memory); }
+ const Memory *memory() const { return static_cast<Memory *>(_memory); }
+ virtual uint nbChecksumChars() const { return 4; }
+ virtual BitValue checksum() const;
+
+private:
+ static const MemoryRangeType::Type MEMORY_DATA[];
+
+ virtual void display();
+};
+
+} // namespace
+
+#endif
diff --git a/src/devices/pic/gui/pic_memory_editor.cpp b/src/devices/pic/gui/pic_memory_editor.cpp
new file mode 100644
index 0000000..3d78097
--- /dev/null
+++ b/src/devices/pic/gui/pic_memory_editor.cpp
@@ -0,0 +1,404 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_memory_editor.h"
+
+#include <qframe.h>
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qscrollbar.h>
+#include <qgrid.h>
+#include <qhbox.h>
+#include <qtooltip.h>
+#include <qregexp.h>
+#include <qcolor.h>
+#include <qlayout.h>
+#include <qpixmap.h>
+
+#include <klocale.h>
+#include <kpushbutton.h>
+#include <kaction.h>
+
+#include "common/common/misc.h"
+#include "pic_config_editor.h"
+#include "libgui/toplevel.h"
+#include "libgui/main_global.h"
+#include "devices/pic/prog/pic_prog.h"
+#include "libgui/global_config.h"
+#include "pic_hex_view.h"
+
+//-----------------------------------------------------------------------------
+Pic::MemoryEditorLegend::Data::Data(const QString &text, QWidget *parent)
+{
+ button = new PopupButton(text, parent);
+ KActionCollection *ac = 0;
+ KAction *a = new KAction(i18n("Go to start"), "top", 0, parent, SLOT(gotoStart()), ac);
+ actions.append(a);
+ button->appendAction(a);
+ a = new KAction(i18n("Go to end"), "bottom", 0, parent, SLOT(gotoEnd()), ac);
+ actions.append(a);
+ button->appendAction(a);
+ label = new QLabel(parent);
+}
+
+void Pic::MemoryEditorLegend::Data::setProtected(bool on)
+{
+ if (on) label->setPaletteBackgroundColor(MemoryEditorLegend::protectedColor());
+ else label->unsetPalette();
+}
+
+bool Pic::MemoryEditorLegend::Data::hasAction(const KAction *action) const
+{
+ for (uint i=0; i<actions.count(); i++) if ( actions[i]==action ) return true;
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+const char * const Pic::MemoryEditorLegend::BLOCK_COLORS[Protection::MAX_NB_BLOCKS] = {
+ "#88FF88", "#88FFFF", "#FFFF88", "#FF88FF", "#0088FF", "#88FF00", "#00FF88", "#FF8800"
+};
+
+Pic::MemoryEditorLegend::MemoryEditorLegend(MemoryRangeType type, Memory &memory, QWidget *parent)
+ : MemoryEditor(type, memory, parent, "memory_displayer_legend")
+{
+ QGridLayout *grid = new QGridLayout(_top);
+
+ QWidget *w = new QWidget(this);
+ w->setFixedWidth(20);
+ w->setPaletteBackgroundColor(protectedColor());
+ grid->addWidget(w, 0, 0);
+ const Protection &protection = device().config().protection();
+ QString s = (protection.family()==Protection::CodeGuard ? i18n("High Security") : i18n("Code protection"));
+ QLabel *label = new QLabel(s, this);
+ grid->addMultiCellWidget(label, 0,0, 1,2);
+ grid->addRowSpacing(1, 10);
+ uint row = 2;
+
+ if ( type==MemoryRangeType::Code && protection.hasBootBlock() ) {
+ w = new QWidget(this);
+ w->setFixedWidth(20);
+ w->setPaletteBackgroundColor(bootColor());
+ grid->addWidget(w, row, 0);
+ _boot = Data(protection.bootLabel(), this);
+ grid->addWidget(_boot.button, row, 1);
+ grid->addWidget(_boot.label, row, 2);
+ row++;
+ }
+
+ uint nb = (type==MemoryRangeType::Code ? protection.nbBlocks() : 0);
+ for (uint i=0; i<nb; i++) {
+ w = new QWidget(this);
+ w->setFixedWidth(20);
+ w->setPaletteBackgroundColor(blockColor(i));
+ grid->addWidget(w, row, 0);
+ _blocks.append(Data(protection.blockLabel(i), this));
+ grid->addWidget(_blocks[i].button, row, 1);
+ grid->addWidget(_blocks[i].label, row, 2);
+ row++;
+ }
+}
+
+void Pic::MemoryEditorLegend::updateDisplay()
+{
+ const Protection &protection = device().config().protection();
+ Protection::Type ptype = (protection.family()==Protection::CodeGuard ? Protection::HighSecurity : Protection::ProgramProtected);
+ uint nbChars = 2 * device().nbBytesAddress();
+ if (_boot.label) {
+ AddressRange r = memory().bootRange();
+ if ( r.isEmpty() ) _boot.label->setText(i18n("not present"));
+ else _boot.label->setText(QString("[%1:%2]").arg(toHex(r.start, nbChars)).arg(toHex(r.end, nbChars)));
+ _boot.button->setEnabled(!r.isEmpty());
+ _boot.setProtected(memory().isBootProtected(ptype));
+ }
+ for (uint i=0; i<_blocks.count(); i++) {
+ AddressRange r = memory().blockRange(i);
+ if ( r.isEmpty() ) _blocks[i].label->setText(i18n("not present"));
+ else _blocks[i].label->setText(QString("[%1:%2]").arg(toHex(r.start, nbChars)).arg(toHex(r.end, nbChars)));
+ _blocks[i].button->setEnabled(!r.isEmpty());
+ _blocks[i].setProtected(memory().isBlockProtected(ptype, i));
+ }
+}
+
+void Pic::MemoryEditorLegend::gotoStart()
+{
+ Address start = device().range(type()).start;
+ const KAction *action = static_cast<const KAction *>(sender());
+ if ( _boot.hasAction(action) ) {
+ AddressRange r = memory().bootRange();
+ emit setStartWord(r.start - start);
+ return;
+ }
+ for (uint i=0; i<_blocks.count(); i++) {
+ if ( _blocks[i].hasAction(action) ) {
+ AddressRange r = memory().blockRange(i);
+ emit setStartWord(r.start - start);
+ return;
+ }
+ }
+ Q_ASSERT(false);
+}
+
+void Pic::MemoryEditorLegend::gotoEnd()
+{
+ Address start = device().range(type()).start;
+ const KAction *action = static_cast<const KAction *>(sender());
+ if ( _boot.hasAction(action) ) {
+ AddressRange r = memory().bootRange();
+ emit setEndWord(r.end - start);
+ return;
+ }
+ for (uint i=0; i<_blocks.count(); i++) {
+ if ( _blocks[i].hasAction(action) ) {
+ AddressRange r = memory().blockRange(i);
+ emit setEndWord(r.end - start);
+ return;
+ }
+ }
+ Q_ASSERT(false);
+}
+
+
+//-----------------------------------------------------------------------------
+Pic::HexWordEditor::HexWordEditor(MemoryRangeType type, Memory &memory, QWidget *parent)
+ : Device::HexWordEditor(memory, memory.device().nbCharsWord(type), parent),
+ MemoryCaster(type, memory)
+{}
+
+void Pic::HexWordEditor::setWord(BitValue value)
+{
+ if ( type()==MemoryRangeType::Config ) {
+ const Config::Word &cword = device().config()._words[_offset];
+ value |= cword.usedMask().complementInMask(device().mask(MemoryRangeType::Config));
+ }
+ memory().setWord(type(), _offset, value);
+}
+
+//-----------------------------------------------------------------------------
+Pic::MemoryRangeEditor::MemoryRangeEditor(MemoryRangeType type, Memory &memory,
+ uint nbLines, uint nbCols,
+ uint wordOffset, int nbWords, QWidget *parent)
+ : Device::MemoryRangeEditor(memory, nbLines, nbCols, wordOffset, nbWords, parent, "pic_memory_range_editor"),
+ MemoryCaster(type, memory), _legend(0)
+{
+ if ( type==MemoryRangeType::Code ) _blockRanges.resize(memory.device().config().protection().nbBlocks());
+}
+
+void Pic::MemoryRangeEditor::addLegend(QVBoxLayout *vbox)
+{
+ if ( type()==MemoryRangeType::Code || type()==MemoryRangeType::Eeprom ) {
+ _legend = new MemoryEditorLegend(type(), memory(), this);
+ connect(_legend, SIGNAL(setStartWord(int)), SLOT(setStartWord(int)));
+ connect(_legend, SIGNAL(setEndWord(int)), SLOT(setEndWord(int)));
+ vbox->addWidget(_legend);
+ }
+}
+
+bool Pic::MemoryRangeEditor::isRangeReadOnly() const
+{
+ return ( (type().data().properties & ReadOnly) || type()==MemoryRangeType::CalBackup );
+}
+
+void Pic::MemoryRangeEditor::updateDisplay()
+{
+ const Protection &protection = device().config().protection();
+ if ( type()==MemoryRangeType::Code ) {
+ if ( protection.hasBootBlock() ) _bootRange = memory().bootRange();
+ for (uint k=0; k<_blockRanges.count(); k++)
+ _blockRanges[k] = memory().blockRange(k);
+ }
+ Protection::Type ptype = (protection.family()==Protection::CodeGuard ? Protection::HighSecurity : Protection::ProgramProtected);
+ _codeProtected = memory().protectedRanges(ptype, type());
+ Device::MemoryRangeEditor::updateDisplay();
+ if (_legend) _legend->updateDisplay();
+}
+
+void Pic::MemoryRangeEditor::updateAddressColor(uint i, Address address)
+{
+ if ( _codeProtected.contains(address) )
+ _addresses[i]->setPaletteBackgroundColor(MemoryEditorLegend::protectedColor());
+ else _addresses[i]->unsetPalette();
+ _blocks[i]->unsetPalette();
+ if ( type()==MemoryRangeType::Code ) {
+ if ( _bootRange.contains(address) ) _blocks[i]->setPaletteBackgroundColor(MemoryEditorLegend::bootColor());
+ else for (uint k=0; k<_blockRanges.count(); k++) {
+ if ( !_blockRanges[k].contains(address) ) continue;
+ _blocks[i]->setPaletteBackgroundColor(MemoryEditorLegend::blockColor(k));
+ break;
+ }
+ }
+}
+
+Device::HexWordEditor *Pic::MemoryRangeEditor::createHexWordEditor(QWidget *parent)
+{
+ return new HexWordEditor(type(), memory(), parent);
+}
+
+//-----------------------------------------------------------------------------
+Pic::MemoryTypeEditor::MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent, const char *name)
+ : Device::MemoryTypeEditor(hexview, memory, parent, name), MemoryCaster(type, memory)
+{}
+
+void Pic::MemoryTypeEditor::init(bool first)
+{
+ Device::MemoryTypeEditor::init(first);
+ _title->setText(type().label());
+
+ uint nbChars = device().nbCharsWord(type());
+ QString add;
+ if ( type()==MemoryRangeType::UserId ) add = i18n(" - recommended mask: %1").arg(toHexLabel(device().userIdRecommendedMask(), nbChars));
+ if ( type()==MemoryRangeType::Cal && _hexview ) add = i18n(" - not programmed by default");
+ QString comment = i18n("%1-bit words - mask: %2")
+ .arg(device().nbBitsWord(type())).arg(toHexLabel(device().mask(type()), nbChars));
+ _comment->setText(comment + add);
+}
+
+bool Pic::MemoryTypeEditor::internalDoAction(Device::Action action)
+{
+ Programmer::PicBase *prog = static_cast<Programmer::PicBase *>(Main::programmer());
+ switch (action) {
+ case Device::Clear: memory().clear(type()); return true;
+ case Device::Zero: memory().fill(type(), 0); return true;
+ case Device::ChecksumCheck : memory().checksumCheckFill(); return true;
+ case Device::Reload: {
+ const Memory *omemory = static_cast<const Memory *>(originalMemory());
+ Q_ASSERT(omemory);
+ memory().copyFrom(type(), *omemory); return true;
+ }
+ case Device::Program:
+ prog->programSingle(type(), memory());
+ return false;
+ case Device::Verify:
+ prog->verifySingle(type(), memory());
+ return false;
+ case Device::Read:
+ return prog->readSingle(type(), memory());
+ case Device::Erase:
+ prog->eraseSingle(type());
+ return false;
+ case Device::BlankCheck:
+ prog->blankCheckSingle(type());
+ return false;
+ case Device::Nb_Actions: break;
+ }
+ Q_ASSERT(false);
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+Pic::MemoryTypeRangeEditor::MemoryTypeRangeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent)
+ : MemoryTypeEditor(hexview, type, memory, parent, "pic_memory_type_range_editor"), _mre(0)
+{}
+
+void Pic::MemoryTypeRangeEditor::init(bool first)
+{
+ MemoryTypeEditor::init(first);
+ uint nbLines = 0;
+ if ( type()==MemoryRangeType::Code ) nbLines = 16;
+ else if ( type()==MemoryRangeType::Eeprom ) nbLines = 8;
+ else nbLines = (device().nbWords(type())/8>1 ? 2 : 1);
+ _mre = new MemoryRangeEditor(type(), memory(), nbLines, 8, 0, -1, this);
+ addEditor(_mre);
+ _top->addWidget(_mre);
+ _mre->init();
+}
+
+//-----------------------------------------------------------------------------
+Pic::MemoryUserIdEditor::MemoryUserIdEditor(const HexView *hexview, Memory &memory, QWidget *parent)
+ : MemoryTypeRangeEditor(hexview, MemoryRangeType::UserId, memory, parent), _saveReadOnly(false)
+{}
+
+void Pic::MemoryUserIdEditor::init(bool first)
+{
+ MemoryTypeRangeEditor::init(first);
+ _setToChecksum = new KToggleAction(i18n("Set to unprotected checksum"), 0, 0,
+ this, SLOT(toggleSetToChecksum()), Main::toplevel().actionCollection());
+ addAction(_setToChecksum);
+ if ( readConfigEntry(BaseGlobalConfig::UserIdSetToChecksum).toBool() && memory().isClear(MemoryRangeType::UserId) ) {
+ _setToChecksum->activate();
+ toggleSetToChecksum();
+ }
+}
+
+void Pic::MemoryUserIdEditor::toggleSetToChecksum()
+{
+ if ( _setToChecksum->isChecked() ) {
+ _mre->setComment(i18n("Set to unprotected checksum"));
+ emit modified();
+ } else _mre->setComment(QString::null);
+ setReadOnly(_saveReadOnly);
+}
+
+void Pic::MemoryUserIdEditor::updateDisplay()
+{
+ if ( _setToChecksum->isChecked() ) memory().setUserIdToUnprotectedChecksum();
+ MemoryTypeRangeEditor::updateDisplay();
+}
+
+void Pic::MemoryUserIdEditor::setReadOnly(bool readOnly)
+{
+ _saveReadOnly = readOnly;
+ MemoryTypeRangeEditor::setReadOnly(readOnly || _setToChecksum->isChecked());
+}
+
+//-----------------------------------------------------------------------------
+Pic::MemoryCalibrationEditor::MemoryCalibrationEditor(const HexView *hexview, Memory &memory, QWidget *parent)
+ : MemoryTypeEditor(hexview, MemoryRangeType::Cal, memory, parent, "pic_memory_calibration_editor")
+{}
+
+void Pic::MemoryCalibrationEditor::init(bool first)
+{
+ MemoryTypeEditor::init(first);
+ MemoryRangeEditor *mre = new MemoryRangeEditor(MemoryRangeType::Cal, memory(), 1, 8, 0, -1, this);
+ addEditor(mre);
+ _top->addWidget(mre);
+ mre->init();
+ if ( device().isReadable(MemoryRangeType::CalBackup) ) {
+ mre = new MemoryRangeEditor(MemoryRangeType::CalBackup, memory(), 1, 8, 0, -1, this);
+ addEditor(mre);
+ _top->addWidget(mre);
+ mre->init();
+ mre->setComment(i18n("(backup)"));
+ }
+}
+
+bool Pic::MemoryCalibrationEditor::hasAction(Device::Action action) const
+{
+ return ( action==Device::Read || action==Device::Verify || action==Device::Program );
+}
+
+bool Pic::MemoryCalibrationEditor::internalDoAction(Device::Action action)
+{
+ Programmer::PicBase *prog = static_cast<Programmer::PicBase *>(Main::programmer());
+ switch (action) {
+ case Device::Reload: {
+ const Memory *omemory = static_cast<const Memory *>(originalMemory());
+ Q_ASSERT(omemory);
+ memory().copyFrom(MemoryRangeType::Cal, *omemory);
+ memory().copyFrom(MemoryRangeType::CalBackup, *omemory);
+ return true;
+ }
+ case Device::Program:
+ if ( prog->programCalibration(memory().arrayForWriting(Pic::MemoryRangeType::Cal)) )
+ return prog->readSingle(MemoryRangeType::Cal, memory());
+ return false;
+ case Device::Verify:
+ prog->verifySingle(MemoryRangeType::Cal, memory());
+ return false;
+ case Device::Read:
+ return prog->readSingle(MemoryRangeType::Cal, memory());
+ case Device::Clear:
+ case Device::Zero:
+ case Device::ChecksumCheck:
+ case Device::Erase:
+ case Device::BlankCheck:
+ case Device::Nb_Actions: break;
+ }
+ Q_ASSERT(false);
+ return false;
+}
diff --git a/src/devices/pic/gui/pic_memory_editor.h b/src/devices/pic/gui/pic_memory_editor.h
new file mode 100644
index 0000000..bf67cd1
--- /dev/null
+++ b/src/devices/pic/gui/pic_memory_editor.h
@@ -0,0 +1,189 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * Copyright (C) 2003-2004 Alain Gibaud <alain.gibaud@free.fr> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_MEMORY_EDITOR_H
+#define PIC_MEMORY_EDITOR_H
+
+#include <qscrollbar.h>
+#include <qgroupbox.h>
+class KToggleAction;
+
+#include "devices/gui/memory_editor.h"
+#include "devices/gui/hex_word_editor.h"
+#include "devices/pic/pic/pic_memory.h"
+class PopupButton;
+
+namespace Pic
+{
+class HexView;
+
+//-----------------------------------------------------------------------------
+class MemoryCaster
+{
+public:
+ MemoryCaster(MemoryRangeType type, Device::Memory &memory) : _type(type), _memory(memory) {}
+ MemoryRangeType type() const { return _type; }
+ const Data &device() const { return static_cast<const Data &>(_memory.device()); }
+ const Memory &memory() const { return static_cast<Memory &>(_memory); }
+ Memory &memory() { return static_cast<Memory &>(_memory); }
+
+private:
+ MemoryRangeType _type;
+ Device::Memory &_memory;
+};
+
+//-----------------------------------------------------------------------------
+class MemoryEditor : public Device::MemoryEditor, public MemoryCaster
+{
+Q_OBJECT
+public:
+ MemoryEditor(MemoryRangeType type, Memory &memory, QWidget *parent, const char *name)
+ : Device::MemoryEditor(&memory, parent, name), MemoryCaster(type, memory) {}
+};
+
+//-----------------------------------------------------------------------------
+class MemoryEditorLegend : public MemoryEditor
+{
+Q_OBJECT
+public:
+ MemoryEditorLegend(MemoryRangeType type, Memory &memory, QWidget *parent);
+ virtual void setReadOnly(bool) {}
+
+ static QColor protectedColor() { return QColor("#FF8888"); }
+ static QColor bootColor() { return QColor("#8888FF"); }
+ static QColor blockColor(uint i) { return QColor(BLOCK_COLORS[i]); }
+
+signals:
+ void setStartWord(int i);
+ void setEndWord(int i);
+
+public slots:
+ virtual void updateDisplay();
+
+private slots:
+ void gotoStart();
+ void gotoEnd();
+
+private:
+ class Data {
+ public:
+ Data() : button(0), label(0) {}
+ Data(const QString &text, QWidget *parent);
+ void setProtected(bool on);
+ bool hasAction(const KAction *action) const;
+ PopupButton *button;
+ QLabel *label;
+ QValueVector<KAction *> actions;
+ };
+ Data _boot;
+ QValueVector<Data> _blocks;
+
+ static const char * const BLOCK_COLORS[Protection::MAX_NB_BLOCKS];
+};
+
+//-----------------------------------------------------------------------------
+class HexWordEditor : public Device::HexWordEditor, public MemoryCaster
+{
+Q_OBJECT
+public:
+ HexWordEditor(MemoryRangeType type, Memory &memory, QWidget *parent);
+
+private:
+ virtual BitValue mask() const { return memory().device().mask(type()); }
+ virtual BitValue normalizeWord(BitValue value) const { return memory().normalizeWord(type(), _offset, value); }
+ virtual BitValue word() const { return memory().word(type(), _offset); }
+ virtual void setWord(BitValue value);
+};
+
+//-----------------------------------------------------------------------------
+class MemoryRangeEditor : public Device::MemoryRangeEditor, public MemoryCaster
+{
+ Q_OBJECT
+public:
+ MemoryRangeEditor(MemoryRangeType type, Memory &memory,
+ uint nbLines, uint nbCols, uint wordOffset, int nbWords, QWidget *parent);
+
+public slots:
+ virtual void updateDisplay();
+
+private:
+ MemoryEditorLegend *_legend;
+ AddressRange _bootRange;
+ AddressRangeVector _blockRanges;
+ AddressRangeVector _codeProtected;
+
+ virtual uint nbWords() const { return device().nbWords(type()); }
+ virtual uint addressIncrement() const { return device().addressIncrement(type()); }
+ virtual Address startAddress() const { return device().range(type()).start; }
+ virtual Device::HexWordEditor *createHexWordEditor(QWidget *parent);
+ virtual void updateAddressColor(uint i, Address address);
+ virtual bool isRangeReadOnly() const;
+ virtual void addLegend(QVBoxLayout *vbox);
+};
+
+//-----------------------------------------------------------------------------
+class MemoryTypeEditor : public Device::MemoryTypeEditor, public MemoryCaster
+{
+Q_OBJECT
+public:
+ MemoryTypeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent, const char *name);
+ virtual void init(bool first);
+
+private:
+ virtual bool internalDoAction(Device::Action action);
+};
+
+//-----------------------------------------------------------------------------
+class MemoryTypeRangeEditor : public MemoryTypeEditor
+{
+Q_OBJECT
+public:
+ MemoryTypeRangeEditor(const HexView *hexview, MemoryRangeType type, Memory &memory, QWidget *parent);
+ virtual void init(bool first);
+
+protected:
+ MemoryRangeEditor *_mre;
+};
+
+//-----------------------------------------------------------------------------
+class MemoryUserIdEditor : public MemoryTypeRangeEditor
+{
+Q_OBJECT
+public:
+ MemoryUserIdEditor(const HexView *hexview, Memory &memory, QWidget *parent);
+ virtual void init(bool first);
+ virtual void setReadOnly(bool readOnly);
+
+public slots:
+ virtual void updateDisplay();
+
+private slots:
+ void toggleSetToChecksum();
+
+private:
+ bool _saveReadOnly;
+ KToggleAction *_setToChecksum;
+};
+
+//-----------------------------------------------------------------------------
+class MemoryCalibrationEditor : public MemoryTypeEditor
+{
+Q_OBJECT
+public:
+ MemoryCalibrationEditor(const HexView *hexview, Memory &memory, QWidget *parent);
+ virtual void init(bool first);
+
+private:
+ virtual bool hasAction(Device::Action action) const;
+ virtual bool internalDoAction(Device::Action action);
+};
+
+} // namespace
+
+#endif
diff --git a/src/devices/pic/gui/pic_prog_group_ui.cpp b/src/devices/pic/gui/pic_prog_group_ui.cpp
new file mode 100644
index 0000000..e063b77
--- /dev/null
+++ b/src/devices/pic/gui/pic_prog_group_ui.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_prog_group_ui.h"
+
+#include "progs/gui/prog_config_widget.h"
+#include "progs/base/prog_group.h"
+
+Programmer::PicAdvancedDialog::PicAdvancedDialog(PicBase &base, QWidget *parent, const char *name)
+ : AdvancedDialog(base, parent, name)
+{
+ if (_voltagesContainer) {
+ uint k = _voltagesContainer->numRows();
+ for (uint i=0; i<Pic::Nb_VoltageTypes; i++) {
+ if ( !base.group().canReadVoltage(Pic::VoltageType(i)) ) _voltages[i] = 0;
+ else {
+ QLabel *label = new QLabel(i18n(Pic::VOLTAGE_TYPE_LABELS[i]) + ":", _voltagesContainer);
+ _voltagesContainer->addWidget(label, k,k, 0,0);
+ _voltages[i] = new QLabel(_voltagesContainer);
+ _voltagesContainer->addWidget(_voltages[i], k,k, 1,1);
+ k++;
+ }
+ }
+ }
+}
+
+void Programmer::PicAdvancedDialog::updateDisplay()
+{
+ ::Programmer::AdvancedDialog::updateDisplay();
+ for (uint i=0; i<Pic::Nb_VoltageTypes; i++) {
+ if ( !base().group().canReadVoltage(Pic::VoltageType(i)) ) continue;
+ double v = base().voltage(Pic::VoltageType(i));
+ if ( v==::Programmer::UNKNOWN_VOLTAGE ) _voltages[i]->setText("---");
+ else _voltages[i]->setText(QString("%1 V").arg(v));
+ }
+}
diff --git a/src/devices/pic/gui/pic_prog_group_ui.h b/src/devices/pic/gui/pic_prog_group_ui.h
new file mode 100644
index 0000000..75821b5
--- /dev/null
+++ b/src/devices/pic/gui/pic_prog_group_ui.h
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * Copyright (C) 2005 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_PROG_GROUP_UI_H
+#define PIC_PROG_GROUP_UI_H
+
+#include "progs/gui/prog_group_ui.h"
+#include "devices/pic/prog/pic_prog.h"
+
+namespace Programmer
+{
+class PicAdvancedDialog : public ::Programmer::AdvancedDialog
+{
+Q_OBJECT
+public:
+ PicAdvancedDialog(PicBase &base, QWidget *parent, const char *name);
+ virtual void updateDisplay();
+
+private:
+ QLabel *_voltages[Pic::Nb_VoltageTypes];
+ PicBase &base() { return static_cast<PicBase &>(_base); }
+};
+
+} // namespace
+
+#endif
diff --git a/src/devices/pic/gui/pic_register_view.cpp b/src/devices/pic/gui/pic_register_view.cpp
new file mode 100644
index 0000000..ef7de9b
--- /dev/null
+++ b/src/devices/pic/gui/pic_register_view.cpp
@@ -0,0 +1,329 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#include "pic_register_view.h"
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qpopupmenu.h>
+
+#include <klocale.h>
+#include <kiconloader.h>
+
+#include "libgui/main_global.h"
+#include "devices/gui/hex_word_editor.h"
+#include "common/gui/misc_gui.h"
+#include "devices/pic/base/pic.h"
+#include "progs/base/generic_prog.h"
+#include "progs/base/generic_debug.h"
+#include "progs/base/prog_group.h"
+#include "libgui/gui_debug_manager.h"
+#include "coff/base/text_coff.h"
+
+//-----------------------------------------------------------------------------
+Pic::BankWidget::BankWidget(uint i, QWidget *parent)
+ : QFrame(parent, "bank_widget"), _bindex(i), _bankCombo(0)
+{
+ setFrameStyle(WinPanel | Sunken);
+ QGridLayout *top = new QGridLayout(this, 1, 1, 5, 0);
+ top->setColSpacing(1, 4);
+ QFont f("courier", font().pointSize());
+
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ bool debugging = Main::programmerGroup().isDebugger();
+ uint row = 0;
+ if ( rdata.nbBanks!=1 ) {
+ if ( data.is18Family() ) {
+ if ( (i/2)==0 ) {
+ QString title = ((i%2)==0 ? i18n("Access Bank (low)") : i18n("Access Bank (high)"));
+ QLabel *label = new QLabel(title, this);
+ label->setAlignment(AlignCenter);
+ top->addMultiCellWidget(label, row,row, 0,6, AlignHCenter);
+ } else {
+ _bankCombo = new QComboBox(this);
+ for (uint k=1; k<2*rdata.nbBanks-1; k++) {
+ _bankCombo->insertItem((k%2)==0 ? i18n("Bank %1 (low)").arg(k/2) : i18n("Bank %1 (high)").arg(k/2));
+ }
+ if ( _bindex==3 ) _bankCombo->setCurrentItem(1);
+ connect(_bankCombo, SIGNAL(activated(int)), SLOT(bankChanged()));
+ top->addMultiCellWidget(_bankCombo, row,row, 0,6, AlignHCenter);
+ }
+ } else {
+ QLabel *label = new QLabel(i18n("Bank %1").arg(i), this);
+ label->setAlignment(AlignCenter);
+ top->addMultiCellWidget(label, row,row, 0,6, AlignHCenter);
+ }
+ row++;
+ top->setRowSpacing(row, 5);
+ row++;
+ }
+
+ KIconLoader loader;
+ QPixmap readIcon = loader.loadIcon("viewmag", KIcon::Small);
+ QPixmap editIcon = loader.loadIcon("edit", KIcon::Small);
+ uint nb;
+ if ( !data.is18Family() ) nb = rdata.nbRegistersPerBank();
+ else nb = kMax(rdata.accessBankSplit, rdata.nbRegistersPerBank() - rdata.accessBankSplit);
+ _registers.resize(nb);
+ for (uint k=0; k<nb; k++) {
+ _registers[k].alabel = new QLabel(this);
+ _registers[k].alabel->setFont(f);
+ top->addWidget(_registers[k].alabel, row, 0);
+ if (debugging) {
+ _registers[k].button = new PopupButton(this);
+ _registers[k].button->appendItem(i18n("Read"), readIcon, ReadId);
+ _registers[k].button->appendItem(i18n("Edit"), editIcon, EditId);
+ _registers[k].button->appendItem(i18n("Watch"), WatchId);
+ connect(_registers[k].button, SIGNAL(activated(int)), SLOT(buttonActivated(int)));
+ top->addWidget(_registers[k].button, row, 2);
+ _registers[k].edit = new Register::LineEdit(this);
+ connect(_registers[k].edit, SIGNAL(modified()), SLOT(write()));
+ _registers[k].edit->setFont(f);
+ top->addWidget(_registers[k].edit, row, 6);
+ } else {
+ _registers[k].label = new QLabel(this);
+ top->addWidget(_registers[k].label, row, 2);
+ }
+ row++;
+ }
+
+ if (debugging) {
+ top->setColSpacing(3, 5);
+ top->setColSpacing(5, 5);
+ }
+ top->setRowStretch(row, 1);
+
+ updateRegisterAddresses();
+}
+
+void Pic::BankWidget::bankChanged()
+{
+ updateRegisterAddresses();
+ updateView();
+}
+
+uint Pic::BankWidget::bank() const
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ if ( !data.is18Family() ) return _bindex;
+ if ( _bindex==0 ) return 0;
+ const Pic::RegistersData &rdata = data.registersData();
+ if ( _bindex==1 ) return rdata.nbBanks - 1;
+ return (_bankCombo->currentItem()+1)/2;
+}
+
+uint Pic::BankWidget::nbRegisters() const
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ if ( !data.is18Family() ) return rdata.nbRegistersPerBank();
+ if ( _bindex==0 || (_bankCombo && _bankCombo->currentItem()==2*int(rdata.nbBanks)-3) ) return rdata.accessBankSplit;
+ if ( _bindex==1 || (_bankCombo && _bankCombo->currentItem()==0) ) return rdata.nbRegistersPerBank() - rdata.accessBankSplit;
+ return rdata.nbRegistersPerBank() / 2;
+}
+
+uint Pic::BankWidget::indexOffset() const
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ uint offset = bank() * rdata.nbRegistersPerBank();
+ if ( !data.is18Family() ) return offset;
+ if ( _bindex==0 || (_bankCombo && (_bankCombo->currentItem()%2)==1) ) return offset;
+ if ( _bindex==1 || (_bankCombo && _bankCombo->currentItem()==0) ) return offset + rdata.accessBankSplit;
+ return offset + rdata.nbRegistersPerBank()/2;
+}
+
+void Pic::BankWidget::updateRegisterAddresses()
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ uint nbChars = rdata.nbCharsAddress();
+ uint nb = nbRegisters();
+ uint offset = indexOffset();
+ for (uint k=0; k<_registers.count(); k++) {
+ if ( k<nb ) {
+ _registers[k].alabel->show();
+ _registers[k].address = rdata.addressFromIndex(offset + k);
+ _registers[k].alabel->setText(toHexLabel(_registers[k].address, nbChars) + ":");
+ } else _registers[k].alabel->hide();
+ }
+}
+
+void Pic::BankWidget::buttonActivated(int id)
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ for (uint i=0; i<_registers.count(); i++) {
+ if ( sender()!=_registers[i].button ) continue;
+ Register::TypeData rtd(_registers[i].address, rdata.nbChars());
+ switch (id) {
+ case ReadId: Debugger::manager->readRegister(rtd); break;
+ case EditId:
+ _registers[i].edit->selectAll();
+ _registers[i].edit->setFocus();
+ break;
+ case WatchId: {
+ bool isWatched = Register::list().isWatched(rtd);
+ Debugger::manager->setRegisterWatched(rtd, !isWatched);
+ break;
+ }
+ }
+ break;
+ }
+}
+
+void Pic::BankWidget::write()
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ for (uint i=0; i<_registers.count(); i++) {
+ if ( sender()!=_registers[i].edit ) continue;
+ Register::TypeData rtd(_registers[i].address, rdata.nbChars());
+ Debugger::manager->writeRegister(rtd, _registers[i].edit->value());
+ break;
+ }
+}
+
+void Pic::BankWidget::updateView()
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ const Pic::RegistersData &rdata = data.registersData();
+ bool active = ( Main::programmerState()==Programmer::Halted );
+ const Coff::Object *coff = Debugger::manager->coff();
+ uint nb = nbRegisters();
+ for (uint i=0; i<_registers.count(); i++) {
+ uint address = _registers[i].address;
+ Device::RegisterProperties rp = rdata.properties(address);
+ QString label = rdata.label(address);
+ Register::TypeData rtd(address, rdata.nbChars());
+ bool isWatched = Register::list().isWatched(rtd);
+ if (coff) {
+ QString name = coff->variableName(address);
+ if ( !name.isEmpty() ) label = "<" + name + ">";
+ }
+ if (_registers[i].button) {
+ if ( i<nb ) {
+ _registers[i].button->show();
+ _registers[i].button->setText(label);
+ if (isWatched) {
+ QFont f = _registers[i].button->font();
+ f.setBold(true);
+ _registers[i].button->setFont(f);
+ } else _registers[i].button->unsetFont();
+ _registers[i].button->popup()->setItemEnabled(ReadId, active && (rp & Device::Readable));
+ _registers[i].button->popup()->setItemEnabled(EditId, active);
+ _registers[i].button->popup()->changeItem(WatchId, isWatched ? i18n("Stop Watching") : i18n("Watch"));
+ _registers[i].button->popup()->setItemEnabled(WatchId, rp & Device::Readable);
+ } else _registers[i].button->hide();
+ }
+ if (_registers[i].label) {
+ if ( i<nb ) {
+ _registers[i].label->show();
+ _registers[i].label->setText(label);
+ } else _registers[i].label->hide();
+ }
+ if (_registers[i].edit) {
+ if ( i<nb ) {
+ _registers[i].edit->show();
+ _registers[i].edit->setEnabled(active);
+ BitValue value = Register::list().value(rtd);
+ if ( value!=Register::list().oldValue(rtd) ) _registers[i].edit->setColor(red);
+ else _registers[i].edit->unsetColor();
+ _registers[i].edit->setValue(NumberBase::Hex, value, rdata.nbChars());
+ } else _registers[i].edit->hide();
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+Pic::RegisterView::RegisterView(QWidget *parent)
+ : Register::View(parent, "pic_register_view"),
+ _readAllButton(0), _clearAllButton(0)
+{
+ QVBoxLayout *vbox = new QVBoxLayout(this, 10, 10);
+ QHBoxLayout *hbox = new QHBoxLayout(vbox);
+
+ bool debugging = Main::programmerGroup().isDebugger();
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ uint nb = data.registersData().nbBanks;
+ if ( debugging && nb!=0 ) {
+ QWidget *w = new QWidget(this);
+ hbox->addWidget(w);
+ QGridLayout *grid = new QGridLayout(w, 1, 1, 0, 10);
+ _readAllButton = new QPushButton(i18n("Read All"), w);
+ connect(_readAllButton, SIGNAL(clicked()), Debugger::manager, SLOT(readAllRegisters()));
+ grid->addWidget(_readAllButton, 0, 0);
+ _clearAllButton = new QPushButton(i18n("Clear all watching"), w);
+ connect(_clearAllButton, SIGNAL(clicked()), SLOT(stopWatchAllRegisters()));
+ grid->addWidget(_clearAllButton, 0, 1);
+ grid->setColStretch(2, 1);
+ }
+
+ QHBoxLayout *hbox2 = 0;
+ if ( nb==0 ) {
+ QLabel *label = new QLabel(i18n("Registers information not available."), this);
+ vbox->addWidget(label);
+ } else {
+ hbox = new QHBoxLayout(vbox);
+ hbox2 = new QHBoxLayout(hbox);
+ hbox->addStretch(1);
+ if ( data.is18Family() ) {
+ nb = 2;
+ for (uint k=1; k<data.registersData().nbBanks-1; k++) {
+ if ( !data.registersData().isBankUsed(k) ) continue;
+ nb += 2;
+ break;
+ }
+ }
+ _banks.resize(nb);
+ for (uint i=0; i<nb; i++) {
+ _banks[i] = new BankWidget(i, this);
+ _banks[i]->show();
+ hbox2->addWidget(_banks[i]);
+ }
+ }
+ vbox->addStretch(1);
+}
+
+void Pic::RegisterView::updateView()
+{
+ if (_readAllButton) _readAllButton->setEnabled(Main::programmerState()==Programmer::Halted);
+ for (uint i=0; i<_banks.count(); i++) if (_banks[i]) _banks[i]->updateView();
+}
+
+void Pic::RegisterView::stopWatchAllRegisters()
+{
+ Debugger::manager->stopWatchAll();
+}
+
+//----------------------------------------------------------------------------
+Pic::RegisterListViewItem::RegisterListViewItem(const Register::TypeData &data, KListViewItem *parent)
+ : Register::ListViewItem(data, parent)
+{}
+
+uint Pic::RegisterListViewItem::nbCharsAddress() const
+{
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ return data.registersData().nbCharsAddress();
+}
+
+QString Pic::RegisterListViewItem::label() const
+{
+ if ( _data.type()!=Register::Regular ) return _data.name();
+ const Coff::Object *coff = Debugger::manager->coff();
+ if (coff) {
+ QString name = coff->variableName(_data.address());
+ if ( !name.isEmpty() ) return "<" + name + ">";
+ }
+ const Pic::Data &data = static_cast<const Pic::Data &>(*Main::deviceData());
+ return data.registersData().label(_data.address());
+}
diff --git a/src/devices/pic/gui/pic_register_view.h b/src/devices/pic/gui/pic_register_view.h
new file mode 100644
index 0000000..f5b9d4b
--- /dev/null
+++ b/src/devices/pic/gui/pic_register_view.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * Copyright (C) 2006 Nicolas Hadacek <hadacek@kde.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ ***************************************************************************/
+#ifndef PIC_REGISTER_VIEW_H
+#define PIC_REGISTER_VIEW_H
+
+#include <qvaluevector.h>
+class QPushButton;
+class QCheckBox;
+class QLabel;
+class QComboBox;
+
+#include "devices/gui/register_view.h"
+#include "devices/pic/base/pic.h"
+#include "devices/pic/base/pic_register.h"
+class PopupButton;
+namespace Device { class RegisterHexWordEditor; }
+
+namespace Pic
+{
+//-----------------------------------------------------------------------------
+class BankWidget : public QFrame
+{
+Q_OBJECT
+public:
+ BankWidget(uint bank, QWidget *parent);
+ void updateView();
+
+private slots:
+ void buttonActivated(int id);
+ void write();
+ void bankChanged();
+
+private:
+ enum Id { ReadId, EditId, WatchId };
+ class Data {
+ public:
+ Data() : label(0), button(0), edit(0) {}
+ uint address;
+ QLabel *alabel, *label;
+ PopupButton *button;
+ Register::LineEdit *edit;
+ };
+ uint _bindex;
+ QComboBox *_bankCombo;
+ QValueVector<Data> _registers;
+
+ uint bank() const;
+ uint nbRegisters() const;
+ uint indexOffset() const;
+ void updateRegisterAddresses();
+};
+
+//-----------------------------------------------------------------------------
+class RegisterView : public Register::View
+{
+Q_OBJECT
+public:
+ RegisterView(QWidget *parent);
+ virtual void updateView();
+
+private slots:
+ void stopWatchAllRegisters();
+
+private:
+ QPushButton *_readAllButton, *_clearAllButton;
+ QValueVector<BankWidget *> _banks;
+};
+
+//-----------------------------------------------------------------------------
+class RegisterListViewItem : public Register::ListViewItem
+{
+public:
+ RegisterListViewItem(const Register::TypeData &data, KListViewItem *parent);
+
+private:
+ virtual uint nbCharsAddress() const;
+ virtual QString label() const;
+};
+
+} // namespace
+
+#endif