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