@@ -148,7 +148,8 @@ static void mos6522_timer1_update(MOS6522State *s, MOS6522Timer *ti,
}
get_counter(s, ti, now);
ti->next_irq_time = get_next_irq_time(s, ti, now);
- if ((s->ier & T1_INT) == 0 || (s->acr & T1MODE) != T1MODE_CONT) {
+ if ((s->ier & T1_INT) == 0 ||
+ ((s->acr & T1MODE) == T1MODE_ONESHOT && ti->state >= irq)) {
timer_del(ti->timer);
} else {
timer_mod(ti->timer, ti->next_irq_time);
@@ -163,7 +164,7 @@ static void mos6522_timer2_update(MOS6522State *s, MOS6522Timer *ti,
}
get_counter(s, ti, now);
ti->next_irq_time = get_next_irq_time(s, ti, now);
- if ((s->ier & T2_INT) == 0) {
+ if ((s->ier & T2_INT) == 0 || (s->acr & T2MODE) || ti->state >= irq) {
timer_del(ti->timer);
} else {
timer_mod(ti->timer, ti->next_irq_time);
@@ -345,6 +346,7 @@ void mos6522_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
case VIA_REG_ACR:
s->acr = val;
mos6522_timer1_update(s, &s->timers[0], now);
+ mos6522_timer2_update(s, &s->timers[1], now);
break;
case VIA_REG_PCR:
s->pcr = val;
@@ -50,8 +50,10 @@
#define T1_INT 0x40 /* Timer 1 interrupt */
/* Bits in ACR */
+#define T2MODE 0x20 /* Timer 2 mode */
#define T1MODE 0xc0 /* Timer 1 mode */
#define T1MODE_CONT 0x40 /* continuous interrupts */
+#define T1MODE_ONESHOT 0x00 /* timed interrupt */
/* VIA registers */
#define VIA_REG_B 0x00
Timer 1 has two modes: continuous interrupt and oneshot. Signed-off-by: Finn Thain <fthain@linux-m68k.org> --- Changed since RFC: - Moved to end of series. This patch is quite a bit shorter here. --- hw/misc/mos6522.c | 6 ++++-- include/hw/misc/mos6522.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)