From nobody Tue Feb 10 12:09:36 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1539887761781707.6187240910652; Thu, 18 Oct 2018 11:36:01 -0700 (PDT) Received: from localhost ([::1]:43807 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gDD9H-0007xk-75 for importer@patchew.org; Thu, 18 Oct 2018 14:35:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37684) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gDD2u-0002vL-TV for qemu-devel@nongnu.org; Thu, 18 Oct 2018 14:29:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gDD2q-00028O-Fk for qemu-devel@nongnu.org; Thu, 18 Oct 2018 14:29:19 -0400 Received: from chuckie.co.uk ([82.165.15.123]:59534 helo=s16892447.onlinehome-server.info) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gDD2q-00027F-50; Thu, 18 Oct 2018 14:29:16 -0400 Received: from host86-162-6-79.range86-162.btcentralplus.com ([86.162.6.79] helo=kentang.home) by s16892447.onlinehome-server.info with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1gDD32-0000e7-9s; Thu, 18 Oct 2018 19:29:29 +0100 From: Mark Cave-Ayland To: qemu-devel@nongnu.org, kwolf@redhat.com, famz@redhat.com, qemu-block@nongnu.org, jasowang@redhat.com, dgilbert@redhat.com, mreitz@redhat.com, hpoussin@reactos.org, kraxel@redhat.com, pbonzini@redhat.com, yongbok.kim@mips.com, afaerber@suse.de, aurelien@aurel32.net, laurent@vivier.eu Date: Thu, 18 Oct 2018 19:28:47 +0100 Message-Id: <20181018182856.28001-3-mark.cave-ayland@ilande.co.uk> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20181018182856.28001-1-mark.cave-ayland@ilande.co.uk> References: <20181018182856.28001-1-mark.cave-ayland@ilande.co.uk> X-SA-Exim-Connect-IP: 86.162.6.79 X-SA-Exim-Mail-From: mark.cave-ayland@ilande.co.uk X-SA-Exim-Version: 4.2.1 (built Sun, 08 Jan 2012 02:45:44 +0000) X-SA-Exim-Scanned: Yes (on s16892447.onlinehome-server.info) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 82.165.15.123 Subject: [Qemu-devel] [PATCH v4 02/11] hw/m68k: implement ADB bus support for via X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Laurent Vivier Co-developed-by: Mark Cave-Ayland Signed-off-by: Mark Cave-Ayland Signed-off-by: Laurent Vivier --- hw/input/adb.c | 2 + hw/misc/mac_via.c | 166 ++++++++++++++++++++++++++++++++++++++++++= ++++ include/hw/misc/mac_via.h | 7 ++ 3 files changed, 175 insertions(+) diff --git a/hw/input/adb.c b/hw/input/adb.c index bbb40aeef1..d69ca74364 100644 --- a/hw/input/adb.c +++ b/hw/input/adb.c @@ -25,6 +25,8 @@ #include "hw/input/adb.h" #include "adb-internal.h" =20 +#define ADB_POLL_FREQ 50 + /* error codes */ #define ADB_RET_NOTPRESENT (-2) =20 diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index 084974a24d..1ec563a707 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -237,6 +237,11 @@ * Table 19-10 ADB transaction states */ =20 +#define ADB_STATE_NEW 0 +#define ADB_STATE_EVEN 1 +#define ADB_STATE_ODD 2 +#define ADB_STATE_IDLE 3 + #define VIA1B_vADB_StateMask (VIA1B_vADBS1 | VIA1B_vADBS2) #define VIA1B_vADB_StateShift 4 =20 @@ -424,6 +429,158 @@ static void via1_rtc_update(MacVIAState *m) } } =20 +static int adb_via_poll(MacVIAState *s, int state, uint8_t *data) +{ + if (state !=3D ADB_STATE_IDLE) { + return 0; + } + if (s->adb_data_in_size < s->adb_data_in_index) { + return 0; + } + if (s->adb_data_out_index !=3D 0) { + return 0; + } + s->adb_data_in_index =3D 0; + s->adb_data_out_index =3D 0; + s->adb_data_in_size =3D adb_poll(&s->adb_bus, s->adb_data_in, 0xffff); + if (s->adb_data_in_size) { + *data =3D s->adb_data_in[s->adb_data_in_index++]; + qemu_irq_raise(s->adb_data_ready); + } + return s->adb_data_in_size; +} + +static int adb_via_send(MacVIAState *s, int state, uint8_t data) +{ + switch (state) { + case ADB_STATE_NEW: + s->adb_data_out_index =3D 0; + break; + case ADB_STATE_EVEN: + if ((s->adb_data_out_index & 1) =3D=3D 0) { + return 0; + } + break; + case ADB_STATE_ODD: + if (s->adb_data_out_index & 1) { + return 0; + } + break; + case ADB_STATE_IDLE: + return 0; + } + s->adb_data_out[s->adb_data_out_index++] =3D data; + qemu_irq_raise(s->adb_data_ready); + return 1; +} + +static int adb_via_receive(MacVIAState *s, int state, uint8_t *data) +{ + switch (state) { + case ADB_STATE_NEW: + return 0; + case ADB_STATE_EVEN: + if (s->adb_data_in_size <=3D 0) { + qemu_irq_raise(s->adb_data_ready); + return 0; + } + if (s->adb_data_in_index >=3D s->adb_data_in_size) { + *data =3D 0; + qemu_irq_raise(s->adb_data_ready); + return 1; + } + if ((s->adb_data_in_index & 1) =3D=3D 0) { + return 0; + } + break; + case ADB_STATE_ODD: + if (s->adb_data_in_size <=3D 0) { + qemu_irq_raise(s->adb_data_ready); + return 0; + } + if (s->adb_data_in_index >=3D s->adb_data_in_size) { + *data =3D 0; + qemu_irq_raise(s->adb_data_ready); + return 1; + } + if (s->adb_data_in_index & 1) { + return 0; + } + break; + case ADB_STATE_IDLE: + if (s->adb_data_out_index =3D=3D 0) { + return 0; + } + s->adb_data_in_size =3D adb_request(&s->adb_bus, s->adb_data_in, + s->adb_data_out, + s->adb_data_out_index); + s->adb_data_out_index =3D 0; + s->adb_data_in_index =3D 0; + if (s->adb_data_in_size < 0) { + *data =3D 0xff; + qemu_irq_raise(s->adb_data_ready); + return -1; + } + if (s->adb_data_in_size =3D=3D 0) { + return 0; + } + break; + } + *data =3D s->adb_data_in[s->adb_data_in_index++]; + qemu_irq_raise(s->adb_data_ready); + if (*data =3D=3D 0xff || *data =3D=3D 0) { + return 0; + } + return 1; +} + +static void via1_adb_update(MacVIAState *m) +{ + MOS6522Q800VIA1State *v1s =3D MOS6522_Q800_VIA1(&m->mos6522_via1); + MOS6522State *s =3D MOS6522(v1s); + int state; + int ret; + + state =3D (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift; + + if (s->acr & VIA1ACR_vShiftOut) { + /* output mode */ + ret =3D adb_via_send(m, state, s->sr); + if (ret > 0) { + s->b &=3D ~VIA1B_vADBInt; + } else { + s->b |=3D VIA1B_vADBInt; + } + } else { + /* input mode */ + ret =3D adb_via_receive(m, state, &s->sr); + if (ret > 0 && s->sr !=3D 0xff) { + s->b &=3D ~VIA1B_vADBInt; + } else { + s->b |=3D VIA1B_vADBInt; + } + } +} + +static void via_adb_poll(void *opaque) +{ + MacVIAState *m =3D opaque; + MOS6522Q800VIA1State *v1s =3D MOS6522_Q800_VIA1(&m->mos6522_via1); + MOS6522State *s =3D MOS6522(v1s); + int state; + + if (s->b & VIA1B_vADBInt) { + state =3D (s->b & VIA1B_vADB_StateMask) >> VIA1B_vADB_StateShift; + if (adb_via_poll(m, state, &s->sr)) { + s->b &=3D ~VIA1B_vADBInt; + } + } + + timer_mod(m->adb_poll_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ)); +} + static uint64_t mos6522_q800_via1_read(void *opaque, hwaddr addr, unsigned= size) { MOS6522Q800VIA1State *s =3D opaque; @@ -486,6 +643,10 @@ static void mac_via_reset(DeviceState *dev) { MacVIAState *m =3D MAC_VIA(dev); =20 + timer_mod(m->adb_poll_timer, + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + + (NANOSECONDS_PER_SECOND / VIA_ADB_POLL_FREQ)); + timer_mod(m->VBL_timer, (qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 16630) / 16630 * 16630); =20 @@ -524,6 +685,10 @@ static void mac_via_realize(DeviceState *dev, Error **= errp) =20 qemu_get_timedate(&tm, 0); m->tick_offset =3D (uint32_t)mktimegm(&tm) + RTC_OFFSET; + + m->adb_poll_timer =3D timer_new_ns(QEMU_CLOCK_VIRTUAL, via_adb_poll, m= ); + m->adb_data_ready =3D qdev_get_gpio_in_named(dev, "via1-irq", + VIA1_IRQ_ADB_READY_BIT); } =20 static void mac_via_init(Object *obj) @@ -572,6 +737,7 @@ static void mos6522_q800_via1_portB_write(MOS6522State = *s) MacVIAState *m =3D container_of(v1s, MacVIAState, mos6522_via1); =20 via1_rtc_update(m); + via1_adb_update(m); =20 v1s->last_b =3D s->b; } diff --git a/include/hw/misc/mac_via.h b/include/hw/misc/mac_via.h index a3a972ccc5..ac56df8c35 100644 --- a/include/hw/misc/mac_via.h +++ b/include/hw/misc/mac_via.h @@ -96,6 +96,13 @@ typedef struct MacVIAState { =20 /* ADB */ ADBBusState adb_bus; + QEMUTimer *adb_poll_timer; + qemu_irq adb_data_ready; + int adb_data_in_size; + int adb_data_in_index; + int adb_data_out_index; + uint8_t adb_data_in[128]; + uint8_t adb_data_out[16]; =20 /* external timers */ QEMUTimer *one_second_timer; --=20 2.11.0