Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Odetti 2019-06-07 19:49:37 +01:00
commit 78ef2cc23c
9 changed files with 46 additions and 21 deletions

View file

@ -9,6 +9,13 @@ https://github.com/AppleWin/AppleWin/issues/new
Tom Charlesworth
1.28.6.0 - 1 Jun 2019
---------------------
. [Bug #651] Cycle-accurate interrupts:
- Interrupts sources are checked after every opcode (full-speed after every 40 opcodes).
- 6522 TIMERs in free-running mode now account for the underflowed cycles when resetting the count.
1.28.5.0 - 6 Apr 2019
---------------------
. [Change #631] Improvements for the RGB AppleColor card:

View file

@ -1,4 +1,4 @@
#define APPLEWIN_VERSION 1,28,5,0
#define APPLEWIN_VERSION 1,28,6,0
#define xstr(a) str(a)
#define str(a) #a

View file

@ -130,12 +130,7 @@ regsrec regs;
unsigned __int64 g_nCumulativeCycles = 0;
static ULONG g_nCyclesExecuted; // # of cycles executed up to last IO access
//static signed long g_uInternalExecutedCycles;
// TODO: Use IRQ_CHECK_TIMEOUT=128 when running at full-speed else with IRQ_CHECK_TIMEOUT=1
// - What about when running benchmark?
static const int IRQ_CHECK_TIMEOUT = 128;
static signed int g_nIrqCheckTimeout = IRQ_CHECK_TIMEOUT;
//
@ -417,21 +412,29 @@ static __forceinline void IRQ(ULONG& uExecutedCycles, BOOL& flagc, BOOL& flagn,
}
}
static __forceinline void CheckInterruptSources(ULONG uExecutedCycles)
const int IRQ_CHECK_OPCODE_FULL_SPEED = 40; // ~128 cycles (assume 3 cycles per opcode)
static int g_fullSpeedOpcodeCount = IRQ_CHECK_OPCODE_FULL_SPEED;
static __forceinline void CheckInterruptSources(ULONG uExecutedCycles, const bool bVideoUpdate)
{
if (g_nIrqCheckTimeout < 0)
if (!bVideoUpdate)
{
MB_UpdateCycles(uExecutedCycles);
sg_Mouse.SetVBlank( !VideoGetVblBar(uExecutedCycles) );
g_nIrqCheckTimeout = IRQ_CHECK_TIMEOUT;
g_fullSpeedOpcodeCount--;
if (g_fullSpeedOpcodeCount >= 0)
return;
g_fullSpeedOpcodeCount = IRQ_CHECK_OPCODE_FULL_SPEED;
}
MB_UpdateCycles(uExecutedCycles);
sg_Mouse.SetVBlank( !VideoGetVblBar(uExecutedCycles) );
}
// GH#608: IRQ needs to occur within 17 cycles (6 opcodes) of configuring the timer interrupt
void CpuAdjustIrqCheck(UINT uCyclesUntilInterrupt)
{
if (uCyclesUntilInterrupt < IRQ_CHECK_TIMEOUT)
g_nIrqCheckTimeout = uCyclesUntilInterrupt;
const UINT opcodesUntilInterrupt = uCyclesUntilInterrupt/3; // assume 3 cycles per opcode
if (g_bFullSpeed && opcodesUntilInterrupt < IRQ_CHECK_OPCODE_FULL_SPEED)
g_fullSpeedOpcodeCount = opcodesUntilInterrupt;
}
//===========================================================================

View file

@ -318,7 +318,7 @@ static DWORD Cpu6502(DWORD uTotalCycles, const bool bVideoUpdate)
#undef $
}
CheckInterruptSources(uExecutedCycles);
CheckInterruptSources(uExecutedCycles, bVideoUpdate);
NMI(uExecutedCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, flagc, flagn, flagv, flagz);

View file

@ -321,7 +321,7 @@ static DWORD Cpu65C02(DWORD uTotalCycles, const bool bVideoUpdate)
#undef $
}
CheckInterruptSources(uExecutedCycles);
CheckInterruptSources(uExecutedCycles, bVideoUpdate);
NMI(uExecutedCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, flagc, flagn, flagv, flagz);

View file

@ -406,7 +406,7 @@ static DWORD Cpu65D02(DWORD uTotalCycles, const bool bVideoUpdate)
}
#undef $
CheckInterruptSources(uExecutedCycles);
CheckInterruptSources(uExecutedCycles, bVideoUpdate);
NMI(uExecutedCycles, flagc, flagn, flagv, flagz);
IRQ(uExecutedCycles, flagc, flagn, flagv, flagz);

View file

@ -49,7 +49,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| (flagz ? AF_ZERO : 0) \
| AF_RESERVED | AF_BREAK;
// CYC(a): This can be optimised, as only certain opcodes will affect uExtraCycles
#define CYC(a) uExecutedCycles += (a)+uExtraCycles; g_nIrqCheckTimeout -= (a)+uExtraCycles;
#define CYC(a) uExecutedCycles += (a)+uExtraCycles;
#define POP (*(mem+((regs.sp >= 0x1FF) ? (regs.sp = 0x100) : ++regs.sp)))
#define PUSH(a) *(mem+regs.sp--) = (a); \
if (regs.sp < 0x100) \

View file

@ -1797,11 +1797,19 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
{
// Free-running mode
// - Ultima4/5 change ACCESS_TIMER1 after a couple of IRQs into tune
pMB->sy6522.TIMER1_COUNTER.w = pMB->sy6522.TIMER1_LATCH.w;
pMB->sy6522.TIMER1_COUNTER.w += pMB->sy6522.TIMER1_LATCH.w; // GH#651: account for underflowed cycles too
if (pMB->sy6522.TIMER1_COUNTER.w > pMB->sy6522.TIMER1_LATCH.w)
{
if (pMB->sy6522.TIMER1_LATCH.w)
pMB->sy6522.TIMER1_COUNTER.w %= pMB->sy6522.TIMER1_LATCH.w; // Only occurs if LATCH.w<0x0007 (# cycles for longest opcode)
else
pMB->sy6522.TIMER1_COUNTER.w = 0;
}
StartTimer1(pMB);
}
}
else if (pMB->bTimer2Active && bTimer2Underflow)
if (pMB->bTimer2Active && bTimer2Underflow)
{
UpdateIFR(pMB, 0, IxR_TIMER2);
@ -1811,7 +1819,14 @@ void MB_UpdateCycles(ULONG uExecutedCycles)
}
else
{
pMB->sy6522.TIMER2_COUNTER.w = pMB->sy6522.TIMER2_LATCH.w;
pMB->sy6522.TIMER2_COUNTER.w += pMB->sy6522.TIMER2_LATCH.w;
if (pMB->sy6522.TIMER2_COUNTER.w > pMB->sy6522.TIMER2_LATCH.w)
{
if (pMB->sy6522.TIMER2_LATCH.w)
pMB->sy6522.TIMER2_COUNTER.w %= pMB->sy6522.TIMER2_LATCH.w;
else
pMB->sy6522.TIMER2_COUNTER.w = 0;
}
StartTimer2(pMB);
}
}

View file

@ -54,7 +54,7 @@ static __forceinline void DoIrqProfiling(DWORD uCycles)
{
}
static __forceinline void CheckInterruptSources(ULONG uExecutedCycles)
static __forceinline void CheckInterruptSources(ULONG uExecutedCycles, const bool bVideoUpdate)
{
}