mirror of https://github.com/stella-emu/stella.git
Added support for accessing/modifying extended RAM (aka SuperChip) from
the debugger RAM UI. A scrollbar is now present, which can scroll through each 128 byte 'bank'. Labels indicate the current readport, so you can distinguish between different areas of RAM. For now, F4SC, F6SC, F8SC, and FASC have been converted, but I'm looking into the other schemes now. The RAM UI takes care of all read/write port issues. From the POV of the UI, the RAM can be treated as zero-page; translation is done behind the scene. Searching/comparing and change-tracking are also supported. The 'ram' command in the debugger prompt now reflects all RAM, and readport/writeport addresses are shown, making it easier to use the command withot having to look up the offsets. Debugger width has been bumped to 1050 pixels wide to accomodate the new functionality. We'll see how much trouble this causes ... git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1747 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
c29a6b26c2
commit
3280901be9
3
Todo.txt
3
Todo.txt
|
@ -19,6 +19,9 @@ Stephen Anthony at stephena@users.sourceforge.net.
|
||||||
* Add new TIA infrastructure with improved HMOVE emulation, including
|
* Add new TIA infrastructure with improved HMOVE emulation, including
|
||||||
fixes for (possibly) incorrect VSYNC handling in Q-Bert.
|
fixes for (possibly) incorrect VSYNC handling in Q-Bert.
|
||||||
|
|
||||||
|
* Add better support for 'floating' TIA reads as described here:
|
||||||
|
http://www.atariage.com/forums/index.php?s=&showtopic=143363&view=findpost&p=1762433
|
||||||
|
|
||||||
* Finalize CRT simulation OpenGL code for the next release, and look
|
* Finalize CRT simulation OpenGL code for the next release, and look
|
||||||
into adding Blargg NTSC filtering (perhaps as a GLSL program).
|
into adding Blargg NTSC filtering (perhaps as a GLSL program).
|
||||||
|
|
||||||
|
|
|
@ -106,7 +106,7 @@ Debugger::Debugger(OSystem* osystem)
|
||||||
myBreakPoints(NULL),
|
myBreakPoints(NULL),
|
||||||
myReadTraps(NULL),
|
myReadTraps(NULL),
|
||||||
myWriteTraps(NULL),
|
myWriteTraps(NULL),
|
||||||
myWidth(1030),
|
myWidth(1050),
|
||||||
myHeight(620)
|
myHeight(620)
|
||||||
{
|
{
|
||||||
// Get the dialog size
|
// Get the dialog size
|
||||||
|
@ -114,7 +114,7 @@ Debugger::Debugger(OSystem* osystem)
|
||||||
myOSystem->settings().getSize("debuggerres", w, h);
|
myOSystem->settings().getSize("debuggerres", w, h);
|
||||||
myWidth = BSPF_max(w, 0);
|
myWidth = BSPF_max(w, 0);
|
||||||
myHeight = BSPF_max(h, 0);
|
myHeight = BSPF_max(h, 0);
|
||||||
myWidth = BSPF_max(myWidth, 1030u);
|
myWidth = BSPF_max(myWidth, 1050u);
|
||||||
myHeight = BSPF_max(myHeight, 620u);
|
myHeight = BSPF_max(myHeight, 620u);
|
||||||
myOSystem->settings().setSize("debuggerres", myWidth, myHeight);
|
myOSystem->settings().setSize("debuggerres", myWidth, myHeight);
|
||||||
|
|
||||||
|
@ -190,6 +190,12 @@ void Debugger::setConsole(Console* console)
|
||||||
delete myRamDebug;
|
delete myRamDebug;
|
||||||
myRamDebug = new RamDebug(*this, *myConsole);
|
myRamDebug = new RamDebug(*this, *myConsole);
|
||||||
|
|
||||||
|
// Register any RAM areas in the Cartridge
|
||||||
|
// Zero-page RAM is automatically recognized by RamDebug
|
||||||
|
uInt16 start, size, roffset, woffset;
|
||||||
|
if(myConsole->cartridge().getRamArea(start, size, roffset, woffset))
|
||||||
|
myRamDebug->addRamArea(start, size, roffset, woffset);
|
||||||
|
|
||||||
delete myRiotDebug;
|
delete myRiotDebug;
|
||||||
myRiotDebug = new RiotDebug(*this, *myConsole);
|
myRiotDebug = new RiotDebug(*this, *myConsole);
|
||||||
|
|
||||||
|
@ -205,6 +211,8 @@ void Debugger::setConsole(Console* console)
|
||||||
autoLoadSymbols(myOSystem->romFile());
|
autoLoadSymbols(myOSystem->romFile());
|
||||||
loadListFile();
|
loadListFile();
|
||||||
|
|
||||||
|
// Make sure cart RAM is added before this is called,
|
||||||
|
// otherwise the debugger state won't know about it
|
||||||
saveOldState();
|
saveOldState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,12 +48,6 @@ class Expression;
|
||||||
typedef map<string,Expression*> FunctionMap;
|
typedef map<string,Expression*> FunctionMap;
|
||||||
typedef map<string,string> FunctionDefMap;
|
typedef map<string,string> FunctionDefMap;
|
||||||
|
|
||||||
// Constants for RAM area
|
|
||||||
enum {
|
|
||||||
kRamStart = 0x80,
|
|
||||||
kRamSize = 128
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// These will probably turn out to be unneeded, left for reference for now
|
// These will probably turn out to be unneeded, left for reference for now
|
||||||
// pointer types for Debugger instance methods
|
// pointer types for Debugger instance methods
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
// $Id$
|
// $Id$
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
#include "Array.hxx"
|
#include "Array.hxx"
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "RamDebug.hxx"
|
#include "RamDebug.hxx"
|
||||||
|
@ -24,14 +25,37 @@
|
||||||
RamDebug::RamDebug(Debugger& dbg, Console& console)
|
RamDebug::RamDebug(Debugger& dbg, Console& console)
|
||||||
: DebuggerSystem(dbg, console)
|
: DebuggerSystem(dbg, console)
|
||||||
{
|
{
|
||||||
|
// Zero-page RAM is always present
|
||||||
|
addRamArea(0x80, 128, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void RamDebug::addRamArea(uInt16 start, uInt16 size,
|
||||||
|
uInt16 roffset, uInt16 woffset)
|
||||||
|
{
|
||||||
|
// First make sure this area isn't already present
|
||||||
|
for(uInt32 i = 0; i < myState.rport.size(); ++i)
|
||||||
|
if(myState.rport[i] == start + roffset ||
|
||||||
|
myState.wport[i] == start + woffset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Otherwise, add a new area
|
||||||
|
for(uInt32 i = 0; i < size; ++i)
|
||||||
|
{
|
||||||
|
myState.rport.push_back(i + start + roffset);
|
||||||
|
myState.wport.push_back(i + start + woffset);
|
||||||
|
|
||||||
|
myOldState.rport.push_back(i + start + roffset);
|
||||||
|
myOldState.wport.push_back(i + start + woffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
const DebuggerState& RamDebug::getState()
|
const DebuggerState& RamDebug::getState()
|
||||||
{
|
{
|
||||||
myState.ram.clear();
|
myState.ram.clear();
|
||||||
for(int i=0; i<0x80; i++)
|
for(uInt32 i = 0; i < myState.rport.size(); ++i)
|
||||||
myState.ram.push_back(read(i));
|
myState.ram.push_back(read(myState.rport[i]));
|
||||||
|
|
||||||
return myState;
|
return myState;
|
||||||
}
|
}
|
||||||
|
@ -40,22 +64,20 @@ const DebuggerState& RamDebug::getState()
|
||||||
void RamDebug::saveOldState()
|
void RamDebug::saveOldState()
|
||||||
{
|
{
|
||||||
myOldState.ram.clear();
|
myOldState.ram.clear();
|
||||||
for(int i=0; i<0x80; i++)
|
for(uInt32 i = 0; i < myOldState.rport.size(); ++i)
|
||||||
myOldState.ram.push_back(read(i));
|
myOldState.ram.push_back(read(myOldState.rport[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
int RamDebug::read(int offset)
|
uInt8 RamDebug::read(uInt16 addr)
|
||||||
{
|
{
|
||||||
offset &= 0x7f; // there are only 128 bytes
|
return mySystem.peek(addr);
|
||||||
return mySystem.peek(offset + 0x80);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void RamDebug::write(int offset, int value)
|
void RamDebug::write(uInt16 addr, uInt8 value)
|
||||||
{
|
{
|
||||||
offset &= 0x7f; // there are only 128 bytes
|
mySystem.poke(addr, value);
|
||||||
mySystem.poke(offset + 0x80, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -63,8 +85,7 @@ string RamDebug::toString()
|
||||||
{
|
{
|
||||||
string result;
|
string result;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
int bytesPerLine;
|
uInt32 bytesPerLine;
|
||||||
int start = kRamStart, len = kRamSize;
|
|
||||||
|
|
||||||
switch(myDebugger.parser().base())
|
switch(myDebugger.parser().base())
|
||||||
{
|
{
|
||||||
|
@ -84,12 +105,24 @@ string RamDebug::toString()
|
||||||
|
|
||||||
const RamState& state = (RamState&) getState();
|
const RamState& state = (RamState&) getState();
|
||||||
const RamState& oldstate = (RamState&) getOldState();
|
const RamState& oldstate = (RamState&) getOldState();
|
||||||
for (uInt8 i = 0x00; i < len; i += bytesPerLine)
|
|
||||||
|
uInt32 curraddr = 0;
|
||||||
|
for(uInt32 i = 0; i < state.ram.size(); i += bytesPerLine)
|
||||||
{
|
{
|
||||||
sprintf(buf, "%.2x: ", start+i);
|
// We detect different 'pages' of RAM when the addresses jump by
|
||||||
|
// more than the number of bytes on the previous line
|
||||||
|
if(state.rport[i] - curraddr > bytesPerLine)
|
||||||
|
{
|
||||||
|
sprintf(buf, "%04x: (rport = %04x, wport = %04x)\n",
|
||||||
|
state.rport[i], state.rport[i], state.wport[i]);
|
||||||
|
buf[2] = buf[3] = 'x';
|
||||||
|
result += buf;
|
||||||
|
}
|
||||||
|
curraddr = state.rport[i];
|
||||||
|
sprintf(buf, "%.2x: ", curraddr & 0x00ff);
|
||||||
result += buf;
|
result += buf;
|
||||||
|
|
||||||
for (uInt8 j = 0; j < bytesPerLine; j++)
|
for(uInt8 j = 0; j < bytesPerLine; ++j)
|
||||||
{
|
{
|
||||||
result += myDebugger.invIfChanged(state.ram[i+j], oldstate.ram[i+j]);
|
result += myDebugger.invIfChanged(state.ram[i+j], oldstate.ram[i+j]);
|
||||||
result += " ";
|
result += " ";
|
||||||
|
|
|
@ -21,13 +21,16 @@
|
||||||
|
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
|
#include "bspf.hxx"
|
||||||
#include "Array.hxx"
|
#include "Array.hxx"
|
||||||
#include "DebuggerSystem.hxx"
|
#include "DebuggerSystem.hxx"
|
||||||
|
|
||||||
class RamState : public DebuggerState
|
class RamState : public DebuggerState
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IntArray ram;
|
IntArray ram; // The actual data values
|
||||||
|
IntArray rport; // Address for reading from RAM
|
||||||
|
IntArray wport; // Address for writing to RAM
|
||||||
};
|
};
|
||||||
|
|
||||||
class RamDebug : public DebuggerSystem
|
class RamDebug : public DebuggerSystem
|
||||||
|
@ -35,14 +38,27 @@ class RamDebug : public DebuggerSystem
|
||||||
public:
|
public:
|
||||||
RamDebug(Debugger& dbg, Console& console);
|
RamDebug(Debugger& dbg, Console& console);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Let the RAM debugger subsystem treat this area as addressable memory.
|
||||||
|
|
||||||
|
@param start The beginning of the RAM area (0x0000 - 0x2000)
|
||||||
|
@param size Total number of bytes of area
|
||||||
|
@param roffset Offset to use when reading from RAM (read port)
|
||||||
|
@param woffset Offset to use when writing to RAM (write port)
|
||||||
|
*/
|
||||||
|
void addRamArea(uInt16 start, uInt16 size, uInt16 roffset, uInt16 woffset);
|
||||||
|
|
||||||
const DebuggerState& getState();
|
const DebuggerState& getState();
|
||||||
const DebuggerState& getOldState() { return myOldState; }
|
const DebuggerState& getOldState() { return myOldState; }
|
||||||
|
|
||||||
void saveOldState();
|
void saveOldState();
|
||||||
string toString();
|
string toString();
|
||||||
|
|
||||||
int read(int offset);
|
// The following assume that the given addresses are using the
|
||||||
void write(int offset, int value);
|
// correct read/write port ranges; no checking will be done to
|
||||||
|
// confirm this.
|
||||||
|
uInt8 read(uInt16 addr);
|
||||||
|
void write(uInt16 addr, uInt8 value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RamState myState;
|
RamState myState;
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int cols, int rows,
|
int x, int y, int cols, int rows,
|
||||||
int colchars, int bits, BaseFormat base)
|
int colchars, int bits, BaseFormat base,
|
||||||
|
bool useScrollbar)
|
||||||
: EditableWidget(boss, font, x, y,
|
: EditableWidget(boss, font, x, y,
|
||||||
cols*(colchars * font.getMaxCharWidth() + 8) + 1,
|
cols*(colchars * font.getMaxCharWidth() + 8) + 1,
|
||||||
font.getLineHeight()*rows + 1),
|
font.getLineHeight()*rows + 1),
|
||||||
|
@ -43,7 +44,8 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
_bits(bits),
|
_bits(bits),
|
||||||
_base(base),
|
_base(base),
|
||||||
_selectedItem(0),
|
_selectedItem(0),
|
||||||
_opsWidget(NULL)
|
_opsWidget(NULL),
|
||||||
|
_scrollBar(NULL)
|
||||||
{
|
{
|
||||||
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS |
|
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS |
|
||||||
WIDGET_WANTS_RAWDATA;
|
WIDGET_WANTS_RAWDATA;
|
||||||
|
@ -59,11 +61,22 @@ DataGridWidget::DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
// Make sure hilite list contains all false values
|
// Make sure hilite list contains all false values
|
||||||
_hiliteList.clear();
|
_hiliteList.clear();
|
||||||
int size = _rows * _cols;
|
int size = _rows * _cols;
|
||||||
while((int)_hiliteList.size() < size)
|
while(size--)
|
||||||
_hiliteList.push_back(false);
|
_hiliteList.push_back(false);
|
||||||
|
|
||||||
// Set lower and upper bounds to sane values
|
// Set lower and upper bounds to sane values
|
||||||
setRange(0, 1 << bits);
|
setRange(0, 1 << bits);
|
||||||
|
|
||||||
|
// Add a scrollbar if necessary
|
||||||
|
if(useScrollbar)
|
||||||
|
{
|
||||||
|
_scrollBar = new ScrollBarWidget(boss, font, _x + _w, _y, kScrollBarWidth, _h);
|
||||||
|
_scrollBar->setTarget(this);
|
||||||
|
_scrollBar->_numEntries = 1;
|
||||||
|
_scrollBar->_currentPos = 0;
|
||||||
|
_scrollBar->_entriesPerPage = 1;
|
||||||
|
_scrollBar->_wheel_lines = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -90,9 +103,9 @@ cerr << "alist.size() = " << alist.size()
|
||||||
_valueStringList.clear();
|
_valueStringList.clear();
|
||||||
_changedList.clear();
|
_changedList.clear();
|
||||||
|
|
||||||
_addrList = alist;
|
_addrList = alist;
|
||||||
_valueList = vlist;
|
_valueList = vlist;
|
||||||
_changedList = changed;
|
_changedList = changed;
|
||||||
|
|
||||||
// An efficiency thing
|
// An efficiency thing
|
||||||
string temp;
|
string temp;
|
||||||
|
@ -132,26 +145,22 @@ void DataGridWidget::setList(const int a, const int v, const bool c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DataGridWidget::setHiliteList(const IntArray& hilitelist)
|
void DataGridWidget::setHiliteList(const BoolArray& hilitelist)
|
||||||
{
|
{
|
||||||
// We can't assume this given list contains the exact number of
|
assert(hilitelist.size() == uInt32(_rows * _cols));
|
||||||
// items in this DataGrid, so we make sure
|
|
||||||
_hiliteList.clear();
|
_hiliteList.clear();
|
||||||
int size = _rows * _cols;
|
_hiliteList = hilitelist;
|
||||||
while((int)_hiliteList.size() < size)
|
|
||||||
_hiliteList.push_back(false);
|
|
||||||
|
|
||||||
// Now fill it with the addresses/positions given in 'hilitelist'
|
|
||||||
for(unsigned int i = 0; i < hilitelist.size(); ++i)
|
|
||||||
{
|
|
||||||
int pos = hilitelist[i];
|
|
||||||
if(pos >= 0 && pos <= size)
|
|
||||||
_hiliteList[pos] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
setDirty(); draw();
|
setDirty(); draw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DataGridWidget::setNumRows(int rows)
|
||||||
|
{
|
||||||
|
if(_scrollBar)
|
||||||
|
_scrollBar->_numEntries = rows;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DataGridWidget::setSelectedValue(int value)
|
void DataGridWidget::setSelectedValue(int value)
|
||||||
{
|
{
|
||||||
|
@ -215,6 +224,12 @@ void DataGridWidget::handleMouseUp(int x, int y, int button, int clickCount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void DataGridWidget::handleMouseWheel(int x, int y, int direction)
|
||||||
|
{
|
||||||
|
_scrollBar->handleMouseWheel(x, y, direction);
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
int DataGridWidget::findItem(int x, int y)
|
int DataGridWidget::findItem(int x, int y)
|
||||||
{
|
{
|
||||||
|
@ -443,8 +458,8 @@ void DataGridWidget::handleCommand(CommandSender* sender, int cmd,
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case kSetPositionCmd:
|
case kSetPositionCmd:
|
||||||
if (_selectedItem != (int)data)
|
// Chain access; pass to parent
|
||||||
_selectedItem = data;
|
sendCommand(kSetPositionCmd, data, _id);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kDGZeroCmd:
|
case kDGZeroCmd:
|
||||||
|
@ -542,6 +557,10 @@ void DataGridWidget::drawWidget(bool hilite)
|
||||||
// Only draw the caret while editing, and if it's in the current viewport
|
// Only draw the caret while editing, and if it's in the current viewport
|
||||||
if(_editMode)
|
if(_editMode)
|
||||||
drawCaret();
|
drawCaret();
|
||||||
|
|
||||||
|
// Draw the scrollbar
|
||||||
|
if(_scrollBar)
|
||||||
|
_scrollBar->recalc(); // takes care of the draw
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "Array.hxx"
|
#include "Array.hxx"
|
||||||
#include "Rect.hxx"
|
#include "Rect.hxx"
|
||||||
#include "DataGridOpsWidget.hxx"
|
#include "DataGridOpsWidget.hxx"
|
||||||
|
#include "ScrollBarWidget.hxx"
|
||||||
|
|
||||||
// Some special commands
|
// Some special commands
|
||||||
enum {
|
enum {
|
||||||
|
@ -46,13 +47,15 @@ class DataGridWidget : public EditableWidget
|
||||||
public:
|
public:
|
||||||
DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
DataGridWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int cols, int rows,
|
int x, int y, int cols, int rows,
|
||||||
int colchars, int bits, BaseFormat format = kBASE_DEFAULT);
|
int colchars, int bits, BaseFormat format = kBASE_DEFAULT,
|
||||||
|
bool useScrollbar = false);
|
||||||
virtual ~DataGridWidget();
|
virtual ~DataGridWidget();
|
||||||
|
|
||||||
void setList(const IntArray& alist, const IntArray& vlist,
|
void setList(const IntArray& alist, const IntArray& vlist,
|
||||||
const BoolArray& changed);
|
const BoolArray& changed);
|
||||||
void setList(const int a, const int v, const bool changed);
|
void setList(const int a, const int v, const bool changed);
|
||||||
void setHiliteList(const IntArray& hilitelist);
|
void setHiliteList(const BoolArray& hilitelist);
|
||||||
|
void setNumRows(int rows);
|
||||||
|
|
||||||
void setSelectedValue(int value);
|
void setSelectedValue(int value);
|
||||||
|
|
||||||
|
@ -63,12 +66,16 @@ class DataGridWidget : public EditableWidget
|
||||||
|
|
||||||
virtual void handleMouseDown(int x, int y, int button, int clickCount);
|
virtual void handleMouseDown(int x, int y, int button, int clickCount);
|
||||||
virtual void handleMouseUp(int x, int y, int button, int clickCount);
|
virtual void handleMouseUp(int x, int y, int button, int clickCount);
|
||||||
|
virtual void handleMouseWheel(int x, int y, int direction);
|
||||||
virtual bool handleKeyDown(int ascii, int keycode, int modifiers);
|
virtual bool handleKeyDown(int ascii, int keycode, int modifiers);
|
||||||
virtual bool handleKeyUp(int ascii, int keycode, int modifiers);
|
virtual bool handleKeyUp(int ascii, int keycode, int modifiers);
|
||||||
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
|
virtual void handleCommand(CommandSender* sender, int cmd, int data, int id);
|
||||||
|
|
||||||
virtual bool wantsFocus() { return true; }
|
virtual bool wantsFocus() { return true; }
|
||||||
|
|
||||||
|
// Account for the extra width of embedded scrollbar
|
||||||
|
virtual int getWidth() const { return _w + (_scrollBar ? kScrollBarWidth : 0); }
|
||||||
|
|
||||||
void startEditMode();
|
void startEditMode();
|
||||||
void endEditMode();
|
void endEditMode();
|
||||||
|
|
||||||
|
@ -116,6 +123,7 @@ class DataGridWidget : public EditableWidget
|
||||||
string _backupString;
|
string _backupString;
|
||||||
|
|
||||||
DataGridOpsWidget* _opsWidget;
|
DataGridOpsWidget* _opsWidget;
|
||||||
|
ScrollBarWidget* _scrollBar;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/** Common operations on the currently selected cell */
|
/** Common operations on the currently selected cell */
|
||||||
|
|
|
@ -37,7 +37,8 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
||||||
: Widget(boss, font, x, y, 16, 16),
|
: Widget(boss, font, x, y, 16, 16),
|
||||||
CommandSender(boss),
|
CommandSender(boss),
|
||||||
myUndoAddress(-1),
|
myUndoAddress(-1),
|
||||||
myUndoValue(-1)
|
myUndoValue(-1),
|
||||||
|
myCurrentRamBank(0)
|
||||||
{
|
{
|
||||||
_type = kRamWidget;
|
_type = kRamWidget;
|
||||||
|
|
||||||
|
@ -49,9 +50,10 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
||||||
int xpos, ypos, lwidth;
|
int xpos, ypos, lwidth;
|
||||||
|
|
||||||
// Create a 16x8 grid holding byte values (16 x 8 = 128 RAM bytes) with labels
|
// Create a 16x8 grid holding byte values (16 x 8 = 128 RAM bytes) with labels
|
||||||
|
// Add a scrollbar, since there may be more than 128 bytes of RAM available
|
||||||
xpos = x; ypos = y + lineHeight; lwidth = 4 * fontWidth;
|
xpos = x; ypos = y + lineHeight; lwidth = 4 * fontWidth;
|
||||||
myRamGrid = new DataGridWidget(boss, font, xpos + lwidth, ypos,
|
myRamGrid = new DataGridWidget(boss, font, xpos + lwidth, ypos,
|
||||||
16, 8, 2, 8, kBASE_16);
|
16, 8, 2, 8, kBASE_16, true);
|
||||||
myRamGrid->setTarget(this);
|
myRamGrid->setTarget(this);
|
||||||
addFocusWidget(myRamGrid);
|
addFocusWidget(myRamGrid);
|
||||||
|
|
||||||
|
@ -83,13 +85,11 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
||||||
|
|
||||||
// Labels for RAM grid
|
// Labels for RAM grid
|
||||||
xpos = x; ypos = y + lineHeight;
|
xpos = x; ypos = y + lineHeight;
|
||||||
for(int row = 0; row < 8; ++row)
|
myRamStart =
|
||||||
{
|
new StaticTextWidget(boss, font, xpos, ypos - lineHeight,
|
||||||
new StaticTextWidget(boss, font, xpos-2, ypos + row*lineHeight + 2,
|
font.getStringWidth("xxxx"), fontHeight,
|
||||||
lwidth-2, fontHeight,
|
"00xx", kTextAlignLeft);
|
||||||
Debugger::to_hex_8(row*16 + kRamStart) + string(":"),
|
|
||||||
kTextAlignLeft);
|
|
||||||
}
|
|
||||||
for(int col = 0; col < 16; ++col)
|
for(int col = 0; col < 16; ++col)
|
||||||
{
|
{
|
||||||
new StaticTextWidget(boss, font, xpos + col*myRamGrid->colWidth() + lwidth + 8,
|
new StaticTextWidget(boss, font, xpos + col*myRamGrid->colWidth() + lwidth + 8,
|
||||||
|
@ -98,7 +98,13 @@ RamWidget::RamWidget(GuiObject* boss, const GUI::Font& font, int x, int y)
|
||||||
Debugger::to_hex_4(col),
|
Debugger::to_hex_4(col),
|
||||||
kTextAlignLeft);
|
kTextAlignLeft);
|
||||||
}
|
}
|
||||||
|
for(int row = 0; row < 8; ++row)
|
||||||
|
{
|
||||||
|
myRamLabels[row] =
|
||||||
|
new StaticTextWidget(boss, font, xpos + 5, ypos + row*lineHeight + 2,
|
||||||
|
3*fontWidth, fontHeight, "", kTextAlignLeft);
|
||||||
|
}
|
||||||
|
|
||||||
xpos = x + 10; ypos += 9 * lineHeight;
|
xpos = x + 10; ypos += 9 * lineHeight;
|
||||||
new StaticTextWidget(boss, font, xpos, ypos,
|
new StaticTextWidget(boss, font, xpos, ypos,
|
||||||
6*fontWidth, fontHeight,
|
6*fontWidth, fontHeight,
|
||||||
|
@ -154,6 +160,7 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
int addr, value;
|
int addr, value;
|
||||||
|
|
||||||
RamDebug& dbg = instance().debugger().ramDebug();
|
RamDebug& dbg = instance().debugger().ramDebug();
|
||||||
|
const RamState& state = (RamState&) dbg.getState();
|
||||||
switch(cmd)
|
switch(cmd)
|
||||||
{
|
{
|
||||||
case kDGItemDataChangedCmd:
|
case kDGItemDataChangedCmd:
|
||||||
|
@ -161,9 +168,9 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
value = myRamGrid->getSelectedValue();
|
value = myRamGrid->getSelectedValue();
|
||||||
|
|
||||||
myUndoAddress = addr;
|
myUndoAddress = addr;
|
||||||
myUndoValue = dbg.read(addr);
|
myUndoValue = dbg.read(state.rport[addr]);
|
||||||
|
|
||||||
dbg.write(addr, value);
|
dbg.write(state.wport[addr], value);
|
||||||
myDecValue->setEditString(instance().debugger().valueToString(value, kBASE_10));
|
myDecValue->setEditString(instance().debugger().valueToString(value, kBASE_10));
|
||||||
myBinValue->setEditString(instance().debugger().valueToString(value, kBASE_2));
|
myBinValue->setEditString(instance().debugger().valueToString(value, kBASE_2));
|
||||||
myRevertButton->setEnabled(true);
|
myRevertButton->setEnabled(true);
|
||||||
|
@ -176,20 +183,20 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
value = myRamGrid->getSelectedValue();
|
value = myRamGrid->getSelectedValue();
|
||||||
|
|
||||||
myLabel->setEditString(
|
myLabel->setEditString(
|
||||||
instance().debugger().equates().getLabel(addr+kRamStart, true));
|
instance().debugger().equates().getLabel(state.rport[addr], true));
|
||||||
myDecValue->setEditString(instance().debugger().valueToString(value, kBASE_10));
|
myDecValue->setEditString(instance().debugger().valueToString(value, kBASE_10));
|
||||||
myBinValue->setEditString(instance().debugger().valueToString(value, kBASE_2));
|
myBinValue->setEditString(instance().debugger().valueToString(value, kBASE_2));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case kRevertCmd:
|
case kRevertCmd:
|
||||||
for(unsigned int i = 0; i < kRamSize; i++)
|
for(uInt32 i = 0; i < myOldValueList.size(); ++i)
|
||||||
dbg.write(i, myOldValueList[i]);
|
dbg.write(state.wport[i], myOldValueList[i]);
|
||||||
fillGrid(true);
|
fillGrid(true);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kUndoCmd:
|
case kUndoCmd:
|
||||||
dbg.write(myUndoAddress, myUndoValue);
|
dbg.write(state.wport[myUndoAddress], myUndoValue);
|
||||||
myUndoButton->setEnabled(false);
|
myUndoButton->setEnabled(false);
|
||||||
fillGrid(false);
|
fillGrid(false);
|
||||||
break;
|
break;
|
||||||
|
@ -225,13 +232,18 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
|
||||||
parent().removeDialog();
|
parent().removeDialog();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case kSetPositionCmd:
|
||||||
|
myCurrentRamBank = data;
|
||||||
|
showSearchResults();
|
||||||
|
fillGrid(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void RamWidget::loadConfig()
|
void RamWidget::loadConfig()
|
||||||
{
|
{
|
||||||
//cerr << "RamWidget::loadConfig()\n";
|
|
||||||
fillGrid(true);
|
fillGrid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,24 +258,42 @@ void RamWidget::fillGrid(bool updateOld)
|
||||||
|
|
||||||
RamDebug& dbg = instance().debugger().ramDebug();
|
RamDebug& dbg = instance().debugger().ramDebug();
|
||||||
|
|
||||||
RamState state = (RamState&) dbg.getState();
|
const RamState& state = (RamState&) dbg.getState();
|
||||||
RamState oldstate = (RamState&) dbg.getOldState();
|
const RamState& oldstate = (RamState&) dbg.getOldState();
|
||||||
|
|
||||||
|
// Jump to the correct 128 byte 'window' in the RAM area
|
||||||
|
// This assumes that the RAM areas are aligned on 128 byte boundaries
|
||||||
|
// TODO - the boundary restriction may not always apply ...
|
||||||
|
uInt32 start = myCurrentRamBank * 128;
|
||||||
|
assert(start+128 <= state.ram.size());
|
||||||
|
|
||||||
vlist = state.ram;
|
|
||||||
if(updateOld) myOldValueList = state.ram;
|
if(updateOld) myOldValueList = state.ram;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < 16*8; i++)
|
for(uInt32 i = start; i < start + 16*8; ++i)
|
||||||
{
|
{
|
||||||
alist.push_back(i);
|
alist.push_back(i);
|
||||||
|
vlist.push_back(state.ram[i]);
|
||||||
changed.push_back(state.ram[i] != oldstate.ram[i]);
|
changed.push_back(state.ram[i] != oldstate.ram[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myRamGrid->setNumRows(state.ram.size() / 128);
|
||||||
myRamGrid->setList(alist, vlist, changed);
|
myRamGrid->setList(alist, vlist, changed);
|
||||||
if(updateOld)
|
if(updateOld)
|
||||||
{
|
{
|
||||||
myRevertButton->setEnabled(false);
|
myRevertButton->setEnabled(false);
|
||||||
myUndoButton->setEnabled(false);
|
myUndoButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update RAM labels
|
||||||
|
char buf[5];
|
||||||
|
sprintf(buf, "%04x", state.rport[start] & 0xff00);
|
||||||
|
buf[2] = buf[3] = 'x';
|
||||||
|
myRamStart->setLabel(buf);
|
||||||
|
for(uInt32 i = start, row = 0; i < start + 16*8; i += 16, ++row)
|
||||||
|
{
|
||||||
|
sprintf(buf, "%02x:", state.rport[i] & 0x00ff);
|
||||||
|
myRamLabels[row]->setLabel(buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -300,23 +330,31 @@ string RamWidget::doSearch(const string& str)
|
||||||
// Clear the search array of previous items
|
// Clear the search array of previous items
|
||||||
mySearchAddr.clear();
|
mySearchAddr.clear();
|
||||||
mySearchValue.clear();
|
mySearchValue.clear();
|
||||||
|
mySearchState.clear();
|
||||||
|
|
||||||
// Now, search all memory locations for this value, and add it to the
|
// Now, search all memory locations for this value, and add it to the
|
||||||
// search array
|
// search array
|
||||||
|
bool hitfound = false;
|
||||||
RamDebug& dbg = instance().debugger().ramDebug();
|
RamDebug& dbg = instance().debugger().ramDebug();
|
||||||
for(int addr = 0; addr < kRamSize; ++addr)
|
const RamState& state = (RamState&) dbg.getState();
|
||||||
|
for(uInt32 addr = 0; addr < state.ram.size(); ++addr)
|
||||||
{
|
{
|
||||||
int value = dbg.read(addr);
|
int value = state.ram[addr];
|
||||||
|
|
||||||
if(comparisonSearch && searchVal != value)
|
if(comparisonSearch && searchVal != value)
|
||||||
continue;
|
{
|
||||||
|
mySearchState.push_back(false);
|
||||||
mySearchAddr.push_back(addr);
|
}
|
||||||
mySearchValue.push_back(value);
|
else
|
||||||
|
{
|
||||||
|
mySearchAddr.push_back(addr);
|
||||||
|
mySearchValue.push_back(value);
|
||||||
|
mySearchState.push_back(true);
|
||||||
|
hitfound = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have some hits, enable the comparison methods
|
// If we have some hits, enable the comparison methods
|
||||||
if(mySearchAddr.size() > 0)
|
if(hitfound)
|
||||||
{
|
{
|
||||||
mySearchButton->setEnabled(false);
|
mySearchButton->setEnabled(false);
|
||||||
myCompareButton->setEnabled(true);
|
myCompareButton->setEnabled(true);
|
||||||
|
@ -324,7 +362,7 @@ string RamWidget::doSearch(const string& str)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, show the search results in the list
|
// Finally, show the search results in the list
|
||||||
myRamGrid->setHiliteList(mySearchAddr);
|
showSearchResults();
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -364,9 +402,15 @@ string RamWidget::doCompare(const string& str)
|
||||||
else
|
else
|
||||||
searchVal = instance().debugger().stringToValue(str);
|
searchVal = instance().debugger().stringToValue(str);
|
||||||
|
|
||||||
// Now, search all memory locations specified in mySearchArray for this value
|
// Now, search all memory locations previously 'found' for this value
|
||||||
|
bool hitfound = false;
|
||||||
RamDebug& dbg = instance().debugger().ramDebug();
|
RamDebug& dbg = instance().debugger().ramDebug();
|
||||||
|
const RamState& state = (RamState&) dbg.getState();
|
||||||
IntArray tempAddrList, tempValueList;
|
IntArray tempAddrList, tempValueList;
|
||||||
|
mySearchState.clear();
|
||||||
|
for(uInt32 i = 0; i < state.rport.size(); ++i)
|
||||||
|
mySearchState.push_back(false);
|
||||||
|
|
||||||
for(unsigned int i = 0; i < mySearchAddr.size(); ++i)
|
for(unsigned int i = 0; i < mySearchAddr.size(); ++i)
|
||||||
{
|
{
|
||||||
if(comparitiveSearch)
|
if(comparitiveSearch)
|
||||||
|
@ -377,10 +421,11 @@ string RamWidget::doCompare(const string& str)
|
||||||
}
|
}
|
||||||
|
|
||||||
int addr = mySearchAddr[i];
|
int addr = mySearchAddr[i];
|
||||||
if(dbg.read(addr) == searchVal)
|
if(dbg.read(state.rport[addr]) == searchVal)
|
||||||
{
|
{
|
||||||
tempAddrList.push_back(addr);
|
tempAddrList.push_back(addr);
|
||||||
tempValueList.push_back(searchVal);
|
tempValueList.push_back(searchVal);
|
||||||
|
mySearchState[addr] = hitfound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -389,14 +434,14 @@ string RamWidget::doCompare(const string& str)
|
||||||
mySearchValue = tempValueList;
|
mySearchValue = tempValueList;
|
||||||
|
|
||||||
// If we have some hits, enable the comparison methods
|
// If we have some hits, enable the comparison methods
|
||||||
if(mySearchAddr.size() > 0)
|
if(hitfound)
|
||||||
{
|
{
|
||||||
myCompareButton->setEnabled(true);
|
myCompareButton->setEnabled(true);
|
||||||
myRestartButton->setEnabled(true);
|
myRestartButton->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, show the search results in the list
|
// Finally, show the search results in the list
|
||||||
myRamGrid->setHiliteList(mySearchAddr);
|
showSearchResults();
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -407,9 +452,29 @@ void RamWidget::doRestart()
|
||||||
// Erase all search buffers, reset to start mode
|
// Erase all search buffers, reset to start mode
|
||||||
mySearchAddr.clear();
|
mySearchAddr.clear();
|
||||||
mySearchValue.clear();
|
mySearchValue.clear();
|
||||||
myRamGrid->setHiliteList(mySearchAddr);
|
mySearchState.clear();
|
||||||
|
showSearchResults();
|
||||||
|
|
||||||
mySearchButton->setEnabled(true);
|
mySearchButton->setEnabled(true);
|
||||||
myCompareButton->setEnabled(false);
|
myCompareButton->setEnabled(false);
|
||||||
myRestartButton->setEnabled(false);
|
myRestartButton->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void RamWidget::showSearchResults()
|
||||||
|
{
|
||||||
|
// Only update the search results for the bank currently being shown
|
||||||
|
BoolArray temp;
|
||||||
|
uInt32 start = myCurrentRamBank * 128;
|
||||||
|
if(mySearchState.size() == 0 || start > mySearchState.size())
|
||||||
|
{
|
||||||
|
for(uInt32 i = 0; i < 128; ++i)
|
||||||
|
temp.push_back(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(uInt32 i = start; i < start + 128; ++i)
|
||||||
|
temp.push_back(mySearchState[i]);
|
||||||
|
}
|
||||||
|
myRamGrid->setHiliteList(temp);
|
||||||
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ class RamWidget : public Widget, public CommandSender
|
||||||
string doSearch(const string& str);
|
string doSearch(const string& str);
|
||||||
string doCompare(const string& str);
|
string doCompare(const string& str);
|
||||||
void doRestart();
|
void doRestart();
|
||||||
|
void showSearchResults();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
|
@ -66,8 +67,12 @@ class RamWidget : public Widget, public CommandSender
|
||||||
|
|
||||||
int myUndoAddress;
|
int myUndoAddress;
|
||||||
int myUndoValue;
|
int myUndoValue;
|
||||||
|
int myCurrentRamBank;
|
||||||
|
|
||||||
|
StaticTextWidget* myRamStart;
|
||||||
|
StaticTextWidget* myRamLabels[8];
|
||||||
|
DataGridWidget* myRamGrid;
|
||||||
|
|
||||||
DataGridWidget* myRamGrid;
|
|
||||||
EditTextWidget* myBinValue;
|
EditTextWidget* myBinValue;
|
||||||
EditTextWidget* myDecValue;
|
EditTextWidget* myDecValue;
|
||||||
EditTextWidget* myLabel;
|
EditTextWidget* myLabel;
|
||||||
|
@ -83,6 +88,7 @@ class RamWidget : public Widget, public CommandSender
|
||||||
IntArray myOldValueList;
|
IntArray myOldValueList;
|
||||||
IntArray mySearchAddr;
|
IntArray mySearchAddr;
|
||||||
IntArray mySearchValue;
|
IntArray mySearchValue;
|
||||||
|
BoolArray mySearchState;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,6 +80,23 @@ class Cartridge : public Device
|
||||||
void lockBank() { myBankLocked = true; }
|
void lockBank() { myBankLocked = true; }
|
||||||
void unlockBank() { myBankLocked = false; }
|
void unlockBank() { myBankLocked = false; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
This informs the caller of the addressable range of any extended RAM
|
||||||
|
present on the cart. If no RAM is present, the method should return
|
||||||
|
false. Cart classes should override this method if they contain
|
||||||
|
any extended RAM.
|
||||||
|
|
||||||
|
@param start The beginning of the RAM area (0x0000 - 0x2000)
|
||||||
|
@param size Total number of bytes of area
|
||||||
|
@param roffset Offset to use when reading from RAM (read port)
|
||||||
|
@param woffset Offset to use when writing to RAM (write port)
|
||||||
|
|
||||||
|
@return True if RAM exists and parameters are modified, else false
|
||||||
|
*/
|
||||||
|
virtual bool getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset)
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// The following methods are cart-specific and must be implemented
|
// The following methods are cart-specific and must be implemented
|
||||||
|
|
|
@ -243,3 +243,15 @@ bool CartridgeF4SC::load(Deserializer& in)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool CartridgeF4SC::getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset)
|
||||||
|
{
|
||||||
|
start = 0x1000;
|
||||||
|
size = 128;
|
||||||
|
roffset = 0x80;
|
||||||
|
woffset = 0x0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -119,6 +119,22 @@ class CartridgeF4SC : public Cartridge
|
||||||
*/
|
*/
|
||||||
virtual string name() const { return "CartridgeF4SC"; }
|
virtual string name() const { return "CartridgeF4SC"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
This informs the caller of the addressable range of any extended RAM
|
||||||
|
present on the cart. If no RAM is present, the method should return
|
||||||
|
false. Cart classes should override this method if they contain
|
||||||
|
any extended RAM.
|
||||||
|
|
||||||
|
@param start The beginning of the RAM area (0x0000 - 0x2000)
|
||||||
|
@param size Total number of bytes of area
|
||||||
|
@param roffset Offset to use when reading from RAM (read port)
|
||||||
|
@param woffset Offset to use when writing to RAM (write port)
|
||||||
|
|
||||||
|
@return True if RAM exists and parameters are modified, else false
|
||||||
|
*/
|
||||||
|
virtual bool getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Get the byte at the specified address.
|
Get the byte at the specified address.
|
||||||
|
|
|
@ -285,3 +285,15 @@ bool CartridgeF6SC::load(Deserializer& in)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool CartridgeF6SC::getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset)
|
||||||
|
{
|
||||||
|
start = 0x1000;
|
||||||
|
size = 128;
|
||||||
|
roffset = 0x80;
|
||||||
|
woffset = 0x0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -119,6 +119,22 @@ class CartridgeF6SC : public Cartridge
|
||||||
*/
|
*/
|
||||||
virtual string name() const { return "CartridgeF6SC"; }
|
virtual string name() const { return "CartridgeF6SC"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
This informs the caller of the addressable range of any extended RAM
|
||||||
|
present on the cart. If no RAM is present, the method should return
|
||||||
|
false. Cart classes should override this method if they contain
|
||||||
|
any extended RAM.
|
||||||
|
|
||||||
|
@param start The beginning of the RAM area (0x0000 - 0x2000)
|
||||||
|
@param size Total number of bytes of area
|
||||||
|
@param roffset Offset to use when reading from RAM (read port)
|
||||||
|
@param woffset Offset to use when writing to RAM (write port)
|
||||||
|
|
||||||
|
@return True if RAM exists and parameters are modified, else false
|
||||||
|
*/
|
||||||
|
virtual bool getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Get the byte at the specified address.
|
Get the byte at the specified address.
|
||||||
|
|
|
@ -263,3 +263,15 @@ bool CartridgeF8SC::load(Deserializer& in)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool CartridgeF8SC::getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset)
|
||||||
|
{
|
||||||
|
start = 0x1000;
|
||||||
|
size = 128;
|
||||||
|
roffset = 0x80;
|
||||||
|
woffset = 0x0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -119,6 +119,22 @@ class CartridgeF8SC : public Cartridge
|
||||||
*/
|
*/
|
||||||
virtual string name() const { return "CartridgeF8SC"; }
|
virtual string name() const { return "CartridgeF8SC"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
This informs the caller of the addressable range of any extended RAM
|
||||||
|
present on the cart. If no RAM is present, the method should return
|
||||||
|
false. Cart classes should override this method if they contain
|
||||||
|
any extended RAM.
|
||||||
|
|
||||||
|
@param start The beginning of the RAM area (0x0000 - 0x2000)
|
||||||
|
@param size Total number of bytes of area
|
||||||
|
@param roffset Offset to use when reading from RAM (read port)
|
||||||
|
@param woffset Offset to use when writing to RAM (write port)
|
||||||
|
|
||||||
|
@return True if RAM exists and parameters are modified, else false
|
||||||
|
*/
|
||||||
|
virtual bool getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Get the byte at the specified address.
|
Get the byte at the specified address.
|
||||||
|
|
|
@ -275,3 +275,15 @@ bool CartridgeFASC::load(Deserializer& in)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
bool CartridgeFASC::getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset)
|
||||||
|
{
|
||||||
|
start = 0x1000;
|
||||||
|
size = 256;
|
||||||
|
roffset = 0x100;
|
||||||
|
woffset = 0x0;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -119,6 +119,22 @@ class CartridgeFASC : public Cartridge
|
||||||
*/
|
*/
|
||||||
virtual string name() const { return "CartridgeFASC"; }
|
virtual string name() const { return "CartridgeFASC"; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
This informs the caller of the addressable range of any extended RAM
|
||||||
|
present on the cart. If no RAM is present, the method should return
|
||||||
|
false. Cart classes should override this method if they contain
|
||||||
|
any extended RAM.
|
||||||
|
|
||||||
|
@param start The beginning of the RAM area (0x0000 - 0x2000)
|
||||||
|
@param size Total number of bytes of area
|
||||||
|
@param roffset Offset to use when reading from RAM (read port)
|
||||||
|
@param woffset Offset to use when writing to RAM (write port)
|
||||||
|
|
||||||
|
@return True if RAM exists and parameters are modified, else false
|
||||||
|
*/
|
||||||
|
virtual bool getRamArea(uInt16& start, uInt16& size,
|
||||||
|
uInt16& roffset, uInt16& woffset);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Get the byte at the specified address.
|
Get the byte at the specified address.
|
||||||
|
|
|
@ -191,7 +191,7 @@ bool OSystem::create()
|
||||||
// This logic should also take into account the size of the
|
// This logic should also take into account the size of the
|
||||||
// framebuffer, and try to be intelligent about font sizes
|
// framebuffer, and try to be intelligent about font sizes
|
||||||
// We can probably add ifdefs to take care of corner cases,
|
// We can probably add ifdefs to take care of corner cases,
|
||||||
// but the means we've failed to abstract it enough ...
|
// but that means we've failed to abstract it enough ...
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
bool smallScreen = myDesktopWidth < 640 || myDesktopHeight < 480;
|
bool smallScreen = myDesktopWidth < 640 || myDesktopHeight < 480;
|
||||||
|
|
||||||
|
@ -972,6 +972,5 @@ OSystem::OSystem(const OSystem& osystem)
|
||||||
OSystem& OSystem::operator = (const OSystem&)
|
OSystem& OSystem::operator = (const OSystem&)
|
||||||
{
|
{
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,23 +61,21 @@ static unsigned int down_arrow[8] = {
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
ScrollBarWidget::ScrollBarWidget(GuiObject* boss, const GUI::Font& font,
|
ScrollBarWidget::ScrollBarWidget(GuiObject* boss, const GUI::Font& font,
|
||||||
int x, int y, int w, int h)
|
int x, int y, int w, int h)
|
||||||
: Widget(boss, font, x, y, w, h), CommandSender(boss)
|
: Widget(boss, font, x, y, w, h), CommandSender(boss),
|
||||||
|
_numEntries(0),
|
||||||
|
_entriesPerPage(0),
|
||||||
|
_currentPos(0),
|
||||||
|
_wheel_lines(0),
|
||||||
|
_part(kNoPart),
|
||||||
|
_draggingPart(kNoPart),
|
||||||
|
_sliderHeight(0),
|
||||||
|
_sliderPos(0),
|
||||||
|
_sliderDeltaMouseDownPos(0)
|
||||||
{
|
{
|
||||||
_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG;
|
_flags = WIDGET_ENABLED | WIDGET_TRACK_MOUSE | WIDGET_CLEARBG;
|
||||||
_type = kScrollBarWidget;
|
_type = kScrollBarWidget;
|
||||||
_bgcolor = kWidColor;
|
_bgcolor = kWidColor;
|
||||||
_bgcolorhi = kWidColor;
|
_bgcolorhi = kWidColor;
|
||||||
|
|
||||||
_part = kNoPart;
|
|
||||||
_sliderHeight = 0;
|
|
||||||
_sliderPos = 0;
|
|
||||||
|
|
||||||
_draggingPart = kNoPart;
|
|
||||||
_sliderDeltaMouseDownPos = 0;
|
|
||||||
|
|
||||||
_numEntries = 0;
|
|
||||||
_entriesPerPage = 0;
|
|
||||||
_currentPos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -136,9 +134,9 @@ void ScrollBarWidget::handleMouseWheel(int x, int y, int direction)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(direction < 0)
|
if(direction < 0)
|
||||||
_currentPos -= _WHEEL_LINES;
|
_currentPos -= _wheel_lines ? _wheel_lines : _WHEEL_LINES;
|
||||||
else
|
else
|
||||||
_currentPos += _WHEEL_LINES;
|
_currentPos += _wheel_lines ? _wheel_lines : _WHEEL_LINES;
|
||||||
|
|
||||||
// Make sure that _currentPos is still inside the bounds
|
// Make sure that _currentPos is still inside the bounds
|
||||||
checkBounds(old_pos);
|
checkBounds(old_pos);
|
||||||
|
|
|
@ -61,6 +61,7 @@ class ScrollBarWidget : public Widget, public CommandSender
|
||||||
int _numEntries;
|
int _numEntries;
|
||||||
int _entriesPerPage;
|
int _entriesPerPage;
|
||||||
int _currentPos;
|
int _currentPos;
|
||||||
|
int _wheel_lines;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -140,7 +140,7 @@ UIDialog::UIDialog(OSystem* osystem, DialogContainer* parent,
|
||||||
myDebuggerWidthSlider = new SliderWidget(myTab, font, xpos, ypos, pwidth,
|
myDebuggerWidthSlider = new SliderWidget(myTab, font, xpos, ypos, pwidth,
|
||||||
lineHeight, "Debugger Width: ",
|
lineHeight, "Debugger Width: ",
|
||||||
lwidth, kDWidthChanged);
|
lwidth, kDWidthChanged);
|
||||||
myDebuggerWidthSlider->setMinValue(1030);
|
myDebuggerWidthSlider->setMinValue(1050);
|
||||||
myDebuggerWidthSlider->setMaxValue(1920);
|
myDebuggerWidthSlider->setMaxValue(1920);
|
||||||
myDebuggerWidthSlider->setStepValue(10);
|
myDebuggerWidthSlider->setStepValue(10);
|
||||||
wid.push_back(myDebuggerWidthSlider);
|
wid.push_back(myDebuggerWidthSlider);
|
||||||
|
@ -280,7 +280,7 @@ void UIDialog::loadConfig()
|
||||||
|
|
||||||
// Debugger size
|
// Debugger size
|
||||||
instance().settings().getSize("debuggerres", w, h);
|
instance().settings().getSize("debuggerres", w, h);
|
||||||
w = BSPF_max(w, 1030);
|
w = BSPF_max(w, 1050);
|
||||||
h = BSPF_max(h, 620);
|
h = BSPF_max(h, 620);
|
||||||
w = BSPF_min(w, 1920);
|
w = BSPF_min(w, 1920);
|
||||||
h = BSPF_min(h, 1200);
|
h = BSPF_min(h, 1200);
|
||||||
|
@ -362,8 +362,8 @@ void UIDialog::setDefaults()
|
||||||
}
|
}
|
||||||
|
|
||||||
case 1: // Debugger options
|
case 1: // Debugger options
|
||||||
myDebuggerWidthSlider->setValue(1030);
|
myDebuggerWidthSlider->setValue(1050);
|
||||||
myDebuggerWidthLabel->setValue(1030);
|
myDebuggerWidthLabel->setValue(1050);
|
||||||
myDebuggerHeightSlider->setValue(690);
|
myDebuggerHeightSlider->setValue(690);
|
||||||
myDebuggerHeightLabel->setValue(690);
|
myDebuggerHeightLabel->setValue(690);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue