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)
* Fixed bug in debugger disassembly when the mirror used for the current
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.
* Several bugfixes and improvements to the debugger:
- Fixed bug in disassembly when the mirror used for the current
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
(from hex) in the debugger TIA tab. Related to this, all data input
widgets in the debugger UI now have the ability to enter binary,
decimal or hex values by using the proper leading character (\, #, $,
respectively).
- Changed display for various TIA position counters to decimal
(from hex) in the TIA tab. Related to this, all data input
widgets in the UI now have the ability to enter binary,
decimal or hex values by using the proper leading character
(\, #, $, respectively).
* Added ability to modify 'tiadriven' commandline argument to the
debugger 'TIA' tab, and 'ramrandom' to the debugger 'I/O' tab. These
options were available for quite some time, but they weren't exposed
in the UI.
- Added 'INTIM Clks' to the 'I/O' tab. which shows the number of
clocks between each 'step' of the INTIM timer.
- 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
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);
// Timer registers
myState.TIM1T = tim1T();
myState.TIM8T = tim8T();
myState.TIM64T = tim64T();
myState.TIM1024T = tim1024T();
myState.INTIM = intim();
myState.TIMINT = timint();
myState.TIMCLKS = timClocks();
myState.TIM1T = tim1T();
myState.TIM8T = tim8T();
myState.TIM64T = tim64T();
myState.TIM1024T = tim1024T();
myState.INTIM = intim();
myState.TIMINT = timint();
myState.TIMCLKS = timClocks();
myState.INTIMCLKS = intimClocks();
return myState;
}
@ -95,13 +96,14 @@ void RiotDebug::saveOldState()
myOldState.INPT5 = inpt(5);
// Timer registers
myOldState.TIM1T = tim1T();
myOldState.TIM8T = tim8T();
myOldState.TIM64T = tim64T();
myOldState.TIM1024T = tim1024T();
myOldState.INTIM = intim();
myOldState.TIMINT = timint();
myOldState.TIMCLKS = timClocks();
myOldState.TIM1T = tim1T();
myOldState.TIM8T = tim8T();
myOldState.TIM64T = tim64T();
myOldState.TIM1024T = tim1024T();
myOldState.INTIM = intim();
myOldState.TIMINT = timint();
myOldState.TIMCLKS = timClocks();
myOldState.INTIMCLKS = intimClocks();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -344,6 +346,8 @@ string RiotDebug::toString()
<< myDebugger.invIfChanged(state.TIMINT, oldstate.TIMINT) << " "
<< "Timer_Clocks="
<< myDebugger.invIfChanged(state.TIMCLKS, oldstate.TIMCLKS) << " "
<< "INTIM_Clocks="
<< myDebugger.invIfChanged(state.INTIMCLKS, oldstate.INTIMCLKS) << " "
<< endl
<< "Left/P0diff: " << diffP0String() << " Right/P1diff: " << diffP0String()

View File

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

View File

@ -112,15 +112,15 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
addFocusWidget(myTimWrite);
// 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;
for(int row = 0; row < 3; ++row)
for(int row = 0; row < 4; ++row)
{
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;
myTimRead = new DataGridWidget(boss, font, xpos, ypos, 1, 3, 8, 32, kBASE_16);
xpos += t->getWidth() + 5;
myTimRead = new DataGridWidget(boss, font, xpos, ypos, 1, 4, 8, 32, kBASE_16);
myTimRead->setTarget(this);
myTimRead->setEditable(false);
@ -211,10 +211,24 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& font,
myReset->setTarget(this);
addFocusWidget(myReset);
// Randomize RAM
// Randomize items
xpos = 10; ypos += 3*lineHeight;
myRandomizeRAM = new CheckboxWidget(boss, font, 10, ypos+1,
"Randomize RAM on startup (requires ROM reload)", kCheckActionCmd);
new StaticTextWidget(boss, font, xpos, ypos,
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->setTarget(this);
addFocusWidget(myRandomizeRAM);
@ -305,6 +319,8 @@ void RiotWidget::loadConfig()
changed.push_back(state.TIMINT != oldstate.TIMINT);
alist.push_back(0); vlist.push_back(state.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);
// Console switches (inverted, since 'selected' in the UI
@ -318,6 +334,7 @@ void RiotWidget::loadConfig()
myLeftControl->loadConfig();
myRightControl->loadConfig();
myRandomizeCPU->setState(instance().settings().getBool("cpurandom"));
myRandomizeRAM->setState(instance().settings().getBool("ramrandom"));
}
@ -383,6 +400,9 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
case kResetID:
riot.reset(!myReset->getState());
break;
case kRandCPUID:
instance().settings().setValue("cpurandom", myRandomizeCPU->getState());
break;
case kRandRAMID:
instance().settings().setValue("ramrandom", myRandomizeRAM->getState());
break;

View File

@ -67,6 +67,7 @@ class RiotWidget : public Widget, public CommandSender
CheckboxWidget* mySelect;
CheckboxWidget* myReset;
CheckboxWidget* myRandomizeCPU;
CheckboxWidget* myRandomizeRAM;
// ID's for the various widgets
@ -75,7 +76,7 @@ class RiotWidget : public Widget, public CommandSender
kTim1TID, kTim8TID, kTim64TID, kTim1024TID, kTimWriteID,
kSWCHABitsID, kSWACNTBitsID, kSWCHBBitsID, kSWBCNTBitsID,
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[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());
myTIA = new TIA(*this, myOSystem->sound(), myOSystem->settings());

View File

@ -42,13 +42,15 @@
#define DISASM_ROW 0
#define DISASM_NONE 0
#endif
#include "Settings.hxx"
#include "M6502.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6502::M6502(uInt32 systemCyclesPerProcessorCycle)
M6502::M6502(uInt32 systemCyclesPerProcessorCycle, const Settings& settings)
: myExecutionStatus(0),
mySystem(0),
mySettings(settings),
mySystemCyclesPerProcessorCycle(systemCyclesPerProcessorCycle),
myLastAccessWasRead(true),
myTotalInstructionCount(0),
@ -108,9 +110,19 @@ void M6502::reset()
myExecutionStatus = 0;
// Set registers to default values
A = X = Y = 0;
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
myLastAccessWasRead = true;

View File

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

View File

@ -429,6 +429,21 @@ uInt8 M6532::timint() const
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)
: myConsole(c.myConsole),

View File

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

View File

@ -129,6 +129,7 @@ Settings::Settings(OSystem* osystem)
setInternal("loglevel", "1");
setInternal("logtoconsole", "0");
setInternal("tiadriven", "false");
setInternal("cpurandom", "true");
setInternal("ramrandom", "true");
setInternal("avoxport", "");
setInternal("stats", "false");
@ -431,6 +432,7 @@ void Settings::usage()
<< " -holdselect Start the emulator with the Game Select switch 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"
<< " -cpurandom <1|0> Randomize the contents of CPU registers on reset\n"
<< " -ramrandom <1|0> Randomize the contents of RAM on reset\n"
<< " -help Show the text you're now reading\n"
#ifdef DEBUGGER_SUPPORT