Timer 1 has two modes: continuous interrupt and oneshot. Signed-off-by: Finn Thain <fth...@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(-)
diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 8957c5e65c..bbed0b84c0 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -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; diff --git a/include/hw/misc/mos6522.h b/include/hw/misc/mos6522.h index a2df5fa942..4dbba6b273 100644 --- a/include/hw/misc/mos6522.h +++ b/include/hw/misc/mos6522.h @@ -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 -- 2.26.3