diff --git a/src/emucore/M6502.cxx b/src/emucore/M6502.cxx index ba0387944..58166c59b 100644 --- a/src/emucore/M6502.cxx +++ b/src/emucore/M6502.cxx @@ -20,6 +20,8 @@ #include "Expression.hxx" #include "CartDebug.hxx" #include "PackedBitArray.hxx" + #include "TIA.hxx" + #include "M6532.hxx" // Flags for disassembly types #define DISASM_CODE CartDebug::CODE @@ -65,7 +67,8 @@ M6502::M6502(const Settings& settings) myLastSrcAddressY(-1), myDataAddressForPoke(0), myOnHaltCallback(nullptr), - myHaltRequested(false) + myHaltRequested(false), + myStepStateByInstruction(false) { #ifdef DEBUGGER_SUPPORT myDebugger = nullptr; @@ -197,12 +200,23 @@ inline void M6502::handleHalt() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void M6502::updateStepStateByInstruction() +{ + myStepStateByInstruction = myCondBreaks.size() || myCondSaveStates.size() || myTrapConds.size(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool M6502::execute(uInt32 number) { // Clear all of the execution status bits except for the fatal error bit myExecutionStatus &= FatalErrorBit; +#ifdef DEBUGGER_SUPPORT + TIA& tia = mySystem->tia(); + M6532& riot = mySystem->m6532(); +#endif + // Loop until execution is stopped or a fatal error occurs for(;;) { @@ -258,6 +272,13 @@ bool M6502::execute(uInt32 number) myExecutionStatus |= FatalErrorBit; } //cycles = mySystem->cycles() - c0; + +#ifdef DEBUGGER_SUPPORT + if (myStepStateByInstruction) { + tia.updateEmulation(); + riot.updateEmulation(); + } +#endif } // See if we need to handle an interrupt @@ -367,6 +388,7 @@ bool M6502::save(Serializer& out) const out.putInt(myLastSrcAddressY); out.putBool(myHaltRequested); + out.putBool(myStepStateByInstruction); } catch(...) { @@ -417,6 +439,7 @@ bool M6502::load(Serializer& in) myLastSrcAddressY = in.getInt(); myHaltRequested = in.getBool(); + myStepStateByInstruction = in.getBool(); } catch(...) { @@ -440,6 +463,9 @@ uInt32 M6502::addCondBreak(Expression* e, const string& name) { myCondBreaks.emplace_back(e); myCondBreakNames.push_back(name); + + updateStepStateByInstruction(); + return uInt32(myCondBreaks.size() - 1); } @@ -450,6 +476,9 @@ bool M6502::delCondBreak(uInt32 idx) { Vec::removeAt(myCondBreaks, idx); Vec::removeAt(myCondBreakNames, idx); + + updateStepStateByInstruction(); + return true; } return false; @@ -460,6 +489,8 @@ void M6502::clearCondBreaks() { myCondBreaks.clear(); myCondBreakNames.clear(); + + updateStepStateByInstruction(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -473,6 +504,9 @@ uInt32 M6502::addCondSaveState(Expression* e, const string& name) { myCondSaveStates.emplace_back(e); myCondSaveStateNames.push_back(name); + + updateStepStateByInstruction(); + return uInt32(myCondSaveStates.size() - 1); } @@ -483,6 +517,9 @@ bool M6502::delCondSaveState(uInt32 idx) { Vec::removeAt(myCondSaveStates, idx); Vec::removeAt(myCondSaveStateNames, idx); + + updateStepStateByInstruction(); + return true; } return false; @@ -493,6 +530,8 @@ void M6502::clearCondSaveStates() { myCondSaveStates.clear(); myCondSaveStateNames.clear(); + + updateStepStateByInstruction(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -506,6 +545,9 @@ uInt32 M6502::addCondTrap(Expression* e, const string& name) { myTrapConds.emplace_back(e); myTrapCondNames.push_back(name); + + updateStepStateByInstruction(); + return uInt32(myTrapConds.size() - 1); } @@ -516,6 +558,9 @@ bool M6502::delCondTrap(uInt32 brk) { Vec::removeAt(myTrapConds, brk); Vec::removeAt(myTrapCondNames, brk); + + updateStepStateByInstruction(); + return true; } return false; @@ -526,6 +571,8 @@ void M6502::clearCondTraps() { myTrapConds.clear(); myTrapCondNames.clear(); + + updateStepStateByInstruction(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/M6502.hxx b/src/emucore/M6502.hxx index 16feb2459..c00d22d85 100644 --- a/src/emucore/M6502.hxx +++ b/src/emucore/M6502.hxx @@ -312,6 +312,12 @@ class M6502 : public Serializable */ void handleHalt(); + /** + Check whether we are required to update hardware (TIA + RIOT) in lockstep + with the CPU and update the flag accordingly. + */ + void updateStepStateByInstruction(); + private: /** Bit fields used to indicate that certain conditions need to be @@ -439,6 +445,8 @@ class M6502 : public Serializable vector> myTrapConds; StringList myTrapCondNames; + bool myStepStateByInstruction; + #endif // DEBUGGER_SUPPORT private: diff --git a/src/emucore/M6532.hxx b/src/emucore/M6532.hxx index ebd298d33..e235fb606 100644 --- a/src/emucore/M6532.hxx +++ b/src/emucore/M6532.hxx @@ -125,13 +125,16 @@ class M6532 : public Device */ bool poke(uInt16 address, uInt8 value) override; + /** + * Update RIOT state to the current timestamp. + */ + void updateEmulation(); + private: void setTimerRegister(uInt8 data, uInt8 interval); void setPinState(bool shcha); - void updateEmulation(); - // The following are used by the debugger to read INTIM/TIMINT // We need separate methods to do this, so the state of the system // isn't changed diff --git a/src/emucore/tia/TIA.hxx b/src/emucore/tia/TIA.hxx index a64b726e6..85fb673c4 100644 --- a/src/emucore/tia/TIA.hxx +++ b/src/emucore/tia/TIA.hxx @@ -443,6 +443,11 @@ class TIA : public Device */ string name() const override { return "TIA"; } + /** + * Run and forward TIA emulation to the current system clock. + */ + void updateEmulation(); + private: /** * During each line, the TIA cycles through these two states. @@ -481,11 +486,6 @@ class TIA : public Device */ void onHalt(); - /** - * Run and forward TIA emulation to the current system clock. - */ - void updateEmulation(); - /** * Execute colorClocks cycles of TIA simulation. */