Added 'cpurandom' commandline argument and associated UI item, to randomize

the CPU registers (A/X/Y/PS) on ROM load.

Added 'INTIM Clks' to the debugger I/O tab, showing the number of clocks
before the current INTIM value decreases by 1.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2768 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-07-21 00:27:52 +00:00
parent 13c3ca9964
commit a1ac026cbc
11 changed files with 113 additions and 45 deletions

View File

@ -14,20 +14,28 @@
3.9 to 3.9.1: (XXXX xx, 2013) 3.9 to 3.9.1: (XXXX xx, 2013)
* Fixed bug in debugger disassembly when the mirror used for the current * Several bugfixes and improvements to the debugger:
PC didn't match the mirror for the current bank. In this case, the - Fixed bug in disassembly when the mirror used for the current
disassembler became confused and didn't properly track the PC address. PC didn't match the mirror for the current bank. In this case,
the disassembler became confused and didn't properly track the
PC address.
* Changed display for various TIA position counters to decimal - Changed display for various TIA position counters to decimal
(from hex) in the debugger TIA tab. Related to this, all data input (from hex) in the TIA tab. Related to this, all data input
widgets in the debugger UI now have the ability to enter binary, widgets in the UI now have the ability to enter binary,
decimal or hex values by using the proper leading character (\, #, $, decimal or hex values by using the proper leading character
respectively). (\, #, $, respectively).
* Added ability to modify 'tiadriven' commandline argument to the - Added 'INTIM Clks' to the 'I/O' tab. which shows the number of
debugger 'TIA' tab, and 'ramrandom' to the debugger 'I/O' tab. These clocks between each 'step' of the INTIM timer.
options were available for quite some time, but they weren't exposed
in the UI. - Added ability to modify 'tiadriven' commandline argument to the
'TIA' tab, and 'ramrandom' to the 'I/O' tab. These options were
available for quite some time, but they weren't exposed in the UI.
- Added 'cpurandom' commandline argument, and associated UI item
to the 'I/O' tab. This works similar to 'ramrandom', and
randomizes the contents on the CPU registers on ROM startup.
* Fixed bug in Linux/UNIX port, whereby a maximize button was always * Fixed bug in Linux/UNIX port, whereby a maximize button was always
present in the window title bar. Stella could not be expanded in present in the window title bar. Stella could not be expanded in

View File

@ -58,13 +58,14 @@ const DebuggerState& RiotDebug::getState()
myState.INPT5 = inpt(5); myState.INPT5 = inpt(5);
// Timer registers // Timer registers
myState.TIM1T = tim1T(); myState.TIM1T = tim1T();
myState.TIM8T = tim8T(); myState.TIM8T = tim8T();
myState.TIM64T = tim64T(); myState.TIM64T = tim64T();
myState.TIM1024T = tim1024T(); myState.TIM1024T = tim1024T();
myState.INTIM = intim(); myState.INTIM = intim();
myState.TIMINT = timint(); myState.TIMINT = timint();
myState.TIMCLKS = timClocks(); myState.TIMCLKS = timClocks();
myState.INTIMCLKS = intimClocks();
return myState; return myState;
} }
@ -95,13 +96,14 @@ void RiotDebug::saveOldState()
myOldState.INPT5 = inpt(5); myOldState.INPT5 = inpt(5);
// Timer registers // Timer registers
myOldState.TIM1T = tim1T(); myOldState.TIM1T = tim1T();
myOldState.TIM8T = tim8T(); myOldState.TIM8T = tim8T();
myOldState.TIM64T = tim64T(); myOldState.TIM64T = tim64T();
myOldState.TIM1024T = tim1024T(); myOldState.TIM1024T = tim1024T();
myOldState.INTIM = intim(); myOldState.INTIM = intim();
myOldState.TIMINT = timint(); myOldState.TIMINT = timint();
myOldState.TIMCLKS = timClocks(); myOldState.TIMCLKS = timClocks();
myOldState.INTIMCLKS = intimClocks();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -344,6 +346,8 @@ string RiotDebug::toString()
<< myDebugger.invIfChanged(state.TIMINT, oldstate.TIMINT) << " " << myDebugger.invIfChanged(state.TIMINT, oldstate.TIMINT) << " "
<< "Timer_Clocks=" << "Timer_Clocks="
<< myDebugger.invIfChanged(state.TIMCLKS, oldstate.TIMCLKS) << " " << myDebugger.invIfChanged(state.TIMCLKS, oldstate.TIMCLKS) << " "
<< "INTIM_Clocks="
<< myDebugger.invIfChanged(state.INTIMCLKS, oldstate.INTIMCLKS) << " "
<< endl << endl
<< "Left/P0diff: " << diffP0String() << " Right/P1diff: " << diffP0String() << "Left/P0diff: " << diffP0String() << " Right/P1diff: " << diffP0String()

View File

@ -39,7 +39,7 @@ class RiotState : public DebuggerState
BoolArray swbcntBits; BoolArray swbcntBits;
uInt8 TIM1T, TIM8T, TIM64T, TIM1024T, INTIM, TIMINT; uInt8 TIM1T, TIM8T, TIM64T, TIM1024T, INTIM, TIMINT;
Int32 TIMCLKS; Int32 TIMCLKS, INTIMCLKS;
// These are actually from the TIA, but are I/O related // These are actually from the TIA, but are I/O related
uInt8 INPT0, INPT1, INPT2, INPT3, INPT4, INPT5; uInt8 INPT0, INPT1, INPT2, INPT3, INPT4, INPT5;
@ -72,9 +72,10 @@ class RiotDebug : public DebuggerSystem
uInt8 tim8T(int newVal = -1); uInt8 tim8T(int newVal = -1);
uInt8 tim64T(int newVal = -1); uInt8 tim64T(int newVal = -1);
uInt8 tim1024T(int newVal = -1); uInt8 tim1024T(int newVal = -1);
uInt8 intim() const { return mySystem.m6532().intim(); } uInt8 intim() const { return mySystem.m6532().intim(); }
uInt8 timint() const { return mySystem.m6532().timint(); } uInt8 timint() const { return mySystem.m6532().timint(); }
Int32 timClocks() const { return mySystem.m6532().timerClocks(); } Int32 timClocks() const { return mySystem.m6532().timerClocks(); }
Int32 intimClocks() const { return mySystem.m6532().intimClocks(); }
/* Controller ports */ /* Controller ports */
Controller& controller(Controller::Jack jack) const; Controller& controller(Controller::Jack jack) const;

View File

@ -112,15 +112,15 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
addFocusWidget(myTimWrite); addFocusWidget(myTimWrite);
// Timer registers (RO) // Timer registers (RO)
const char* readNames[] = { "INTIM:", "TIMINT:", "Tim Clks:" }; const char* readNames[] = { "INTIM:", "TIMINT:", "Total Clks:", "INTIM Clks:" };
xpos = 10; ypos += myTimWrite->getHeight() + lineHeight; xpos = 10; ypos += myTimWrite->getHeight() + lineHeight;
for(int row = 0; row < 3; ++row) for(int row = 0; row < 4; ++row)
{ {
t = new StaticTextWidget(boss, font, xpos, ypos + row*lineHeight + 2, t = new StaticTextWidget(boss, font, xpos, ypos + row*lineHeight + 2,
9*fontWidth, fontHeight, readNames[row], kTextAlignLeft); 11*fontWidth, fontHeight, readNames[row], kTextAlignLeft);
} }
xpos += 9*fontWidth + 5; xpos += t->getWidth() + 5;
myTimRead = new DataGridWidget(boss, font, xpos, ypos, 1, 3, 8, 32, kBASE_16); myTimRead = new DataGridWidget(boss, font, xpos, ypos, 1, 4, 8, 32, kBASE_16);
myTimRead->setTarget(this); myTimRead->setTarget(this);
myTimRead->setEditable(false); myTimRead->setEditable(false);
@ -211,10 +211,24 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
myReset->setTarget(this); myReset->setTarget(this);
addFocusWidget(myReset); addFocusWidget(myReset);
// Randomize RAM // Randomize items
xpos = 10; ypos += 3*lineHeight; xpos = 10; ypos += 3*lineHeight;
myRandomizeRAM = new CheckboxWidget(boss, font, 10, ypos+1, new StaticTextWidget(boss, font, xpos, ypos,
"Randomize RAM on startup (requires ROM reload)", kCheckActionCmd); font.getStringWidth("When loading a ROM:"), fontHeight,
"When loading a ROM:", kTextAlignLeft);
// Randomize CPU
xpos += 30; ypos += lineHeight + 4;
myRandomizeCPU = new CheckboxWidget(boss, font, xpos, ypos+1,
"Randomize CPU registers (A/X/Y/PS)", kCheckActionCmd);
myRandomizeCPU->setID(kRandCPUID);
myRandomizeCPU->setTarget(this);
addFocusWidget(myRandomizeCPU);
// Randomize RAM
ypos += lineHeight + 4;
myRandomizeRAM = new CheckboxWidget(boss, font, xpos, ypos+1,
"Randomize zero-page and extended RAM", kCheckActionCmd);
myRandomizeRAM->setID(kRandRAMID); myRandomizeRAM->setID(kRandRAMID);
myRandomizeRAM->setTarget(this); myRandomizeRAM->setTarget(this);
addFocusWidget(myRandomizeRAM); addFocusWidget(myRandomizeRAM);
@ -305,6 +319,8 @@ void RiotWidget::loadConfig()
changed.push_back(state.TIMINT != oldstate.TIMINT); changed.push_back(state.TIMINT != oldstate.TIMINT);
alist.push_back(0); vlist.push_back(state.TIMCLKS); alist.push_back(0); vlist.push_back(state.TIMCLKS);
changed.push_back(state.TIMCLKS != oldstate.TIMCLKS); changed.push_back(state.TIMCLKS != oldstate.TIMCLKS);
alist.push_back(0); vlist.push_back(state.INTIMCLKS);
changed.push_back(state.INTIMCLKS != oldstate.INTIMCLKS);
myTimRead->setList(alist, vlist, changed); myTimRead->setList(alist, vlist, changed);
// Console switches (inverted, since 'selected' in the UI // Console switches (inverted, since 'selected' in the UI
@ -318,6 +334,7 @@ void RiotWidget::loadConfig()
myLeftControl->loadConfig(); myLeftControl->loadConfig();
myRightControl->loadConfig(); myRightControl->loadConfig();
myRandomizeCPU->setState(instance().settings().getBool("cpurandom"));
myRandomizeRAM->setState(instance().settings().getBool("ramrandom")); myRandomizeRAM->setState(instance().settings().getBool("ramrandom"));
} }
@ -383,6 +400,9 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
case kResetID: case kResetID:
riot.reset(!myReset->getState()); riot.reset(!myReset->getState());
break; break;
case kRandCPUID:
instance().settings().setValue("cpurandom", myRandomizeCPU->getState());
break;
case kRandRAMID: case kRandRAMID:
instance().settings().setValue("ramrandom", myRandomizeRAM->getState()); instance().settings().setValue("ramrandom", myRandomizeRAM->getState());
break; break;

View File

@ -67,6 +67,7 @@ class RiotWidget : public Widget, public CommandSender
CheckboxWidget* mySelect; CheckboxWidget* mySelect;
CheckboxWidget* myReset; CheckboxWidget* myReset;
CheckboxWidget* myRandomizeCPU;
CheckboxWidget* myRandomizeRAM; CheckboxWidget* myRandomizeRAM;
// ID's for the various widgets // ID's for the various widgets
@ -75,7 +76,7 @@ class RiotWidget : public Widget, public CommandSender
kTim1TID, kTim8TID, kTim64TID, kTim1024TID, kTimWriteID, kTim1TID, kTim8TID, kTim64TID, kTim1024TID, kTimWriteID,
kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kSWBCNTBitsID, kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kSWBCNTBitsID,
kP0DiffChanged, kP1DiffChanged, kTVTypeChanged, kSelectID, kResetID, kP0DiffChanged, kP1DiffChanged, kTVTypeChanged, kSelectID, kResetID,
kRandRAMID kRandCPUID, kRandRAMID
}; };
}; };

View File

@ -99,7 +99,7 @@ Console::Console(OSystem* osystem, Cartridge* cart, const Properties& props)
myControllers[0] = new Joystick(Controller::Left, myEvent, *mySystem); myControllers[0] = new Joystick(Controller::Left, myEvent, *mySystem);
myControllers[1] = new Joystick(Controller::Right, myEvent, *mySystem); myControllers[1] = new Joystick(Controller::Right, myEvent, *mySystem);
M6502* m6502 = new M6502(1); M6502* m6502 = new M6502(1, myOSystem->settings());
myRiot = new M6532(*this, myOSystem->settings()); myRiot = new M6532(*this, myOSystem->settings());
myTIA = new TIA(*this, myOSystem->sound(), myOSystem->settings()); myTIA = new TIA(*this, myOSystem->sound(), myOSystem->settings());

View File

@ -42,13 +42,15 @@
#define DISASM_ROW 0 #define DISASM_ROW 0
#define DISASM_NONE 0 #define DISASM_NONE 0
#endif #endif
#include "Settings.hxx"
#include "M6502.hxx" #include "M6502.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6502::M6502(uInt32 systemCyclesPerProcessorCycle) M6502::M6502(uInt32 systemCyclesPerProcessorCycle, const Settings& settings)
: myExecutionStatus(0), : myExecutionStatus(0),
mySystem(0), mySystem(0),
mySettings(settings),
mySystemCyclesPerProcessorCycle(systemCyclesPerProcessorCycle), mySystemCyclesPerProcessorCycle(systemCyclesPerProcessorCycle),
myLastAccessWasRead(true), myLastAccessWasRead(true),
myTotalInstructionCount(0), myTotalInstructionCount(0),
@ -108,9 +110,19 @@ void M6502::reset()
myExecutionStatus = 0; myExecutionStatus = 0;
// Set registers to default values // Set registers to default values
A = X = Y = 0;
SP = 0xff; SP = 0xff;
PS(0x20); if(mySettings.getBool("cpurandom"))
{
A = mySystem->randGenerator().next();
X = mySystem->randGenerator().next();
Y = mySystem->randGenerator().next();
PS(mySystem->randGenerator().next());
}
else
{
A = X = Y = 0;
PS(0x20);
}
// Reset access flag // Reset access flag
myLastAccessWasRead = true; myLastAccessWasRead = true;

View File

@ -25,6 +25,7 @@ class Debugger;
class CpuDebug; class CpuDebug;
class Expression; class Expression;
class PackedBitArray; class PackedBitArray;
class Settings;
#include "bspf.hxx" #include "bspf.hxx"
#include "System.hxx" #include "System.hxx"
@ -61,7 +62,7 @@ class M6502 : public Serializable
@param systemCyclesPerProcessorCycle The cycle multiplier @param systemCyclesPerProcessorCycle The cycle multiplier
*/ */
M6502(uInt32 systemCyclesPerProcessorCycle); M6502(uInt32 systemCyclesPerProcessorCycle, const Settings& settings);
/** /**
Destructor Destructor
@ -320,6 +321,9 @@ class M6502 : public Serializable
/// Pointer to the system the processor is installed in or the null pointer /// Pointer to the system the processor is installed in or the null pointer
System* mySystem; System* mySystem;
/// Reference to the settings
const Settings& mySettings;
/// Indicates the number of system cycles per processor cycle /// Indicates the number of system cycles per processor cycle
const uInt32 mySystemCyclesPerProcessorCycle; const uInt32 mySystemCyclesPerProcessorCycle;

View File

@ -429,6 +429,21 @@ uInt8 M6532::timint() const
return interrupt; return interrupt;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 M6532::intimClocks() const
{
// This method is similar to intim(), except instead of giving the actual
// INTIM value, it will give the current number of clocks between one
// INTIM value and the next
// Get number of clocks since timer was set
Int32 timer = timerClocks();
if(!(timer & 0x40000))
return timerClocks() & ((1 << myIntervalShift) - 1);
else
return timer & 0xff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6532::M6532(const M6532& c) M6532::M6532(const M6532& c)
: myConsole(c.myConsole), : myConsole(c.myConsole),

View File

@ -151,6 +151,7 @@ class M6532 : public Device
// isn't changed // isn't changed
uInt8 intim() const; uInt8 intim() const;
uInt8 timint() const; uInt8 timint() const;
Int32 intimClocks() const;
private: private:
// Accessible bits in the interrupt flag register // Accessible bits in the interrupt flag register

View File

@ -129,6 +129,7 @@ Settings::Settings(OSystem* osystem)
setInternal("loglevel", "1"); setInternal("loglevel", "1");
setInternal("logtoconsole", "0"); setInternal("logtoconsole", "0");
setInternal("tiadriven", "false"); setInternal("tiadriven", "false");
setInternal("cpurandom", "true");
setInternal("ramrandom", "true"); setInternal("ramrandom", "true");
setInternal("avoxport", ""); setInternal("avoxport", "");
setInternal("stats", "false"); setInternal("stats", "false");
@ -431,6 +432,7 @@ void Settings::usage()
<< " -holdselect Start the emulator with the Game Select switch held down\n" << " -holdselect Start the emulator with the Game Select switch held down\n"
<< " -holdbutton0 Start the emulator with the left joystick button held down\n" << " -holdbutton0 Start the emulator with the left joystick button held down\n"
<< " -tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n" << " -tiadriven <1|0> Drive unused TIA pins randomly on a read/peek\n"
<< " -cpurandom <1|0> Randomize the contents of CPU registers on reset\n"
<< " -ramrandom <1|0> Randomize the contents of RAM on reset\n" << " -ramrandom <1|0> Randomize the contents of RAM on reset\n"
<< " -help Show the text you're now reading\n" << " -help Show the text you're now reading\n"
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT