mirror of https://github.com/stella-emu/stella.git
Properly emulate interrupt flag behavior of INITM read on wraparound.
This commit is contained in:
parent
471db61254
commit
317169c59a
|
@ -30,7 +30,7 @@ M6532::M6532(const Console& console, const Settings& settings)
|
||||||
: myConsole(console),
|
: myConsole(console),
|
||||||
mySettings(settings),
|
mySettings(settings),
|
||||||
myTimer(0), mySubTimer(0), myDivider(1),
|
myTimer(0), mySubTimer(0), myDivider(1),
|
||||||
myTimerWrapped(false), mySetTimerCycle(0), myLastCycle(0),
|
myTimerWrapped(false), myWrappedThisCycle(false), mySetTimerCycle(0), myLastCycle(0),
|
||||||
myDDRA(0), myDDRB(0), myOutA(0), myOutB(0),
|
myDDRA(0), myDDRB(0), myOutA(0), myOutB(0),
|
||||||
myInterruptFlag(false),
|
myInterruptFlag(false),
|
||||||
myEdgeDetectPositive(false)
|
myEdgeDetectPositive(false)
|
||||||
|
@ -51,6 +51,8 @@ void M6532::reset()
|
||||||
myDivider = 1024;
|
myDivider = 1024;
|
||||||
mySubTimer = 0;
|
mySubTimer = 0;
|
||||||
myTimerWrapped = false;
|
myTimerWrapped = false;
|
||||||
|
myWrappedThisCycle = false;
|
||||||
|
|
||||||
mySetTimerCycle = 0;
|
mySetTimerCycle = 0;
|
||||||
myLastCycle = mySystem->cycles();
|
myLastCycle = mySystem->cycles();
|
||||||
|
|
||||||
|
@ -109,6 +111,11 @@ void M6532::updateEmulation()
|
||||||
uInt32 cycles = mySystem->cycles() - myLastCycle;
|
uInt32 cycles = mySystem->cycles() - myLastCycle;
|
||||||
uInt32 subTimer = mySubTimer;
|
uInt32 subTimer = mySubTimer;
|
||||||
|
|
||||||
|
// Guard against further state changes if the debugger alread forwarded emulation
|
||||||
|
// state (in particular myWrappedThisCycle)
|
||||||
|
if (cycles == 0) return;
|
||||||
|
|
||||||
|
myWrappedThisCycle = false;
|
||||||
mySubTimer = (cycles + mySubTimer) % myDivider;
|
mySubTimer = (cycles + mySubTimer) % myDivider;
|
||||||
|
|
||||||
if(!myTimerWrapped)
|
if(!myTimerWrapped)
|
||||||
|
@ -118,6 +125,7 @@ void M6532::updateEmulation()
|
||||||
if(timerTicks > myTimer)
|
if(timerTicks > myTimer)
|
||||||
{
|
{
|
||||||
cycles -= ((myTimer + 1) * myDivider - subTimer);
|
cycles -= ((myTimer + 1) * myDivider - subTimer);
|
||||||
|
myWrappedThisCycle = cycles == 0;
|
||||||
myTimer = 0xFF;
|
myTimer = 0xFF;
|
||||||
myTimerWrapped = true;
|
myTimerWrapped = true;
|
||||||
myInterruptFlag |= TimerBit;
|
myInterruptFlag |= TimerBit;
|
||||||
|
@ -201,7 +209,7 @@ uInt8 M6532::peek(uInt16 addr)
|
||||||
case 0x06:
|
case 0x06:
|
||||||
{
|
{
|
||||||
// Timer Flag is always cleared when accessing INTIM
|
// Timer Flag is always cleared when accessing INTIM
|
||||||
myInterruptFlag &= ~TimerBit;
|
if (!myWrappedThisCycle) myInterruptFlag &= ~TimerBit;
|
||||||
myTimerWrapped = false;
|
myTimerWrapped = false;
|
||||||
return myTimer;
|
return myTimer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,6 +175,7 @@ class M6532 : public Device
|
||||||
|
|
||||||
// Has the timer wrapped?
|
// Has the timer wrapped?
|
||||||
bool myTimerWrapped;
|
bool myTimerWrapped;
|
||||||
|
bool myWrappedThisCycle;
|
||||||
|
|
||||||
// Cycle when the timer set. Debugging only.
|
// Cycle when the timer set. Debugging only.
|
||||||
Int32 mySetTimerCycle;
|
Int32 mySetTimerCycle;
|
||||||
|
|
Loading…
Reference in New Issue