qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Finn Thain <fthain@linux-m68k.org>
To: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>,
	David Gibson <david@gibson.dropbear.id.au>,
	Greg Kurz <groug@kaod.org>
Cc: qemu-ppc@nongnu.org, Laurent Vivier <laurent@vivier.eu>,
	qemu-devel@nongnu.org
Subject: [RFC 07/10] hw/mos6522: Fix initial timer counter reload
Date: Tue, 24 Aug 2021 20:09:36 +1000	[thread overview]
Message-ID: <ae3528be683e131503ea272847a4490d505739ca.1629799776.git.fthain@linux-m68k.org> (raw)
In-Reply-To: <cover.1629799776.git.fthain@linux-m68k.org>

The first reload of timer 1 is early by half of a clock cycle as it gets
measured from a falling edge. By contrast, the succeeding reloads are
measured from rising edge to rising edge.

Neglecting that complication, the behaviour of the counter should be the
same from one reload to the next. The sequence is always:

N, N-1, N-2, ... 2, 1, 0, -1, N, N-1, N-2, ...

But at the first reload, the present driver does this instead:

N, N-1, N-2, ... 2, 1, 0, -1, N-1, N-2, ...

Fix this deviation for both timer 1 and timer 2, and allow for the fact
that on a real 6522 the timer 2 counter is not reloaded when it wraps.

Signed-off-by: Finn Thain <fthain@linux-m68k.org>
---
 hw/misc/mos6522.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c
index 5b1657ac0d..0a241fe9f8 100644
--- a/hw/misc/mos6522.c
+++ b/hw/misc/mos6522.c
@@ -63,15 +63,16 @@ static unsigned int get_counter(MOS6522State *s, MOS6522Timer *ti)
     if (ti->index == 0) {
         /* the timer goes down from latch to -1 (period of latch + 2) */
         if (d <= (ti->counter_value + 1)) {
-            counter = (ti->counter_value - d) & 0xffff;
+            counter = ti->counter_value - d;
         } else {
-            counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
-            counter = (ti->latch - counter) & 0xffff;
+            int64_t d_post_reload = d - (ti->counter_value + 2);
+            /* XXX this calculation assumes that ti->latch has not changed */
+            counter = ti->latch - (d_post_reload % (ti->latch + 2));
         }
     } else {
-        counter = (ti->counter_value - d) & 0xffff;
+        counter = ti->counter_value - d;
     }
-    return counter;
+    return counter & 0xffff;
 }
 
 static void set_counter(MOS6522State *s, MOS6522Timer *ti, unsigned int val)
@@ -103,11 +104,13 @@ static int64_t get_next_irq_time(MOS6522State *s, MOS6522Timer *ti,
 
     /* the timer goes down from latch to -1 (period of latch + 2) */
     if (d <= (ti->counter_value + 1)) {
-        counter = (ti->counter_value - d) & 0xffff;
+        counter = ti->counter_value - d;
     } else {
-        counter = (d - (ti->counter_value + 1)) % (ti->latch + 2);
-        counter = (ti->latch - counter) & 0xffff;
+        int64_t d_post_reload = d - (ti->counter_value + 2);
+        /* XXX this calculation assumes that ti->latch has not changed */
+        counter = ti->latch - (d_post_reload % (ti->latch + 2));
     }
+    counter &= 0xffff;
 
     /* Note: we consider the irq is raised on 0 */
     if (counter == 0xffff) {
-- 
2.26.3



  parent reply	other threads:[~2021-08-24 10:17 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-24 10:09 [RFC 00/10] hw/mos6522: VIA timer emulation fixes and improvements Finn Thain
2021-08-24 10:09 ` [RFC 09/10] hw/mos6522: Avoid using discrepant QEMU clock values Finn Thain
2021-08-24 10:28   ` Philippe Mathieu-Daudé
2021-08-29  1:23     ` Finn Thain
2021-08-25  8:44   ` Mark Cave-Ayland
2021-08-29  1:55     ` Finn Thain
2021-08-24 10:09 ` [RFC 06/10] hw/mos6522: Implement oneshot mode Finn Thain
2021-08-25  8:18   ` Mark Cave-Ayland
2021-08-29  1:20     ` Finn Thain
2021-08-24 10:09 ` [RFC 01/10] hw/mos6522: Remove get_load_time() methods and functions Finn Thain
2021-08-24 10:29   ` Philippe Mathieu-Daudé
2021-08-25  6:55   ` Mark Cave-Ayland
2021-08-28  1:00     ` Finn Thain
2021-08-24 10:09 ` [RFC 08/10] hw/mos6522: Call mos6522_update_irq() when appropriate Finn Thain
2021-08-24 10:22   ` Philippe Mathieu-Daudé
2021-08-25  8:26   ` Mark Cave-Ayland
2021-08-24 10:09 ` Finn Thain [this message]
2021-08-25  8:23   ` [RFC 07/10] hw/mos6522: Fix initial timer counter reload Mark Cave-Ayland
2021-08-28  0:46     ` Finn Thain
2021-08-24 10:09 ` [RFC 10/10] hw/mos6522: Synchronize timer interrupt and timer counter Finn Thain
2021-08-25  8:52   ` Mark Cave-Ayland
2021-08-26  6:43     ` Finn Thain
2021-08-24 10:09 ` [RFC 04/10] hw/mos6522: Rename timer callback functions Finn Thain
2021-08-24 10:28   ` Philippe Mathieu-Daudé
2021-08-25  7:11   ` Mark Cave-Ayland
2021-08-26  7:42     ` Philippe Mathieu-Daudé
2021-08-24 10:09 ` [RFC 02/10] hw/mos6522: Remove get_counter_value() methods and functions Finn Thain
2021-08-24 10:29   ` Philippe Mathieu-Daudé
2021-08-24 10:09 ` [RFC 05/10] hw/mos6522: Don't clear T1 interrupt flag on latch write Finn Thain
2021-08-25  7:20   ` Mark Cave-Ayland
2021-08-26  5:21     ` Finn Thain
2021-09-01 14:32       ` Laurent Vivier
2021-09-01 22:26         ` Finn Thain
2021-08-24 10:09 ` [RFC 03/10] hw/mos6522: Remove redundant mos6522_timer1_update() calls Finn Thain
2021-08-25  7:09   ` Mark Cave-Ayland
2021-08-24 10:34 ` [RFC 00/10] hw/mos6522: VIA timer emulation fixes and improvements Philippe Mathieu-Daudé
2021-08-28  1:22   ` Finn Thain
2021-08-31 21:14     ` Mark Cave-Ayland
2021-08-31 22:44       ` Finn Thain
2021-09-01  7:57         ` Mark Cave-Ayland
2021-09-01  8:06           ` Mark Cave-Ayland
2021-09-10 17:29             ` Mark Cave-Ayland
2021-09-11  0:08               ` Finn Thain
2021-09-01  2:20       ` Finn Thain
2021-08-25  3:11 ` David Gibson
2021-08-25  9:10 ` Mark Cave-Ayland
2021-08-28  4:11   ` Finn Thain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ae3528be683e131503ea272847a4490d505739ca.1629799776.git.fthain@linux-m68k.org \
    --to=fthain@linux-m68k.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=laurent@vivier.eu \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).