From 520d6e65402fe8aa2ff6d311d9f3b2135bea6879 Mon Sep 17 00:00:00 2001 From: Stephen White Date: Sun, 28 Apr 2019 15:50:57 +1000 Subject: [PATCH] 6522 timer IRQs were triggering one cycle too late. --- src/m6522.cpp | 48 ++++++++++++++++++++++-------------------------- src/m6522.h | 2 +- 2 files changed, 23 insertions(+), 27 deletions(-) diff --git a/src/m6522.cpp b/src/m6522.cpp index 58ceeac..7147887 100644 --- a/src/m6522.cpp +++ b/src/m6522.cpp @@ -147,22 +147,6 @@ void m6522::Execute() { t1c.value = t1l.value; t1TimedOut = false; - - if (t1FreeRun) - { - if (t1FreeRunIRQsOn) - SetInterrupt(IR_T1); - } - else - { - if (!t1OneShotTriggeredIRQ) - { - t1OneShotTriggeredIRQ = true; - SetInterrupt(IR_T1); - } - // At this time the counter will continue to decrement at system clock rate. - // This allows the system processor to read the contents of the counter to determine the time since interrupt. - } } else if (t1Ticking && !t1Reload && !t1c.value--) { @@ -170,6 +154,9 @@ void m6522::Execute() if (t1FreeRun) { + if (t1FreeRunIRQsOn) + SetInterrupt(IR_T1); + if (t1l.value > 1) // A real VIA will not flip PB7 if the frequency is above a certain (ie 1 cycle) threshold { t1_pb7 = !t1_pb7; @@ -189,6 +176,9 @@ void m6522::Execute() { if (!t1OneShotTriggeredIRQ) { + t1OneShotTriggeredIRQ = true; + SetInterrupt(IR_T1); + if (t1OutPB7) { // PB7 was set low on the write to T1CH now the signal on PB7 will go high @@ -216,16 +206,7 @@ void m6522::Execute() t2TimedOut = false; // In both modes the interrupt is only set once - if (!t2OneShotTriggeredIRQ) - { - t2OneShotTriggeredIRQ = true; - SetInterrupt(IR_T2); - } - else - { - // At this time the counter will continue to decrement at system clock rate or PB6 negative edge counts (depending upon mode) - // This allows the system processor to read the contents of the counter to determine the time since interrupt. - } + if ((auxiliaryControlRegister & 0xc) == 4) // shift by timer 2? { @@ -302,6 +283,21 @@ void m6522::Execute() { t2Reload = false; } + + if (t2TimedOut) + { + // In both modes the interrupt is only set once + if (!t2OneShotTriggeredIRQ) + { + t2OneShotTriggeredIRQ = true; + SetInterrupt(IR_T2); + } + else + { + // At this time the counter will continue to decrement at system clock rate or PB6 negative edge counts (depending upon mode) + // This allows the system processor to read the contents of the counter to determine the time since interrupt. + } + } } pb6Old = pb6; t2CountingPB6ModeOld = t2CountingPB6Mode; diff --git a/src/m6522.h b/src/m6522.h index 7d1f767..7c753fb 100644 --- a/src/m6522.h +++ b/src/m6522.h @@ -29,7 +29,7 @@ class m6522 // PB 1 data out // PB 2 clock in // PB 3 clock out - // PB 4 ATNA + // PB 4 ATNA out // PB 5,6 device address // PB 7,CA1 ATN IN