2005-08-30 17:51:26 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// SSSS tt lll lll
|
|
|
|
// SS SS tt ll ll
|
|
|
|
// SS tttttt eeee ll ll aaaa
|
|
|
|
// SSSS tt ee ee ll ll aa
|
|
|
|
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
|
|
|
// SS SS tt ee ll ll aa aa
|
|
|
|
// SSSS ttt eeeee llll llll aaaaa
|
|
|
|
//
|
2008-02-06 13:45:24 +00:00
|
|
|
// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team
|
2005-08-30 17:51:26 +00:00
|
|
|
//
|
|
|
|
// See the file "license" for information on usage and redistribution of
|
|
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
|
|
//
|
2008-06-19 19:15:44 +00:00
|
|
|
// $Id: RamWidget.cxx,v 1.19 2008-06-19 19:15:44 stephena Exp $
|
2005-08-30 17:51:26 +00:00
|
|
|
//
|
|
|
|
// Based on code from ScummVM - Scumm Interpreter
|
|
|
|
// Copyright (C) 2002-2004 The ScummVM project
|
|
|
|
//============================================================================
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
|
2007-09-03 18:37:24 +00:00
|
|
|
#include "DataGridWidget.hxx"
|
|
|
|
#include "EditTextWidget.hxx"
|
2005-08-30 17:51:26 +00:00
|
|
|
#include "FrameBuffer.hxx"
|
|
|
|
#include "GuiObject.hxx"
|
|
|
|
#include "InputTextDialog.hxx"
|
2007-09-03 18:37:24 +00:00
|
|
|
#include "OSystem.hxx"
|
2005-08-30 17:51:26 +00:00
|
|
|
#include "RamDebug.hxx"
|
2007-09-03 18:37:24 +00:00
|
|
|
#include "Widget.hxx"
|
|
|
|
|
2005-08-30 17:51:26 +00:00
|
|
|
#include "RamWidget.hxx"
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
RamWidget::RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
2006-02-22 17:38:04 +00:00
|
|
|
: Widget(boss, font, x, y, 16, 16),
|
2005-08-30 17:51:26 +00:00
|
|
|
CommandSender(boss),
|
|
|
|
myUndoAddress(-1),
|
|
|
|
myUndoValue(-1)
|
|
|
|
{
|
2006-11-06 00:52:04 +00:00
|
|
|
_type = kRamWidget;
|
|
|
|
|
2005-08-30 17:51:26 +00:00
|
|
|
const int fontWidth = font.getMaxCharWidth(),
|
|
|
|
fontHeight = font.getFontHeight(),
|
|
|
|
lineHeight = font.getLineHeight(),
|
2006-03-23 16:16:33 +00:00
|
|
|
bwidth = 44,//font.getStringWidth("Undo "),
|
|
|
|
bheight = lineHeight + 2;
|
2005-08-30 17:51:26 +00:00
|
|
|
int xpos, ypos, lwidth;
|
|
|
|
|
|
|
|
// Create a 16x8 grid holding byte values (16 x 8 = 128 RAM bytes) with labels
|
|
|
|
xpos = x; ypos = y + lineHeight; lwidth = 4 * fontWidth;
|
|
|
|
myRamGrid = new DataGridWidget(boss, font, xpos + lwidth, ypos,
|
|
|
|
16, 8, 2, 8, kBASE_16);
|
|
|
|
myRamGrid->setTarget(this);
|
|
|
|
addFocusWidget(myRamGrid);
|
|
|
|
|
|
|
|
// Create actions buttons to the left of the RAM grid
|
|
|
|
xpos += lwidth + myRamGrid->getWidth() + 4;
|
2006-02-22 17:38:04 +00:00
|
|
|
myUndoButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
|
Huge GUI-related changes. The GUI in launcher/options/command modes
is now fully navigable via the keyboard be means of 'tab-like'
functionality. This means that eventually systems without a keyboard
will also be able to navigate the interface without resorting to the
buggy joymouse code (which is soon to be removed).
Laid the infrastructure for remapping GUI events, whereby (for example)
a widget checks for Event::UISelect for 'doing its thing', vs. looking
at the Enter/Return key. So widgets now respond to events, and events
can (eventually) be remapped to *any* device.
Currently, these UI events are as follows:
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
UIPrevDir, UINavNext, UINavPrev, UITabNext, UITabPrev, UISelect
At present, they're hardcoded to key events only, so pressing 'Return'
will send a UISelect, cursor up a UIUp, etc. When the remapping code
is complete, *any* input will be able to send these events, and that
remapping will be distinct from emulation mode. So, for example,
cursor up in GUI mode might generate a UIUp event, but in emulation
mode might generate a left joystick up event.
Modified 'tab' key while in emulation mode to only enter the options
menu. Once inside the menu, the tab key acts as navigation between
elements, and exiting the options menu requires navigating to the
'Exit menu' button.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1100 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2006-05-04 17:45:25 +00:00
|
|
|
"Undo", kUndoCmd);
|
2005-08-30 17:51:26 +00:00
|
|
|
myUndoButton->setTarget(this);
|
|
|
|
|
2006-03-23 16:16:33 +00:00
|
|
|
ypos += bheight + 4;
|
2006-02-22 17:38:04 +00:00
|
|
|
myRevertButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
|
Huge GUI-related changes. The GUI in launcher/options/command modes
is now fully navigable via the keyboard be means of 'tab-like'
functionality. This means that eventually systems without a keyboard
will also be able to navigate the interface without resorting to the
buggy joymouse code (which is soon to be removed).
Laid the infrastructure for remapping GUI events, whereby (for example)
a widget checks for Event::UISelect for 'doing its thing', vs. looking
at the Enter/Return key. So widgets now respond to events, and events
can (eventually) be remapped to *any* device.
Currently, these UI events are as follows:
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
UIPrevDir, UINavNext, UINavPrev, UITabNext, UITabPrev, UISelect
At present, they're hardcoded to key events only, so pressing 'Return'
will send a UISelect, cursor up a UIUp, etc. When the remapping code
is complete, *any* input will be able to send these events, and that
remapping will be distinct from emulation mode. So, for example,
cursor up in GUI mode might generate a UIUp event, but in emulation
mode might generate a left joystick up event.
Modified 'tab' key while in emulation mode to only enter the options
menu. Once inside the menu, the tab key acts as navigation between
elements, and exiting the options menu requires navigating to the
'Exit menu' button.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1100 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2006-05-04 17:45:25 +00:00
|
|
|
"Rev", kRevertCmd);
|
2005-08-30 17:51:26 +00:00
|
|
|
myRevertButton->setTarget(this);
|
|
|
|
|
|
|
|
ypos += 2 * bheight + 2;
|
2006-02-22 17:38:04 +00:00
|
|
|
mySearchButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
|
Huge GUI-related changes. The GUI in launcher/options/command modes
is now fully navigable via the keyboard be means of 'tab-like'
functionality. This means that eventually systems without a keyboard
will also be able to navigate the interface without resorting to the
buggy joymouse code (which is soon to be removed).
Laid the infrastructure for remapping GUI events, whereby (for example)
a widget checks for Event::UISelect for 'doing its thing', vs. looking
at the Enter/Return key. So widgets now respond to events, and events
can (eventually) be remapped to *any* device.
Currently, these UI events are as follows:
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
UIPrevDir, UINavNext, UINavPrev, UITabNext, UITabPrev, UISelect
At present, they're hardcoded to key events only, so pressing 'Return'
will send a UISelect, cursor up a UIUp, etc. When the remapping code
is complete, *any* input will be able to send these events, and that
remapping will be distinct from emulation mode. So, for example,
cursor up in GUI mode might generate a UIUp event, but in emulation
mode might generate a left joystick up event.
Modified 'tab' key while in emulation mode to only enter the options
menu. Once inside the menu, the tab key acts as navigation between
elements, and exiting the options menu requires navigating to the
'Exit menu' button.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1100 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2006-05-04 17:45:25 +00:00
|
|
|
"Srch", kSearchCmd);
|
2005-08-30 17:51:26 +00:00
|
|
|
mySearchButton->setTarget(this);
|
|
|
|
|
2006-03-23 16:16:33 +00:00
|
|
|
ypos += bheight + 4;
|
2006-02-22 17:38:04 +00:00
|
|
|
myCompareButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
|
Huge GUI-related changes. The GUI in launcher/options/command modes
is now fully navigable via the keyboard be means of 'tab-like'
functionality. This means that eventually systems without a keyboard
will also be able to navigate the interface without resorting to the
buggy joymouse code (which is soon to be removed).
Laid the infrastructure for remapping GUI events, whereby (for example)
a widget checks for Event::UISelect for 'doing its thing', vs. looking
at the Enter/Return key. So widgets now respond to events, and events
can (eventually) be remapped to *any* device.
Currently, these UI events are as follows:
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
UIPrevDir, UINavNext, UINavPrev, UITabNext, UITabPrev, UISelect
At present, they're hardcoded to key events only, so pressing 'Return'
will send a UISelect, cursor up a UIUp, etc. When the remapping code
is complete, *any* input will be able to send these events, and that
remapping will be distinct from emulation mode. So, for example,
cursor up in GUI mode might generate a UIUp event, but in emulation
mode might generate a left joystick up event.
Modified 'tab' key while in emulation mode to only enter the options
menu. Once inside the menu, the tab key acts as navigation between
elements, and exiting the options menu requires navigating to the
'Exit menu' button.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1100 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2006-05-04 17:45:25 +00:00
|
|
|
"Cmp", kCmpCmd);
|
2005-08-30 17:51:26 +00:00
|
|
|
myCompareButton->setTarget(this);
|
|
|
|
|
2006-03-23 16:16:33 +00:00
|
|
|
ypos += bheight + 4;
|
2006-02-22 17:38:04 +00:00
|
|
|
myRestartButton = new ButtonWidget(boss, font, xpos, ypos, bwidth, bheight,
|
Huge GUI-related changes. The GUI in launcher/options/command modes
is now fully navigable via the keyboard be means of 'tab-like'
functionality. This means that eventually systems without a keyboard
will also be able to navigate the interface without resorting to the
buggy joymouse code (which is soon to be removed).
Laid the infrastructure for remapping GUI events, whereby (for example)
a widget checks for Event::UISelect for 'doing its thing', vs. looking
at the Enter/Return key. So widgets now respond to events, and events
can (eventually) be remapped to *any* device.
Currently, these UI events are as follows:
UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown,
UIPrevDir, UINavNext, UINavPrev, UITabNext, UITabPrev, UISelect
At present, they're hardcoded to key events only, so pressing 'Return'
will send a UISelect, cursor up a UIUp, etc. When the remapping code
is complete, *any* input will be able to send these events, and that
remapping will be distinct from emulation mode. So, for example,
cursor up in GUI mode might generate a UIUp event, but in emulation
mode might generate a left joystick up event.
Modified 'tab' key while in emulation mode to only enter the options
menu. Once inside the menu, the tab key acts as navigation between
elements, and exiting the options menu requires navigating to the
'Exit menu' button.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1100 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2006-05-04 17:45:25 +00:00
|
|
|
"Rset", kRestartCmd);
|
2005-08-30 17:51:26 +00:00
|
|
|
myRestartButton->setTarget(this);
|
|
|
|
|
|
|
|
// Labels for RAM grid
|
|
|
|
xpos = x; ypos = y + lineHeight;
|
|
|
|
for(int row = 0; row < 8; ++row)
|
|
|
|
{
|
2006-02-22 17:38:04 +00:00
|
|
|
new StaticTextWidget(boss, font, xpos-2, ypos + row*lineHeight + 2,
|
|
|
|
lwidth-2, fontHeight,
|
|
|
|
Debugger::to_hex_8(row*16 + kRamStart) + string(":"),
|
|
|
|
kTextAlignLeft);
|
2005-08-30 17:51:26 +00:00
|
|
|
}
|
|
|
|
for(int col = 0; col < 16; ++col)
|
|
|
|
{
|
2006-02-22 17:38:04 +00:00
|
|
|
new StaticTextWidget(boss, font, xpos + col*myRamGrid->colWidth() + lwidth + 8,
|
|
|
|
ypos - lineHeight,
|
|
|
|
fontWidth, fontHeight,
|
|
|
|
Debugger::to_hex_4(col),
|
|
|
|
kTextAlignLeft);
|
2005-08-30 17:51:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
xpos = x + 10; ypos += 9 * lineHeight;
|
2006-02-22 17:38:04 +00:00
|
|
|
new StaticTextWidget(boss, font, xpos, ypos,
|
|
|
|
6*fontWidth, fontHeight,
|
|
|
|
"Label:", kTextAlignLeft);
|
2005-08-30 17:51:26 +00:00
|
|
|
xpos += 6*fontWidth + 5;
|
2006-02-22 17:38:04 +00:00
|
|
|
myLabel = new EditTextWidget(boss, font, xpos, ypos-2, 17*fontWidth,
|
|
|
|
lineHeight, "");
|
2005-08-30 17:51:26 +00:00
|
|
|
myLabel->setEditable(false);
|
|
|
|
|
|
|
|
xpos += 17*fontWidth + 20;
|
2006-02-22 17:38:04 +00:00
|
|
|
new StaticTextWidget(boss, font, xpos, ypos, 4*fontWidth, fontHeight,
|
|
|
|
"Dec:", kTextAlignLeft);
|
2005-08-30 17:51:26 +00:00
|
|
|
xpos += 4*fontWidth + 5;
|
2006-02-22 17:38:04 +00:00
|
|
|
myDecValue = new EditTextWidget(boss, font, xpos, ypos-2, 4*fontWidth,
|
|
|
|
lineHeight, "");
|
2005-08-30 17:51:26 +00:00
|
|
|
myDecValue->setEditable(false);
|
|
|
|
|
|
|
|
xpos += 4*fontWidth + 20;
|
2006-02-22 17:38:04 +00:00
|
|
|
new StaticTextWidget(boss, font, xpos, ypos, 4*fontWidth, fontHeight,
|
|
|
|
"Bin:", kTextAlignLeft);
|
2005-08-30 17:51:26 +00:00
|
|
|
xpos += 4*fontWidth + 5;
|
2006-02-22 17:38:04 +00:00
|
|
|
myBinValue = new EditTextWidget(boss, font, xpos, ypos-2, 9*fontWidth,
|
|
|
|
lineHeight, "");
|
2005-08-30 17:51:26 +00:00
|
|
|
myBinValue->setEditable(false);
|
|
|
|
|
2005-11-27 22:37:25 +00:00
|
|
|
// Calculate real dimensions
|
|
|
|
_w = lwidth + myRamGrid->getWidth();
|
|
|
|
_h = ypos + lineHeight - y;
|
|
|
|
|
2005-08-30 17:51:26 +00:00
|
|
|
// Inputbox which will pop up when searching RAM
|
2008-06-19 19:15:44 +00:00
|
|
|
StringList labels;
|
|
|
|
labels.push_back("Search: ");
|
|
|
|
myInputBox = new InputTextDialog(boss, font, labels);
|
2005-08-30 17:51:26 +00:00
|
|
|
myInputBox->setTarget(this);
|
|
|
|
|
|
|
|
// Start with these buttons disabled
|
|
|
|
myCompareButton->clearFlags(WIDGET_ENABLED);
|
|
|
|
myRestartButton->clearFlags(WIDGET_ENABLED);
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
RamWidget::~RamWidget()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
|
|
|
{
|
|
|
|
// We simply change the values in the ByteGridWidget
|
|
|
|
// It will then send the 'kDGItemDataChangedCmd' signal to change the actual
|
|
|
|
// memory location
|
|
|
|
int addr, value;
|
|
|
|
|
2008-06-13 13:14:52 +00:00
|
|
|
RamDebug& dbg = instance().debugger().ramDebug();
|
2005-08-30 17:51:26 +00:00
|
|
|
switch(cmd)
|
|
|
|
{
|
|
|
|
case kDGItemDataChangedCmd:
|
|
|
|
addr = myRamGrid->getSelectedAddr();
|
|
|
|
value = myRamGrid->getSelectedValue();
|
|
|
|
|
|
|
|
myUndoAddress = addr;
|
|
|
|
myUndoValue = dbg.read(addr);
|
|
|
|
|
|
|
|
dbg.write(addr, value);
|
2008-06-13 13:14:52 +00:00
|
|
|
myDecValue->setEditString(instance().debugger().valueToString(value, kBASE_10));
|
|
|
|
myBinValue->setEditString(instance().debugger().valueToString(value, kBASE_2));
|
2005-08-30 17:51:26 +00:00
|
|
|
myRevertButton->setEnabled(true);
|
|
|
|
myUndoButton->setEnabled(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kDGSelectionChangedCmd:
|
2008-02-24 16:51:52 +00:00
|
|
|
{
|
2005-08-30 17:51:26 +00:00
|
|
|
addr = myRamGrid->getSelectedAddr();
|
|
|
|
value = myRamGrid->getSelectedValue();
|
|
|
|
|
2008-02-24 16:51:52 +00:00
|
|
|
myLabel->setEditString(
|
2008-06-13 13:14:52 +00:00
|
|
|
instance().debugger().equates().getLabel(addr+kRamStart, true));
|
|
|
|
myDecValue->setEditString(instance().debugger().valueToString(value, kBASE_10));
|
|
|
|
myBinValue->setEditString(instance().debugger().valueToString(value, kBASE_2));
|
2005-08-30 17:51:26 +00:00
|
|
|
break;
|
2008-02-24 16:51:52 +00:00
|
|
|
}
|
2005-08-30 17:51:26 +00:00
|
|
|
|
|
|
|
case kRevertCmd:
|
|
|
|
for(unsigned int i = 0; i < kRamSize; i++)
|
|
|
|
dbg.write(i, myOldValueList[i]);
|
|
|
|
fillGrid(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kUndoCmd:
|
|
|
|
dbg.write(myUndoAddress, myUndoValue);
|
|
|
|
myUndoButton->setEnabled(false);
|
|
|
|
fillGrid(false);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kSearchCmd:
|
2008-06-19 19:15:44 +00:00
|
|
|
showInputBox(kSValEntered);
|
2005-08-30 17:51:26 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kCmpCmd:
|
2008-06-19 19:15:44 +00:00
|
|
|
showInputBox(kCValEntered);
|
2005-08-30 17:51:26 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case kRestartCmd:
|
|
|
|
doRestart();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kSValEntered:
|
|
|
|
{
|
|
|
|
const string& result = doSearch(myInputBox->getResult());
|
|
|
|
if(result != "")
|
|
|
|
myInputBox->setTitle(result);
|
|
|
|
else
|
2008-06-13 13:14:52 +00:00
|
|
|
parent().removeDialog();
|
2005-08-30 17:51:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case kCValEntered:
|
|
|
|
{
|
|
|
|
const string& result = doCompare(myInputBox->getResult());
|
|
|
|
if(result != "")
|
|
|
|
myInputBox->setTitle(result);
|
|
|
|
else
|
2008-06-13 13:14:52 +00:00
|
|
|
parent().removeDialog();
|
2005-08-30 17:51:26 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void RamWidget::loadConfig()
|
|
|
|
{
|
|
|
|
//cerr << "RamWidget::loadConfig()\n";
|
|
|
|
fillGrid(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void RamWidget::fillGrid(bool updateOld)
|
|
|
|
{
|
|
|
|
IntArray alist;
|
|
|
|
IntArray vlist;
|
|
|
|
BoolArray changed;
|
|
|
|
|
|
|
|
if(updateOld) myOldValueList.clear();
|
|
|
|
|
2008-06-13 13:14:52 +00:00
|
|
|
RamDebug& dbg = instance().debugger().ramDebug();
|
2005-08-30 17:51:26 +00:00
|
|
|
|
|
|
|
RamState state = (RamState&) dbg.getState();
|
|
|
|
RamState oldstate = (RamState&) dbg.getOldState();
|
|
|
|
|
|
|
|
vlist = state.ram;
|
|
|
|
if(updateOld) myOldValueList = state.ram;
|
|
|
|
|
|
|
|
for(unsigned int i = 0; i < 16*8; i++)
|
|
|
|
{
|
|
|
|
alist.push_back(i);
|
|
|
|
changed.push_back(state.ram[i] != oldstate.ram[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
myRamGrid->setList(alist, vlist, changed);
|
|
|
|
if(updateOld)
|
|
|
|
{
|
|
|
|
myRevertButton->setEnabled(false);
|
|
|
|
myUndoButton->setEnabled(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2008-06-19 19:15:44 +00:00
|
|
|
void RamWidget::showInputBox(int cmd)
|
|
|
|
{
|
|
|
|
// Add inputbox in the middle of the RAM widget
|
|
|
|
uInt32 tx, ty;
|
|
|
|
dialog().surface().getPos(tx, ty);
|
|
|
|
tx += getAbsX() + ((getWidth() - myInputBox->getWidth()) >> 1);
|
|
|
|
ty += getAbsY() + ((getHeight() - myInputBox->getHeight()) >> 1);
|
|
|
|
myInputBox->show(tx, ty);
|
|
|
|
myInputBox->setEditString("");
|
|
|
|
myInputBox->setTitle("");
|
|
|
|
myInputBox->setFocus(0);
|
|
|
|
myInputBox->setEmitSignal(cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
string RamWidget::doSearch(const string& str)
|
2005-08-30 17:51:26 +00:00
|
|
|
{
|
|
|
|
bool comparisonSearch = true;
|
|
|
|
|
|
|
|
if(str.length() == 0)
|
|
|
|
{
|
|
|
|
// An empty field means return all memory locations
|
|
|
|
comparisonSearch = false;
|
|
|
|
}
|
|
|
|
else if(str.find_first_of("+-", 0) != string::npos)
|
|
|
|
{
|
|
|
|
// Don't accept these characters here, only in compare
|
|
|
|
return "Invalid input +|-";
|
|
|
|
}
|
|
|
|
|
2008-06-13 13:14:52 +00:00
|
|
|
int searchVal = instance().debugger().stringToValue(str);
|
2005-08-30 17:51:26 +00:00
|
|
|
|
|
|
|
// Clear the search array of previous items
|
|
|
|
mySearchAddr.clear();
|
|
|
|
mySearchValue.clear();
|
|
|
|
|
|
|
|
// Now, search all memory locations for this value, and add it to the
|
|
|
|
// search array
|
2008-06-13 13:14:52 +00:00
|
|
|
RamDebug& dbg = instance().debugger().ramDebug();
|
2005-08-30 17:51:26 +00:00
|
|
|
for(int addr = 0; addr < kRamSize; ++addr)
|
|
|
|
{
|
|
|
|
int value = dbg.read(addr);
|
|
|
|
|
|
|
|
if(comparisonSearch && searchVal != value)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
mySearchAddr.push_back(addr);
|
|
|
|
mySearchValue.push_back(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have some hits, enable the comparison methods
|
|
|
|
if(mySearchAddr.size() > 0)
|
|
|
|
{
|
|
|
|
mySearchButton->setEnabled(false);
|
|
|
|
myCompareButton->setEnabled(true);
|
|
|
|
myRestartButton->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, show the search results in the list
|
|
|
|
myRamGrid->setHiliteList(mySearchAddr);
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2008-06-19 19:15:44 +00:00
|
|
|
string RamWidget::doCompare(const string& str)
|
2005-08-30 17:51:26 +00:00
|
|
|
{
|
|
|
|
bool comparitiveSearch = false;
|
|
|
|
int searchVal = 0, offset = 0;
|
|
|
|
|
|
|
|
if(str.length() == 0)
|
|
|
|
return "Enter an absolute or comparitive value";
|
|
|
|
|
|
|
|
// Do some pre-processing on the string
|
|
|
|
string::size_type pos = str.find_first_of("+-", 0);
|
|
|
|
if(pos > 0 && pos != string::npos)
|
|
|
|
{
|
|
|
|
// Only accept '+' or '-' at the start of the string
|
|
|
|
return "Input must be [+|-]NUM";
|
|
|
|
}
|
|
|
|
|
|
|
|
// A comparitive search searches memory for locations that have changed by
|
|
|
|
// the specified amount, vs. for exact values
|
|
|
|
if(str[0] == '+' || str[0] == '-')
|
|
|
|
{
|
|
|
|
comparitiveSearch = true;
|
|
|
|
bool negative = false;
|
|
|
|
if(str[0] == '-')
|
|
|
|
negative = true;
|
|
|
|
|
|
|
|
string tmp = str;
|
|
|
|
tmp.erase(0, 1); // remove the operator
|
2008-06-13 13:14:52 +00:00
|
|
|
offset = instance().debugger().stringToValue(tmp);
|
2005-08-30 17:51:26 +00:00
|
|
|
if(negative)
|
|
|
|
offset = -offset;
|
|
|
|
}
|
|
|
|
else
|
2008-06-13 13:14:52 +00:00
|
|
|
searchVal = instance().debugger().stringToValue(str);
|
2005-08-30 17:51:26 +00:00
|
|
|
|
|
|
|
// Now, search all memory locations specified in mySearchArray for this value
|
2008-06-13 13:14:52 +00:00
|
|
|
RamDebug& dbg = instance().debugger().ramDebug();
|
2006-03-29 13:53:00 +00:00
|
|
|
IntArray tempAddrList, tempValueList;
|
2005-08-30 17:51:26 +00:00
|
|
|
for(unsigned int i = 0; i < mySearchAddr.size(); ++i)
|
|
|
|
{
|
|
|
|
if(comparitiveSearch)
|
|
|
|
{
|
|
|
|
searchVal = mySearchValue[i] + offset;
|
|
|
|
if(searchVal < 0 || searchVal > 255)
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
int addr = mySearchAddr[i];
|
|
|
|
if(dbg.read(addr) == searchVal)
|
2006-03-29 13:53:00 +00:00
|
|
|
{
|
|
|
|
tempAddrList.push_back(addr);
|
|
|
|
tempValueList.push_back(searchVal);
|
|
|
|
}
|
2005-08-30 17:51:26 +00:00
|
|
|
}
|
|
|
|
|
2006-03-29 13:53:00 +00:00
|
|
|
// Update the searchArray for the new addresses and data
|
|
|
|
mySearchAddr = tempAddrList;
|
|
|
|
mySearchValue = tempValueList;
|
2005-08-30 17:51:26 +00:00
|
|
|
|
|
|
|
// If we have some hits, enable the comparison methods
|
|
|
|
if(mySearchAddr.size() > 0)
|
|
|
|
{
|
|
|
|
myCompareButton->setEnabled(true);
|
|
|
|
myRestartButton->setEnabled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally, show the search results in the list
|
|
|
|
myRamGrid->setHiliteList(mySearchAddr);
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void RamWidget::doRestart()
|
|
|
|
{
|
|
|
|
// Erase all search buffers, reset to start mode
|
|
|
|
mySearchAddr.clear();
|
|
|
|
mySearchValue.clear();
|
|
|
|
myRamGrid->setHiliteList(mySearchAddr);
|
|
|
|
|
|
|
|
mySearchButton->setEnabled(true);
|
|
|
|
myCompareButton->setEnabled(false);
|
|
|
|
myRestartButton->setEnabled(false);
|
|
|
|
}
|