Cleaned up the Debugger class by moving all CPU related stuff to

CpuDebug.  This is similar to the last commit, which moved all RAM
stuff to RamDebug.

Removed D6502, since it's functionality is provided by CpuDebug and is
no longer required.

The only user-visible change is that the CPU registers in CPU tab now
track changes.  It may seem like a lot of work to just accomplish that,
but the infrastructure will make it much easier to add similar
functionality to new tabs.  Besides, we needed to step back a little
and clean up the codebase.

Still TODO is turn TIADebug into a real DebuggerSystem object, and
finish the TIA tab.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@624 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-07-08 14:36:18 +00:00
parent 9b780540fb
commit 6aa2830d71
14 changed files with 379 additions and 711 deletions

View File

@ -13,16 +13,18 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: CpuDebug.cxx,v 1.1 2005-07-07 18:56:40 stephena Exp $ // $Id: CpuDebug.cxx,v 1.2 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#include "Array.hxx" #include "Array.hxx"
#include "EquateList.hxx"
#include "M6502.hxx" #include "M6502.hxx"
#include "CpuDebug.hxx" #include "CpuDebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CpuDebug::CpuDebug(Console* console) CpuDebug::CpuDebug(Debugger* dbg, Console* console)
: DebuggerSystem(console), : DebuggerSystem(dbg, console),
mySystem(&(console->system())) mySystem(&(console->system()))
{ {
saveOldState(); saveOldState();
@ -70,6 +72,100 @@ void CpuDebug::saveOldState()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CpuDebug::disassemble(int address, char* buffer, EquateList* equateList)
{
// equateList->dumpAll();
int opcode = mySystem->peek(address);
switch(M6502::ourAddressingModeTable[opcode])
{
case M6502::Absolute:
sprintf(buffer, "%s %s ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::AbsoluteX:
sprintf(buffer, "%s %s,x ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::AbsoluteY:
sprintf(buffer, "%s %s,y ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::Immediate:
sprintf(buffer, "%s #$%02X ; %d", M6502::ourInstructionMnemonicTable[opcode],
mySystem->peek(address + 1),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::Implied:
sprintf(buffer, "%s ; %d", M6502::ourInstructionMnemonicTable[opcode],
M6502::ourInstructionProcessorCycleTable[opcode]);
return 1;
case M6502::Indirect:
sprintf(buffer, "%s (%s) ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::IndirectX:
sprintf(buffer, "%s (%s,x) ; %d",
M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::IndirectY:
sprintf(buffer, "%s (%s),y ; %d",
M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::Relative:
sprintf(buffer, "%s %s ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(address + 2 + ((Int16)(Int8)mySystem->peek(address + 1)), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::Zero:
sprintf(buffer, "%s %s ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::ZeroX:
sprintf(buffer, "%s %s,x ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::ZeroY:
sprintf(buffer, "%s %s,y ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
default:
sprintf(buffer, "dc $%02X ; %d", opcode,
M6502::ourInstructionProcessorCycleTable[opcode]);
return 1;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int CpuDebug::dPeek(int address)
{
return dpeek(mySystem, address);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setPC(int pc) void CpuDebug::setPC(int pc)
{ {
@ -82,6 +178,12 @@ void CpuDebug::setSP(int sp)
mySystem->m6502().SP = sp; mySystem->m6502().SP = sp;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setPS(int ps)
{
mySystem->m6502().PS(ps);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setA(int a) void CpuDebug::setA(int a)
{ {
@ -99,3 +201,87 @@ void CpuDebug::setY(int y)
{ {
mySystem->m6502().Y = y; mySystem->m6502().Y = y;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setN(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 7, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setV(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 6, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setB(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 4, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setD(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 3, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setI(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 2, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setZ(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 1, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setC(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 0, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleN()
{
setPS( mySystem->m6502().PS() ^ 0x80 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleV()
{
setPS( mySystem->m6502().PS() ^ 0x40 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleB()
{
setPS( mySystem->m6502().PS() ^ 0x10 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleD()
{
setPS( mySystem->m6502().PS() ^ 0x08 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleI()
{
setPS( mySystem->m6502().PS() ^ 0x04 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleZ()
{
setPS( mySystem->m6502().PS() ^ 0x02 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleC()
{
setPS( mySystem->m6502().PS() ^ 0x01 );
}

View File

@ -13,16 +13,16 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: CpuDebug.hxx,v 1.1 2005-07-07 18:56:41 stephena Exp $ // $Id: CpuDebug.hxx,v 1.2 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#ifndef CPU_DEBUG_HXX #ifndef CPU_DEBUG_HXX
#define CPU_DEBUG_HXX #define CPU_DEBUG_HXX
class System; class EquateList;
#include "Array.hxx" #include "Array.hxx"
#include "Console.hxx" #include "System.hxx"
#include "DebuggerSystem.hxx" #include "DebuggerSystem.hxx"
class CpuState : public DebuggerState class CpuState : public DebuggerState
@ -35,18 +35,54 @@ class CpuState : public DebuggerState
class CpuDebug : public DebuggerSystem class CpuDebug : public DebuggerSystem
{ {
public: public:
CpuDebug(Console* console); CpuDebug(Debugger* dbg, Console* console);
DebuggerState& getState(); DebuggerState& getState();
DebuggerState& getOldState() { return myOldState; } DebuggerState& getOldState() { return myOldState; }
void saveOldState(); void saveOldState();
int disassemble(int address, char* buffer, EquateList* equateList);
int dPeek(int address);
int pc() { return mySystem->m6502().PC; }
void setPC(int pc);
void setSP(int sp);
void setPS(int ps);
void setA(int a); void setA(int a);
void setX(int x); void setX(int x);
void setY(int y); void setY(int y);
void setSP(int sp);
void setPC(int pc); void setN(bool on);
void setV(bool on);
void setB(bool on);
void setD(bool on);
void setI(bool on);
void setZ(bool on);
void setC(bool on);
void toggleN();
void toggleV();
void toggleB();
void toggleD();
void toggleI();
void toggleZ();
void toggleC();
private:
static unsigned char set_bit(unsigned char input, int bit, bool on)
{
if(on)
return input | (1 << bit);
else
return input & (~(1 << bit));
}
static int dpeek(System* system, int address)
{
return system->peek(address) | (system->peek(address + 1) << 8);
}
private: private:
CpuState myState; CpuState myState;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Debugger.cxx,v 1.55 2005-07-08 12:35:53 stephena Exp $ // $Id: Debugger.cxx,v 1.56 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
@ -29,20 +29,21 @@
#include "Console.hxx" #include "Console.hxx"
#include "System.hxx" #include "System.hxx"
#include "M6502.hxx" #include "M6502.hxx"
#include "D6502.hxx"
#include "Debugger.hxx"
#include "EquateList.hxx" #include "EquateList.hxx"
#include "CpuDebug.hxx"
#include "RamDebug.hxx" #include "RamDebug.hxx"
#include "TIADebug.hxx" #include "TIADebug.hxx"
#include "Debugger.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::Debugger(OSystem* osystem) Debugger::Debugger(OSystem* osystem)
: DialogContainer(osystem), : DialogContainer(osystem),
myConsole(NULL), myConsole(NULL),
mySystem(NULL), mySystem(NULL),
myParser(NULL), myParser(NULL),
myDebugger(NULL), myCpuDebug(NULL),
myRamDebug(NULL), myRamDebug(NULL),
myTIAdebug(NULL), myTIAdebug(NULL),
equateList(NULL), equateList(NULL),
@ -56,17 +57,17 @@ Debugger::Debugger(OSystem* osystem)
breakPoints = new PackedBitArray(0x10000); breakPoints = new PackedBitArray(0x10000);
readTraps = new PackedBitArray(0x10000); readTraps = new PackedBitArray(0x10000);
writeTraps = new PackedBitArray(0x10000); writeTraps = new PackedBitArray(0x10000);
oldA = oldX = oldY = oldS = oldP = oldPC = -1;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Debugger::~Debugger() Debugger::~Debugger()
{ {
delete myParser; delete myParser;
delete myDebugger;
delete myCpuDebug;
delete myRamDebug; delete myRamDebug;
delete myTIAdebug; delete myTIAdebug;
delete equateList; delete equateList;
delete breakPoints; delete breakPoints;
delete readTraps; delete readTraps;
@ -127,8 +128,11 @@ void Debugger::setConsole(Console* console)
mySystem = &(myConsole->system()); mySystem = &(myConsole->system());
// Create debugger subsystems // Create debugger subsystems
delete myCpuDebug;
myCpuDebug = new CpuDebug(this, myConsole);
delete myRamDebug; delete myRamDebug;
myRamDebug = new RamDebug(myConsole); myRamDebug = new RamDebug(this, myConsole);
// Create a new TIA debugger for this console // Create a new TIA debugger for this console
// This code is somewhat ugly, since we derive a TIA from the MediaSource // This code is somewhat ugly, since we derive a TIA from the MediaSource
@ -138,13 +142,9 @@ void Debugger::setConsole(Console* console)
myTIAdebug = new TIADebug((TIA*)&myConsole->mediaSource()); myTIAdebug = new TIADebug((TIA*)&myConsole->mediaSource());
myTIAdebug->setDebugger(this); myTIAdebug->setDebugger(this);
// Create a new 6502 debugger for this console
delete myDebugger;
myDebugger = new D6502(mySystem);
autoLoadSymbols(myOSystem->romFile()); autoLoadSymbols(myOSystem->romFile());
saveState(); saveOldState();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -216,26 +216,28 @@ const string Debugger::invIfChanged(int reg, int oldReg) {
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::state() const string Debugger::cpuState()
{ {
string result; string result;
char buf[255]; char buf[255];
//cerr << "state(): pc is " << myDebugger->pc() << endl; CpuState state = (CpuState&) myCpuDebug->getState();
CpuState oldstate = (CpuState&) myCpuDebug->getOldState();
result += "\nPC="; result += "\nPC=";
result += invIfChanged(myDebugger->pc(), oldPC); result += invIfChanged(state.PC, oldstate.PC);
result += " A="; result += " A=";
result += invIfChanged(myDebugger->a(), oldA); result += invIfChanged(state.A, oldstate.A);
result += " X="; result += " X=";
result += invIfChanged(myDebugger->x(), oldX); result += invIfChanged(state.X, oldstate.X);
result += " Y="; result += " Y=";
result += invIfChanged(myDebugger->y(), oldY); result += invIfChanged(state.Y, oldstate.Y);
result += " S="; result += " S=";
result += invIfChanged(myDebugger->sp(), oldS); result += invIfChanged(state.SP, oldstate.SP);
result += " P="; result += " P=";
result += invIfChanged(myDebugger->ps(), oldP); result += invIfChanged(state.PS, oldstate.PS);
result += "/"; result += "/";
formatFlags(myDebugger->ps(), buf); formatFlags(state.PSbits, buf);
result += buf; result += buf;
result += "\n Cyc:"; result += "\n Cyc:";
sprintf(buf, "%d", mySystem->cycles()); sprintf(buf, "%d", mySystem->cycles());
@ -251,7 +253,7 @@ const string Debugger::state()
result += buf; result += buf;
result += "\n "; result += "\n ";
result += disassemble(myDebugger->pc(), 1); result += disassemble(state.PC, 1);
return result; return result;
} }
@ -339,47 +341,47 @@ const string Debugger::riotState() {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::reset() { void Debugger::reset() {
int pc = myDebugger->dPeek(0xfffc); int pc = myCpuDebug->dPeek(0xfffc);
myDebugger->pc(pc); myCpuDebug->setPC(pc);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::formatFlags(int f, char *out) { void Debugger::formatFlags(BoolArray& b, char *out) {
// NV-BDIZC // NV-BDIZC
if(f & 128) if(b[7])
out[0] = 'N'; out[0] = 'N';
else else
out[0] = 'n'; out[0] = 'n';
if(f & 64) if(b[6])
out[1] = 'V'; out[1] = 'V';
else else
out[1] = 'v'; out[1] = 'v';
out[2] = '-'; out[2] = '-';
if(f & 16) if(b[4])
out[3] = 'B'; out[3] = 'B';
else else
out[3] = 'b'; out[3] = 'b';
if(f & 8) if(b[3])
out[4] = 'D'; out[4] = 'D';
else else
out[4] = 'd'; out[4] = 'd';
if(f & 4) if(b[2])
out[5] = 'I'; out[5] = 'I';
else else
out[5] = 'i'; out[5] = 'i';
if(f & 2) if(b[1])
out[6] = 'Z'; out[6] = 'Z';
else else
out[6] = 'z'; out[6] = 'z';
if(f & 1) if(b[0])
out[7] = 'C'; out[7] = 'C';
else else
out[7] = 'c'; out[7] = 'c';
@ -387,31 +389,6 @@ void Debugger::formatFlags(int f, char *out) {
out[8] = '\0'; out[8] = '\0';
} }
/* Danger: readRAM() and writeRAM() take an *offset* into RAM, *not* an
actual address. This means you don't get to use these to read/write
outside of the RIOT RAM. It also means that e.g. to read location 0x80,
you pass 0 (because 0x80 is the 0th byte of RAM).
However, setRAM() actually uses addresses, not offsets. This means that
setRAM() can poke anywhere in the address space. However, it still can't
change ROM: you use patchROM() for that. setRAM() *can* trigger a bank
switch, if you poke to the "hot spot" for the cartridge.
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Debugger::readRAM(uInt16 offset)
{
offset &= 0x7f; // there are only 128 bytes
return mySystem->peek(offset + kRamStart);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::writeRAM(uInt16 offset, uInt8 value)
{
offset &= 0x7f; // there are only 128 bytes
mySystem->poke(offset + kRamStart, value);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* Element 0 of args is the address. The remaining elements are the data /* Element 0 of args is the address. The remaining elements are the data
to poke, starting at the given address. to poke, starting at the given address.
@ -521,7 +498,7 @@ void Debugger::quit()
// execute one instruction on quit, IF we're // execute one instruction on quit, IF we're
// sitting at a breakpoint. This will get us past it. // sitting at a breakpoint. This will get us past it.
// Somehow this feels like a hack to me, but I don't know why // Somehow this feels like a hack to me, but I don't know why
if(breakPoints->isSet(myDebugger->pc())) if(breakPoints->isSet(myCpuDebug->pc()))
mySystem->m6502().execute(1); mySystem->m6502().execute(1);
myOSystem->eventHandler().leaveDebugMode(); myOSystem->eventHandler().leaveDebugMode();
} }
@ -542,7 +519,7 @@ void Debugger::loadState(int state)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::step() int Debugger::step()
{ {
saveState(); saveOldState();
int cyc = mySystem->cycles(); int cyc = mySystem->cycles();
mySystem->m6502().execute(1); mySystem->m6502().execute(1);
@ -567,12 +544,12 @@ int Debugger::step()
int Debugger::trace() int Debugger::trace()
{ {
// 32 is the 6502 JSR instruction: // 32 is the 6502 JSR instruction:
if(mySystem->peek(myDebugger->pc()) == 32) { if(mySystem->peek(myCpuDebug->pc()) == 32) {
saveState(); saveOldState();
int cyc = mySystem->cycles(); int cyc = mySystem->cycles();
int targetPC = myDebugger->pc() + 3; // return address int targetPC = myCpuDebug->pc() + 3; // return address
while(myDebugger->pc() != targetPC) while(myCpuDebug->pc() != targetPC)
mySystem->m6502().execute(1); mySystem->m6502().execute(1);
myTIAdebug->updateTIA(); myTIAdebug->updateTIA();
myOSystem->frameBuffer().refreshTIA(true); myOSystem->frameBuffer().refreshTIA(true);
@ -582,112 +559,6 @@ int Debugger::trace()
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setA(int a) {
myDebugger->a(a);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setX(int x) {
myDebugger->x(x);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setY(int y) {
myDebugger->y(y);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setSP(int sp) {
myDebugger->sp(sp);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setPC(int pc) {
myDebugger->pc(pc);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// NV-BDIZC
void Debugger::toggleC() {
myDebugger->ps( myDebugger->ps() ^ 0x01 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleZ() {
myDebugger->ps( myDebugger->ps() ^ 0x02 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleI() {
myDebugger->ps( myDebugger->ps() ^ 0x04 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleD() {
myDebugger->ps( myDebugger->ps() ^ 0x08 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleB() {
myDebugger->ps( myDebugger->ps() ^ 0x10 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleV() {
myDebugger->ps( myDebugger->ps() ^ 0x40 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleN() {
myDebugger->ps( myDebugger->ps() ^ 0x80 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// NV-BDIZC
void Debugger::setC(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 0, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x01 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setZ(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 1, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x02 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setI(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 2, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x04 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setD(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 3, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x08 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setB(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 4, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x10 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setV(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 6, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x40 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::setN(bool value) {
myDebugger->ps( set_bit(myDebugger->ps(), 7, value) );
// myDebugger->ps( myDebugger->ps() ^ 0x80 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EquateList *Debugger::equates() { EquateList *Debugger::equates() {
return equateList; return equateList;
@ -696,13 +567,13 @@ EquateList *Debugger::equates() {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::toggleBreakPoint(int bp) { void Debugger::toggleBreakPoint(int bp) {
mySystem->m6502().setBreakPoints(breakPoints); mySystem->m6502().setBreakPoints(breakPoints);
if(bp < 0) bp = myDebugger->pc(); if(bp < 0) bp = myCpuDebug->pc();
breakPoints->toggle(bp); breakPoints->toggle(bp);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Debugger::breakPoint(int bp) { bool Debugger::breakPoint(int bp) {
if(bp < 0) bp = myDebugger->pc(); if(bp < 0) bp = myCpuDebug->pc();
return breakPoints->isSet(bp) != 0; return breakPoints->isSet(bp) != 0;
} }
@ -734,36 +605,6 @@ bool Debugger::writeTrap(int t) {
return writeTraps->isSet(t) != 0; return writeTraps->isSet(t) != 0;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::getPC() {
return myDebugger->pc();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::getA() {
return myDebugger->a();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::getX() {
return myDebugger->x();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::getY() {
return myDebugger->y();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::getSP() {
return myDebugger->sp();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::getPS() {
return myDebugger->ps();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Debugger::cycles() { int Debugger::cycles() {
return mySystem->cycles(); return mySystem->cycles();
@ -780,7 +621,7 @@ string Debugger::disassemble(int start, int lines) {
result += label; result += label;
result += ": "; result += ": ";
int count = myDebugger->disassemble(start, buf, equateList); int count = myCpuDebug->disassemble(start, buf, equateList);
for(int i=0; i<count; i++) { for(int i=0; i<count; i++) {
sprintf(bbuf, "%02x ", peek(start++)); sprintf(bbuf, "%02x ", peek(start++));
@ -800,7 +641,7 @@ string Debugger::disassemble(int start, int lines) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::nextFrame(int frames) { void Debugger::nextFrame(int frames) {
saveState(); saveOldState();
myOSystem->frameBuffer().advance(frames); myOSystem->frameBuffer().advance(frames);
} }
@ -833,6 +674,8 @@ int Debugger::dpeek(int addr) {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Debugger::setHeight(int height) bool Debugger::setHeight(int height)
{ {
// FIXME - this doesn't seem to work ...
myOSystem->settings().getInt("debugheight"); myOSystem->settings().getInt("debugheight");
if(height == 0) if(height == 0)
@ -894,14 +737,8 @@ bool Debugger::patchROM(int addr, int value) {
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::saveState() void Debugger::saveOldState()
{ {
myCpuDebug->saveOldState();
myRamDebug->saveOldState(); myRamDebug->saveOldState();
oldA = getA();
oldX = getX();
oldY = getY();
oldS = getSP();
oldP = getPS();
oldPC = getPC();
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: Debugger.hxx,v 1.44 2005-07-08 12:36:06 stephena Exp $ // $Id: Debugger.hxx,v 1.45 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_HXX #ifndef DEBUGGER_HXX
@ -23,10 +23,11 @@ class OSystem;
class Console; class Console;
class System; class System;
class D6502; class CpuDebug;
class RamDebug; class RamDebug;
class TIADebug; class TIADebug;
#include "Array.hxx"
#include "DialogContainer.hxx" #include "DialogContainer.hxx"
#include "M6502.hxx" #include "M6502.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
@ -52,17 +53,15 @@ enum {
for all debugging operations in Stella (parser, 6502 debugger, etc). for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony @author Stephen Anthony
@version $Id: Debugger.hxx,v 1.44 2005-07-08 12:36:06 stephena Exp $ @version $Id: Debugger.hxx,v 1.45 2005-07-08 14:36:17 stephena Exp $
*/ */
class Debugger : public DialogContainer class Debugger : public DialogContainer
{ {
friend class DebuggerParser; friend class DebuggerParser;
friend class RamDebug;
friend class TIADebug;
public: public:
/** /**
Create a new menu stack Create a new debugger parent object
*/ */
Debugger(OSystem* osystem); Debugger(OSystem* osystem);
@ -87,13 +86,24 @@ class Debugger : public DialogContainer
*/ */
void setConsole(Console* console); void setConsole(Console* console);
/* Save state of each debugger subsystem */ /**
void saveState(); Save state of each debugger subsystem
*/
void saveOldState();
/* The debugger subsystem responsible for all RAM state */ /**
The debugger subsystem responsible for all CPU state
*/
CpuDebug& cpuDebug() { return *myCpuDebug; }
/**
The debugger subsystem responsible for all RAM state
*/
RamDebug& ramDebug() { return *myRamDebug; } RamDebug& ramDebug() { return *myRamDebug; }
/* The debugger subsystem responsible for all TIA state */ /**
The debugger subsystem responsible for all TIA state
*/
TIADebug& tiaDebug() { return *myTIAdebug; } TIADebug& tiaDebug() { return *myTIAdebug; }
/** Convenience methods to convert to hexidecimal values */ /** Convenience methods to convert to hexidecimal values */
@ -137,14 +147,6 @@ class Debugger : public DialogContainer
return to_bin(dec, 16, buf); return to_bin(dec, 16, buf);
} }
static unsigned char set_bit(unsigned char input, int bit, bool value) {
if(value)
return input | (1 << bit);
else
return input & (~(1 << bit));
}
int stringToValue(const string& stringval) int stringToValue(const string& stringval)
{ return myParser->decipher_arg(stringval); } { return myParser->decipher_arg(stringval); }
const string valueToString(int value, BaseFormat outputBase = kBASE_DEFAULT); const string valueToString(int value, BaseFormat outputBase = kBASE_DEFAULT);
@ -159,7 +161,6 @@ class Debugger : public DialogContainer
bool writeTrap(int t); bool writeTrap(int t);
void clearAllTraps(); void clearAllTraps();
string disassemble(int start, int lines); string disassemble(int start, int lines);
bool setHeight(int height); bool setHeight(int height);
@ -175,7 +176,7 @@ class Debugger : public DialogContainer
Give the contents of the CPU registers and disassembly of Give the contents of the CPU registers and disassembly of
next instruction. next instruction.
*/ */
const string state(); const string cpuState();
/** /**
Get contents of RIOT switch & timer registers Get contents of RIOT switch & timer registers
@ -189,10 +190,6 @@ class Debugger : public DialogContainer
const string dumpRAM(); const string dumpRAM();
const string dumpTIA(); const string dumpTIA();
// Read and write 128-byte RAM area
uInt8 readRAM(uInt16 addr);
void writeRAM(uInt16 addr, uInt8 value);
// set a bunch of RAM locations at once // set a bunch of RAM locations at once
const string setRAM(IntArray& args); const string setRAM(IntArray& args);
@ -200,42 +197,17 @@ class Debugger : public DialogContainer
void quit(); void quit();
int trace(); int trace();
int step(); int step();
void setA(int a);
void setX(int x);
void setY(int y);
void setSP(int sp);
void setPC(int pc);
int getPC();
int getA();
int getX();
int getY();
int getPS();
int getSP();
int cycles(); int cycles();
int peek(int addr); int peek(int addr);
int dpeek(int addr); int dpeek(int addr);
// CPU flags: NV-BDIZC
void toggleN();
void toggleV();
void toggleB();
void toggleD();
void toggleI();
void toggleZ();
void toggleC();
void setN(bool value);
void setV(bool value);
void setB(bool value);
void setD(bool value);
void setI(bool value);
void setZ(bool value);
void setC(bool value);
void reset(); void reset();
void autoLoadSymbols(string file); void autoLoadSymbols(string file);
void nextFrame(int frames); void nextFrame(int frames);
void clearAllBreakPoints(); void clearAllBreakPoints();
void formatFlags(int f, char *out); void formatFlags(BoolArray& b, char *out);
EquateList *equates(); EquateList *equates();
PromptWidget *prompt() { return myPrompt; } PromptWidget *prompt() { return myPrompt; }
string showWatches(); string showWatches();
@ -262,22 +234,15 @@ class Debugger : public DialogContainer
System* mySystem; System* mySystem;
DebuggerParser* myParser; DebuggerParser* myParser;
D6502* myDebugger; CpuDebug* myCpuDebug;
RamDebug *myRamDebug; RamDebug* myRamDebug;
TIADebug *myTIAdebug; TIADebug* myTIAdebug;
EquateList *equateList; EquateList *equateList;
PackedBitArray *breakPoints; PackedBitArray *breakPoints;
PackedBitArray *readTraps; PackedBitArray *readTraps;
PackedBitArray *writeTraps; PackedBitArray *writeTraps;
PromptWidget *myPrompt; PromptWidget *myPrompt;
int oldA;
int oldX;
int oldY;
int oldS;
int oldP;
int oldPC;
}; };
#endif #endif

View File

@ -13,16 +13,17 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: DebuggerParser.cxx,v 1.48 2005-07-07 15:18:57 stephena Exp $ // $Id: DebuggerParser.cxx,v 1.49 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#include "bspf.hxx" #include "bspf.hxx"
#include "Debugger.hxx" #include "Debugger.hxx"
#include "DebuggerParser.hxx" #include "CpuDebug.hxx"
#include "D6502.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
#include "YaccParser.hxx" #include "YaccParser.hxx"
#include "DebuggerParser.hxx"
Command DebuggerParser::commands[] = { Command DebuggerParser::commands[] = {
{ {
"a", "a",
@ -488,12 +489,13 @@ int DebuggerParser::decipher_arg(const string &str) {
if(bin && dec) return -1; if(bin && dec) return -1;
// Special cases (registers): // Special cases (registers):
if(arg == "a") result = debugger->getA(); CpuState& state = (CpuState&) debugger->cpuDebug().getState();
else if(arg == "x") result = debugger->getX(); if(arg == "a") result = state.A;
else if(arg == "y") result = debugger->getY(); else if(arg == "x") result = state.X;
else if(arg == "p") result = debugger->getPS(); else if(arg == "y") result = state.Y;
else if(arg == "s") result = debugger->getSP(); else if(arg == "p") result = state.PS;
else if(arg == "pc" || arg == ".") result = debugger->getPC(); else if(arg == "s") result = state.SP;
else if(arg == "pc" || arg == ".") result = state.PC;
else { // Not a special, must be a regular arg: check for label first else { // Not a special, must be a regular arg: check for label first
const char *a = arg.c_str(); const char *a = arg.c_str();
result = debugger->equateList->getAddress(a); result = debugger->equateList->getAddress(a);
@ -654,7 +656,7 @@ string DebuggerParser::disasm() {
int start, lines = 20; int start, lines = 20;
if(argCount == 0) { if(argCount == 0) {
start = debugger->getPC(); start = debugger->cpuDebug().pc();
} else if(argCount == 1) { } else if(argCount == 1) {
start = args[0]; start = args[0];
} else if(argCount == 2) { } else if(argCount == 2) {
@ -939,7 +941,7 @@ const char *DebuggerParser::getCompletionPrefix() {
// "a" // "a"
void DebuggerParser::executeA() { void DebuggerParser::executeA() {
debugger->setA(args[0]); debugger->cpuDebug().setA(args[0]);
} }
// "bank" // "bank"
@ -1001,7 +1003,7 @@ void DebuggerParser::executeBase() {
void DebuggerParser::executeBreak() { void DebuggerParser::executeBreak() {
int bp; int bp;
if(argCount == 0) if(argCount == 0)
bp = debugger->getPC(); bp = debugger->cpuDebug().pc();
else else
bp = args[0]; bp = args[0];
@ -1019,9 +1021,9 @@ void DebuggerParser::executeBreak() {
// "c" // "c"
void DebuggerParser::executeC() { void DebuggerParser::executeC() {
if(argCount == 0) if(argCount == 0)
debugger->toggleC(); debugger->cpuDebug().toggleC();
else if(argCount == 1) else if(argCount == 1)
debugger->setC(args[0]); debugger->cpuDebug().setC(args[0]);
} }
// "clearbreaks" // "clearbreaks"
@ -1052,9 +1054,9 @@ void DebuggerParser::executeColortest() {
// "d" // "d"
void DebuggerParser::executeD() { void DebuggerParser::executeD() {
if(argCount == 0) if(argCount == 0)
debugger->toggleD(); debugger->cpuDebug().toggleD();
else if(argCount == 1) else if(argCount == 1)
debugger->setD(args[0]); debugger->cpuDebug().setD(args[0]);
} }
// "define" // "define"
@ -1137,14 +1139,14 @@ void DebuggerParser::executeLoadsym() {
// "n" // "n"
void DebuggerParser::executeN() { void DebuggerParser::executeN() {
if(argCount == 0) if(argCount == 0)
debugger->toggleN(); debugger->cpuDebug().toggleN();
else if(argCount == 1) else if(argCount == 1)
debugger->setN(args[0]); debugger->cpuDebug().setN(args[0]);
} }
// "pc" // "pc"
void DebuggerParser::executePc() { void DebuggerParser::executePc() {
debugger->setPC(args[0]); debugger->cpuDebug().setPC(args[0]);
} }
// "print" // "print"
@ -1195,14 +1197,14 @@ void DebuggerParser::executeRom() {
// "run" // "run"
void DebuggerParser::executeRun() { void DebuggerParser::executeRun() {
debugger->saveState(); debugger->saveOldState(); // FIXME - why is this here?
debugger->quit(); debugger->quit();
commandResult = "exiting debugger"; commandResult = "exiting debugger";
} }
// "s" // "s"
void DebuggerParser::executeS() { void DebuggerParser::executeS() {
debugger->setSP(args[0]); debugger->cpuDebug().setSP(args[0]);
} }
// "saveses" // "saveses"
@ -1282,9 +1284,9 @@ void DebuggerParser::executeUndef() {
// "v" // "v"
void DebuggerParser::executeV() { void DebuggerParser::executeV() {
if(argCount == 0) if(argCount == 0)
debugger->toggleV(); debugger->cpuDebug().toggleV();
else if(argCount == 1) else if(argCount == 1)
debugger->setV(args[0]); debugger->cpuDebug().setV(args[0]);
} }
// "watch" // "watch"
@ -1295,19 +1297,19 @@ void DebuggerParser::executeWatch() {
// "x" // "x"
void DebuggerParser::executeX() { void DebuggerParser::executeX() {
debugger->setX(args[0]); debugger->cpuDebug().setX(args[0]);
} }
// "y" // "y"
void DebuggerParser::executeY() { void DebuggerParser::executeY() {
debugger->setY(args[0]); debugger->cpuDebug().setY(args[0]);
} }
// "z" // "z"
void DebuggerParser::executeZ() { void DebuggerParser::executeZ() {
if(argCount == 0) if(argCount == 0)
debugger->toggleZ(); debugger->cpuDebug().toggleZ();
else if(argCount == 1) else if(argCount == 1)
debugger->setZ(args[0]); debugger->cpuDebug().setZ(args[0]);
} }

View File

@ -13,12 +13,13 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: DebuggerSystem.hxx,v 1.2 2005-07-07 18:56:41 stephena Exp $ // $Id: DebuggerSystem.hxx,v 1.3 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#ifndef DEBUGGER_SYSTEM_HXX #ifndef DEBUGGER_SYSTEM_HXX
#define DEBUGGER_SYSTEM_HXX #define DEBUGGER_SYSTEM_HXX
#include "Debugger.hxx"
#include "Console.hxx" #include "Console.hxx"
/** /**
@ -41,13 +42,16 @@ class DebuggerState
class DebuggerSystem class DebuggerSystem
{ {
public: public:
DebuggerSystem(Console* console) { } DebuggerSystem(Debugger* dbg, Console* console) { myDebugger = dbg; }
virtual ~DebuggerSystem() { } virtual ~DebuggerSystem() { }
virtual DebuggerState& getState() = 0; virtual DebuggerState& getState() = 0;
virtual DebuggerState& getOldState() = 0; virtual DebuggerState& getOldState() = 0;
virtual void saveOldState() = 0; virtual void saveOldState() = 0;
protected:
Debugger* myDebugger;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: RamDebug.cxx,v 1.2 2005-07-07 18:56:41 stephena Exp $ // $Id: RamDebug.cxx,v 1.3 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#include "Array.hxx" #include "Array.hxx"
@ -21,8 +21,8 @@
#include "RamDebug.hxx" #include "RamDebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RamDebug::RamDebug(Console* console) RamDebug::RamDebug(Debugger* dbg, Console* console)
: DebuggerSystem(console), : DebuggerSystem(dbg, console),
mySystem(&(console->system())) mySystem(&(console->system()))
{ {
saveOldState(); saveOldState();

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: RamDebug.hxx,v 1.2 2005-07-07 18:56:41 stephena Exp $ // $Id: RamDebug.hxx,v 1.3 2005-07-08 14:36:17 stephena Exp $
//============================================================================ //============================================================================
#ifndef RAM_DEBUG_HXX #ifndef RAM_DEBUG_HXX
@ -33,7 +33,7 @@ class RamState : public DebuggerState
class RamDebug : public DebuggerSystem class RamDebug : public DebuggerSystem
{ {
public: public:
RamDebug(Console* console); RamDebug(Debugger* dbg, Console* console);
DebuggerState& getState(); DebuggerState& getState();
DebuggerState& getOldState() { return myOldState; } DebuggerState& getOldState() { return myOldState; }

View File

@ -1,7 +1,6 @@
MODULE := src/emucore/m6502 MODULE := src/emucore/m6502
MODULE_OBJS := \ MODULE_OBJS := \
src/emucore/m6502/src/D6502.o \
src/emucore/m6502/src/Device.o \ src/emucore/m6502/src/Device.o \
src/emucore/m6502/src/M6502.o \ src/emucore/m6502/src/M6502.o \
src/emucore/m6502/src/M6502Hi.o \ src/emucore/m6502/src/M6502Hi.o \

View File

@ -1,208 +0,0 @@
//============================================================================
//
// MM MM 6666 555555 0000 2222
// MMMM MMMM 66 66 55 00 00 22 22
// MM MMM MM 66 55 00 00 22
// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator"
// MM MM 66 66 55 00 00 22
// MM MM 66 66 55 55 00 00 22
// MM MM 6666 5555 0000 222222
//
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: D6502.cxx,v 1.10 2005-06-29 03:43:38 urchlay Exp $
//============================================================================
#include <stdio.h>
#include "D6502.hxx"
#include "M6502.hxx"
#include "System.hxx"
#include "EquateList.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
D6502::D6502(System* system)
: mySystem(system)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
D6502::~D6502()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static uInt16 dpeek(System* system, uInt16 address)
{
return (uInt16)system->peek(address) |
(((uInt16)system->peek(address + 1)) << 8);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 D6502::dPeek(uInt16 address)
{
return dpeek(mySystem, address);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 D6502::disassemble(uInt16 address, char* buffer, EquateList *equateList)
{
// equateList->dumpAll();
uInt8 opcode = mySystem->peek(address);
switch(M6502::ourAddressingModeTable[opcode])
{
case M6502::Absolute:
sprintf(buffer, "%s %s ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::AbsoluteX:
sprintf(buffer, "%s %s,x ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::AbsoluteY:
sprintf(buffer, "%s %s,y ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::Immediate:
sprintf(buffer, "%s #$%02X ; %d", M6502::ourInstructionMnemonicTable[opcode],
mySystem->peek(address + 1),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::Implied:
sprintf(buffer, "%s ; %d", M6502::ourInstructionMnemonicTable[opcode],
M6502::ourInstructionProcessorCycleTable[opcode]);
return 1;
case M6502::Indirect:
sprintf(buffer, "%s (%s) ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(dpeek(mySystem, address + 1), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 3;
case M6502::IndirectX:
sprintf(buffer, "%s (%s,x) ; %d",
M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::IndirectY:
sprintf(buffer, "%s (%s),y ; %d",
M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::Relative:
sprintf(buffer, "%s %s ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(address + 2 + ((Int16)(Int8)mySystem->peek(address + 1)), 4),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::Zero:
sprintf(buffer, "%s %s ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::ZeroX:
sprintf(buffer, "%s %s,x ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
case M6502::ZeroY:
sprintf(buffer, "%s %s,y ; %d", M6502::ourInstructionMnemonicTable[opcode],
equateList->getFormatted(mySystem->peek(address + 1), 2),
M6502::ourInstructionProcessorCycleTable[opcode]);
return 2;
default:
sprintf(buffer, "dc $%02X ; %d", opcode,
M6502::ourInstructionProcessorCycleTable[opcode]);
return 1;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 D6502::a()
{
return mySystem->m6502().A;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void D6502::a(uInt8 value)
{
mySystem->m6502().A = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 D6502::pc()
{
return mySystem->m6502().PC;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void D6502::pc(uInt16 value)
{
mySystem->m6502().PC = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 D6502::ps()
{
return mySystem->m6502().PS();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void D6502::ps(uInt8 value)
{
mySystem->m6502().PS(value);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 D6502::sp()
{
return mySystem->m6502().SP;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void D6502::sp(uInt8 value)
{
mySystem->m6502().SP = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 D6502::x()
{
return mySystem->m6502().X;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void D6502::x(uInt8 value)
{
mySystem->m6502().X = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 D6502::y()
{
return mySystem->m6502().Y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void D6502::y(uInt8 value)
{
mySystem->m6502().Y = value;
}

View File

@ -1,155 +0,0 @@
//============================================================================
//
// MM MM 6666 555555 0000 2222
// MMMM MMMM 66 66 55 00 00 22 22
// MM MMM MM 66 55 00 00 22
// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator"
// MM MM 66 66 55 00 00 22
// MM MM 66 66 55 55 00 00 22
// MM MM 6666 5555 0000 222222
//
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: D6502.hxx,v 1.6 2005-06-16 01:11:28 stephena Exp $
//============================================================================
#ifndef D6502_HXX
#define D6502_HXX
class D6502;
class M6502;
class System;
#include "bspf.hxx"
#include "EquateList.hxx"
/**
This is a base class for 6502 debuggers. This class provides the
basic functionality needed for interactive debuggers.
@author Bradford W. Mott
@version $Id: D6502.hxx,v 1.6 2005-06-16 01:11:28 stephena Exp $
*/
class D6502
{
public:
/**
Create a new 6502 debugger for the specified system
@param system The system the debugger should operate on
*/
D6502(System* system);
/**
Destructor
*/
virtual ~D6502();
public:
/**
Disassemble a single instruction at the specified address into
the given buffer and answer the number of bytes disassembled.
The buffer should be at least 20 characters long.
@param address The address to disassemble code at
@param buffer The buffer where the ASCII disassemble should be stored
@return The number of bytes disassembled
*/
uInt16 disassemble(uInt16 address, char* buffer, EquateList *equateList);
public:
/**
Get the value of the accumulator
@return The accumulator's value
*/
uInt8 a();
/**
Change value of the accumulator
@param value The value to set the accumulator to
*/
void a(uInt8 value);
/**
Get value of the program counter
@return The program counter's value
*/
uInt16 pc();
/**
Change value of the program counter
@param value The value to set the program counter to
*/
void pc(uInt16 value);
/**
Get the value of the processor status register
@return The processor status register's value
*/
uInt8 ps();
/**
Change value of the processor status register
@param value The value to set the processor status register to
*/
void ps(uInt8 value);
/**
Get the value of the stack pointer
@return The stack pointer's value
*/
uInt8 sp();
/**
Change value of the stack pointer
@param value The value to set the stack pointer to
*/
void sp(uInt8 value);
/**
Get the value of the X index register
@return The X register's value
*/
uInt8 x();
/**
Change value of the X index register
@param value The value to set the X register to
*/
void x(uInt8 value);
/**
Get the value of the Y index register
@return The Y register's value
*/
uInt8 y();
/**
Change value of the Y index register
@param value The value to set the Y register to
*/
void y(uInt8 value);
uInt16 dPeek(uInt16 address);
protected:
// Pointer to the system I'm debugging
System* mySystem;
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: CheatWidget.cxx,v 1.11 2005-07-05 15:25:44 stephena Exp $ // $Id: CheatWidget.cxx,v 1.12 2005-07-08 14:36:18 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -25,7 +25,7 @@
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "GuiUtils.hxx" #include "GuiUtils.hxx"
#include "GuiObject.hxx" #include "GuiObject.hxx"
#include "Debugger.hxx" #include "RamDebug.hxx"
#include "Widget.hxx" #include "Widget.hxx"
#include "EditNumWidget.hxx" #include "EditNumWidget.hxx"
#include "AddrValueWidget.hxx" #include "AddrValueWidget.hxx"
@ -123,7 +123,7 @@ void CheatWidget::handleCommand(CommandSender* sender, int cmd, int data, int id
case kAVItemDataChangedCmd: case kAVItemDataChangedCmd:
int addr = myResultsList->getSelectedAddr() - kRamStart; int addr = myResultsList->getSelectedAddr() - kRamStart;
int value = myResultsList->getSelectedValue(); int value = myResultsList->getSelectedValue();
instance()->debugger().writeRAM(addr, value); instance()->debugger().ramDebug().write(addr, value);
break; break;
} }
} }
@ -153,7 +153,7 @@ void CheatWidget::doSearch()
// 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
Debugger& dbg = instance()->debugger(); RamDebug& dbg = instance()->debugger().ramDebug();
AddrValue av; AddrValue av;
int searchCount = 0; int searchCount = 0;
for(int addr = 0; addr < kRamSize; ++addr) for(int addr = 0; addr < kRamSize; ++addr)
@ -163,7 +163,7 @@ void CheatWidget::doSearch()
av.addr = addr; av.addr = addr;
av.value = searchVal; av.value = searchVal;
if(dbg.readRAM(av.addr) == av.value) if(dbg.read(av.addr) == av.value)
{ {
mySearchArray.push_back(av); mySearchArray.push_back(av);
++searchCount; ++searchCount;
@ -172,7 +172,7 @@ void CheatWidget::doSearch()
else // match all memory locations else // match all memory locations
{ {
av.addr = addr; av.addr = addr;
av.value = dbg.readRAM(av.addr); av.value = dbg.read(av.addr);
mySearchArray.push_back(av); mySearchArray.push_back(av);
++searchCount; ++searchCount;
} }
@ -236,7 +236,7 @@ void CheatWidget::doCompare()
AddrValueList tempList; AddrValueList tempList;
// Now, search all memory locations specified in mySearchArray for this value // Now, search all memory locations specified in mySearchArray for this value
Debugger& dbg = instance()->debugger(); RamDebug& dbg = instance()->debugger().ramDebug();
AddrValue av; AddrValue av;
int searchCount = 0; int searchCount = 0;
@ -255,7 +255,7 @@ void CheatWidget::doCompare()
else else
av.value = searchVal; av.value = searchVal;
if(dbg.readRAM(av.addr) == av.value) if(dbg.read(av.addr) == av.value)
{ {
tempList.push_back(av); tempList.push_back(av);
++searchCount; ++searchCount;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: CpuWidget.cxx,v 1.13 2005-07-07 15:19:01 stephena Exp $ // $Id: CpuWidget.cxx,v 1.14 2005-07-08 14:36:18 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -25,6 +25,7 @@
#include "GuiUtils.hxx" #include "GuiUtils.hxx"
#include "GuiObject.hxx" #include "GuiObject.hxx"
#include "Debugger.hxx" #include "Debugger.hxx"
#include "CpuDebug.hxx"
#include "Widget.hxx" #include "Widget.hxx"
#include "DataGridWidget.hxx" #include "DataGridWidget.hxx"
#include "EditTextWidget.hxx" #include "EditTextWidget.hxx"
@ -140,7 +141,7 @@ CpuWidget::~CpuWidget()
void CpuWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) void CpuWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
{ {
int addr, value; int addr, value;
Debugger& dbg = instance()->debugger(); CpuDebug& dbg = instance()->debugger().cpuDebug();
switch(cmd) switch(cmd)
{ {
@ -226,6 +227,10 @@ void CpuWidget::fillGrid()
IntArray vlist; IntArray vlist;
BoolArray changed; BoolArray changed;
CpuDebug& cpu = instance()->debugger().cpuDebug();
CpuState state = (CpuState&) cpu.getState();
CpuState oldstate = (CpuState&) cpu.getOldState();
// We push the enumerated items as addresses, and deal with the real // We push the enumerated items as addresses, and deal with the real
// address in the callback (handleCommand) // address in the callback (handleCommand)
alist.push_back(kPCRegAddr); alist.push_back(kPCRegAddr);
@ -235,33 +240,30 @@ void CpuWidget::fillGrid()
alist.push_back(kYRegAddr); alist.push_back(kYRegAddr);
// And now fill the values // And now fill the values
Debugger& dbg = instance()->debugger(); vlist.push_back(state.PC);
vlist.push_back(dbg.getPC()); vlist.push_back(state.SP);
vlist.push_back(dbg.getSP()); vlist.push_back(state.A);
vlist.push_back(dbg.getA()); vlist.push_back(state.X);
vlist.push_back(dbg.getX()); vlist.push_back(state.Y);
vlist.push_back(dbg.getY());
for(int i = 0; i < 6; ++i) // FIXME - track changes in registers // Figure out which items have changed
changed.push_back(false); changed.push_back(state.PC != oldstate.PC);
changed.push_back(state.SP != oldstate.SP);
changed.push_back(state.A != oldstate.A);
changed.push_back(state.X != oldstate.X);
changed.push_back(state.Y != oldstate.Y);
// Finally, update the register list
myCpuGrid->setList(alist, vlist, changed); myCpuGrid->setList(alist, vlist, changed);
// Update the PS register booleans // Update the PS register booleans
BoolArray b; myPSRegister->setState(state.PSbits);
int ps = dbg.getPS();
for(int i = 0; i < 8; ++i)
{
if(ps & (1<<(7-i)))
b.push_back(true);
else
b.push_back(false);
}
myPSRegister->setState(b);
// Update the other status fields // Update the other status fields
int pc = dbg.getPC(); int pc = state.PC;
const char* buf; const char* buf;
Debugger& dbg = instance()->debugger();
buf = dbg.equates()->getLabel(pc); buf = dbg.equates()->getLabel(pc);
if(buf) if(buf)
myPCLabel->setEditString(buf); myPCLabel->setEditString(buf);

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: PromptWidget.cxx,v 1.25 2005-07-05 15:25:44 stephena Exp $ // $Id: PromptWidget.cxx,v 1.26 2005-07-08 14:36:18 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -158,7 +158,7 @@ void PromptWidget::handleMouseWheel(int x, int y, int direction)
void PromptWidget::printPrompt() { void PromptWidget::printPrompt() {
print( instance()->debugger().showWatches() ); print( instance()->debugger().showWatches() );
print( instance()->debugger().state() ); print( instance()->debugger().cpuState() );
print(PROMPT); print(PROMPT);
_promptStartPos = _promptEndPos = _currentPos; _promptStartPos = _promptEndPos = _currentPos;
} }