OpenASIP 2.2
Loading...
Searching...
No Matches
MemoryControl.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file MemoryControl.cc
26 *
27 * Definition of MemoryControl class.
28 *
29 * @author Jussi Nyk�nen 2004 (nykanen-no.spam-cs.tut.fi)
30 * @author Veli-Pekka J��skel�inen 2005 (vjaaskel-no.spam-cs.tut.fi)
31 * @note rating: red
32 */
33
34#include <string>
35#include <wx/clipbrd.h>
36#include "MemoryControl.hh"
37#include "tce_config.h"
38#include "WxConversion.hh"
39#include "Conversion.hh"
40#include "ErrorDialog.hh"
41#include "MemoryValueDialog.hh"
42#include "NumberControl.hh"
43#include "MemoryGridTable.hh"
44#include "Memory.hh"
45
46using std::string;
47
48const string MemoryControl::SIZE_MAU = "MAU";
49const string MemoryControl::SIZE_TWO_MAUS = "2 MAUs";
50const string MemoryControl::SIZE_FOUR_MAUS = "4 MAUs";
51const string MemoryControl::SIZE_EIGHT_MAUS = "8 MAUs";
52
53
54const string MemoryControl::DATA_BIN = "Binary";
55const string MemoryControl::DATA_HEX = "Hex";
56const string MemoryControl::DATA_SIGNED_INT = "Signed int";
57const string MemoryControl::DATA_UNSIGNED_INT = "Unsigned int";
58const string MemoryControl::DATA_FLOAT = "Float";
59const string MemoryControl::DATA_DOUBLE = "Double";
60
61const wxString MemoryControl::WIDTH_8 = _T("8");
62const wxString MemoryControl::WIDTH_16 = _T("16");
63const wxString MemoryControl::WIDTH_32 = _T("32");
64
65BEGIN_EVENT_TABLE(MemoryControl, wxPanel)
66
67 EVT_BUTTON(ID_BUTTON_GO_TO, MemoryControl::onGoTo)
68
69 EVT_CHOICE(ID_CHOICE_MODE, MemoryControl::onSizeModeChanged)
70 EVT_CHOICE(ID_CHOICE_DATA, MemoryControl::onDataModeChanged)
71 EVT_CHOICE(ID_CHOICE_WIDTH, MemoryControl::onWidthChanged)
72 EVT_GRID_CELL_LEFT_DCLICK(MemoryControl::onWriteMemory)
73 EVT_TEXT_ENTER(ID_ADDRESS_GO_TO, MemoryControl::onGoTo)
74
75 EVT_KEY_DOWN(MemoryControl::onChar)
76 EVT_CHAR(MemoryControl::onChar)
78
79
80/**
81 * Constructor.
82 *
83 * @param parent Parent window.
84 * @param memory The memory.
85 * @param start The start point of memory.
86 * @param end The end point of memory.
87 * @param id Id of the widget.
88 * @param pos Position of the widget.
89 * @param size Size of the widget.
90 * @param name Name of the widget.
91 */
93 wxWindow* parent,
94 Memory* memory,
95 wxWindowID id,
96 const wxPoint& pos,
97 const wxSize& size,
98 const wxString& name) :
99 wxPanel(parent, id, pos, size, wxTAB_TRAVERSAL, name),
100 memory_(memory), MAUSize_(memory->MAUSize()),
101 start_(memory->start()), end_(memory->end()),
102 grid_(NULL),
103 goToAddress_(_T("0")),
104 table_(NULL),
105 sizer_(NULL),
106 mausPerCell_(1) {
107
108 createContents();
109
110 dataMode_->Append(WxConversion::toWxString(DATA_BIN));
111 dataMode_->Append(WxConversion::toWxString(DATA_HEX));
112 dataMode_->Append(WxConversion::toWxString(DATA_SIGNED_INT));
113 dataMode_->Append(WxConversion::toWxString(DATA_UNSIGNED_INT));
114 dataMode_->Append(WxConversion::toWxString(DATA_FLOAT));
115 dataMode_->Append(WxConversion::toWxString(DATA_DOUBLE));
116
117 dataMode_->SetSelection(1);
118
119 sizeMode_->Append(WxConversion::toWxString(SIZE_MAU));
120 if (MAUSize_ <= 32) {
121 sizeMode_->Append(WxConversion::toWxString(SIZE_TWO_MAUS));
122 }
123 if (MAUSize_ <= 16) {
124 sizeMode_->Append(WxConversion::toWxString(SIZE_FOUR_MAUS));
125 }
126 if (MAUSize_ <= 8) {
127 sizeMode_->Append(WxConversion::toWxString(SIZE_EIGHT_MAUS));
128 }
129
130 sizeMode_->SetSelection(0);
131
132 widthMode_->Append(WIDTH_8);
133 widthMode_->Append(WIDTH_16);
134 widthMode_->Append(WIDTH_32);
135
136 widthMode_->SetSelection(0);
137
138 wxTextValidator hexValidator(wxFILTER_INCLUDE_CHAR_LIST, &goToAddress_);
139
140#if wxCHECK_VERSION(2, 5, 4)
141 wxArrayString includes;
142 includes.Add(_T("0"));
143 includes.Add(_T("1"));
144 includes.Add(_T("2"));
145 includes.Add(_T("3"));
146 includes.Add(_T("4"));
147 includes.Add(_T("5"));
148 includes.Add(_T("6"));
149 includes.Add(_T("7"));
150 includes.Add(_T("8"));
151 includes.Add(_T("9"));
152 includes.Add(_T("a"));
153 includes.Add(_T("b"));
154 includes.Add(_T("c"));
155 includes.Add(_T("d"));
156 includes.Add(_T("e"));
157 includes.Add(_T("f"));
158 includes.Add(_T("A"));
159 includes.Add(_T("B"));
160 includes.Add(_T("C"));
161 includes.Add(_T("D"));
162 includes.Add(_T("E"));
163 includes.Add(_T("F"));
164 hexValidator.SetIncludes(includes);
165#else
166 hexValidator.SetIncludeList(
167 wxStringList(
168 _T("0"), _T("1"), _T("2"), _T("3"), _T("4"), _T("5"), _T("6"),
169 _T("7"), _T("8"), _T("9"), _T("a"), _T("b"), _T("c"), _T("d"),
170 _T("e"), _T("f"), _T("A"), _T("B"), _T("C"), _T("D"), _T("E"),
171 _T("F"), NULL));
172#endif
173
174 FindWindow(ID_ADDRESS_GO_TO)->SetValidator(hexValidator);
175 updateView();
176}
177
178
179/**
180 * Destructor.
181 */
184
185
186/**
187 * Creates the components of the widget.
188 */
189void
191
192 sizer_ = new wxBoxSizer(wxVERTICAL);
193
195 grid_ = new wxGrid(this, ID_GRID, wxDefaultPosition, wxDefaultSize);
196 grid_->SetTable(table_);
197
198 grid_->SetDefaultCellAlignment(wxALIGN_RIGHT, wxALIGN_BOTTOM);
199 grid_->SetRowLabelSize(100);
200 grid_->SetDefaultCellFont(
201 wxFont(12, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
202 wxFONTWEIGHT_NORMAL));
203
204 grid_->EnableEditing(false);
205 grid_->DisableDragGridSize();
206 grid_->DisableDragRowSize();
207
208 sizer_->Add(grid_, 1, wxGROW|wxALL, 5);
209
210 dataMode_ = new wxChoice(
211 this, ID_CHOICE_DATA, wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
212 sizeMode_ = new wxChoice(
213 this, ID_CHOICE_MODE, wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
214 widthMode_ = new wxChoice(
215 this, ID_CHOICE_WIDTH, wxDefaultPosition, wxDefaultSize, 0, NULL, 0);
216
217 wxTextCtrl* addressCtrl = new wxTextCtrl(
218 this, ID_ADDRESS_GO_TO, wxT(""), wxDefaultPosition, wxDefaultSize,
219 wxTE_PROCESS_ENTER);
220
221 wxButton* goTo = new wxButton(this, ID_BUTTON_GO_TO, wxT("Go to"));
222 wxSizer* sizer1 = new wxBoxSizer(wxHORIZONTAL);
223
224 wxStaticText* columnsLabel = new wxStaticText(this, -1, _T("Columns:"));
225 wxStaticText* asLabel = new wxStaticText(this, -1, _T("as"));
226
227 sizer1->Add(sizeMode_, 0, wxALIGN_CENTER|wxALL, 5);
228 sizer1->Add(asLabel, 0, wxALIGN_CENTER|wxALL, 5);
229 sizer1->Add(dataMode_, 0, wxALIGN_CENTER|wxALL, 5);
230 sizer1->Add(addressCtrl, 0, wxALIGN_CENTER|wxALL, 5);
231 sizer1->Add(goTo, 0, wxALIGN_CENTER|wxALL, 5);
232 sizer1->Add(columnsLabel, 0, wxALIGN_CENTER|wxALL, 5);
233 sizer1->Add(widthMode_, 0, wxALIGN_CENTER|wxALL, 5);
234
235 sizer_->Add(sizer1, 0, wxALIGN_CENTER|wxALL, 5);
236
237 SetSizer(sizer_);
238 Fit();
239}
240
241
242/**
243 * Handles the event when Go to button is pushed.
244 *
245 * The row which represents the asked address is selected.
246 */
247void
248MemoryControl::onGoTo(wxCommandEvent&) {
249
250 TransferDataFromWindow();
251 if (goToAddress_ != _T("")) {
252
253 Word addr = 0;
254 try {
255 // add 0x to the beginning of the address string
256 goToAddress_ = _T("0x") + goToAddress_;
258 } catch (const NumberFormatException& n) {
259 string msg = "Invalid number: " +
261 ErrorDialog dialog(this, WxConversion::toWxString(msg));
262 dialog.ShowModal();
263 return;
264 }
265
266 if (addr >= end_) {
267 string msg = "Address " + WxConversion::toString(goToAddress_) +
268 " out of memory bounds.";
269 ErrorDialog dialog(this, WxConversion::toWxString(msg));
270 dialog.ShowModal();
271 return;
272 }
273
274 int row = 0;
275 int col = 0;
276 table_->findAddress(addr, row, col);
277 //grid_->SetCellBackgroundColour(row, col, *wxGREEN);
278 grid_->MakeCellVisible(row, col);
279 grid_->SetGridCursor(row, col);
280 updateView();
281 }
282}
283
284/**
285 * Updates the contents of the memory.
286 *
287 * Data is retrieved only for those area that is visible to user.
288 */
289void
291
292 unsigned digits = table_->sizeOfCell() * MAUSize_;
293
294 string dataMode = WxConversion::toString(dataMode_->GetStringSelection());
295
296 if (dataMode == DATA_HEX) {
297 digits = (digits / 4) + 3;
298 } else if (dataMode == DATA_SIGNED_INT ||
299 dataMode == DATA_UNSIGNED_INT) {
300
301 digits = (digits / 3) + 1;
302 } else if (dataMode == DATA_FLOAT ||
303 dataMode == DATA_DOUBLE) {
304
305 digits = 16;
306 }
307
308 grid_->SetDefaultColSize(digits * 12, true);
309 grid_->ForceRefresh();
310}
311
312
313/**
314 * Handles the event size in which data is shown is changed.
315 */
316void
318
320 string sizeMode = WxConversion::toString(sizeMode_->GetStringSelection());
321
322 if (sizeMode == SIZE_MAU) {
323 mausPerCell_ = 1;
325 } else if (sizeMode == SIZE_TWO_MAUS) {
326 mausPerCell_ = 2;
328 } else if (sizeMode == SIZE_FOUR_MAUS) {
329 mausPerCell_ = 4;
331 } else if (sizeMode == SIZE_EIGHT_MAUS) {
332 mausPerCell_ = 8;
334 }
335
336 updateView();
337}
338
339
340/**
341 * Handles the event when the data mode is changed.
342 */
343void
345
346 string dataMode = WxConversion::toString(dataMode_->GetStringSelection());
347
348 if (dataMode == DATA_BIN) {
350 } else if (dataMode == DATA_HEX) {
352 } else if (dataMode == DATA_SIGNED_INT) {
354 } else if (dataMode == DATA_UNSIGNED_INT) {
356 } else if (dataMode == DATA_FLOAT) {
358 } else if (dataMode == DATA_DOUBLE) {
360 }
361 updateView();
362}
363
364/**
365 * Handles the event when the size of the window is changed.
366 */
367void
368MemoryControl::onSize(wxSizeEvent& event) {
369 updateView();
370 event.Skip();
371}
372
373/**
374 * Handles the event when user double clicks a memory cell.
375 *
376 * A new dialog is opened in which user can type a new value for the cell.
377 */
378void
379MemoryControl::onWriteMemory(wxGridEvent& event) {
380
381 int column = event.GetCol();
382 int row = event.GetRow();
383
384 string stringValue =
385 WxConversion::toString(grid_->GetCellValue(row, column));
386
387 int value = 0;
388 MemoryValueDialog dialog(this, table_->sizeOfCell() * MAUSize_);
389 dialog.CenterOnParent();
390
391 try {
392 value = Conversion::toInt(stringValue);
393 dialog.setValue(value);
394 } catch (const NumberFormatException& n) {
395 // can not convert for some reason (do something?)
396 dialog.setValue(0);
397 }
398
399 if(dialog.ShowModal() == wxID_OK) {
400
401 if (dialog.mode() != NumberControl::MODE_DOUBLE) {
402 UIntWord memoryValue = dialog.intValue();
403 table_->writeValue(row, column, memoryValue);
404 } else {
405 DoubleWord memoryValue = dialog.doubleValue();
406 table_->writeValue(row, column, memoryValue);
407 }
408 updateView();
409 }
410
411}
412
413/**
414 * Handles the event when key is pressed.
415 *
416 * Two hardcoded keyboard commands currently exist: delete and copy.
417 *
418 * @param event Key event ot be handled.
419 */
420void
421MemoryControl::onChar(wxKeyEvent& event) {
422
423 if (event.GetKeyCode() == WXK_DELETE) {
424 if (grid_->IsSelection()) {
425 clearMemory();
426 }
427 } else if (event.m_controlDown &&
428 (event.GetKeyCode() == 'c' ||
429 event.GetKeyCode() == 'C' ||
430 event.GetKeyCode() == WXK_INSERT)) {
431
432 // Copy contents of the selected cells to the clipboard.
433 if (grid_->IsSelection()) {
435 }
436 }
437}
438
439
440/**
441 * Clears the contents of the selected cells, that is, the contents
442 * is set to zero.
443 */
444void
446
447 wxGridCellCoordsArray topLeft = grid_->GetSelectionBlockTopLeft();
448 wxGridCellCoordsArray botRight = grid_->GetSelectionBlockBottomRight();
449
450 int currentRow = topLeft[0].GetRow();
451 int currentCol = topLeft[0].GetCol();
452
453 int endRow = botRight[0].GetRow();
454 int endCol = botRight[0].GetCol();
455
456 while (currentRow <= endRow) {
457 currentCol = topLeft[0].GetCol();
458 while (currentCol <= endCol) {
459
460 UIntWord data = 0;
461 table_->writeValue(currentRow, currentCol, data);
462 currentCol++;
463 }
464 currentRow++;
465 }
466 updateView();
467
468}
469
470
471/**
472 * Sets the memory to display in the window.
473 *
474 * @param memory Memory to display.
475 */
476void
478
480 MAUSize_ = memory->MAUSize();
481 memory_ = memory;
482 start_ = memory->start();
483 end_ = memory->end();
484
486 grid_->SetTable(table_);
487
488 updateView();
489}
490
491
492/**
493 * Event handler for the grid width choicer.
494 */
495void
498 wxString width = widthMode_->GetStringSelection();
499 if (width == WIDTH_8) {
501 } else if (width == WIDTH_16) {
503 } else if (width == WIDTH_32) {
505 }
506 grid_->SetTable(table_);
507 updateView();
508}
509
510
511/**
512 * Copies contents of the selected cells to the clipboard.
513 */
514void
516
517 if (grid_ == NULL || !(grid_->IsSelection())) {
518 return;
519 }
520
521 if (wxTheClipboard->Open()) {
522
523 wxTextDataObject* data = new wxTextDataObject();
524 wxString contents;
525
526 wxGridCellCoordsArray topLs = grid_->GetSelectionBlockTopLeft();
527 wxGridCellCoordsArray bottomRs = grid_->GetSelectionBlockBottomRight();
528
529 for (unsigned i = 0; i < topLs.Count(); i++) {
530 if (i > 0) {
531 contents.Append(_T("\n"));
532 }
533 int row = topLs.Item(i).GetRow();
534 for (; row <= bottomRs.Item(i).GetRow(); row++) {
535 int col = topLs.Item(i).GetCol();
536 for (; col <= bottomRs.Item(i).GetCol(); col++) {
537 contents.Append(grid_->GetCellValue(row, col));
538 contents.Append(_T(" "));
539 }
540 contents.Append(_T("\n"));
541 }
542 }
543
544 data->SetText(contents);
545
546 wxTheClipboard->SetData(data);
547 wxTheClipboard->Close();
548 }
549}
550
551
552void
554 int cols = table_->GetNumberCols();
555 while (!highlights_.empty()) {
556 int row = *highlights_.begin() / cols;
557 int col = *highlights_.begin() % cols;
558 grid_->SetCellBackgroundColour(row, col, *wxWHITE);
559 highlights_.erase(highlights_.begin());
560 }
561}
562
563void
564MemoryControl::highlight(Word address, unsigned count, const wxColour& colour) {
565 if (count < 1 || address < start_ || address + count > end_) {
566 throw OutOfRange(__FILE__, __LINE__, __func__);
567 }
568
569 int cols = table_->GetNumberCols();
570 for (unsigned i = 0; i < count; i++) {
571 unsigned cell = (address - start_ + i) / mausPerCell_;
572 int row = cell / cols;
573 int col = cell % cols;
574 highlights_.push_back(cell);
575 grid_->SetCellBackgroundColour(row, col, colour);
576 }
577}
#define __func__
Word UIntWord
Definition BaseType.hh:144
double DoubleWord
Definition BaseType.hh:166
END_EVENT_TABLE() using namespace IDF
EVT_BUTTON(ID_EDIT_ARCH_PORT, FUImplementationDialog::onEditArchitecturePort) EVT_BUTTON(ID_ADD_EXTERNAL_PORT
static int toInt(const T &source)
MemoryGridTable * table_
Grid contents.
void highlight(Word address, unsigned count, const wxColour &colour)
static const std::string DATA_SIGNED_INT
Data label for signed int format.
void onGoTo(wxCommandEvent &event)
static const wxString WIDTH_16
Table width label for 16 column mode.
wxString goToAddress_
Go to address.
Word end_
End point of memory.
static const std::string DATA_UNSIGNED_INT
Data label for unsigned int format.
Word start_
Start point of memory.
void setMemory(Memory *memory)
static const std::string SIZE_MAU
Size label for byte size.
static const std::string DATA_DOUBLE
Data label for double format.
Memory * memory_
Used for access to memory contents.
void onChar(wxKeyEvent &event)
static const wxString WIDTH_32
Table width label for 32 column mode.
static const wxString WIDTH_8
Table width label for 8 column mode.
virtual ~MemoryControl()
void onSizeModeChanged(wxCommandEvent &)
static const std::string DATA_BIN
Data label for binary format.
static const std::string SIZE_EIGHT_MAUS
Size label for word size.
wxGrid * grid_
Grid in which the contents of the memory is written.
wxBoxSizer * sizer_
Top level sizer of the window.
void onSize(wxSizeEvent &)
static const std::string DATA_FLOAT
Data label for float format.
void onWriteMemory(wxGridEvent &event)
static const std::string SIZE_FOUR_MAUS
Size label for word size.
wxChoice * sizeMode_
Mode of the data size.
std::vector< unsigned > highlights_
int MAUSize_
Size of the minimum addressable unit.
wxChoice * widthMode_
Grid width choicer.
wxChoice * dataMode_
Mode of the data in the cells.
static const std::string DATA_HEX
Data label for hexa format.
void onWidthChanged(wxCommandEvent &)
static const std::string SIZE_TWO_MAUS
Size label for half word size.
void onDataModeChanged(wxCommandEvent &)
unsigned mausPerCell_
Number of maus displayed in a cell.
void writeValue(int row, int column, UIntWord memoryValue)
void setNumberOfColumns(unsigned columns)
virtual int GetNumberCols()
void findAddress(Word addr, int &row, int &col)
unsigned sizeOfCell() const
void setDataMode(DataMode mode)
void setSizeMode(SizeMode mode)
void setValue(int value)
virtual ULongWord end()
Definition Memory.hh:117
virtual ULongWord MAUSize()
Definition Memory.hh:118
virtual ULongWord start()
Definition Memory.hh:116
static const long MODE_DOUBLE
Style flag for double mode availability.
static wxString toWxString(const std::string &source)
static std::string toString(const wxString &source)