Added RiotDebug class, which for now only duplicates the previous

functionality of the Debugger::riotState() method.  It will become
more useful when I add a RIOT tab to the debugger.  Also, added
change tracking infrastructure.

Fixed long-standing bug with viewing the contents of TIM{1, 8, 64, 1024}T
registers.  Apparently, the output generated by the 'riot' debugger
command showed either INTIM or TIMINT for those registers, and not the
actual value written to those registers.

Added INTIM, TIMINT, and TIMCLKS to the riot output, which show the
current values of the timer, the timer interrupt, and the number of
'timer clocks' resulting from writing to a timer register.

Cleaned up some of the debugger API, removing pointers and using
references instead.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1479 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-04-19 21:11:52 +00:00
parent 6cde4a35af
commit 735144457d
17 changed files with 852 additions and 558 deletions

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Array.hxx,v 1.5 2008-02-06 13:45:19 stephena Exp $
// $Id: Array.hxx,v 1.6 2008-04-19 21:11:52 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -22,7 +22,7 @@
#ifndef ARRAY_HXX
#define ARRAY_HXX
#include <assert.h>
#include <cassert>
#include "bspf.hxx"

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: CpuDebug.cxx,v 1.10 2008-04-02 01:54:31 stephena Exp $
// $Id: CpuDebug.cxx,v 1.11 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include <sstream>
@ -21,34 +21,27 @@
#include "Array.hxx"
#include "EquateList.hxx"
#include "M6502.hxx"
#include "TIADebug.hxx"
#include "CpuDebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CpuDebug::CpuDebug(Debugger* dbg, Console* console)
: DebuggerSystem(dbg, console),
mySystem(&(console->system()))
CpuDebug::CpuDebug(Debugger& dbg, Console& console)
: DebuggerSystem(dbg, console)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DebuggerState& CpuDebug::getState()
const DebuggerState& CpuDebug::getState()
{
myState.PC = mySystem->m6502().PC;
myState.SP = mySystem->m6502().SP;
myState.PS = mySystem->m6502().PS();
myState.A = mySystem->m6502().A;
myState.X = mySystem->m6502().X;
myState.Y = mySystem->m6502().Y;
myState.PC = mySystem.m6502().PC;
myState.SP = mySystem.m6502().SP;
myState.PS = mySystem.m6502().PS();
myState.A = mySystem.m6502().A;
myState.X = mySystem.m6502().X;
myState.Y = mySystem.m6502().Y;
myState.PSbits.clear();
for(int i = 0; i < 8; ++i)
{
if(myState.PS & (1<<(7-i)))
myState.PSbits.push_back(true);
else
myState.PSbits.push_back(false);
}
Debugger::set_bits(myState.PS, myState.PSbits);
return myState;
}
@ -56,21 +49,72 @@ DebuggerState& CpuDebug::getState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::saveOldState()
{
myOldState.PC = mySystem->m6502().PC;
myOldState.SP = mySystem->m6502().SP;
myOldState.PS = mySystem->m6502().PS();
myOldState.A = mySystem->m6502().A;
myOldState.X = mySystem->m6502().X;
myOldState.Y = mySystem->m6502().Y;
myOldState.PC = mySystem.m6502().PC;
myOldState.SP = mySystem.m6502().SP;
myOldState.PS = mySystem.m6502().PS();
myOldState.A = mySystem.m6502().A;
myOldState.X = mySystem.m6502().X;
myOldState.Y = mySystem.m6502().Y;
myOldState.PSbits.clear();
for(int i = 0; i < 8; ++i)
{
if(myOldState.PS & (1<<(7-i)))
myOldState.PSbits.push_back(true);
else
myOldState.PSbits.push_back(false);
}
Debugger::set_bits(myOldState.PS, myOldState.PSbits);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string CpuDebug::toString()
{
// TODO - this doesn't seem to be used anywhere ??
string result;
char buf[255];
const CpuState& state = (CpuState&) getState();
const CpuState& oldstate = (CpuState&) getOldState();
result += "\nPC=";
result += myDebugger.invIfChanged(state.PC, oldstate.PC);
result += " A=";
result += myDebugger.invIfChanged(state.A, oldstate.A);
result += " X=";
result += myDebugger.invIfChanged(state.X, oldstate.X);
result += " Y=";
result += myDebugger.invIfChanged(state.Y, oldstate.Y);
result += " S=";
result += myDebugger.invIfChanged(state.SP, oldstate.SP);
result += " P=";
result += myDebugger.invIfChanged(state.PS, oldstate.PS);
result += "/";
// NV-BDIZC
buf[0] = n() ? 'N' : 'n';
buf[1] = v() ? 'V' : 'v';
buf[2] = '-';
buf[3] = b() ? 'B' : 'b';
buf[4] = d() ? 'D' : 'd';
buf[5] = i() ? 'I' : 'i';
buf[6] = z() ? 'Z' : 'z';
buf[7] = c() ? 'C' : 'c';
buf[8] = '\0';
result += buf;
result += "\n FrameCyc:";
sprintf(buf, "%d", mySystem.cycles());
result += buf;
result += " Frame:";
sprintf(buf, "%d", myDebugger.tiaDebug().frameCount());
result += buf;
result += " ScanLine:";
sprintf(buf, "%d", myDebugger.tiaDebug().scanlines());
result += buf;
result += " Clk/Pix/Cyc:";
int clk = myDebugger.tiaDebug().clocksThisLine();
sprintf(buf, "%d/%d/%d", clk, clk-68, clk/3);
result += buf;
result += " 6502Ins:";
sprintf(buf, "%d", mySystem.m6502().totalInstructionCount());
result += buf;
result += "\n ";
result += myDebugger.disassemble(state.PC, 1);
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -78,7 +122,7 @@ int CpuDebug::disassemble(int address, string& result, EquateList* equateList)
{
ostringstream buf;
int count = 0;
int opcode = mySystem->peek(address);
int opcode = mySystem.peek(address);
switch(M6502::ourAddressingModeTable[opcode])
{
@ -105,7 +149,7 @@ int CpuDebug::disassemble(int address, string& result, EquateList* equateList)
case M6502::Immediate:
buf << M6502::ourInstructionMnemonicTable[opcode] << " #$"
<< hex << setw(2) << setfill('0') << (int) mySystem->peek(address + 1) << " ; "
<< hex << setw(2) << setfill('0') << (int) mySystem.peek(address + 1) << " ; "
<< dec << M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
@ -125,42 +169,42 @@ int CpuDebug::disassemble(int address, string& result, EquateList* equateList)
case M6502::IndirectX:
buf << M6502::ourInstructionMnemonicTable[opcode] << " ("
<< equateList->getFormatted(mySystem->peek(address + 1), 2) << ",x) ; "
<< equateList->getFormatted(mySystem.peek(address + 1), 2) << ",x) ; "
<< M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
case M6502::IndirectY:
buf << M6502::ourInstructionMnemonicTable[opcode] << " ("
<< equateList->getFormatted(mySystem->peek(address + 1), 2) << "),y ; "
<< equateList->getFormatted(mySystem.peek(address + 1), 2) << "),y ; "
<< M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
case M6502::Relative:
buf << M6502::ourInstructionMnemonicTable[opcode] << " "
<< equateList->getFormatted(address + 2 + ((Int16)(Int8)mySystem->peek(address + 1)), 4)
<< equateList->getFormatted(address + 2 + ((Int16)(Int8)mySystem.peek(address + 1)), 4)
<< " ; " << M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
case M6502::Zero:
buf << M6502::ourInstructionMnemonicTable[opcode] << " "
<< equateList->getFormatted(mySystem->peek(address + 1), 2) << " ; "
<< equateList->getFormatted(mySystem.peek(address + 1), 2) << " ; "
<< M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
case M6502::ZeroX:
buf << M6502::ourInstructionMnemonicTable[opcode] << " "
<< equateList->getFormatted(mySystem->peek(address + 1), 2) << ",x ; "
<< equateList->getFormatted(mySystem.peek(address + 1), 2) << ",x ; "
<< M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
case M6502::ZeroY:
buf << M6502::ourInstructionMnemonicTable[opcode] << " "
<< equateList->getFormatted(mySystem->peek(address + 1), 2) << ",y ; "
<< equateList->getFormatted(mySystem.peek(address + 1), 2) << ",y ; "
<< M6502::ourInstructionProcessorCycleTable[opcode];
count = 2;
break;
@ -193,119 +237,119 @@ int CpuDebug::dPeek(int address)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setPC(int pc)
{
mySystem->m6502().PC = pc;
mySystem.m6502().PC = pc;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setSP(int sp)
{
mySystem->m6502().SP = sp;
mySystem.m6502().SP = sp;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setPS(int ps)
{
mySystem->m6502().PS(ps);
mySystem.m6502().PS(ps);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setA(int a)
{
mySystem->m6502().A = a;
mySystem.m6502().A = a;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setX(int x)
{
mySystem->m6502().X = x;
mySystem.m6502().X = x;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 7, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setV(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 6, on) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 6, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setB(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 4, on) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 4, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setD(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 3, on) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 3, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setI(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 2, on) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 2, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setZ(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 1, on) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 1, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::setC(bool on)
{
setPS( set_bit(mySystem->m6502().PS(), 0, on) );
setPS( Debugger::set_bit(mySystem.m6502().PS(), 0, on) );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleN()
{
setPS( mySystem->m6502().PS() ^ 0x80 );
setPS( mySystem.m6502().PS() ^ 0x80 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleV()
{
setPS( mySystem->m6502().PS() ^ 0x40 );
setPS( mySystem.m6502().PS() ^ 0x40 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleB()
{
setPS( mySystem->m6502().PS() ^ 0x10 );
setPS( mySystem.m6502().PS() ^ 0x10 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleD()
{
setPS( mySystem->m6502().PS() ^ 0x08 );
setPS( mySystem.m6502().PS() ^ 0x08 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleI()
{
setPS( mySystem->m6502().PS() ^ 0x04 );
setPS( mySystem.m6502().PS() ^ 0x04 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleZ()
{
setPS( mySystem->m6502().PS() ^ 0x02 );
setPS( mySystem.m6502().PS() ^ 0x02 );
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CpuDebug::toggleC()
{
setPS( mySystem->m6502().PS() ^ 0x01 );
setPS( mySystem.m6502().PS() ^ 0x01 );
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: CpuDebug.hxx,v 1.12 2008-04-02 01:54:31 stephena Exp $
// $Id: CpuDebug.hxx,v 1.13 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef CPU_DEBUG_HXX
@ -41,34 +41,35 @@ class CpuState : public DebuggerState
class CpuDebug : public DebuggerSystem
{
public:
CpuDebug(Debugger* dbg, Console* console);
CpuDebug(Debugger& dbg, Console& console);
DebuggerState& getState();
DebuggerState& getOldState() { return myOldState; }
const DebuggerState& getState();
const DebuggerState& getOldState() { return myOldState; }
void saveOldState();
string toString();
// I know, we ain't supposed to do this...
M6502 &m6502() { return mySystem->m6502(); }
M6502 &m6502() { return mySystem.m6502(); }
int disassemble(int address, string& result, EquateList* equateList);
int dPeek(int address);
int getBank();
int pc() { return mySystem->m6502().PC; }
int sp() { return mySystem->m6502().SP; }
int a() { return mySystem->m6502().A; }
int x() { return mySystem->m6502().X; }
int y() { return mySystem->m6502().Y; }
int pc() { return mySystem.m6502().PC; }
int sp() { return mySystem.m6502().SP; }
int a() { return mySystem.m6502().A; }
int x() { return mySystem.m6502().X; }
int y() { return mySystem.m6502().Y; }
// these return int, not boolean!
int n() { return mySystem->m6502().N; }
int v() { return mySystem->m6502().V; }
int b() { return mySystem->m6502().B; }
int d() { return mySystem->m6502().D; }
int i() { return mySystem->m6502().I; }
int z() { return !mySystem->m6502().notZ; }
int c() { return mySystem->m6502().C; }
int n() { return mySystem.m6502().N; }
int v() { return mySystem.m6502().V; }
int b() { return mySystem.m6502().B; }
int d() { return mySystem.m6502().D; }
int i() { return mySystem.m6502().I; }
int z() { return !mySystem.m6502().notZ; }
int c() { return mySystem.m6502().C; }
void setPC(int pc);
void setSP(int sp);
@ -94,24 +95,14 @@ class CpuDebug : public DebuggerSystem
void toggleC();
private:
static unsigned char set_bit(unsigned char input, int bit, bool on)
static int dpeek(System& system, int address)
{
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);
return system.peek(address) | (system.peek(address + 1) << 8);
}
private:
CpuState myState;
CpuState myOldState;
System* mySystem;
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Debugger.cxx,v 1.122 2008-04-02 01:54:31 stephena Exp $
// $Id: Debugger.cxx,v 1.123 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include "bspf.hxx"
@ -38,6 +38,7 @@
#include "EquateList.hxx"
#include "CpuDebug.hxx"
#include "RamDebug.hxx"
#include "RiotDebug.hxx"
#include "TIADebug.hxx"
#include "TiaInfoWidget.hxx"
@ -95,6 +96,7 @@ Debugger::Debugger(OSystem* osystem)
myParser(NULL),
myCpuDebug(NULL),
myRamDebug(NULL),
myRiotDebug(NULL),
myTiaDebug(NULL),
myTiaInfo(NULL),
myTiaOutput(NULL),
@ -137,6 +139,7 @@ Debugger::~Debugger()
delete myCpuDebug;
delete myRamDebug;
delete myRiotDebug;
delete myTiaDebug;
delete myEquateList;
@ -183,13 +186,16 @@ void Debugger::setConsole(Console* console)
// Create debugger subsystems
delete myCpuDebug;
myCpuDebug = new CpuDebug(this, myConsole);
myCpuDebug = new CpuDebug(*this, *myConsole);
delete myRamDebug;
myRamDebug = new RamDebug(this, myConsole);
myRamDebug = new RamDebug(*this, *myConsole);
delete myRiotDebug;
myRiotDebug = new RiotDebug(*this, *myConsole);
delete myTiaDebug;
myTiaDebug = new TIADebug(this, myConsole);
myTiaDebug = new TIADebug(*this, *myConsole);
// Initialize equates and breakpoints to known state
delete myEquateList;
@ -410,136 +416,6 @@ const string Debugger::invIfChanged(int reg, int oldReg)
return ret;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::cpuState()
{
string result;
char buf[255];
CpuState state = (CpuState&) myCpuDebug->getState();
CpuState oldstate = (CpuState&) myCpuDebug->getOldState();
result += "\nPC=";
result += invIfChanged(state.PC, oldstate.PC);
result += " A=";
result += invIfChanged(state.A, oldstate.A);
result += " X=";
result += invIfChanged(state.X, oldstate.X);
result += " Y=";
result += invIfChanged(state.Y, oldstate.Y);
result += " S=";
result += invIfChanged(state.SP, oldstate.SP);
result += " P=";
result += invIfChanged(state.PS, oldstate.PS);
result += "/";
formatFlags(state.PSbits, buf);
result += buf;
result += "\n FrameCyc:";
sprintf(buf, "%d", mySystem->cycles());
result += buf;
result += " Frame:";
sprintf(buf, "%d", myTiaDebug->frameCount());
result += buf;
result += " ScanLine:";
sprintf(buf, "%d", myTiaDebug->scanlines());
result += buf;
result += " Clk/Pix/Cyc:";
int clk = myTiaDebug->clocksThisLine();
sprintf(buf, "%d/%d/%d", clk, clk-68, clk/3);
result += buf;
result += " 6502Ins:";
sprintf(buf, "%d", mySystem->m6502().totalInstructionCount());
result += buf;
result += "\n ";
result += disassemble(state.PC, 1);
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* The timers, joysticks, and switches can be read via peeks, so
I didn't write a separate RIOTDebug class. */
const string Debugger::riotState()
{
string ret;
// TODO: inverse video for changed regs. Core needs to track this.
// TODO: keyboard controllers?
for(int i=0x280; i<0x284; i++)
{
ret += valueToString(i);
ret += "/";
ret += equates().getFormatted(i, 2);
ret += "=";
ret += valueToString(mySystem->peek(i));
ret += " ";
}
ret += "\n";
// These are squirrely: some symbol files will define these as
// 0x284-0x287. Doesn't actually matter, these registers repeat
// every 16 bytes.
ret += valueToString(0x294);
ret += "/TIM1T=";
ret += valueToString(mySystem->peek(0x294));
ret += " ";
ret += valueToString(0x295);
ret += "/TIM8T=";
ret += valueToString(mySystem->peek(0x295));
ret += " ";
ret += valueToString(0x296);
ret += "/TIM64T=";
ret += valueToString(mySystem->peek(0x296));
ret += " ";
ret += valueToString(0x297);
ret += "/TIM1024T=";
ret += valueToString(mySystem->peek(0x297));
ret += "\n";
ret += "Left/P0diff: ";
ret += (mySystem->peek(0x282) & 0x40) ? "hard/A" : "easy/B";
ret += " ";
ret += "Right/P1diff: ";
ret += (mySystem->peek(0x282) & 0x80) ? "hard/A" : "easy/B";
ret += "\n";
ret += "TVType: ";
ret += (mySystem->peek(0x282) & 0x8) ? "Color" : "B&W";
ret += " Switches: ";
ret += (mySystem->peek(0x282) & 0x2) ? "-" : "+";
ret += "select ";
ret += (mySystem->peek(0x282) & 0x1) ? "-" : "+";
ret += "reset";
ret += "\n";
// Yes, the fire buttons are in the TIA, but we might as well
// show them here for convenience.
ret += "Left/P0 stick: ";
ret += (mySystem->peek(0x280) & 0x80) ? "" : "right ";
ret += (mySystem->peek(0x280) & 0x40) ? "" : "left ";
ret += (mySystem->peek(0x280) & 0x20) ? "" : "down ";
ret += (mySystem->peek(0x280) & 0x10) ? "" : "up ";
ret += ((mySystem->peek(0x280) & 0xf0) == 0xf0) ? "(no directions) " : "";
ret += (mySystem->peek(0x03c) & 0x80) ? "" : "(button) ";
ret += "\n";
ret += "Right/P1 stick: ";
ret += (mySystem->peek(0x280) & 0x08) ? "" : "right ";
ret += (mySystem->peek(0x280) & 0x04) ? "" : "left ";
ret += (mySystem->peek(0x280) & 0x02) ? "" : "down ";
ret += (mySystem->peek(0x280) & 0x01) ? "" : "up ";
ret += ((mySystem->peek(0x280) & 0x0f) == 0x0f) ? "(no directions) " : "";
ret += (mySystem->peek(0x03d) & 0x80) ? "" : "(button) ";
//ret += "\n"; // caller will add
return ret;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::reset()
{
@ -547,21 +423,6 @@ void Debugger::reset()
myCpuDebug->setPC(pc);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::formatFlags(BoolArray& b, char *out)
{
// NV-BDIZC
out[0] = myCpuDebug->n() ? 'N' : 'n';
out[1] = myCpuDebug->v() ? 'V' : 'v';
out[2] = '-';
out[3] = myCpuDebug->b() ? 'B' : 'b';
out[4] = myCpuDebug->d() ? 'D' : 'd';
out[5] = myCpuDebug->i() ? 'I' : 'i';
out[6] = myCpuDebug->z() ? 'Z' : 'z';
out[7] = myCpuDebug->c() ? 'C' : 'c';
out[8] = '\0';
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* Element 0 of args is the address. The remaining elements are the data
to poke, starting at the given address.
@ -584,73 +445,6 @@ const string Debugger::setRAM(IntArray& args)
return ret;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/* Warning: this method really is for dumping *RAM*, not ROM or I/O! */
const string Debugger::dumpRAM()
{
string result;
char buf[128];
int bytesPerLine;
int start = kRamStart, len = kRamSize;
switch(myParser->base())
{
case kBASE_16:
case kBASE_10:
bytesPerLine = 0x10;
break;
case kBASE_2:
bytesPerLine = 0x04;
break;
case kBASE_DEFAULT:
default:
return DebuggerParser::red("invalid base, this is a BUG");
}
RamState state = (RamState&) myRamDebug->getState();
RamState oldstate = (RamState&) myRamDebug->getOldState();
for (uInt8 i = 0x00; i < len; i += bytesPerLine)
{
sprintf(buf, "%.2x: ", start+i);
result += buf;
for (uInt8 j = 0; j < bytesPerLine; j++)
{
result += invIfChanged(state.ram[i+j], oldstate.ram[i+j]);
result += " ";
if(j == 0x07) result += " ";
}
result += "\n";
}
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string Debugger::dumpTIA()
{
string result;
char buf[128];
sprintf(buf, "%.2x: ", 0);
result += buf;
for (uInt8 j = 0; j < 0x010; j++)
{
sprintf(buf, "%.2x ", mySystem->peek(j));
result += buf;
if(j == 0x07) result += "- ";
}
result += "\n";
result += myTiaDebug->state();
return result;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Debugger::saveState(int state)
{
@ -935,6 +729,7 @@ void Debugger::saveOldState()
{
myCpuDebug->saveOldState();
myRamDebug->saveOldState();
myRiotDebug->saveOldState();
myTiaDebug->saveOldState();
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Debugger.hxx,v 1.92 2008-03-23 17:43:21 stephena Exp $
// $Id: Debugger.hxx,v 1.93 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef DEBUGGER_HXX
@ -24,6 +24,7 @@ class Console;
class System;
class CpuDebug;
class RamDebug;
class RiotDebug;
class TIADebug;
class TiaInfoWidget;
class TiaOutputWidget;
@ -69,7 +70,7 @@ typedef uInt16 (Debugger::*DEBUGGER_WORD_METHOD)();
for all debugging operations in Stella (parser, 6502 debugger, etc).
@author Stephen Anthony
@version $Id: Debugger.hxx,v 1.92 2008-03-23 17:43:21 stephena Exp $
@version $Id: Debugger.hxx,v 1.93 2008-04-19 21:11:52 stephena Exp $
*/
class Debugger : public DialogContainer
{
@ -143,6 +144,11 @@ class Debugger : public DialogContainer
*/
RamDebug& ramDebug() const { return *myRamDebug; }
/**
The debugger subsystem responsible for all RIOT state
*/
RiotDebug& riotDebug() const { return *myRiotDebug; }
/**
The debugger subsystem responsible for all TIA state
*/
@ -163,17 +169,6 @@ class Debugger : public DialogContainer
*/
const string run(const string& command);
/**
Give the contents of the CPU registers and disassembly of
next instruction.
*/
const string cpuState();
/**
Get contents of RIOT switch & timer registers
*/
const string riotState();
/**
The current cycle count of the System.
*/
@ -249,6 +244,41 @@ class Debugger : public DialogContainer
else return -1;
}
/* Convenience methods to get/set bit(s) in an 8-bit register */
static uInt8 set_bit(uInt8 input, uInt8 bit, bool on)
{
if(on)
return input | (1 << bit);
else
return input & ~(1 << bit);
}
static void set_bits(uInt8 reg, BoolArray& bits)
{
bits.clear();
for(int i = 0; i < 8; ++i)
{
if(reg & (1<<(7-i)))
bits.push_back(true);
else
bits.push_back(false);
}
}
static uInt8 get_bits(BoolArray& bits)
{
uInt8 result = 0x0;
for(int i = 0; i < 8; ++i)
{
if(bits[i])
result |= (1<<(7-i));
else
return result &= ~(1<<(7-i));
}
return result;
}
/* Invert given input if it differs from its previous value */
const string invIfChanged(int reg, int oldReg);
/**
This is used when we want the debugger from a class that can't
receive the debugger object in any other way.
@ -322,21 +352,13 @@ class Debugger : public DialogContainer
void reloadROM();
/**
Return a formatted string containing the contents of the specified
device.
*/
const string dumpRAM();
const string dumpTIA();
// set a bunch of RAM locations at once
// Set a bunch of RAM locations at once
const string setRAM(IntArray& args);
void reset();
void autoLoadSymbols(string file);
void clearAllBreakPoints();
void formatFlags(BoolArray& b, char *out);
PromptWidget *prompt() { return myPrompt; }
void addLabel(string label, int address);
@ -344,8 +366,6 @@ class Debugger : public DialogContainer
void saveState(int state);
void loadState(int state);
const string invIfChanged(int reg, int oldReg);
private:
typedef multimap<string,string> ListFile;
typedef ListFile::const_iterator ListIter;
@ -356,6 +376,7 @@ class Debugger : public DialogContainer
DebuggerParser* myParser;
CpuDebug* myCpuDebug;
RamDebug* myRamDebug;
RiotDebug* myRiotDebug;
TIADebug* myTiaDebug;
TiaInfoWidget* myTiaInfo;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DebuggerParser.cxx,v 1.104 2008-04-02 21:22:16 stephena Exp $
// $Id: DebuggerParser.cxx,v 1.105 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include <fstream>
@ -23,6 +23,9 @@
#include "Dialog.hxx"
#include "Debugger.hxx"
#include "CpuDebug.hxx"
#include "RamDebug.hxx"
#include "RiotDebug.hxx"
#include "TIADebug.hxx"
#include "DebuggerParser.hxx"
#include "YaccParser.hxx"
#include "M6502.hxx"
@ -1093,7 +1096,7 @@ void DebuggerParser::executePrint()
void DebuggerParser::executeRam()
{
if(argCount == 0)
commandResult = debugger->dumpRAM();
commandResult = debugger->ramDebug().toString();
else
commandResult = debugger->setRAM(args);
}
@ -1110,7 +1113,7 @@ void DebuggerParser::executeReset()
// "riot"
void DebuggerParser::executeRiot()
{
commandResult = debugger->riotState();
commandResult = debugger->riotDebug().toString();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1257,7 +1260,7 @@ void DebuggerParser::executeStep()
// "tia"
void DebuggerParser::executeTia()
{
commandResult = debugger->dumpTIA();
commandResult = debugger->tiaDebug().toString();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: DebuggerSystem.hxx,v 1.6 2008-02-06 13:45:20 stephena Exp $
// $Id: DebuggerSystem.hxx,v 1.7 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef DEBUGGER_SYSTEM_HXX
@ -42,16 +42,20 @@ class DebuggerState
class DebuggerSystem
{
public:
DebuggerSystem(Debugger* dbg, Console* console) { myDebugger = dbg; }
DebuggerSystem(Debugger& dbg, Console& console) :
myDebugger(dbg), myConsole(console), mySystem(console.system()) { }
virtual ~DebuggerSystem() { }
virtual DebuggerState& getState() = 0;
virtual DebuggerState& getOldState() = 0;
virtual const DebuggerState& getState() = 0;
virtual const DebuggerState& getOldState() = 0;
virtual void saveOldState() = 0;
virtual string toString() = 0;
protected:
Debugger* myDebugger;
Debugger& myDebugger;
Console& myConsole;
System& mySystem;
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RamDebug.cxx,v 1.7 2008-02-06 13:45:20 stephena Exp $
// $Id: RamDebug.cxx,v 1.8 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include "Array.hxx"
@ -21,14 +21,13 @@
#include "RamDebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RamDebug::RamDebug(Debugger* dbg, Console* console)
: DebuggerSystem(dbg, console),
mySystem(&(console->system()))
RamDebug::RamDebug(Debugger& dbg, Console& console)
: DebuggerSystem(dbg, console)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DebuggerState& RamDebug::getState()
const DebuggerState& RamDebug::getState()
{
myState.ram.clear();
for(int i=0; i<0x80; i++)
@ -49,12 +48,56 @@ void RamDebug::saveOldState()
int RamDebug::read(int offset)
{
offset &= 0x7f; // there are only 128 bytes
return mySystem->peek(offset + 0x80);
return mySystem.peek(offset + 0x80);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RamDebug::write(int offset, int value)
{
offset &= 0x7f; // there are only 128 bytes
mySystem->poke(offset + 0x80, value);
mySystem.poke(offset + 0x80, value);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RamDebug::toString()
{
string result;
char buf[128];
int bytesPerLine;
int start = kRamStart, len = kRamSize;
switch(myDebugger.parser().base())
{
case kBASE_16:
case kBASE_10:
bytesPerLine = 0x10;
break;
case kBASE_2:
bytesPerLine = 0x04;
break;
case kBASE_DEFAULT:
default:
return DebuggerParser::red("invalid base, this is a BUG");
}
const RamState& state = (RamState&) getState();
const RamState& oldstate = (RamState&) getOldState();
for (uInt8 i = 0x00; i < len; i += bytesPerLine)
{
sprintf(buf, "%.2x: ", start+i);
result += buf;
for (uInt8 j = 0; j < bytesPerLine; j++)
{
result += myDebugger.invIfChanged(state.ram[i+j], oldstate.ram[i+j]);
result += " ";
if(j == 0x07) result += " ";
}
result += "\n";
}
return result;
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: RamDebug.hxx,v 1.6 2008-02-06 13:45:20 stephena Exp $
// $Id: RamDebug.hxx,v 1.7 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef RAM_DEBUG_HXX
@ -33,12 +33,13 @@ class RamState : public DebuggerState
class RamDebug : public DebuggerSystem
{
public:
RamDebug(Debugger* dbg, Console* console);
RamDebug(Debugger& dbg, Console& console);
DebuggerState& getState();
DebuggerState& getOldState() { return myOldState; }
const DebuggerState& getState();
const DebuggerState& getOldState() { return myOldState; }
void saveOldState();
string toString();
int read(int offset);
void write(int offset, int value);
@ -46,8 +47,6 @@ class RamDebug : public DebuggerSystem
private:
RamState myState;
RamState myOldState;
System* mySystem;
};
#endif

View File

@ -0,0 +1,281 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2008 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: RiotDebug.cxx,v 1.1 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include <sstream>
#include "System.hxx"
#include "Debugger.hxx"
#include "RiotDebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RiotDebug::RiotDebug(Debugger& dbg, Console& console)
: DebuggerSystem(dbg, console)
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const DebuggerState& RiotDebug::getState()
{
// Port A & B registers
myState.SWCHA = swcha();
myState.SWCHB = swchb();
myState.SWACNT = swacnt();
myState.SWBCNT = swbcnt();
Debugger::set_bits(swcha(), myState.swchaBits);
Debugger::set_bits(swchb(), myState.swchbBits);
Debugger::set_bits(swacnt(), myState.swacntBits);
Debugger::set_bits(swbcnt(), myState.swbcntBits);
// Timer registers
myState.TIM1T = tim1T();
myState.TIM8T = tim8T();
myState.TIM64T = tim64T();
myState.TIM1024T = tim1024T();
myState.INTIM = intim();
myState.TIMINT = timint();
myState.TIMCLKS = timClocks();
return myState;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void RiotDebug::saveOldState()
{
// Port A & B registers
myOldState.SWCHA = swcha();
myOldState.SWCHB = swchb();
myOldState.SWACNT = swacnt();
myOldState.SWBCNT = swbcnt();
Debugger::set_bits(swcha(), myOldState.swchaBits);
Debugger::set_bits(swchb(), myOldState.swchbBits);
Debugger::set_bits(swacnt(), myOldState.swacntBits);
Debugger::set_bits(swbcnt(), myOldState.swbcntBits);
// Timer registers
myOldState.TIM1T = tim1T();
myOldState.TIM8T = tim8T();
myOldState.TIM64T = tim64T();
myOldState.TIM1024T = tim1024T();
myOldState.INTIM = intim();
myOldState.TIMINT = timint();
myOldState.TIMCLKS = timClocks();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::swcha(int newVal)
{
if(newVal > -1)
mySystem.poke(0x280, newVal);
return mySystem.peek(0x280);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::swchb(int newVal)
{
// TODO: directly access the Switches class to change this
// if(newVal > -1)
// mySystem.poke(0x282, newVal);
return mySystem.peek(0x282);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::swacnt(int newVal)
{
if(newVal > -1)
mySystem.poke(0x281, newVal);
return mySystem.peek(0x281);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::swbcnt(int newVal)
{
// This is read-only on a real system; it makes no sense to change it
return mySystem.peek(0x283);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::tim1T(int newVal)
{
if(newVal > -1)
mySystem.poke(0x294, newVal);
return mySystem.m6532().myOutTimer[0];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::tim8T(int newVal)
{
if(newVal > -1)
mySystem.poke(0x295, newVal);
return mySystem.m6532().myOutTimer[1];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::tim64T(int newVal)
{
if(newVal > -1)
mySystem.poke(0x296, newVal);
return mySystem.m6532().myOutTimer[2];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::tim1024T(int newVal)
{
if(newVal > -1)
mySystem.poke(0x297, newVal);
return mySystem.m6532().myOutTimer[3];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::intim()
{
return mySystem.peek(0x284);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 RiotDebug::timint()
{
return mySystem.peek(0x285);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 RiotDebug::timClocks()
{
return mySystem.m6532().timerClocks();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::dirP0String()
{
uInt8 reg = swcha();
ostringstream buf;
buf << (reg & 0x80 ? "" : "right ")
<< (reg & 0x40 ? "" : "left ")
<< (reg & 0x20 ? "" : "left ")
<< (reg & 0x10 ? "" : "left ")
<< (reg & 0xf0 == 0xf0 ? "(no directions) " : "");
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::dirP1String()
{
uInt8 reg = swcha();
ostringstream buf;
buf << (reg & 0x08 ? "" : "right ")
<< (reg & 0x04 ? "" : "left ")
<< (reg & 0x02 ? "" : "left ")
<< (reg & 0x01 ? "" : "left ")
<< (reg & 0x0f == 0x0f ? "(no directions) " : "");
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::diffP0String()
{
return (swchb() & 0x40) ? "hard/A" : "easy/B";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::diffP1String()
{
return (swchb() & 0x80) ? "hard/A" : "easy/B";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::tvTypeString()
{
return (swchb() & 0x8) ? "Color" : "B&W";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::switchesString()
{
ostringstream buf;
buf << (swchb() & 0x2 ? "-" : "+") << "select " <<
(swchb() & 0x1 ? "-" : "+") << "reset";
return buf.str();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string RiotDebug::toString()
{
// TODO: keyboard controllers?
const RiotState& state = (RiotState&) getState();
const RiotState& oldstate = (RiotState&) getOldState();
string ret;
ret += myDebugger.valueToString(0x280) + "/" +
myDebugger.equates().getFormatted(0x280, 2) + "=" +
myDebugger.invIfChanged(state.SWCHA, oldstate.SWCHA) + " ";
ret += myDebugger.valueToString(0x281) + "/" +
myDebugger.equates().getFormatted(0x281, 2) + "=" +
myDebugger.invIfChanged(state.SWCHB, oldstate.SWCHB) + " ";
ret += myDebugger.valueToString(0x282) + "/" +
myDebugger.equates().getFormatted(0x282, 2) + "=" +
myDebugger.invIfChanged(state.SWACNT, oldstate.SWACNT) + " ";
ret += myDebugger.valueToString(0x283) + "/" +
myDebugger.equates().getFormatted(0x283, 2) + "=" +
myDebugger.invIfChanged(state.SWBCNT, oldstate.SWBCNT) + " ";
ret += "\n";
// These are squirrely: some symbol files will define these as
// 0x284-0x287. Doesn't actually matter, these registers repeat
// every 16 bytes.
ret += myDebugger.valueToString(0x294) + "/TIM1T=" +
myDebugger.invIfChanged(state.TIM1T, oldstate.TIM1T) + " ";
ret += myDebugger.valueToString(0x295) + "/TIM8T=" +
myDebugger.invIfChanged(state.TIM8T, oldstate.TIM8T) + " ";
ret += myDebugger.valueToString(0x296) + "/TIM64T=" +
myDebugger.invIfChanged(state.TIM64T, oldstate.TIM64T) + " ";
ret += myDebugger.valueToString(0x297) + "/TIM1024T=" +
myDebugger.invIfChanged(state.TIM1024T, oldstate.TIM1024T) + " ";
ret += "\n";
ret += myDebugger.valueToString(0x284) + "/INTIM=" +
myDebugger.invIfChanged(state.INTIM, oldstate.INTIM) + " ";
ret += myDebugger.valueToString(0x285) + "/TIMINT=" +
myDebugger.invIfChanged(state.TIMINT, oldstate.TIMINT) + " ";
ret += "Timer_Clocks=" +
myDebugger.invIfChanged(state.TIMCLKS, oldstate.TIMCLKS) + " ";
ret += "\n";
ret += "Left/P0diff: " + diffP0String() + " Right/P1diff: " + diffP0String();
ret += "\n";
ret += "TVType: " + tvTypeString() + " Switches: " + switchesString();
ret += "\n";
// Yes, the fire buttons are in the TIA, but we might as well
// show them here for convenience.
ret += "Left/P0 stick: " + dirP0String();
ret += (mySystem.peek(0x03c) & 0x80) ? "" : "(button) ";
ret += "\n";
ret += "Right/P1 stick: " + dirP1String();
ret += (mySystem.peek(0x03d) & 0x80) ? "" : "(button) ";
return ret;
}

View File

@ -0,0 +1,82 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2008 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: RiotDebug.hxx,v 1.1 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef RIOT_DEBUG_HXX
#define RIOT_DEBUG_HXX
class Debugger;
class RiotDebug;
#include "Array.hxx"
#include "DebuggerSystem.hxx"
class RiotState : public DebuggerState
{
public:
uInt8 SWCHA, SWCHB, SWACNT, SWBCNT;
BoolArray swchaBits;
BoolArray swchbBits;
BoolArray swacntBits;
BoolArray swbcntBits;
uInt8 TIM1T, TIM8T, TIM64T, TIM1024T, INTIM, TIMINT;
Int32 TIMCLKS;
};
class RiotDebug : public DebuggerSystem
{
public:
RiotDebug(Debugger& dbg, Console& console);
const DebuggerState& getState();
const DebuggerState& getOldState() { return myOldState; }
void saveOldState();
string toString();
/* Port A and B registers */
uInt8 swcha(int newVal = -1);
uInt8 swchb(int newVal = -1);
uInt8 swacnt(int newVal = -1);
uInt8 swbcnt(int newVal = -1);
/* Timer registers & associated clock */
uInt8 tim1T(int newVal = -1);
uInt8 tim8T(int newVal = -1);
uInt8 tim64T(int newVal = -1);
uInt8 tim1024T(int newVal = -1);
uInt8 intim();
uInt8 timint();
Int32 timClocks();
/* Port A description */
string dirP0String();
string dirP1String();
/* Port B description */
string diffP0String();
string diffP1String();
string tvTypeString();
string switchesString();
private:
RiotState myState;
RiotState myOldState;
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TIADebug.cxx,v 1.26 2008-02-06 13:45:20 stephena Exp $
// $Id: TIADebug.cxx,v 1.27 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include "System.hxx"
@ -22,10 +22,9 @@
#include "TIADebug.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIADebug::TIADebug(Debugger* dbg, Console* console)
TIADebug::TIADebug(Debugger& dbg, Console& console)
: DebuggerSystem(dbg, console),
mySystem(&console->system()),
myTIA((TIA*)&console->mediaSource())
myTIA((TIA&)console.mediaSource())
{
nusizStrings[0] = "size=8 copy=1";
nusizStrings[1] = "size=8 copy=2 spac=8";
@ -38,11 +37,11 @@ TIADebug::TIADebug(Debugger* dbg, Console* console)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DebuggerState& TIADebug::getState()
const DebuggerState& TIADebug::getState()
{
myState.ram.clear();
for(int i = 0; i < 0x010; ++i)
myState.ram.push_back(myTIA->peek(i));
myState.ram.push_back(myTIA.peek(i));
// Color registers
myState.coluRegs.clear();
@ -103,7 +102,7 @@ void TIADebug::saveOldState()
{
myOldState.ram.clear();
for(int i = 0; i < 0x010; ++i)
myOldState.ram.push_back(myTIA->peek(i));
myOldState.ram.push_back(myTIA.peek(i));
// Color registers
myOldState.coluRegs.clear();
@ -157,7 +156,7 @@ void TIADebug::saveOldState()
myOldState.aud.push_back(audV1());
}
/* the set methods now use mySystem->poke(). This will save us the
/* the set methods now use mySystem.poke(). This will save us the
trouble of masking the values here, since TIA::poke() will do it
for us.
@ -187,90 +186,90 @@ void TIADebug::saveOldState()
bool TIADebug::vdelP0(int newVal)
{
if(newVal > -1)
mySystem->poke(VDELP0, ((bool)newVal));
mySystem.poke(VDELP0, ((bool)newVal));
return myTIA->myVDELP0;
return myTIA.myVDELP0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::vdelP1(int newVal)
{
if(newVal > -1)
mySystem->poke(VDELP1, ((bool)newVal));
mySystem.poke(VDELP1, ((bool)newVal));
return myTIA->myVDELP1;
return myTIA.myVDELP1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::vdelBL(int newVal)
{
if(newVal > -1)
mySystem->poke(VDELBL, ((bool)newVal));
mySystem.poke(VDELBL, ((bool)newVal));
return myTIA->myVDELBL;
return myTIA.myVDELBL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::enaM0(int newVal)
{
if(newVal > -1)
mySystem->poke(ENAM0, ((bool)newVal) << 1);
mySystem.poke(ENAM0, ((bool)newVal) << 1);
return myTIA->myENAM0;
return myTIA.myENAM0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::enaM1(int newVal)
{
if(newVal > -1)
mySystem->poke(ENAM1, ((bool)newVal) << 1);
mySystem.poke(ENAM1, ((bool)newVal) << 1);
return myTIA->myENAM1;
return myTIA.myENAM1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::enaBL(int newVal)
{
if(newVal > -1)
mySystem->poke(ENABL, ((bool)newVal) << 1);
mySystem.poke(ENABL, ((bool)newVal) << 1);
return myTIA->myENABL;
return myTIA.myENABL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::resMP0(int newVal)
{
if(newVal > -1)
mySystem->poke(RESMP0, ((bool)newVal) << 1);
mySystem.poke(RESMP0, ((bool)newVal) << 1);
return myTIA->myRESMP0;
return myTIA.myRESMP0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::resMP1(int newVal)
{
if(newVal > -1)
mySystem->poke(RESMP1, ((bool)newVal) << 1);
mySystem.poke(RESMP1, ((bool)newVal) << 1);
return myTIA->myRESMP1;
return myTIA.myRESMP1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::refP0(int newVal)
{
if(newVal > -1)
mySystem->poke(REFP0, ((bool)newVal) << 3);
mySystem.poke(REFP0, ((bool)newVal) << 3);
return myTIA->myREFP0;
return myTIA.myREFP0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::refP1(int newVal)
{
if(newVal > -1)
mySystem->poke(REFP1, ((bool)newVal) << 3);
mySystem.poke(REFP1, ((bool)newVal) << 3);
return myTIA->myREFP1;
return myTIA.myREFP1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -278,15 +277,15 @@ bool TIADebug::refPF(int newVal)
{
if(newVal > -1)
{
int tmp = myTIA->myCTRLPF;
int tmp = myTIA.myCTRLPF;
if(newVal)
tmp |= 0x01;
else
tmp &= ~0x01;
mySystem->poke(CTRLPF, tmp);
mySystem.poke(CTRLPF, tmp);
}
return myTIA->myCTRLPF & 0x01;
return myTIA.myCTRLPF & 0x01;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -294,15 +293,15 @@ bool TIADebug::scorePF(int newVal)
{
if(newVal > -1)
{
int tmp = myTIA->myCTRLPF;
int tmp = myTIA.myCTRLPF;
if(newVal)
tmp |= 0x02;
else
tmp &= ~0x02;
mySystem->poke(CTRLPF, tmp);
mySystem.poke(CTRLPF, tmp);
}
return myTIA->myCTRLPF & 0x02;
return myTIA.myCTRLPF & 0x02;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -310,15 +309,15 @@ bool TIADebug::priorityPF(int newVal)
{
if(newVal > -1)
{
int tmp = myTIA->myCTRLPF;
int tmp = myTIA.myCTRLPF;
if(newVal)
tmp |= 0x04;
else
tmp &= ~0x04;
mySystem->poke(CTRLPF, tmp);
mySystem.poke(CTRLPF, tmp);
}
return myTIA->myCTRLPF & 0x04;
return myTIA.myCTRLPF & 0x04;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -329,147 +328,147 @@ bool TIADebug::collision(int collID, int newVal)
if(newVal > -1)
{
if(newVal)
myTIA->myCollision |= mask;
myTIA.myCollision |= mask;
else
myTIA->myCollision &= ~mask;
myTIA.myCollision &= ~mask;
}
return myTIA->myCollision & mask;
return myTIA.myCollision & mask;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::audC0(int newVal)
{
if(newVal > -1)
mySystem->poke(AUDC0, newVal);
mySystem.poke(AUDC0, newVal);
return myTIA->myAUDC0;
return myTIA.myAUDC0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::audC1(int newVal)
{
if(newVal > -1)
mySystem->poke(AUDC1, newVal);
mySystem.poke(AUDC1, newVal);
return myTIA->myAUDC1;
return myTIA.myAUDC1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::audV0(int newVal)
{
if(newVal > -1)
mySystem->poke(AUDV0, newVal);
mySystem.poke(AUDV0, newVal);
return myTIA->myAUDV0;
return myTIA.myAUDV0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::audV1(int newVal)
{
if(newVal > -1)
mySystem->poke(AUDV1, newVal);
mySystem.poke(AUDV1, newVal);
return myTIA->myAUDV1;
return myTIA.myAUDV1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::audF0(int newVal)
{
if(newVal > -1)
mySystem->poke(AUDF0, newVal);
mySystem.poke(AUDF0, newVal);
return myTIA->myAUDF0;
return myTIA.myAUDF0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::audF1(int newVal)
{
if(newVal > -1)
mySystem->poke(AUDF1, newVal);
mySystem.poke(AUDF1, newVal);
return myTIA->myAUDF1;
return myTIA.myAUDF1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::pf0(int newVal)
{
if(newVal > -1)
mySystem->poke(PF0, newVal << 4);
mySystem.poke(PF0, newVal << 4);
return myTIA->myPF & 0x0f;
return myTIA.myPF & 0x0f;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::pf1(int newVal)
{
if(newVal > -1)
mySystem->poke(PF1, newVal);
mySystem.poke(PF1, newVal);
return (myTIA->myPF & 0xff0) >> 4;
return (myTIA.myPF & 0xff0) >> 4;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::pf2(int newVal)
{
if(newVal > -1)
mySystem->poke(PF2, newVal);
mySystem.poke(PF2, newVal);
return (myTIA->myPF & 0xff000) >> 12;
return (myTIA.myPF & 0xff000) >> 12;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::coluP0(int newVal)
{
if(newVal > -1)
mySystem->poke(COLUP0, newVal);
mySystem.poke(COLUP0, newVal);
return myTIA->myCOLUP0 & 0xff;
return myTIA.myCOLUP0 & 0xff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::coluP1(int newVal)
{
if(newVal > -1)
mySystem->poke(COLUP1, newVal);
mySystem.poke(COLUP1, newVal);
return myTIA->myCOLUP1 & 0xff;
return myTIA.myCOLUP1 & 0xff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::coluPF(int newVal)
{
if(newVal > -1)
mySystem->poke(COLUPF, newVal);
mySystem.poke(COLUPF, newVal);
return myTIA->myCOLUPF & 0xff;
return myTIA.myCOLUPF & 0xff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::coluBK(int newVal)
{
if(newVal > -1)
mySystem->poke(COLUBK, newVal);
mySystem.poke(COLUBK, newVal);
return myTIA->myCOLUBK & 0xff;
return myTIA.myCOLUBK & 0xff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::nusiz0(int newVal)
{
if(newVal > -1)
mySystem->poke(NUSIZ0, newVal);
mySystem.poke(NUSIZ0, newVal);
return myTIA->myNUSIZ0;
return myTIA.myNUSIZ0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::nusiz1(int newVal)
{
if(newVal > -1)
mySystem->poke(NUSIZ1, newVal);
mySystem.poke(NUSIZ1, newVal);
return myTIA->myNUSIZ1;
return myTIA.myNUSIZ1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -477,12 +476,12 @@ uInt8 TIADebug::nusizP0(int newVal)
{
if(newVal > -1)
{
uInt8 tmp = myTIA->myNUSIZ0 & ~0x07;
uInt8 tmp = myTIA.myNUSIZ0 & ~0x07;
tmp |= (newVal & 0x07);
mySystem->poke(NUSIZ0, tmp);
mySystem.poke(NUSIZ0, tmp);
}
return myTIA->myNUSIZ0 & 0x07;
return myTIA.myNUSIZ0 & 0x07;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -490,12 +489,12 @@ uInt8 TIADebug::nusizP1(int newVal)
{
if(newVal > -1)
{
uInt8 tmp = myTIA->myNUSIZ1 & ~0x07;
uInt8 tmp = myTIA.myNUSIZ1 & ~0x07;
tmp |= newVal & 0x07;
mySystem->poke(NUSIZ1, tmp);
mySystem.poke(NUSIZ1, tmp);
}
return myTIA->myNUSIZ1 & 0x07;
return myTIA.myNUSIZ1 & 0x07;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -503,12 +502,12 @@ uInt8 TIADebug::nusizM0(int newVal)
{
if(newVal > -1)
{
uInt8 tmp = myTIA->myNUSIZ0 & ~0x30;
uInt8 tmp = myTIA.myNUSIZ0 & ~0x30;
tmp |= (newVal & 0x04) << 4;
mySystem->poke(NUSIZ0, tmp);
mySystem.poke(NUSIZ0, tmp);
}
return (myTIA->myNUSIZ0 & 0x30) >> 4;
return (myTIA.myNUSIZ0 & 0x30) >> 4;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -516,46 +515,46 @@ uInt8 TIADebug::nusizM1(int newVal)
{
if(newVal > -1)
{
uInt8 tmp = myTIA->myNUSIZ1 & ~0x30;
uInt8 tmp = myTIA.myNUSIZ1 & ~0x30;
tmp |= (newVal & 0x04) << 4;
mySystem->poke(NUSIZ1, tmp);
mySystem.poke(NUSIZ1, tmp);
}
return (myTIA->myNUSIZ1 & 0x30) >> 4;
return (myTIA.myNUSIZ1 & 0x30) >> 4;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::grP0(int newVal)
{
if(newVal > -1)
mySystem->poke(GRP0, newVal);
mySystem.poke(GRP0, newVal);
return myTIA->myGRP0;
return myTIA.myGRP0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::grP1(int newVal)
{
if(newVal > -1)
mySystem->poke(GRP1, newVal);
mySystem.poke(GRP1, newVal);
return myTIA->myGRP1;
return myTIA.myGRP1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::posP0(int newVal)
{
if(newVal > -1)
myTIA->myPOSP0 = newVal;
return myTIA->myPOSP0;
myTIA.myPOSP0 = newVal;
return myTIA.myPOSP0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::posP1(int newVal)
{
if(newVal > -1)
myTIA->myPOSP1 = newVal;
return myTIA->myPOSP1;
myTIA.myPOSP1 = newVal;
return myTIA.myPOSP1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -563,9 +562,9 @@ uInt8 TIADebug::posM0(int newVal)
{
/* FIXME
if(newVal > -1)
mySystem->poke(???, newVal);
mySystem.poke(???, newVal);
*/
return myTIA->myPOSM0;
return myTIA.myPOSM0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -573,9 +572,9 @@ uInt8 TIADebug::posM1(int newVal)
{
/* FIXME
if(newVal > -1)
mySystem->poke(???, newVal);
mySystem.poke(???, newVal);
*/
return myTIA->myPOSM1;
return myTIA.myPOSM1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -583,18 +582,18 @@ uInt8 TIADebug::posBL(int newVal)
{
/* FIXME
if(newVal > -1)
mySystem->poke(???, newVal);
mySystem.poke(???, newVal);
*/
return myTIA->myPOSBL;
return myTIA.myPOSBL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::ctrlPF(int newVal)
{
if(newVal > -1)
mySystem->poke(CTRLPF, newVal);
mySystem.poke(CTRLPF, newVal);
return myTIA->myCTRLPF;
return myTIA.myCTRLPF;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -602,87 +601,87 @@ uInt8 TIADebug::sizeBL(int newVal)
{
if(newVal > -1)
{
uInt8 tmp = myTIA->myCTRLPF & ~0x30;
uInt8 tmp = myTIA.myCTRLPF & ~0x30;
tmp |= (newVal & 0x04) << 4;
mySystem->poke(CTRLPF, tmp);
mySystem.poke(CTRLPF, tmp);
}
return (myTIA->myCTRLPF & 0x30) >> 4;
return (myTIA.myCTRLPF & 0x30) >> 4;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::hmP0(int newVal)
{
if(newVal > -1)
mySystem->poke(HMP0, newVal << 4);
mySystem.poke(HMP0, newVal << 4);
return myTIA->myHMP0;
return myTIA.myHMP0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::hmP1(int newVal)
{
if(newVal > -1)
mySystem->poke(HMP1, newVal << 4);
mySystem.poke(HMP1, newVal << 4);
return myTIA->myHMP1;
return myTIA.myHMP1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::hmM0(int newVal)
{
if(newVal > -1)
mySystem->poke(HMM0, newVal << 4);
mySystem.poke(HMM0, newVal << 4);
return myTIA->myHMM0;
return myTIA.myHMM0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::hmM1(int newVal)
{
if(newVal > -1)
mySystem->poke(HMM1, newVal << 4);
mySystem.poke(HMM1, newVal << 4);
return myTIA->myHMM1;
return myTIA.myHMM1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIADebug::hmBL(int newVal)
{
if(newVal > -1)
mySystem->poke(HMBL, newVal << 4);
mySystem.poke(HMBL, newVal << 4);
return myTIA->myHMBL;
return myTIA.myHMBL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int TIADebug::frameCount()
{
return myTIA->myFrameCounter;
return myTIA.myFrameCounter;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int TIADebug::scanlines()
{
return myTIA->scanlines();
return myTIA.scanlines();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int TIADebug::clocksThisLine()
{
return myTIA->clocksThisLine();
return myTIA.clocksThisLine();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::vsync()
{
return (myTIA->myVSYNC & 2) == 2;
return (myTIA.myVSYNC & 2) == 2;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool TIADebug::vblank()
{
return (myTIA->myVBLANK & 2) == 2;
return (myTIA.myVBLANK & 2) == 2;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -713,7 +712,7 @@ const string audFreq(uInt8 div)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string booleanWithLabel(string label, bool value)
string TIADebug::booleanWithLabel(string label, bool value)
{
char buf[64];
string ret;
@ -733,20 +732,33 @@ const string booleanWithLabel(string label, bool value)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string TIADebug::state()
string TIADebug::toString()
{
string ret;
char buf[128];
sprintf(buf, "%.2x: ", 0);
ret += buf;
for (uInt8 j = 0; j < 0x010; j++)
{
sprintf(buf, "%.2x ", mySystem.peek(j));
ret += buf;
if(j == 0x07) ret += "- ";
}
ret += "\n";
// TODO: inverse video for changed regs. Core needs to track this.
// TODO: strobes? WSYNC RSYNC RESP0/1 RESM0/1 RESBL HMOVE HMCLR CXCLR
TiaState state = (TiaState&) getState();
// FIXME - change tracking TiaState oldstate = (TiaState&) getOldState();
const TiaState& state = (TiaState&) getState();
// const TiaState& oldstate = (TiaState&) getOldState();
// build up output, then return it.
ret += "scanline ";
ret += myDebugger->valueToString(myTIA->scanlines());
ret += myDebugger.valueToString(myTIA.scanlines());
ret += " ";
ret += booleanWithLabel("vsync", vsync());
@ -755,38 +767,38 @@ string TIADebug::state()
ret += booleanWithLabel("vblank", vblank());
ret += "\n";
ret += booleanWithLabel("inpt0", myTIA->peek(0x08) & 0x80);
ret += booleanWithLabel("inpt0", myTIA.peek(0x08) & 0x80);
ret += " ";
ret += booleanWithLabel("inpt1", myTIA->peek(0x09) & 0x80);
ret += booleanWithLabel("inpt1", myTIA.peek(0x09) & 0x80);
ret += " ";
ret += booleanWithLabel("inpt2", myTIA->peek(0x0a) & 0x80);
ret += booleanWithLabel("inpt2", myTIA.peek(0x0a) & 0x80);
ret += " ";
ret += booleanWithLabel("inpt3", myTIA->peek(0x0b) & 0x80);
ret += booleanWithLabel("inpt3", myTIA.peek(0x0b) & 0x80);
ret += " ";
ret += booleanWithLabel("inpt4", myTIA->peek(0x0c) & 0x80);
ret += booleanWithLabel("inpt4", myTIA.peek(0x0c) & 0x80);
ret += " ";
ret += booleanWithLabel("inpt5", myTIA->peek(0x0d) & 0x80);
ret += booleanWithLabel("inpt5", myTIA.peek(0x0d) & 0x80);
ret += " ";
ret += booleanWithLabel("dump_gnd_0123", myTIA->myDumpEnabled);
ret += booleanWithLabel("dump_gnd_0123", myTIA.myDumpEnabled);
ret += "\n";
ret += "COLUP0: ";
ret += myDebugger->valueToString(state.coluRegs[0]);
ret += myDebugger.valueToString(state.coluRegs[0]);
ret += "/";
ret += colorSwatch(state.coluRegs[0]);
ret += "COLUP1: ";
ret += myDebugger->valueToString(state.coluRegs[1]);
ret += myDebugger.valueToString(state.coluRegs[1]);
ret += "/";
ret += colorSwatch(state.coluRegs[1]);
ret += "COLUPF: ";
ret += myDebugger->valueToString(state.coluRegs[2]);
ret += myDebugger.valueToString(state.coluRegs[2]);
ret += "/";
ret += colorSwatch(state.coluRegs[2]);
ret += "COLUBK: ";
ret += myDebugger->valueToString(state.coluRegs[3]);
ret += myDebugger.valueToString(state.coluRegs[3]);
ret += "/";
ret += colorSwatch(state.coluRegs[3]);
@ -795,11 +807,11 @@ string TIADebug::state()
ret += "P0: GR=";
ret += Debugger::to_bin_8(state.gr[P0]);
ret += "/";
ret += myDebugger->valueToString(state.gr[P0]);
ret += myDebugger.valueToString(state.gr[P0]);
ret += " pos=";
ret += myDebugger->valueToString(state.pos[P0]);
ret += myDebugger.valueToString(state.pos[P0]);
ret += " HM=";
ret += myDebugger->valueToString(state.hm[P0]);
ret += myDebugger.valueToString(state.hm[P0]);
ret += " ";
ret += nusizP0String();
ret += " ";
@ -811,11 +823,11 @@ string TIADebug::state()
ret += "P1: GR=";
ret += Debugger::to_bin_8(state.gr[P1]);
ret += "/";
ret += myDebugger->valueToString(state.gr[P1]);
ret += myDebugger.valueToString(state.gr[P1]);
ret += " pos=";
ret += myDebugger->valueToString(state.pos[P1]);
ret += myDebugger.valueToString(state.pos[P1]);
ret += " HM=";
ret += myDebugger->valueToString(state.hm[P1]);
ret += myDebugger.valueToString(state.hm[P1]);
ret += " ";
ret += nusizP1String();
ret += " ";
@ -825,37 +837,37 @@ string TIADebug::state()
ret += "\n";
ret += "M0: ";
ret += (myTIA->myENAM0 ? " ENABLED" : "disabled");
ret += (myTIA.myENAM0 ? " ENABLED" : "disabled");
ret += " pos=";
ret += myDebugger->valueToString(state.pos[M0]);
ret += myDebugger.valueToString(state.pos[M0]);
ret += " HM=";
ret += myDebugger->valueToString(state.hm[M0]);
ret += myDebugger.valueToString(state.hm[M0]);
ret += " size=";
ret += myDebugger->valueToString(state.size[M0]);
ret += myDebugger.valueToString(state.size[M0]);
ret += " ";
ret += booleanWithLabel("reset", resMP0());
ret += "\n";
ret += "M1: ";
ret += (myTIA->myENAM1 ? " ENABLED" : "disabled");
ret += (myTIA.myENAM1 ? " ENABLED" : "disabled");
ret += " pos=";
ret += myDebugger->valueToString(state.pos[M1]);
ret += myDebugger.valueToString(state.pos[M1]);
ret += " HM=";
ret += myDebugger->valueToString(state.hm[M1]);
ret += myDebugger.valueToString(state.hm[M1]);
ret += " size=";
ret += myDebugger->valueToString(state.size[M1]);
ret += myDebugger.valueToString(state.size[M1]);
ret += " ";
ret += booleanWithLabel("reset", resMP1());
ret += "\n";
ret += "BL: ";
ret += (myTIA->myENABL ? " ENABLED" : "disabled");
ret += (myTIA.myENABL ? " ENABLED" : "disabled");
ret += " pos=";
ret += myDebugger->valueToString(state.pos[BL]);
ret += myDebugger.valueToString(state.pos[BL]);
ret += " HM=";
ret += myDebugger->valueToString(state.hm[BL]);
ret += myDebugger.valueToString(state.hm[BL]);
ret += " size=";
ret += myDebugger->valueToString(state.size[BL]);
ret += myDebugger.valueToString(state.size[BL]);
ret += " ";
ret += booleanWithLabel("delay", vdelBL());
ret += "\n";
@ -863,15 +875,15 @@ string TIADebug::state()
ret += "PF0: ";
ret += Debugger::to_bin_8(state.pf[0]);
ret += "/";
ret += myDebugger->valueToString(state.pf[0]);
ret += myDebugger.valueToString(state.pf[0]);
ret += " PF1: ";
ret += Debugger::to_bin_8(state.pf[1]);
ret += "/";
ret += myDebugger->valueToString(state.pf[1]);
ret += myDebugger.valueToString(state.pf[1]);
ret += " PF2: ";
ret += Debugger::to_bin_8(state.pf[2]);
ret += "/";
ret += myDebugger->valueToString(state.pf[2]);
ret += myDebugger.valueToString(state.pf[2]);
ret += "\n ";
ret += booleanWithLabel("reflect", refPF());
ret += " ";
@ -900,31 +912,31 @@ string TIADebug::state()
ret += "\n";
ret += "AUDF0: ";
ret += myDebugger->valueToString(myTIA->myAUDF0);
ret += myDebugger.valueToString(myTIA.myAUDF0);
ret += "/";
ret += audFreq(myTIA->myAUDF0);
ret += audFreq(myTIA.myAUDF0);
ret += " ";
ret += "AUDC0: ";
ret += myDebugger->valueToString(myTIA->myAUDC0);
ret += myDebugger.valueToString(myTIA.myAUDC0);
ret += " ";
ret += "AUDV0: ";
ret += myDebugger->valueToString(myTIA->myAUDV0);
ret += myDebugger.valueToString(myTIA.myAUDV0);
ret += "\n";
ret += "AUDF1: ";
ret += myDebugger->valueToString(myTIA->myAUDF1);
ret += myDebugger.valueToString(myTIA.myAUDF1);
ret += "/";
ret += audFreq(myTIA->myAUDF1);
ret += audFreq(myTIA.myAUDF1);
ret += " ";
ret += "AUDC1: ";
ret += myDebugger->valueToString(myTIA->myAUDC1);
ret += myDebugger.valueToString(myTIA.myAUDC1);
ret += " ";
ret += "AUDV1: ";
ret += myDebugger->valueToString(myTIA->myAUDV1);
ret += myDebugger.valueToString(myTIA.myAUDV1);
//ret += "\n";
// note: last "ret +=" line should not contain \n, caller will add.

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TIADebug.hxx,v 1.22 2008-02-06 13:45:20 stephena Exp $
// $Id: TIADebug.hxx,v 1.23 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef TIA_DEBUG_HXX
@ -102,12 +102,13 @@ class TiaState : public DebuggerState
class TIADebug : public DebuggerSystem
{
public:
TIADebug(Debugger* dbg, Console* console);
TIADebug(Debugger& dbg, Console& console);
DebuggerState& getState();
DebuggerState& getOldState() { return myOldState; }
const DebuggerState& getState();
const DebuggerState& getOldState() { return myOldState; }
void saveOldState();
string toString();
/* TIA byte (or part of a byte) registers */
uInt8 nusiz0(int newVal = -1);
@ -187,16 +188,16 @@ class TIADebug : public DebuggerSystem
bool collM0_M1(int newVal = -1) { return collision(14, newVal); }
/* TIA strobe registers */
void strobeWsync() { mySystem->poke(WSYNC, 0); }
void strobeRsync() { mySystem->poke(RSYNC, 0); } // not emulated!
void strobeResP0() { mySystem->poke(RESP0, 0); }
void strobeResP1() { mySystem->poke(RESP1, 0); }
void strobeResM0() { mySystem->poke(RESM0, 0); }
void strobeResM1() { mySystem->poke(RESM1, 0); }
void strobeResBL() { mySystem->poke(RESBL, 0); }
void strobeHmove() { mySystem->poke(HMOVE, 0); }
void strobeHmclr() { mySystem->poke(HMCLR, 0); }
void strobeCxclr() { mySystem->poke(CXCLR, 0); }
void strobeWsync() { mySystem.poke(WSYNC, 0); }
void strobeRsync() { mySystem.poke(RSYNC, 0); } // not emulated!
void strobeResP0() { mySystem.poke(RESP0, 0); }
void strobeResP1() { mySystem.poke(RESP1, 0); }
void strobeResM0() { mySystem.poke(RESM0, 0); }
void strobeResM1() { mySystem.poke(RESM1, 0); }
void strobeResBL() { mySystem.poke(RESBL, 0); }
void strobeHmove() { mySystem.poke(HMOVE, 0); }
void strobeHmclr() { mySystem.poke(HMCLR, 0); }
void strobeCxclr() { mySystem.poke(CXCLR, 0); }
/* read-only internal TIA state */
int scanlines();
@ -204,7 +205,6 @@ class TIADebug : public DebuggerSystem
int clocksThisLine();
bool vsync();
bool vblank();
string state();
private:
/** Display a color patch for color at given index in the palette */
@ -213,12 +213,13 @@ class TIADebug : public DebuggerSystem
/** Get/set specific bits in the collision register (used by collXX_XX) */
bool collision(int collID, int newVal);
string booleanWithLabel(string label, bool value);
private:
TiaState myState;
TiaState myOldState;
System* mySystem;
TIA* myTIA;
TIA& myTIA;
string nusizStrings[8];
};

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: TiaWidget.cxx,v 1.10 2008-03-23 17:43:22 stephena Exp $
// $Id: TiaWidget.cxx,v 1.11 2008-04-19 21:11:52 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -272,17 +272,6 @@ TiaWidget::TiaWidget(GuiObject* boss, const GUI::Font& font,
"CxClr", kCxclrCmd);
b->setTarget(this);
// Set the strings to be used in the grPx registers
// We only do this once because it's the state that changes, not the strings
const char* offstr[] = { "0", "0", "0", "0", "0", "0", "0", "0" };
const char* onstr[] = { "1", "1", "1", "1", "1", "1", "1", "1" };
StringList off, on;
for(int i = 0; i < 8; ++i)
{
off.push_back(offstr[i]);
on.push_back(onstr[i]);
}
////////////////////////////
// P0 register info
////////////////////////////
@ -931,8 +920,8 @@ void TiaWidget::fillGrid()
Debugger& dbg = instance()->debugger();
TIADebug& tia = dbg.tiaDebug();
TiaState state = (TiaState&) tia.getState();
TiaState oldstate = (TiaState&) tia.getOldState();
TiaState& state = (TiaState&) tia.getState();
TiaState& oldstate = (TiaState&) tia.getOldState();
// TIA RAM
alist.clear(); vlist.clear(); changed.clear();

View File

@ -8,6 +8,7 @@ MODULE_OBJS := \
src/debugger/PackedBitArray.o \
src/debugger/CpuDebug.o \
src/debugger/RamDebug.o \
src/debugger/RiotDebug.o \
src/debugger/TIADebug.o
MODULE_DIRS += \

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: M6532.cxx,v 1.18 2008-04-17 13:39:14 stephena Exp $
// $Id: M6532.cxx,v 1.19 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#include <assert.h>
@ -61,6 +61,9 @@ void M6532::reset()
myOutA = 0x00;
myDDRA = 0x00;
myDDRB = 0x00;
// Zero the timer registers
myOutTimer[0] = myOutTimer[1] = myOutTimer[2] = myOutTimer[3] = 0x0;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -164,7 +167,7 @@ uInt8 M6532::peek(uInt16 addr)
case 0x04: // Timer Output
case 0x06:
{
uInt32 timer = myTimer - (mySystem->cycles() - myCyclesWhenTimerSet);
uInt32 timer = timerClocks();
// See if the timer has expired yet?
// Note that this constant comes from z26, and corresponds to
@ -184,9 +187,7 @@ uInt8 M6532::peek(uInt16 addr)
case 0x05: // Interrupt Flag
case 0x07:
{
Int32 timer = myTimer - (mySystem->cycles() - myCyclesWhenTimerSet);
if((timer >= 0) || myTimerReadAfterInterrupt)
if((timerClocks() >= 0) || myTimerReadAfterInterrupt)
return 0x00;
else
return 0x80;
@ -273,29 +274,33 @@ void M6532::poke(uInt16 addr, uInt8 value)
}
else if((addr & 0x17) == 0x14) // Write timer divide by 1
{
myOutTimer[0] = value;
myIntervalShift = 0;
myTimer = value << myIntervalShift;
myTimer = myOutTimer[0] << myIntervalShift;
myCyclesWhenTimerSet = mySystem->cycles();
myTimerReadAfterInterrupt = false;
}
else if((addr & 0x17) == 0x15) // Write timer divide by 8
{
myOutTimer[1] = value;
myIntervalShift = 3;
myTimer = value << myIntervalShift;
myTimer = myOutTimer[1] << myIntervalShift;
myCyclesWhenTimerSet = mySystem->cycles();
myTimerReadAfterInterrupt = false;
}
else if((addr & 0x17) == 0x16) // Write timer divide by 64
{
myOutTimer[2] = value;
myIntervalShift = 6;
myTimer = value << myIntervalShift;
myTimer = myOutTimer[2] << myIntervalShift;
myCyclesWhenTimerSet = mySystem->cycles();
myTimerReadAfterInterrupt = false;
}
else if((addr & 0x17) == 0x17) // Write timer divide by 1024
{
myOutTimer[3] = value;
myIntervalShift = 10;
myTimer = value << myIntervalShift;
myTimer = myOutTimer[3] << myIntervalShift;
myCyclesWhenTimerSet = mySystem->cycles();
myTimerReadAfterInterrupt = false;
}
@ -338,6 +343,10 @@ bool M6532::save(Serializer& out) const
out.putByte((char)myOutA);
out.putByte((char)myDDRA);
out.putByte((char)myDDRB);
out.putByte((char)myOutTimer[0]);
out.putByte((char)myOutTimer[1]);
out.putByte((char)myOutTimer[2]);
out.putByte((char)myOutTimer[3]);
}
catch(char *msg)
{
@ -376,6 +385,11 @@ bool M6532::load(Deserializer& in)
myOutA = (uInt8) in.getByte();
myDDRA = (uInt8) in.getByte();
myDDRB = (uInt8) in.getByte();
myOutTimer[0] = (uInt8) in.getByte();
myOutTimer[1] = (uInt8) in.getByte();
myOutTimer[2] = (uInt8) in.getByte();
myOutTimer[3] = (uInt8) in.getByte();
}
catch(char *msg)
{

View File

@ -13,28 +13,35 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: M6532.hxx,v 1.9 2008-04-17 13:39:14 stephena Exp $
// $Id: M6532.hxx,v 1.10 2008-04-19 21:11:52 stephena Exp $
//============================================================================
#ifndef M6532_HXX
#define M6532_HXX
class Console;
class System;
class RiotDebug;
class Serializer;
class Deserializer;
#include "bspf.hxx"
#include "Device.hxx"
#include "System.hxx"
/**
RIOT
@author Bradford W. Mott
@version $Id: M6532.hxx,v 1.9 2008-04-17 13:39:14 stephena Exp $
@version $Id: M6532.hxx,v 1.10 2008-04-19 21:11:52 stephena Exp $
*/
class M6532 : public Device
{
public:
/**
The RIOT debugger class is a friend who needs special access
*/
friend class RiotDebug;
public:
/**
Create a new 6532 for the specified console
@ -119,6 +126,10 @@ class M6532 : public Device
*/
virtual void poke(uInt16 address, uInt8 value);
private:
inline Int32 timerClocks()
{ return myTimer - (mySystem->cycles() - myCyclesWhenTimerSet); }
private:
// Reference to the console
const Console& myConsole;
@ -147,6 +158,9 @@ class M6532 : public Device
// Data Direction Register for Port B
uInt8 myDDRB;
// Last value written to the timer registers
uInt8 myOutTimer[4];
private:
// Copy constructor isn't supported by this class so make it private
M6532(const M6532&);