diff --git a/Changes.txt b/Changes.txt index c1459467e..0cf475fca 100644 --- a/Changes.txt +++ b/Changes.txt @@ -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 diff --git a/src/debugger/RiotDebug.cxx b/src/debugger/RiotDebug.cxx index e7aa5e86b..769188a9f 100644 --- a/src/debugger/RiotDebug.cxx +++ b/src/debugger/RiotDebug.cxx @@ -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() diff --git a/src/debugger/RiotDebug.hxx b/src/debugger/RiotDebug.hxx index 8b2306a32..cbf781ffc 100644 --- a/src/debugger/RiotDebug.hxx +++ b/src/debugger/RiotDebug.hxx @@ -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; diff --git a/src/debugger/gui/RiotWidget.cxx b/src/debugger/gui/RiotWidget.cxx index 13a1d9ac8..2c4100176 100644 --- a/src/debugger/gui/RiotWidget.cxx +++ b/src/debugger/gui/RiotWidget.cxx @@ -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; diff --git a/src/debugger/gui/RiotWidget.hxx b/src/debugger/gui/RiotWidget.hxx index fb731d92b..6da8c2f9e 100644 --- a/src/debugger/gui/RiotWidget.hxx +++ b/src/debugger/gui/RiotWidget.hxx @@ -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 }; }; diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index b3ab7b2be..70d52ab59 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -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()); diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index b21ab2211..327dee550 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -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; diff --git a/src/emucore/M6502.hxx b/src/emucore/M6502.hxx index d966d3764..c26478381 100644 --- a/src/emucore/M6502.hxx +++ b/src/emucore/M6502.hxx @@ -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; diff --git a/src/emucore/M6532.cxx b/src/emucore/M6532.cxx index 799aa458c..cc47d5b55 100644 --- a/src/emucore/M6532.cxx +++ b/src/emucore/M6532.cxx @@ -179,7 +179,7 @@ uInt8 M6532::peek(uInt16 addr) myInterruptFlag &= ~TimerBit; // Get number of clocks since timer was set - Int32 timer = timerClocks(); + Int32 timer = timerClocks(); // Note that this constant comes from z26, and corresponds to // 256 intervals of T1024T (ie, the maximum that the timer should hold) @@ -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), diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index d7a6f8287..1341dedd6 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -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 diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index 72459c6cc..fb346c91e 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -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