From a16fb19be9eec4ff3fbf0cec9560dfb59d2b0d0a Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Mon, 21 Jan 2019 23:33:13 +1100 Subject: vsmile_ctrl: fix controller not working if buttons are pushed too early --- src/devices/bus/vsmile/pad.cpp | 222 ++++++++++++++++++++++++++------- src/devices/bus/vsmile/pad.h | 24 +++- src/devices/bus/vsmile/vsmile_ctrl.cpp | 74 ++++++++++- src/devices/bus/vsmile/vsmile_ctrl.h | 7 +- src/mame/drivers/vsmile.cpp | 2 +- 5 files changed, 273 insertions(+), 56 deletions(-) diff --git a/src/devices/bus/vsmile/pad.cpp b/src/devices/bus/vsmile/pad.cpp index b5b46abadf2..c1a0ff74eeb 100644 --- a/src/devices/bus/vsmile/pad.cpp +++ b/src/devices/bus/vsmile/pad.cpp @@ -1,29 +1,42 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Ryan Holtz, Vas Crabb #include "emu.h" #include "pad.h" +#include + +//#define VERBOSE 1 +#include "logmacro.h" + //************************************************************************** // GLOBAL VARIABLES //************************************************************************** -DEFINE_DEVICE_TYPE(VSMILE_PAD, vsmile_pad_device, "vsmile_pad", "V.Smile Control Pad") +DEFINE_DEVICE_TYPE(VSMILE_PAD, vsmile_pad_device, "vsmile_pad", "V.Smile Joystick") //************************************************************************** // V.Smile control pad //************************************************************************** +DECLARE_ENUM_BITWISE_OPERATORS(vsmile_pad_device::stale_inputs) +ALLOW_SAVE_TYPE(vsmile_pad_device::stale_inputs); + vsmile_pad_device::vsmile_pad_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock) : vsmile_ctrl_device_base(mconfig, VSMILE_PAD, tag, owner, clock) , m_io_joy(*this, "JOY") , m_io_colors(*this, "COLORS") , m_io_buttons(*this, "BUTTONS") , m_idle_timer(nullptr) - , m_ctrl_probe_count(0U) + , m_sent_joy(0x00U) + , m_sent_colors(0x00U) + , m_sent_buttons(0x00U) + , m_stale(STALE_ALL) + , m_active(false) { + std::fill(std::begin(m_ctrl_probe_history), std::end(m_ctrl_probe_history), 0U); } vsmile_pad_device::~vsmile_pad_device() @@ -36,27 +49,104 @@ void vsmile_pad_device::device_start() m_idle_timer = machine().scheduler().timer_alloc( timer_expired_delegate(FUNC(vsmile_pad_device::handle_idle), this)); - m_idle_timer->adjust(attotime::from_hz(1)); + m_idle_timer->adjust(attotime::from_seconds(1)); + m_sent_joy = 0x00U; + m_sent_colors = 0x00U; + m_sent_buttons = 0x00U; + m_stale = STALE_ALL; + m_active = false; + + save_item(NAME(m_sent_joy)); + save_item(NAME(m_sent_colors)); + save_item(NAME(m_sent_buttons)); + save_item(NAME(m_stale)); + save_item(NAME(m_active)); save_item(NAME(m_ctrl_probe_history)); - save_item(NAME(m_ctrl_probe_count)); } void vsmile_pad_device::tx_complete() { - m_idle_timer->adjust(attotime::from_hz(1)); + // update joystick + if ((m_stale & STALE_JOY) != STALE_NONE) + { + m_sent_joy = m_io_joy->read(); + if ((m_stale & STALE_UP_DOWN) != STALE_NONE) + { + if (BIT(m_sent_joy, 0)) + uart_tx_fifo_push(0x87); // up + else if (BIT(m_sent_joy, 1)) + uart_tx_fifo_push(0x8f); // down + else + uart_tx_fifo_push(0x80); + } + if ((m_stale & STALE_LEFT_RIGHT) != STALE_NONE) + { + if (BIT(m_sent_joy, 2)) + uart_tx_fifo_push(0xcf); // left + else if (BIT(m_sent_joy, 3)) + uart_tx_fifo_push(0xc7); // right + else + uart_tx_fifo_push(0xc0); + } + } + + // update colors + if ((m_stale & STALE_COLORS) != STALE_NONE) + { + m_sent_colors = m_io_colors->read(); + uart_tx_fifo_push(0x90 | m_sent_colors); + } + + // update buttons + if ((m_stale & STALE_BUTTONS) != STALE_NONE) + { + m_sent_buttons = m_io_buttons->read(); + if (((m_stale & STALE_OK) != STALE_NONE) && BIT(m_sent_buttons, 0)) + uart_tx_fifo_push(0xa1); + if (((m_stale & STALE_QUIT) != STALE_NONE) && BIT(m_sent_buttons, 1)) + uart_tx_fifo_push(0xa2); + if (((m_stale & STALE_HELP) != STALE_NONE) && BIT(m_sent_buttons, 2)) + uart_tx_fifo_push(0xa3); + if (((m_stale & STALE_ABC) != STALE_NONE) && BIT(m_sent_buttons, 3)) + uart_tx_fifo_push(0xa4); + if (!m_sent_buttons) + uart_tx_fifo_push(0xa0); + } + + // if nothing happens in the next second we'll queue a keep-alive + if (!m_active) + LOG("entered active state\n"); + m_idle_timer->adjust(attotime::from_seconds(1)); + m_active = true; + m_stale = STALE_NONE; +} + +void vsmile_pad_device::tx_timeout() +{ + if (m_active) + { + m_idle_timer->adjust(attotime::from_seconds(1)); + m_active = false; + m_stale = STALE_ALL; + LOG("left active state\n"); + } } void vsmile_pad_device::rx_complete(uint8_t data, bool select) { if (select) { - //printf("%s Receiving: %02x\n", tag(), data); - if ((data >> 4) == 7 || (data >> 4) == 11) + if (((data & 0xf0) == 0x70) || ((data & 0xf0) == 0xb0)) { m_ctrl_probe_history[0] = m_ctrl_probe_history[1]; m_ctrl_probe_history[1] = data; - const uint8_t response = ((m_ctrl_probe_history[0] + m_ctrl_probe_history[1] + 0x0f) & 0x0f) ^ 0x05; + uint8_t const response = ((m_ctrl_probe_history[0] + m_ctrl_probe_history[1] + 0x0f) & 0x0f) ^ 0x05; + LOG( + "received probe %02X, %02X, sending response %02X\n", + m_ctrl_probe_history[0], + m_ctrl_probe_history[1], + 0xb0 | response); uart_tx_fifo_push(0xb0 | response); } } @@ -70,67 +160,109 @@ void vsmile_pad_device::uart_tx_fifo_push(uint8_t data) TIMER_CALLBACK_MEMBER(vsmile_pad_device::handle_idle) { + LOG("idle timer expired, sending keep-alive 55\n"); queue_tx(0x55); } INPUT_CHANGED_MEMBER(vsmile_pad_device::pad_joy_changed) { - const uint8_t value = m_io_joy->read(); - - if (BIT(value, 2)) - uart_tx_fifo_push(0xcf); - else if (BIT(value, 3)) - uart_tx_fifo_push(0xc7); - else - uart_tx_fifo_push(0xc0); - - if (BIT(value, 0)) - uart_tx_fifo_push(0x87); - else if (BIT(value, 1)) - uart_tx_fifo_push(0x8f); - else - uart_tx_fifo_push(0x80); + if (m_active) + { + if (!is_tx_empty()) + { + LOG("joy changed while transmission in progress, marking stale\n"); + m_stale |= stale_inputs(uintptr_t(param)); + } + else + { + uint8_t const joy = m_io_joy->read(); + if ((joy ^ m_sent_joy) & 0x03) + { + if (BIT(joy, 0)) + uart_tx_fifo_push(0x87); // up + else if (BIT(joy, 1)) + uart_tx_fifo_push(0x8f); // down + else + uart_tx_fifo_push(0x80); + } + if ((joy ^ m_sent_joy) & 0x0c) + { + if (BIT(joy, 2)) + uart_tx_fifo_push(0xcf); // left + else if (BIT(joy, 3)) + uart_tx_fifo_push(0xc7); // right + else + uart_tx_fifo_push(0xc0); + } + m_sent_joy = joy; + } + } } INPUT_CHANGED_MEMBER(vsmile_pad_device::pad_color_changed) { - uart_tx_fifo_push(0x90 | m_io_colors->read()); + if (m_active) + { + if (!is_tx_empty()) + { + LOG("colors changed while transmission in progress, marking stale\n"); + m_stale |= STALE_COLORS; + } + else + { + m_sent_colors = m_io_colors->read(); + uart_tx_fifo_push(0x90 | m_io_colors->read()); + } + } } INPUT_CHANGED_MEMBER(vsmile_pad_device::pad_button_changed) { - const uint8_t value = m_io_buttons->read(); - const size_t bit = reinterpret_cast(param); - if (BIT(value, bit)) - { - uart_tx_fifo_push(0xa1 + (uint8_t)bit); - } - else + if (m_active) { - uart_tx_fifo_push(0xa0); + if (!is_tx_empty()) + { + LOG("buttons changed while transmission in progress, marking stale\n"); + m_stale |= stale_inputs(uintptr_t(param)); + } + else + { + uint8_t const buttons = m_io_buttons->read(); + if (BIT((m_sent_buttons ^ buttons) & buttons, 0)) + uart_tx_fifo_push(0xa1); + if (BIT((m_sent_buttons ^ buttons) & buttons, 1)) + uart_tx_fifo_push(0xa2); + if (BIT((m_sent_buttons ^ buttons) & buttons, 2)) + uart_tx_fifo_push(0xa3); + if (BIT((m_sent_buttons ^ buttons) & buttons, 3)) + uart_tx_fifo_push(0xa4); + if (!buttons) + uart_tx_fifo_push(0xa0); + m_sent_buttons = buttons; + } } } static INPUT_PORTS_START( vsmile_pad ) PORT_START("JOY") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, 0) PORT_NAME("Joypad Up") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, 0) PORT_NAME("Joypad Down") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, 0) PORT_NAME("Joypad Left") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, 0) PORT_NAME("Joypad Right") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, vsmile_pad_device::STALE_UP_DOWN) PORT_NAME("Joypad Up") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, vsmile_pad_device::STALE_UP_DOWN) PORT_NAME("Joypad Down") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, vsmile_pad_device::STALE_LEFT_RIGHT) PORT_NAME("Joypad Left") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_joy_changed, vsmile_pad_device::STALE_LEFT_RIGHT) PORT_NAME("Joypad Right") PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("COLORS") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, 0) PORT_NAME("Green") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, 0) PORT_NAME("Blue") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, 0) PORT_NAME("Yellow") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, 0) PORT_NAME("Red") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, vsmile_pad_device::STALE_COLORS) PORT_NAME("Green") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, vsmile_pad_device::STALE_COLORS) PORT_NAME("Blue") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, vsmile_pad_device::STALE_COLORS) PORT_NAME("Yellow") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_color_changed, vsmile_pad_device::STALE_COLORS) PORT_NAME("Red") PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("BUTTONS") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, 0) PORT_NAME("OK") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, 1) PORT_NAME("Quit") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, 2) PORT_NAME("Help") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, 3) PORT_NAME("ABC") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, vsmile_pad_device::STALE_OK) PORT_NAME("OK") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, vsmile_pad_device::STALE_QUIT) PORT_NAME("Quit") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, vsmile_pad_device::STALE_HELP) PORT_NAME("Help") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vsmile_pad_device, pad_button_changed, vsmile_pad_device::STALE_ABC) PORT_NAME("ABC") PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) INPUT_PORTS_END diff --git a/src/devices/bus/vsmile/pad.h b/src/devices/bus/vsmile/pad.h index e2773a238f0..5e2515c2b58 100644 --- a/src/devices/bus/vsmile/pad.h +++ b/src/devices/bus/vsmile/pad.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Ryan Holtz, Vas Crabb #ifndef MAME_BUS_VSMILE_PAD_H #define MAME_BUS_VSMILE_PAD_H @@ -16,10 +16,27 @@ class vsmile_pad_device : public vsmile_ctrl_device_base { public: + enum stale_inputs : uint8_t + { + STALE_NONE = 0U, + STALE_LEFT_RIGHT = 1U << 0, + STALE_UP_DOWN = 1U << 1, + STALE_COLORS = 1U << 2, + STALE_OK = 1U << 3, + STALE_QUIT = 1U << 4, + STALE_HELP = 1U << 5, + STALE_ABC = 1U << 6, + + STALE_JOY = STALE_LEFT_RIGHT | STALE_UP_DOWN, + STALE_BUTTONS = STALE_OK | STALE_QUIT | STALE_HELP | STALE_ABC, + STALE_ALL = STALE_JOY | STALE_COLORS | STALE_BUTTONS + }; + // construction/destruction vsmile_pad_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U); virtual ~vsmile_pad_device(); + // input handlers DECLARE_INPUT_CHANGED_MEMBER(pad_joy_changed); DECLARE_INPUT_CHANGED_MEMBER(pad_color_changed); DECLARE_INPUT_CHANGED_MEMBER(pad_button_changed); @@ -31,6 +48,7 @@ protected: // vsmile_ctrl_device_base implementation virtual void tx_complete() override; + virtual void tx_timeout() override; virtual void rx_complete(uint8_t data, bool cts) override; private: @@ -44,8 +62,10 @@ private: emu_timer *m_idle_timer; + uint8_t m_sent_joy, m_sent_colors, m_sent_buttons; + stale_inputs m_stale; + bool m_active; uint8_t m_ctrl_probe_history[2]; - uint8_t m_ctrl_probe_count; }; diff --git a/src/devices/bus/vsmile/vsmile_ctrl.cpp b/src/devices/bus/vsmile/vsmile_ctrl.cpp index 599700cb187..3a109484be1 100644 --- a/src/devices/bus/vsmile/vsmile_ctrl.cpp +++ b/src/devices/bus/vsmile/vsmile_ctrl.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Vas Crabb #include "emu.h" #include "vsmile_ctrl.h" @@ -7,6 +7,9 @@ #include #include +//#define VERBOSE 1 +#include "logmacro.h" + //************************************************************************** // GLOBAL VARIABLES @@ -125,6 +128,7 @@ vsmile_ctrl_device_base::vsmile_ctrl_device_base( : device_t(mconfig, type, tag, owner, clock) , device_vsmile_ctrl_interface(mconfig, *this) , m_tx_timer(nullptr) + , m_rts_timer(nullptr) , m_tx_fifo_head(0U) , m_tx_fifo_tail(0U) , m_tx_fifo_empty(true) @@ -144,6 +148,10 @@ void vsmile_ctrl_device_base::device_start() m_tx_timer = machine().scheduler().timer_alloc( timer_expired_delegate(FUNC(vsmile_ctrl_device_base::tx_timer_expired), this)); + // allocate a timer for RTS timeouts + m_rts_timer = machine().scheduler().timer_alloc( + timer_expired_delegate(FUNC(vsmile_ctrl_device_base::rts_timer_expired), this)); + // start with transmit queue empty m_tx_fifo_head = m_tx_fifo_tail = 0U; m_tx_fifo_empty = true; @@ -162,7 +170,10 @@ bool vsmile_ctrl_device_base::queue_tx(uint8_t data) // return false on overrun and drop byte bool const was_empty(m_tx_fifo_empty); if (!was_empty && (m_tx_fifo_head == m_tx_fifo_tail)) + { + LOG("discarding byte %02X because FIFO is full (length %u, Tx %sactive)\n", data, ARRAY_LENGTH(m_tx_fifo), m_tx_active ? "" : "in"); return false; + } // queue the byte m_tx_fifo[m_tx_fifo_tail] = data; @@ -175,9 +186,20 @@ bool vsmile_ctrl_device_base::queue_tx(uint8_t data) rts_out(1); if (m_select) { + LOG("transmitting byte %02X immediately (Tx was %sactive)\n", data, m_tx_active ? "" : "in"); m_tx_active = true; m_tx_timer->adjust(attotime::from_hz(9600 / 10)); } + else + { + LOG("asserting RTS to transmit byte %02X\n", data); + m_rts_timer->adjust(attotime::from_msec(500)); + } + } + else + { + unsigned const fifo_used((m_tx_fifo_tail + ARRAY_LENGTH(m_tx_fifo) - m_tx_fifo_head) % ARRAY_LENGTH(m_tx_fifo)); + LOG("queued byte %02X (%u bytes queued, Tx %sactive)\n", data, fifo_used, m_tx_active ? "" : "in"); } // data was queued @@ -186,16 +208,27 @@ bool vsmile_ctrl_device_base::queue_tx(uint8_t data) void vsmile_ctrl_device_base::select_w(int state) { - m_select = bool(state); - if (m_select && !m_tx_fifo_empty && !m_tx_active) + if (bool(state) != m_select) { - m_tx_active = true; - m_tx_timer->adjust(attotime::from_hz(9600 / 10)); + if (state && !m_tx_fifo_empty && !m_tx_active) + { + m_rts_timer->reset(); + unsigned const fifo_used((m_tx_fifo_tail + ARRAY_LENGTH(m_tx_fifo) - m_tx_fifo_head) % ARRAY_LENGTH(m_tx_fifo)); + LOG("select asserted, starting transmission (%u bytes queued)\n", fifo_used); + m_tx_active = true; + m_tx_timer->adjust(attotime::from_hz(9600 / 10)); + } + else + { + LOG("select %sasserted (Tx %sactive)\n", state ? "" : "de", m_tx_active ? "" : "in"); + } + m_select = bool(state); } } void vsmile_ctrl_device_base::data_w(uint8_t data) { + LOG("received byte %02X (select %sasserted, Tx %sactive)\n", data, m_select ? "" : "de", m_tx_active ? "" : "in"); rx_complete(data, m_select); } @@ -213,21 +246,50 @@ TIMER_CALLBACK_MEMBER(vsmile_ctrl_device_base::tx_timer_expired) // if queue is drained give implmentation a chance to queue more before dropping RTS if (m_tx_fifo_empty) + { + LOG("transmitted byte %02X, queue empty (select %sasserted)\n", data, m_select ? "" : "de"); tx_complete(); + } + else + { + unsigned const fifo_used((m_tx_fifo_tail + ARRAY_LENGTH(m_tx_fifo) - m_tx_fifo_head) % ARRAY_LENGTH(m_tx_fifo)); + LOG("transmitted byte %02X (%u bytes queued, select %sasserted)\n", data, fifo_used, m_select ? "" : "de"); + } // drop RTS if no more data, otherwise keep transmitting if CTS is still high if (m_tx_fifo_empty) { + LOG("nothing to transmit, deasserting RTS\n"); m_tx_active = false; rts_out(0); } else if (m_select) { + LOG("select asserted, transmitting next byte %02X\n", m_tx_fifo[m_tx_fifo_head]); m_tx_timer->adjust(attotime::from_hz(9600 / 10)); } else { + LOG("select deasserted, waiting to transmit\n"); m_tx_active = false; + m_rts_timer->adjust(attotime::from_msec(500)); + } +} + + +TIMER_CALLBACK_MEMBER(vsmile_ctrl_device_base::rts_timer_expired) +{ + assert(!m_tx_fifo_empty); + assert(!m_tx_active); + + // clear out anything queued and let the implementation deal with it + if (!m_tx_fifo_empty) + { + unsigned const fifo_used((m_tx_fifo_tail + ARRAY_LENGTH(m_tx_fifo) - m_tx_fifo_head) % ARRAY_LENGTH(m_tx_fifo)); + LOG("timeout waiting for select after asserting RTS (%u bytes queued)\n", fifo_used); + m_tx_fifo_head = m_tx_fifo_tail = 0U; + m_tx_fifo_empty = true; + tx_timeout(); } } @@ -236,5 +298,5 @@ TIMER_CALLBACK_MEMBER(vsmile_ctrl_device_base::tx_timer_expired) void vsmile_controllers(device_slot_interface &device) { - device.option_add("pad", VSMILE_PAD); + device.option_add("joy", VSMILE_PAD); } diff --git a/src/devices/bus/vsmile/vsmile_ctrl.h b/src/devices/bus/vsmile/vsmile_ctrl.h index 715886fd37f..66921ce817a 100644 --- a/src/devices/bus/vsmile/vsmile_ctrl.h +++ b/src/devices/bus/vsmile/vsmile_ctrl.h @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Ryan Holtz +// copyright-holders:Vas Crabb #ifndef MAME_BUS_VSMILE_VSMILE_CTRL_H #define MAME_BUS_VSMILE_VSMILE_CTRL_H @@ -103,6 +103,7 @@ protected: virtual void device_start() override; // UART simulation helpers + bool is_tx_empty() const { return m_tx_fifo_empty; } bool queue_tx(uint8_t data); private: @@ -112,12 +113,14 @@ private: // UART simulation handlers virtual void tx_complete() = 0; + virtual void tx_timeout() = 0; virtual void rx_complete(uint8_t data, bool select) = 0; // internal helpers TIMER_CALLBACK_MEMBER(tx_timer_expired); + TIMER_CALLBACK_MEMBER(rts_timer_expired); - emu_timer *m_tx_timer; + emu_timer *m_tx_timer, *m_rts_timer; uint8_t m_tx_fifo[32]; uint8_t m_tx_fifo_head, m_tx_fifo_tail; diff --git a/src/mame/drivers/vsmile.cpp b/src/mame/drivers/vsmile.cpp index 10e06a8e26c..7342e23b8cd 100644 --- a/src/mame/drivers/vsmile.cpp +++ b/src/mame/drivers/vsmile.cpp @@ -435,7 +435,7 @@ void vsmile_state::vsmile(machine_config &config) m_spg->portc_out().set(FUNC(vsmile_state::portc_w)); m_spg->uart_tx().set(FUNC(vsmile_state::uart_rx)); - VSMILE_CTRL_PORT(config, m_ctrl[0], vsmile_controllers, "pad"); + VSMILE_CTRL_PORT(config, m_ctrl[0], vsmile_controllers, "joy"); m_ctrl[0]->rts_cb().set(FUNC(vsmile_state::ctrl_rts_w<0>)); m_ctrl[0]->data_cb().set(FUNC(vsmile_state::ctrl_tx_w)); -- cgit v1.2.3