From patchwork Thu Sep 23 22:49:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Finn Thain X-Patchwork-Id: 12513779 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8DE9BC433EF for ; Fri, 24 Sep 2021 00:06:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 40286601FF for ; Fri, 24 Sep 2021 00:06:36 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 40286601FF Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=linux-m68k.org Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:33254 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mTYjb-0004g2-EF for qemu-devel@archiver.kernel.org; Thu, 23 Sep 2021 20:06:35 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39824) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mTYgu-0001pH-Dv; Thu, 23 Sep 2021 20:03:48 -0400 Received: from out5-smtp.messagingengine.com ([66.111.4.29]:60189) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mTYgs-0005wD-LY; Thu, 23 Sep 2021 20:03:48 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id E03135C019D; Thu, 23 Sep 2021 20:03:45 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Thu, 23 Sep 2021 20:03:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; bh=TbSWpafMo8Kfp9k0Ir5UbxAx68Nqj kbe+zXc52aXycw=; b=FYaK5d9aeARvmOZk5W06sujc9y4MUJOLSXJXmOAUDm5ox xgDKG9arw80N1/4kIEG7Zx2DRqF3z0v+9jve3kqDgW3i2iWRpxJGkoBNJCYQUOaj qmOYZWmrVpOCsIUQIfedIXYEGYy8fsZoTUQ/t/k4j/9cK47Zk01bdddHaIoPksb7 2UeVNhqb3bXvmwsIXWSzL8F4nWPpm9y5bnCrIc+Nq5LR7o0Bpq6Uu+hlQl+6IH6P 0wAmRQXaQP3kigaf5Rk24M2XYndVbEFHsD73jfEmYQB+bmNRLLogbRZ6o6oKaDQG w3El+B/E6UcZ2CiRfSv4rSLgIEiP6by8ziAsBOnJQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvtddrudejtddgvdejucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepvffkjghfhffuffestddtredttddttdenucfhrhhomhephfhinhhnucfvhhgr ihhnuceofhhthhgrihhnsehlihhnuhigqdhmieekkhdrohhrgheqnecuggftrfgrthhtvg hrnhephfetledtgeffuedujedvteevgfdtudeufeekvdfhveekkefhgfevtdfhveeuueet necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepfhhthh grihhnsehlihhnuhigqdhmieekkhdrohhrgh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 23 Sep 2021 20:03:44 -0400 (EDT) To: Mark Cave-Ayland , Greg Kurz Message-Id: <005b55c5dccb3786d15188f76f689002448383ae.1632437396.git.fthain@linux-m68k.org> In-Reply-To: References: From: Finn Thain Subject: [PATCH v1 5/9] hw/mos6522: Fix initial timer counter reload Date: Fri, 24 Sep 2021 08:49:56 +1000 Received-SPF: none client-ip=66.111.4.29; envelope-from=fthain@linux-m68k.org; helo=out5-smtp.messagingengine.com X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_PASS=-0.001, SPF_NONE=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-ppc@nongnu.org, Laurent Vivier , qemu-devel@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" 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 --- 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 c0d6bee4cc..6bd60f2118 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) @@ -102,11 +103,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) {