summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2018-09-19 20:00:56 +1000
committer Vas Crabb <vas@vastheman.com>2018-09-19 20:00:56 +1000
commitb5758f5273e030845f94678ae8a4302c5d3343c2 (patch)
tree7492b13381400e7925e6271e5d60b97aa078dc56
parent56fb60aa22dce853baa661fbce2a4187e9da0459 (diff)
Re-write serial mouse support:
* Separate Microsoft 2-button mouse and Logitech 3-button Microsoft-compatible mouse * Add Microsoft wheel mouse * Make Mouse Systems mouse behave more realistically * Add Mouse Systems "rotatable" mouse * Simplify code and eliminate timers (nw) X/Y translation and buttons works for all devices. The wheel on the wheel mouse seems to be transmitting the right data, and CuteMouse detects the wheel as being present, but no software seems to support it properly. Software supporting the Mouse Systems "rotatable" mouse is very rare - typically people just set the DIP switches on their M-1 for "non-rotatable" mode. A standard mouse driver will see the "rotatable" mouse moving two mickeys for each count, and move eratically on rotation. The "rotable" mouse is poorly tested due to lack of software. (nw) MAME doesn't have a proper input type for a mouse wheel, and it doesn't seem to be possible to map the host mouse wheel to an axis when configuring inputs. The default mapping ends up assigining the wheel or rotation to one of the translation axes, which is very unhelpful.
-rw-r--r--scripts/src/bus.lua4
-rw-r--r--src/devices/bus/isa/com.cpp18
-rw-r--r--src/devices/bus/rs232/hlemouse.cpp691
-rw-r--r--src/devices/bus/rs232/hlemouse.h221
-rw-r--r--src/devices/bus/rs232/ser_mouse.cpp267
-rw-r--r--src/devices/bus/rs232/ser_mouse.h84
-rw-r--r--src/devices/bus/sunmouse/hlemouse.cpp4
-rw-r--r--src/emu/diserial.h24
-rw-r--r--src/mame/drivers/ibmpcjr.cpp9
-rw-r--r--src/mame/drivers/pcat_dyn.cpp4
-rw-r--r--src/mame/drivers/pcipc.cpp15
-rw-r--r--src/mame/drivers/pcw16.cpp4
-rw-r--r--src/mame/drivers/rainbow.cpp9
13 files changed, 967 insertions, 387 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index c006658333b..0abd88b3765 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2028,8 +2028,8 @@ if (BUSES["RS232"]~=null) then
MAME_DIR .. "src/devices/bus/rs232/rs232.h",
MAME_DIR .. "src/devices/bus/rs232/pty.cpp",
MAME_DIR .. "src/devices/bus/rs232/pty.h",
- MAME_DIR .. "src/devices/bus/rs232/ser_mouse.cpp",
- MAME_DIR .. "src/devices/bus/rs232/ser_mouse.h",
+ MAME_DIR .. "src/devices/bus/rs232/hlemouse.cpp",
+ MAME_DIR .. "src/devices/bus/rs232/hlemouse.h",
MAME_DIR .. "src/devices/bus/rs232/sun_kbd.cpp",
MAME_DIR .. "src/devices/bus/rs232/sun_kbd.h",
MAME_DIR .. "src/devices/bus/rs232/terminal.cpp",
diff --git a/src/devices/bus/isa/com.cpp b/src/devices/bus/isa/com.cpp
index 57393a52500..bd2b500d611 100644
--- a/src/devices/bus/isa/com.cpp
+++ b/src/devices/bus/isa/com.cpp
@@ -8,18 +8,24 @@
#include "emu.h"
#include "com.h"
+
+#include "bus/rs232/hlemouse.h"
+#include "bus/rs232/null_modem.h"
#include "bus/rs232/rs232.h"
-#include "bus/rs232/ser_mouse.h"
+#include "bus/rs232/sun_kbd.h"
#include "bus/rs232/terminal.h"
-#include "bus/rs232/null_modem.h"
#include "machine/ins8250.h"
static void isa_com(device_slot_interface &device)
{
- device.option_add("microsoft_mouse", MSFT_SERIAL_MOUSE);
- device.option_add("msystems_mouse", MSYSTEM_SERIAL_MOUSE);
+ device.option_add("microsoft_mouse", MSFT_HLE_SERIAL_MOUSE);
+ device.option_add("logitech_mouse", LOGITECH_HLE_SERIAL_MOUSE);
+ device.option_add("wheel_mouse", WHEEL_HLE_SERIAL_MOUSE);
+ device.option_add("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE);
+ device.option_add("rotatable_mouse", ROTATABLE_HLE_SERIAL_MOUSE);
device.option_add("terminal", SERIAL_TERMINAL);
device.option_add("null_modem", NULL_MODEM);
+ device.option_add("sun_kbd", SUN_KBD_ADAPTOR);
}
@@ -55,7 +61,7 @@ MACHINE_CONFIG_START(isa8_com_device::device_add_mconfig)
uart3.out_rts_callback().set("serport3", FUNC(rs232_port_device::write_rts));
uart3.out_int_callback().set(FUNC(isa8_com_device::pc_com_interrupt_2));*/
- MCFG_DEVICE_ADD( "serport0", RS232_PORT, isa_com, "microsoft_mouse" )
+ MCFG_DEVICE_ADD( "serport0", RS232_PORT, isa_com, "logitech_mouse" )
MCFG_RS232_RXD_HANDLER(WRITELINE(uart0, ins8250_uart_device, rx_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(uart0, ins8250_uart_device, dcd_w))
MCFG_RS232_DSR_HANDLER(WRITELINE(uart0, ins8250_uart_device, dsr_w))
@@ -156,7 +162,7 @@ MACHINE_CONFIG_START(isa8_com_at_device::device_add_mconfig)
uart3.out_dtr_callback().set("serport3", FUNC(rs232_port_device::write_dtr));
uart3.out_rts_callback().set("serport3", FUNC(rs232_port_device::write_rts));
uart3.out_int_callback().set(FUNC(isa8_com_device::pc_com_interrupt_2));*/
- MCFG_DEVICE_ADD( "serport0", RS232_PORT, isa_com, "microsoft_mouse" )
+ MCFG_DEVICE_ADD( "serport0", RS232_PORT, isa_com, "logitech_mouse" )
MCFG_RS232_RXD_HANDLER(WRITELINE(uart0, ins8250_uart_device, rx_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(uart0, ins8250_uart_device, dcd_w))
MCFG_RS232_DSR_HANDLER(WRITELINE(uart0, ins8250_uart_device, dsr_w))
diff --git a/src/devices/bus/rs232/hlemouse.cpp b/src/devices/bus/rs232/hlemouse.cpp
new file mode 100644
index 00000000000..caf9ebcdb57
--- /dev/null
+++ b/src/devices/bus/rs232/hlemouse.cpp
@@ -0,0 +1,691 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/**************************************************************************
+
+ PC Serial Mouse Simulation
+
+ Microsoft mouse is the classic two-button PC mouse. Data is 7N1 at
+ 1,200 Baud. Mouse can be reset by de-asserting RTS. On start, the
+ mouse identifies itself with the string "M". Bit 6 is only set for
+ the first byte of a report - it's clear for all subsequent bytes of
+ a report, and also for all identification bytes.
+
+ Reports consist of three bytes: the first byte contains the button
+ state and the two high bits of the Y and X delta; the second byte
+ contains the low six bits of the X delta; the third byte contains
+ the low six bits of the Y delta. Button bits are set when pressed,
+ and positive delta is rightwards/downwards.
+
+ 1lryyxx 0xxxxxx 0yyyyyy
+
+ Logitech extended the Microsoft protocol to support a third button.
+ The mouse identifies itself with the string "M3". If the third
+ button changes state, and additional byte is sent indicating the
+ new state of the third button.
+
+ 1lryyxx 0xxxxxx 0yyyyyy 0m00000
+
+ The serial wheel mouse protocol extends the Microsoft mouse protocol
+ in a different way. The mouse identifies itself with the string
+ "MZ@\0\0\0". If the third button or wheel state changes, a fourth
+ an additional byte is sent containing the third button state and a
+ four-bit wheel delta value. The wheel value is positive for
+ downward movement. Note that the third button is value is in a
+ different position to the logitech protocol.
+
+ 1lryyxx 0xxxxxx 0yyyyyy 00mwwww
+
+ The Mouse Systems non-rotatable protocol provides two-axis movement
+ and three buttons. Data is 8N1 at 1,200 Baud (the M-1 mouse could
+ also be configured for 300 Baud by turning DIP switch 1 off). The
+ mouse does not send an identification string. The first byte of a
+ report can be identified by a fixed pattern in the five most
+ significant bits.
+
+ Reports are five bytes long. The first byte contains the the button
+ state; the second and fourth bytes contain X delta; the third and
+ fifth bytes contain Y delta. The two delta values for each axis
+ should be summed. Delta values range from -120 to 127 to prevent
+ being mistaken for the lead byte of a report. Button bits are clear
+ when set, and positive delta is rightwards/upwards. Delta values
+ are generated immediately before transmission - reports are not
+ atomic.
+
+ 10000lmr xxxxxxxx yyyyyyyy xxxxxxxx yyyyyyyy
+
+ The Mouse systems rotatable protcol allows the host to infer
+ rotation around the third axis at the cost of halving the maximum
+ sustained movement speed. The M-1 mouse has two sensors spaced 100
+ counts apart horizontally. If DIP switch 2 is on, the X and Y delta
+ for each sensor is reported separately. The right sensor delta is
+ reported before the left sensor delta. If the mouse is rotated, the
+ delta values for the two sensors will differ.
+
+**************************************************************************/
+
+#include "emu.h"
+#include "hlemouse.h"
+
+#include <cassert>
+#include <cmath>
+
+
+//**************************************************
+// Device type globals
+//**************************************************
+
+DEFINE_DEVICE_TYPE_NS(MSFT_HLE_SERIAL_MOUSE, bus::rs232, hle_msft_mouse_device, "rs232_mouse_hle_msft", "Microsoft 2-Button Serial Mouse (HLE)")
+DEFINE_DEVICE_TYPE_NS(LOGITECH_HLE_SERIAL_MOUSE, bus::rs232, hle_logitech_mouse_device, "rs232_mouse_hle_logitech", "Logitech 3-Button Serial Mouse (HLE)")
+DEFINE_DEVICE_TYPE_NS(WHEEL_HLE_SERIAL_MOUSE, bus::rs232, hle_wheel_mouse_device, "rs232_mouse_hle_wheel", "Microsoft Serial Mouse with Wheel (HLE)")
+DEFINE_DEVICE_TYPE_NS(MSYSTEMS_HLE_SERIAL_MOUSE, bus::rs232, hle_msystems_mouse_device, "rs232_mouse_hle_msystems", "Mouse Systems Non-rotatable Mouse (HLE)")
+DEFINE_DEVICE_TYPE_NS(ROTATABLE_HLE_SERIAL_MOUSE, bus::rs232, hle_rotatable_mouse_device, "rs232_mouse_hle_rotatable", "Mouse Systems Rotatable Mouse (HLE)")
+
+namespace bus { namespace rs232 {
+
+namespace {
+
+INPUT_PORTS_START(msft)
+ PORT_START("BTN")
+ PORT_BIT( 0xfffc, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CODE(MOUSECODE_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+
+ PORT_START("X")
+ PORT_BIT( 0xf000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0fff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+
+ PORT_START("Y")
+ PORT_BIT( 0xf000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0fff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+INPUT_PORTS_END
+
+
+INPUT_PORTS_START(logitech)
+ PORT_INCLUDE(msft)
+
+ PORT_MODIFY("BTN")
+ PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CODE(MOUSECODE_BUTTON2) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+ PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CODE(MOUSECODE_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+INPUT_PORTS_END
+
+
+INPUT_PORTS_START(wheel)
+ PORT_INCLUDE(logitech)
+
+ PORT_START("WHEEL")
+ PORT_BIT( 0xf000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0fff, 0x00, IPT_DIAL_V ) PORT_SENSITIVITY(10) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msmouse_device_base, input_changed, nullptr)
+INPUT_PORTS_END
+
+
+INPUT_PORTS_START(msystems)
+ PORT_START("BTN")
+ PORT_BIT( 0xfff8, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msystems_device_base, input_changed, nullptr)
+ PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_CODE(MOUSECODE_BUTTON2) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msystems_device_base, input_changed, nullptr)
+ PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_CODE(MOUSECODE_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msystems_device_base, input_changed, nullptr)
+
+ PORT_START("X")
+ PORT_BIT( 0xf000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0fff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msystems_device_base, input_changed, nullptr)
+
+ PORT_START("Y")
+ PORT_BIT( 0xf000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0fff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msystems_device_base, input_changed, nullptr)
+INPUT_PORTS_END
+
+
+INPUT_PORTS_START(rotatable)
+ PORT_INCLUDE(msystems)
+
+ PORT_START("ROT")
+ PORT_BIT( 0xf000, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x0fff, 0x00, IPT_DIAL ) PORT_SENSITIVITY(10) PORT_CHANGED_MEMBER(DEVICE_SELF, hle_msystems_device_base, input_changed, nullptr)
+INPUT_PORTS_END
+
+
+template <unsigned Bits, typename T>
+std::make_signed_t<T> read_axis(ioport_port &port, T &val)
+{
+ static_assert((1U < Bits) && ((sizeof(T) * 8) > Bits), "invalid field bits");
+
+ T const updated(T(std::make_unsigned_t<T>(port.read())) & make_bitmask<T>(Bits));
+ std::make_signed_t<T> delta(std::make_signed_t<T>(updated) - std::make_signed_t<T>(val));
+ if (std::make_signed_t<T>(std::make_unsigned_t<T>(1) << (Bits - 1)) <= delta)
+ delta -= std::make_signed_t<T>(std::make_unsigned_t<T>(1) << Bits);
+ else if (-std::make_signed_t<T>(std::make_unsigned_t<T>(1) << (Bits - 1)) >= delta)
+ delta += std::make_signed_t<T>(std::make_unsigned_t<T>(1) << Bits);
+ val = updated;
+ return delta;
+}
+
+
+template <typename T>
+uint8_t report_axis(T &delta, T low, T high)
+{
+ T const result(std::min<T>(std::max<T>(delta, low), high));
+ delta -= result;
+ return uint8_t(int8_t(result));
+}
+
+} // anonymous namespace
+
+
+//**************************************************
+// Microsoft mouse base
+//**************************************************
+
+INPUT_CHANGED_MEMBER(hle_msmouse_device_base::input_changed)
+{
+ if (fifo_empty() && is_transmit_register_empty())
+ check_inputs();
+}
+
+hle_msmouse_device_base::hle_msmouse_device_base(
+ machine_config const &mconfig,
+ device_type type,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock)
+ : buffered_rs232_device<8>(mconfig, type, tag, owner, clock)
+ , m_buttons(*this, "BTN")
+ , m_x_axis(*this, "X")
+ , m_y_axis(*this, "Y")
+ , m_x_delta(0)
+ , m_y_delta(0)
+ , m_x_val(0U)
+ , m_y_val(0U)
+ , m_btn_val(0x00U)
+ , m_btn_sent(0x00U)
+ , m_dtr(0U)
+ , m_rts(0U)
+ , m_enable(0U)
+{
+}
+
+void hle_msmouse_device_base::device_resolve_objects()
+{
+ buffered_rs232_device<8>::device_resolve_objects();
+
+ m_dtr = 0U;
+ m_rts = 0U;
+}
+
+void hle_msmouse_device_base::device_start()
+{
+ buffered_rs232_device<8>::device_start();
+
+ save_item(NAME(m_x_delta));
+ save_item(NAME(m_y_delta));
+ save_item(NAME(m_x_val));
+ save_item(NAME(m_y_val));
+ save_item(NAME(m_btn_val));
+ save_item(NAME(m_btn_sent));
+ save_item(NAME(m_dtr));
+ save_item(NAME(m_rts));
+ save_item(NAME(m_enable));
+
+ set_data_frame(1, 7, PARITY_NONE, STOP_BITS_2);
+ set_rate(1'200);
+ receive_register_reset();
+ transmit_register_reset();
+
+ m_x_delta = m_y_delta = 0;
+ m_x_val = m_y_val = 0U;
+ m_btn_val = m_btn_sent = 0x00U;
+ m_enable = 0U;
+
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(hle_msmouse_device_base::start_mouse), this));
+}
+
+WRITE_LINE_MEMBER(hle_msmouse_device_base::input_dtr)
+{
+ m_dtr = state ? 1U : 0U;
+ check_enable();
+}
+
+WRITE_LINE_MEMBER(hle_msmouse_device_base::input_rts)
+{
+ m_dtr = state ? 1U : 0U;
+ check_enable();
+}
+
+void hle_msmouse_device_base::tra_complete()
+{
+ buffered_rs232_device<8>::tra_complete();
+ if (fifo_empty() && is_transmit_register_empty())
+ check_inputs();
+}
+
+void hle_msmouse_device_base::received_byte(u8 byte)
+{
+}
+
+
+TIMER_CALLBACK_MEMBER(hle_msmouse_device_base::start_mouse)
+{
+ check_enable();
+}
+
+void hle_msmouse_device_base::check_enable()
+{
+ bool const enable(!m_dtr && !m_rts);
+ if (bool(m_enable) != enable)
+ {
+ m_enable = enable ? 1U : 0U;
+ clear_fifo();
+ receive_register_reset();
+ transmit_register_reset();
+ if (enable)
+ {
+ read_inputs();
+ m_x_delta = m_y_delta = 0;
+ m_btn_sent = m_btn_val;
+ reset_and_identify();
+ }
+ }
+}
+
+void hle_msmouse_device_base::check_inputs()
+{
+ if (m_enable && read_inputs())
+ {
+ uint8_t const x(report_axis<int16_t>(m_x_delta, -128, 127));
+ uint8_t const y(report_axis<int16_t>(m_y_delta, -128, 127));
+ transmit_byte(0x40U | ((m_btn_val << 4) & 0x30U) | ((y >> 4) & 0x0cU) | ((x >> 6) & 0x03U));
+ transmit_byte(x & 0x3fU);
+ transmit_byte(y & 0x3fU);
+ transmit_extensions(m_btn_val, m_btn_sent);
+ m_btn_sent = m_btn_val;
+ }
+}
+
+bool hle_msmouse_device_base::read_inputs()
+{
+ m_x_delta += read_axis<12>(*m_x_axis, m_x_val);
+ m_y_delta += read_axis<12>(*m_y_axis, m_y_val);
+ m_btn_val = m_buttons->read();
+ return m_x_delta || m_y_delta || (m_btn_val != m_btn_sent);
+}
+
+
+//**************************************************
+// Microsoft 2-button mouse
+//**************************************************
+
+hle_msft_mouse_device::hle_msft_mouse_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock)
+ : hle_msmouse_device_base(mconfig, MSFT_HLE_SERIAL_MOUSE, tag, owner, clock)
+{
+}
+
+ioport_constructor hle_msft_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msft);
+}
+
+void hle_msft_mouse_device::reset_and_identify()
+{
+ // assume ASCII host system
+ transmit_byte('M');
+}
+
+void hle_msft_mouse_device::transmit_extensions(uint8_t btn_val, uint8_t btn_sent)
+{
+}
+
+
+//**************************************************
+// Logitech 3-button mouse
+//**************************************************
+
+hle_logitech_mouse_device::hle_logitech_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
+ : hle_msmouse_device_base(mconfig, LOGITECH_HLE_SERIAL_MOUSE, tag, owner, clock)
+{
+}
+
+ioport_constructor hle_logitech_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(logitech);
+}
+
+void hle_logitech_mouse_device::reset_and_identify()
+{
+ // assume ASCII host system
+ transmit_byte('M');
+ transmit_byte('3');
+}
+
+void hle_logitech_mouse_device::transmit_extensions(uint8_t btn_val, uint8_t btn_sent)
+{
+ if (BIT(btn_val | btn_sent, 2))
+ transmit_byte(BIT(btn_val, 2) << 5);
+}
+
+
+
+//**************************************************
+// Microsoft wheel mouse
+//**************************************************
+
+hle_wheel_mouse_device::hle_wheel_mouse_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock)
+ : hle_msmouse_device_base(mconfig, WHEEL_HLE_SERIAL_MOUSE, tag, owner, clock)
+ , m_wheel(*this, "WHEEL")
+ , m_wheel_delta(0)
+ , m_wheel_val(0U)
+{
+}
+
+ioport_constructor hle_wheel_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(wheel);
+}
+
+void hle_wheel_mouse_device::device_start()
+{
+ hle_msmouse_device_base::device_start();
+
+ save_item(NAME(m_wheel_delta));
+ save_item(NAME(m_wheel_val));
+
+ m_wheel_delta = 0;
+ m_wheel_val = 0U;
+}
+
+bool hle_wheel_mouse_device::read_inputs()
+{
+ m_wheel_delta += read_axis<12>(*m_wheel, m_wheel_val);
+ return hle_msmouse_device_base::read_inputs() || m_wheel_delta;
+}
+
+void hle_wheel_mouse_device::reset_and_identify()
+{
+ m_wheel_delta = 0;
+
+ // assume ASCII host system
+ transmit_byte('M');
+ transmit_byte('Z');
+ transmit_byte('@');
+ transmit_byte('\0');
+ transmit_byte('\0');
+ transmit_byte('\0');
+}
+
+void hle_wheel_mouse_device::transmit_extensions(uint8_t btn_val, uint8_t btn_sent)
+{
+ if (BIT(btn_val | btn_sent, 2) || m_wheel_delta)
+ transmit_byte((BIT(btn_val, 2) << 4) | (report_axis<int16_t>(m_wheel_delta, -8, 7) & 0x0fU));
+}
+
+
+//**************************************************
+// Mouse Systems mouse base
+//**************************************************
+
+INPUT_CHANGED_MEMBER(hle_msystems_device_base::input_changed)
+{
+ if (is_transmit_register_empty())
+ {
+ assert(0U == m_phase);
+ tra_complete();
+ }
+}
+
+hle_msystems_device_base::hle_msystems_device_base(
+ machine_config const &mconfig,
+ device_type type,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_rs232_port_interface(mconfig, *this)
+ , device_serial_interface(mconfig, *this)
+ , m_phase(0U)
+{
+}
+
+void hle_msystems_device_base::device_start()
+{
+ save_item(NAME(m_phase));
+
+ set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1);
+ set_rate(1'200);
+ receive_register_reset();
+ transmit_register_reset();
+
+ m_phase = 0U;
+
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(hle_msystems_device_base::start_mouse), this));
+}
+
+void hle_msystems_device_base::tra_callback()
+{
+ output_rxd(transmit_register_get_data_bit());
+}
+
+void hle_msystems_device_base::tra_complete()
+{
+ if (4U <= m_phase)
+ m_phase = 0U;
+ else
+ ++m_phase;
+
+ bool const dirty(read_inputs());
+ switch (m_phase)
+ {
+ case 0U:
+ if (dirty)
+ transmit_register_setup((report_buttons() & 0x07U) | 0x80U);
+ break;
+ case 1U:
+ transmit_register_setup(report_x1_delta());
+ break;
+ case 2U:
+ transmit_register_setup(report_y1_delta());
+ break;
+ case 3U:
+ transmit_register_setup(report_x2_delta());
+ break;
+ case 4U:
+ transmit_register_setup(report_y2_delta());
+ break;
+ };
+}
+
+TIMER_CALLBACK_MEMBER(hle_msystems_device_base::start_mouse)
+{
+ if (is_transmit_register_empty())
+ {
+ assert(0U == m_phase);
+ tra_complete();
+ }
+}
+
+
+//**************************************************
+// Mouse Systems non-rotatable mouse
+//**************************************************
+
+hle_msystems_mouse_device::hle_msystems_mouse_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock)
+ : hle_msystems_device_base(mconfig, MSYSTEMS_HLE_SERIAL_MOUSE, tag, owner, clock)
+ , m_buttons(*this, "BTN")
+ , m_x_axis(*this, "X")
+ , m_y_axis(*this, "Y")
+ , m_x_delta(0)
+ , m_y_delta(0)
+ , m_x_val(0U)
+ , m_y_val(0U)
+ , m_btn_val(0x00U)
+ , m_btn_sent(0x00U)
+{
+}
+
+ioport_constructor hle_msystems_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(msystems);
+}
+
+void hle_msystems_mouse_device::device_start()
+{
+ hle_msystems_device_base::device_start();
+
+ save_item(NAME(m_x_delta));
+ save_item(NAME(m_y_delta));
+ save_item(NAME(m_x_val));
+ save_item(NAME(m_y_val));
+ save_item(NAME(m_btn_val));
+ save_item(NAME(m_btn_sent));
+
+ m_x_delta = m_y_delta = 0;
+ m_x_val = m_y_val = 0U;
+ m_btn_val = m_btn_sent = 0x00U;
+}
+
+bool hle_msystems_mouse_device::read_inputs()
+{
+ m_x_delta += read_axis<12>(*m_x_axis, m_x_val);
+ m_y_delta -= read_axis<12>(*m_y_axis, m_y_val);
+ m_btn_val = m_buttons->read();
+ return m_x_delta || m_y_delta || (m_btn_val != m_btn_sent);
+}
+
+uint8_t hle_msystems_mouse_device::report_buttons()
+{
+ m_btn_sent = m_btn_val;
+ return m_btn_sent;
+}
+
+uint8_t hle_msystems_mouse_device::report_x1_delta()
+{
+ return report_axis<int16_t>(m_x_delta, -120, 127);
+}
+
+uint8_t hle_msystems_mouse_device::report_y1_delta()
+{
+ return report_axis<int16_t>(m_y_delta, -120, 127);
+}
+
+uint8_t hle_msystems_mouse_device::report_x2_delta()
+{
+ return report_axis<int16_t>(m_x_delta, -120, 127);
+}
+
+uint8_t hle_msystems_mouse_device::report_y2_delta()
+{
+ return report_axis<int16_t>(m_y_delta, -120, 127);
+}
+
+
+//**************************************************
+// Mouse Systems rotatable mouse
+//**************************************************
+
+hle_rotatable_mouse_device::hle_rotatable_mouse_device(
+ machine_config const &mconfig,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock)
+ : hle_msystems_device_base(mconfig, ROTATABLE_HLE_SERIAL_MOUSE, tag, owner, clock)
+ , m_buttons(*this, "BTN")
+ , m_x_axis(*this, "X")
+ , m_y_axis(*this, "Y")
+ , m_rotation(*this, "ROT")
+ , m_x_delta{ 0, 0 }
+ , m_y_delta{ 0, 0 }
+ , m_x_val(0U)
+ , m_y_val(0U)
+ , m_rot_val(0U)
+ , m_btn_val(0x00U)
+ , m_btn_sent(0x00U)
+{
+}
+
+ioport_constructor hle_rotatable_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(rotatable);
+}
+
+void hle_rotatable_mouse_device::device_start()
+{
+ hle_msystems_device_base::device_start();
+
+ save_item(NAME(m_x_delta));
+ save_item(NAME(m_y_delta));
+ save_item(NAME(m_x_val));
+ save_item(NAME(m_y_val));
+ save_item(NAME(m_rot_val));
+ save_item(NAME(m_btn_val));
+ save_item(NAME(m_btn_sent));
+
+ m_x_delta[0] = m_x_delta[1] = m_y_delta[0] = m_y_delta[1] = 0;
+ m_x_val = m_y_val = m_rot_val = 0U;
+ m_btn_val = m_btn_sent = 0x00U;
+}
+
+bool hle_rotatable_mouse_device::read_inputs()
+{
+ // translation is straighforward
+ int16_t const x_delta(read_axis<12>(*m_x_axis, m_x_val));
+ int16_t const y_delta(read_axis<12>(*m_y_axis, m_y_val));
+ m_x_delta[0] += x_delta;
+ m_x_delta[1] += x_delta;
+ m_y_delta[0] -= y_delta;
+ m_y_delta[1] -= y_delta;
+
+ // there are two sensors 100 counts apart, one inch below the centre of the mouse
+ // for simplicity, assume the mouse is rotated around the point midway the sensors
+ int16_t const rot_delta(read_axis<12>(*m_rotation, m_rot_val));
+ if (rot_delta)
+ {
+ double const rot_angle(-0.15 * rot_delta);
+ long const x_diff(std::lround((1 - std::cos(rot_angle)) * 100));
+ long const y_diff(std::lround(std::sin(rot_angle) * 100));
+ m_x_delta[0] -= x_diff / 2;
+ m_x_delta[1] += x_diff - (x_diff / 2);
+ m_y_delta[0] += y_diff / 2;
+ m_y_delta[1] -= y_diff - (y_diff / 2);
+ }
+
+ // this is straightforward, too
+ m_btn_val = m_buttons->read();
+ return m_x_delta[0] || m_x_delta[1] || m_y_delta[0] || m_y_delta[1] || (m_btn_val != m_btn_sent);
+}
+
+uint8_t hle_rotatable_mouse_device::report_buttons()
+{
+ m_btn_sent = m_btn_val;
+ return m_btn_sent;
+}
+
+uint8_t hle_rotatable_mouse_device::report_x1_delta()
+{
+ return report_axis<int16_t>(m_x_delta[0], -120, 127);
+}
+
+uint8_t hle_rotatable_mouse_device::report_y1_delta()
+{
+ return report_axis<int16_t>(m_y_delta[0], -120, 127);
+}
+
+uint8_t hle_rotatable_mouse_device::report_x2_delta()
+{
+ return report_axis<int16_t>(m_x_delta[1], -120, 127);
+}
+
+uint8_t hle_rotatable_mouse_device::report_y2_delta()
+{
+ return report_axis<int16_t>(m_y_delta[1], -120, 127);
+}
+
+} } // namespace bus::rs232
diff --git a/src/devices/bus/rs232/hlemouse.h b/src/devices/bus/rs232/hlemouse.h
new file mode 100644
index 00000000000..be3142ad118
--- /dev/null
+++ b/src/devices/bus/rs232/hlemouse.h
@@ -0,0 +1,221 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/**************************************************************************
+
+ PC Serial Mouse Simulation
+
+**************************************************************************/
+#ifndef MAME_BUS_RS232_HLEMOUSE_H
+#define MAME_BUS_RS232_HLEMOUSE_H
+
+#pragma once
+
+#include "rs232.h"
+#include "diserial.h"
+
+#include <type_traits>
+
+
+namespace bus { namespace rs232 {
+
+//**************************************************
+// Microsoft mouse base
+//**************************************************
+
+class hle_msmouse_device_base : public buffered_rs232_device<8>
+{
+public:
+ DECLARE_INPUT_CHANGED_MEMBER(input_changed);
+
+protected:
+ hle_msmouse_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_resolve_objects() override;
+ virtual void device_start() override;
+
+ virtual DECLARE_WRITE_LINE_MEMBER(input_dtr) override;
+ virtual DECLARE_WRITE_LINE_MEMBER(input_rts) override;
+
+ virtual void tra_complete() override;
+
+ virtual void received_byte(u8 byte) override;
+
+ virtual bool read_inputs();
+
+private:
+ TIMER_CALLBACK_MEMBER(start_mouse);
+ void check_enable();
+ void check_inputs();
+
+ virtual void reset_and_identify() = 0;
+ virtual void transmit_extensions(uint8_t btn_val, uint8_t btn_sent) = 0;
+
+ required_ioport m_buttons, m_x_axis, m_y_axis;
+ int16_t m_x_delta, m_y_delta;
+ uint16_t m_x_val, m_y_val;
+ uint8_t m_btn_val, m_btn_sent;
+ uint8_t m_dtr, m_rts, m_enable;
+};
+
+
+//**************************************************
+// Microsoft 2-button mouse
+//**************************************************
+
+class hle_msft_mouse_device : public hle_msmouse_device_base
+{
+public:
+ hle_msft_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ virtual void reset_and_identify() override;
+ virtual void transmit_extensions(uint8_t btn_val, uint8_t btn_sent) override;
+};
+
+
+//**************************************************
+// Logitech 3-button mouse
+//**************************************************
+
+class hle_logitech_mouse_device : public hle_msmouse_device_base
+{
+public:
+ hle_logitech_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual ioport_constructor device_input_ports() const override;
+
+private:
+ virtual void reset_and_identify() override;
+ virtual void transmit_extensions(uint8_t btn_val, uint8_t btn_sent) override;
+};
+
+
+//**************************************************
+// Microsoft wheel mouse
+//**************************************************
+
+class hle_wheel_mouse_device : public hle_msmouse_device_base
+{
+public:
+ hle_wheel_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_start() override;
+
+ virtual bool read_inputs() override;
+
+private:
+ virtual void reset_and_identify() override;
+ virtual void transmit_extensions(uint8_t btn_val, uint8_t btn_sent) override;
+
+ required_ioport m_wheel;
+ int16_t m_wheel_delta;
+ uint16_t m_wheel_val;
+};
+
+
+//**************************************************
+// Mouse Systems mouse base
+//**************************************************
+
+class hle_msystems_device_base : public device_t, public device_rs232_port_interface, public device_serial_interface
+{
+public:
+ DECLARE_INPUT_CHANGED_MEMBER(input_changed);
+
+protected:
+ hle_msystems_device_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock);
+
+ virtual void device_start() override;
+
+ virtual void tra_callback() override;
+ virtual void tra_complete() override;
+
+private:
+ TIMER_CALLBACK_MEMBER(start_mouse);
+
+ virtual bool read_inputs() = 0;
+ virtual uint8_t report_buttons() = 0;
+ virtual uint8_t report_x1_delta() = 0;
+ virtual uint8_t report_y1_delta() = 0;
+ virtual uint8_t report_x2_delta() = 0;
+ virtual uint8_t report_y2_delta() = 0;
+
+ uint8_t m_phase;
+};
+
+
+//**************************************************
+// Mouse Systems non-rotatable mouse
+//**************************************************
+
+class hle_msystems_mouse_device : public hle_msystems_device_base
+{
+public:
+ hle_msystems_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_start() override;
+
+private:
+ virtual bool read_inputs() override;
+ virtual uint8_t report_buttons() override;
+ virtual uint8_t report_x1_delta() override;
+ virtual uint8_t report_y1_delta() override;
+ virtual uint8_t report_x2_delta() override;
+ virtual uint8_t report_y2_delta() override;
+
+ required_ioport m_buttons, m_x_axis, m_y_axis;
+ int16_t m_x_delta, m_y_delta;
+ uint16_t m_x_val, m_y_val;
+ uint8_t m_btn_val, m_btn_sent;
+};
+
+
+//**************************************************
+// Mouse Systems rotatable mouse
+//**************************************************
+
+class hle_rotatable_mouse_device : public hle_msystems_device_base
+{
+public:
+ hle_rotatable_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ virtual ioport_constructor device_input_ports() const override;
+ virtual void device_start() override;
+
+private:
+ virtual bool read_inputs() override;
+ virtual uint8_t report_buttons() override;
+ virtual uint8_t report_x1_delta() override;
+ virtual uint8_t report_y1_delta() override;
+ virtual uint8_t report_x2_delta() override;
+ virtual uint8_t report_y2_delta() override;
+
+ required_ioport m_buttons, m_x_axis, m_y_axis, m_rotation;
+ int16_t m_x_delta[2], m_y_delta[2];
+ uint16_t m_x_val, m_y_val, m_rot_val;
+ uint8_t m_btn_val, m_btn_sent;
+};
+
+} } // namespace bus::rs232
+
+
+//**************************************************
+// Device type globals
+//**************************************************
+
+DECLARE_DEVICE_TYPE_NS(MSFT_HLE_SERIAL_MOUSE, bus::rs232, hle_msft_mouse_device)
+DECLARE_DEVICE_TYPE_NS(LOGITECH_HLE_SERIAL_MOUSE, bus::rs232, hle_logitech_mouse_device)
+DECLARE_DEVICE_TYPE_NS(WHEEL_HLE_SERIAL_MOUSE, bus::rs232, hle_wheel_mouse_device)
+DECLARE_DEVICE_TYPE_NS(MSYSTEMS_HLE_SERIAL_MOUSE, bus::rs232, hle_msystems_mouse_device)
+DECLARE_DEVICE_TYPE_NS(ROTATABLE_HLE_SERIAL_MOUSE, bus::rs232, hle_rotatable_mouse_device)
+
+#endif // MAME_BUS_RS232_SER_MOUSE_H
diff --git a/src/devices/bus/rs232/ser_mouse.cpp b/src/devices/bus/rs232/ser_mouse.cpp
deleted file mode 100644
index 2c80fc43ef5..00000000000
--- a/src/devices/bus/rs232/ser_mouse.cpp
+++ /dev/null
@@ -1,267 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:smf
-/***************************************************************************
-
- machine/ser_mouse.c
-
- Code for emulating PC-style serial mouses
-
-***************************************************************************/
-
-#include "emu.h"
-#include "ser_mouse.h"
-
-
-serial_mouse_device::serial_mouse_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, type, tag, owner, clock),
- device_rs232_port_interface(mconfig, *this),
- device_serial_interface(mconfig, *this),
- m_dtr(1),
- m_rts(1),
- m_head(0),
- m_tail(0),
- m_mb(0),
- m_timer(nullptr),
- m_enabled(false),
- m_x(*this, "ser_mouse_x"),
- m_y(*this, "ser_mouse_y"),
- m_btn(*this, "ser_mouse_btn")
-{
-}
-
-DEFINE_DEVICE_TYPE(MSFT_SERIAL_MOUSE, microsoft_mouse_device, "microsoft_mouse", "Microsoft Serial Mouse")
-
-microsoft_mouse_device::microsoft_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : serial_mouse_device(mconfig, MSFT_SERIAL_MOUSE, tag, owner, clock)
-{
-}
-
-DEFINE_DEVICE_TYPE(MSYSTEM_SERIAL_MOUSE, mouse_systems_mouse_device, "mouse_systems_mouse", "Mouse Systems Serial Mouse")
-
-mouse_systems_mouse_device::mouse_systems_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : serial_mouse_device(mconfig, MSYSTEM_SERIAL_MOUSE, tag, owner, clock)
-{
-}
-
-void serial_mouse_device::device_start()
-{
- m_timer = timer_alloc();
- m_enabled = false;
- set_frame();
- set_tra_rate(1200);
- reset_mouse();
-
- save_item(NAME(m_dtr));
- save_item(NAME(m_rts));
- save_item(NAME(m_queue));
- save_item(NAME(m_head));
- save_item(NAME(m_tail));
- save_item(NAME(m_mb));
- save_item(NAME(m_enabled));
-}
-
-void serial_mouse_device::reset_mouse()
-{
- m_head = m_tail = 0;
- output_rxd(1);
- output_dcd(0);
- output_dsr(0);
- output_ri(0);
- output_cts(0);
-}
-
-void serial_mouse_device::tra_complete()
-{
- if(m_tail != m_head)
- transmit_register_setup(unqueue_data());
-}
-
-void serial_mouse_device::tra_callback()
-{
- output_rxd(transmit_register_get_data_bit());
-}
-
-/**************************************************************************
- * Check for mouse moves and buttons. Build delta x/y packets
- **************************************************************************/
-void serial_mouse_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- if (!id)
- {
- static int ox = 0, oy = 0;
- int nx,ny;
- int dx, dy, nb;
- int mbc;
-
- /* Do not get deltas or send packets if queue is not empty (Prevents drifting) */
- if (m_head==m_tail)
- {
- nx = m_x->read();
-
- dx = nx - ox;
- if (dx<=-0x800) dx = nx + 0x1000 - ox; /* Prevent jumping */
- if (dx>=0x800) dx = nx - 0x1000 - ox;
- ox = nx;
-
- ny = m_y->read();
-
- dy = ny - oy;
- if (dy<=-0x800) dy = ny + 0x1000 - oy;
- if (dy>=0x800) dy = ny - 0x1000 - oy;
- oy = ny;
-
- nb = m_btn->read();
- mbc = nb^m_mb;
- m_mb = nb;
-
- /* check if there is any delta or mouse buttons changed */
- if ( (dx!=0) || (dy!=0) || (mbc!=0) )
- mouse_trans(dx, dy, nb, mbc);
- }
-
- if(m_tail != m_head && is_transmit_register_empty())
- transmit_register_setup(unqueue_data());
- }
-}
-
-void microsoft_mouse_device::mouse_trans(int dx, int dy, int nb, int mbc)
-{
- /* split deltas into packets of -128..+127 max */
- do
- {
- uint8_t m0, m1, m2;
- int ddx = (dx < -128) ? -128 : (dx > 127) ? 127 : dx;
- int ddy = (dy < -128) ? -128 : (dy > 127) ? 127 : dy;
- m0 = 0x40 | ((nb << 4) & 0x30) | ((ddx >> 6) & 0x03) | ((ddy >> 4) & 0x0c);
- m1 = ddx & 0x3f;
- m2 = ddy & 0x3f;
-
- /* KT - changed to use a function */
- queue_data(m0 | 0x40);
- queue_data(m1 & 0x03f);
- queue_data(m2 & 0x03f);
- if ((mbc & 0x04) != 0) /* If button 3 changed send extra byte */
- queue_data( (nb & 0x04) << 3);
-
- dx -= ddx;
- dy -= ddy;
- } while( dx || dy );
-}
-
-/* mouse systems mouse
- from "PC Mouse information" by Tomi Engdahl */
-
-/*
- The data is sent in 5 byte packets in following format:
- D7 D6 D5 D4 D3 D2 D1 D0
-
- 1. 1 0 0 0 0 LB CB RB
- 2. X7 X6 X5 X4 X3 X2 X1 X0
- 3. Y7 Y6 Y5 Y4 Y3 Y4 Y1 Y0
- 4. X7' X6' X5' X4' X3' X2' X1' X0'
- 5. Y7' Y6' Y5' Y4' Y3' Y4' Y1' Y0'
-
- LB is left button state (0=pressed, 1=released)
- CB is center button state (0=pressed, 1=released)
- RB is right button state (0=pressed, 1=released)
- X7-X0 movement in X direction since last packet in signed byte
- format (-128..+127), positive direction right
- Y7-Y0 movement in Y direction since last packet in signed byte
- format (-128..+127), positive direction up
- X7'-X0' movement in X direction since sending of X7-X0 packet in signed byte
- format (-128..+127), positive direction right
- Y7'-Y0' movement in Y direction since sending of Y7-Y0 in signed byte
- format (-128..+127), positive direction up
-
- The last two bytes in the packet (bytes 4 and 5) contains information
- about movement data changes which have occurred after data bytes 2 and 3 have been sent. */
-
-void mouse_systems_mouse_device::mouse_trans(int dx, int dy, int nb, int mbc)
-{
- dy =-dy;
-
- do
- {
- int ddx = (dx < -128) ? -128 : (dx > 127) ? 127 : dx;
- int ddy = (dy < -128) ? -128 : (dy > 127) ? 127 : dy;
-
- /* KT - changed to use a function */
- queue_data(0x080 | ((((nb & 0x04) >> 1) + ((nb & 0x02) << 1) + (nb & 0x01)) ^ 0x07));
- queue_data(ddx);
- queue_data(ddy);
- /* for now... */
- queue_data(0);
- queue_data(0);
- dx -= ddx;
- dy -= ddy;
- } while( dx || dy );
-}
-
-/**************************************************************************
- * Check for mouse control line changes and (de-)install timer
- **************************************************************************/
-
-void serial_mouse_device::set_mouse_enable(bool state)
-{
- if(state && !m_enabled)
- {
- m_timer->adjust(attotime::zero, 0, attotime::from_hz(240));
- }
- else if(!state && m_enabled)
- {
- m_timer->adjust(attotime::never);
- m_head = m_tail = 0;
- }
- m_enabled = state;
-
-}
-
-
-WRITE_LINE_MEMBER(serial_mouse_device::input_dtr)
-{
- m_dtr = state;
- check_state();
-}
-
-WRITE_LINE_MEMBER(serial_mouse_device::input_rts)
-{
- m_rts = state;
- check_state();
-}
-
-WRITE_LINE_MEMBER(microsoft_mouse_device::input_rts)
-{
- if (!m_dtr && m_rts && !state)
- {
- reset_mouse();
- /* Identify as Microsoft 3 Button Mouse */
- queue_data('M');
- queue_data('3');
- }
-
- serial_mouse_device::input_rts(state);
-}
-
-
-
-/**************************************************************************
- * Mouse INPUT_PORT declarations
- **************************************************************************/
-
-static INPUT_PORTS_START( ser_mouse )
- PORT_START( "ser_mouse_btn" )
- PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Mouse Left Button") PORT_CODE(MOUSECODE_BUTTON1)
- PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Mouse Middle Button") PORT_CODE(MOUSECODE_BUTTON3)
- PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Mouse Right Button") PORT_CODE(MOUSECODE_BUTTON2)
-
- PORT_START( "ser_mouse_x" ) /* Mouse - X AXIS */
- PORT_BIT( 0xfff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
-
- PORT_START( "ser_mouse_y" ) /* Mouse - Y AXIS */
- PORT_BIT( 0xfff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(0) PORT_PLAYER(1)
-INPUT_PORTS_END
-
-ioport_constructor serial_mouse_device::device_input_ports() const
-{
- return INPUT_PORTS_NAME(ser_mouse);
-}
diff --git a/src/devices/bus/rs232/ser_mouse.h b/src/devices/bus/rs232/ser_mouse.h
deleted file mode 100644
index ff4e7a81995..00000000000
--- a/src/devices/bus/rs232/ser_mouse.h
+++ /dev/null
@@ -1,84 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:smf
-/*****************************************************************************
- *
- * machine/ser_mouse.h
- *
- ****************************************************************************/
-
-#ifndef MAME_BUS_RS232_SER_MOUSE_H
-#define MAME_BUS_RS232_SER_MOUSE_H
-
-#include "rs232.h"
-#include "diserial.h"
-
-class serial_mouse_device :
- public device_t,
- public device_rs232_port_interface,
- public device_serial_interface
-{
-public:
- virtual ioport_constructor device_input_ports() const override;
-
-protected:
- serial_mouse_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
-
- virtual void device_start() override;
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
-
- virtual void mouse_trans(int dx, int dy, int nb, int mbc) = 0;
- virtual void set_frame() = 0;
- void set_mouse_enable(bool state);
- void queue_data(uint8_t data) {m_queue[m_head] = data; ++m_head %= 256;}
- uint8_t unqueue_data() {uint8_t ret = m_queue[m_tail]; ++m_tail %= 256; return ret;}
- virtual void tra_complete() override;
- virtual void tra_callback() override;
- void reset_mouse();
-
- virtual WRITE_LINE_MEMBER(input_dtr) override;
- virtual WRITE_LINE_MEMBER(input_rts) override;
-
- int m_dtr;
- int m_rts;
-
-private:
- void check_state() { set_mouse_enable(!m_dtr && !m_rts); }
-
- uint8_t m_queue[256];
- uint8_t m_head, m_tail, m_mb;
-
- emu_timer *m_timer;
- bool m_enabled;
-
- required_ioport m_x;
- required_ioport m_y;
- required_ioport m_btn;
-};
-
-class microsoft_mouse_device : public serial_mouse_device
-{
-public:
- microsoft_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- virtual WRITE_LINE_MEMBER(input_rts) override;
-
- virtual void set_frame() override { set_data_frame(1, 7, PARITY_NONE, STOP_BITS_2); }
- virtual void mouse_trans(int dx, int dy, int nb, int mbc) override;
-};
-
-DECLARE_DEVICE_TYPE(MSFT_SERIAL_MOUSE, microsoft_mouse_device)
-
-class mouse_systems_mouse_device : public serial_mouse_device
-{
-public:
- mouse_systems_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-
-protected:
- virtual void set_frame() override { set_data_frame(1, 8, PARITY_NONE, STOP_BITS_2); }
- virtual void mouse_trans(int dx, int dy, int nb, int mbc) override;
-};
-
-DECLARE_DEVICE_TYPE(MSYSTEM_SERIAL_MOUSE, mouse_systems_mouse_device)
-
-#endif // MAME_BUS_RS232_SER_MOUSE_H
diff --git a/src/devices/bus/sunmouse/hlemouse.cpp b/src/devices/bus/sunmouse/hlemouse.cpp
index 0737f5e4702..9f3422188dc 100644
--- a/src/devices/bus/sunmouse/hlemouse.cpp
+++ b/src/devices/bus/sunmouse/hlemouse.cpp
@@ -264,11 +264,11 @@ void hle_device_base::check_inputs()
// deal with wraparound
if (0x0800 <= x_delta)
x_delta -= 0x1000;
- else if (-0x8000 >= x_delta)
+ else if (-0x0800 >= x_delta)
x_delta += 0x1000;
if (0x0800 <= y_delta)
y_delta -= 0x1000;
- else if (-0x8000 >= y_delta)
+ else if (-0x0800 >= y_delta)
x_delta += 0x1000;
// update state
diff --git a/src/emu/diserial.h b/src/emu/diserial.h
index af55c7d4bc5..e1e2a447dff 100644
--- a/src/emu/diserial.h
+++ b/src/emu/diserial.h
@@ -188,6 +188,16 @@ class device_buffered_serial_interface : public device_serial_interface
protected:
using device_serial_interface::device_serial_interface;
+ void interface_post_start() override
+ {
+ device_serial_interface::interface_post_start();
+
+ device().save_item(NAME(m_fifo));
+ device().save_item(NAME(m_head));
+ device().save_item(NAME(m_tail));
+ device().save_item(NAME(m_empty));
+ }
+
virtual void tra_complete() override
{
assert(!m_empty || (m_head == m_tail));
@@ -236,20 +246,14 @@ protected:
}
}
- bool fifo_full() const
+ bool fifo_empty() const
{
- return !m_empty && (m_head == m_tail);
+ return m_empty;
}
-protected:
- void interface_post_start() override
+ bool fifo_full() const
{
- device_serial_interface::interface_post_start();
-
- device().save_item(NAME(m_fifo));
- device().save_item(NAME(m_head));
- device().save_item(NAME(m_tail));
- device().save_item(NAME(m_empty));
+ return !m_empty && (m_head == m_tail);
}
private:
diff --git a/src/mame/drivers/ibmpcjr.cpp b/src/mame/drivers/ibmpcjr.cpp
index 07774a1eef6..1e6ef97f708 100644
--- a/src/mame/drivers/ibmpcjr.cpp
+++ b/src/mame/drivers/ibmpcjr.cpp
@@ -20,8 +20,8 @@
#include "bus/generic/slot.h"
#include "bus/isa/fdc.h"
#include "bus/pc_joy/pc_joy.h"
+#include "bus/rs232/hlemouse.h"
#include "bus/rs232/rs232.h"
-#include "bus/rs232/ser_mouse.h"
#include "screen.h"
#include "softlist.h"
@@ -512,8 +512,11 @@ static void pcjr_floppies(device_slot_interface &device)
static void pcjr_com(device_slot_interface &device)
{
- device.option_add("microsoft_mouse", MSFT_SERIAL_MOUSE);
- device.option_add("mousesys_mouse", MSYSTEM_SERIAL_MOUSE);
+ device.option_add("microsoft_mouse", MSFT_HLE_SERIAL_MOUSE);
+ device.option_add("logitech_mouse", LOGITECH_HLE_SERIAL_MOUSE);
+ device.option_add("wheel_mouse", WHEEL_HLE_SERIAL_MOUSE);
+ device.option_add("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE);
+ device.option_add("rotatable_mouse", ROTATABLE_HLE_SERIAL_MOUSE);
}
static const gfx_layout pc_8_charlayout =
diff --git a/src/mame/drivers/pcat_dyn.cpp b/src/mame/drivers/pcat_dyn.cpp
index 6aa0d303c17..72ff59519f0 100644
--- a/src/mame/drivers/pcat_dyn.cpp
+++ b/src/mame/drivers/pcat_dyn.cpp
@@ -33,8 +33,8 @@ If the output isn't satisfactory, it prints "I/O BOARD FAILURE".
#include "bus/isa/isa.h"
#include "bus/isa/sblaster.h"
#include "bus/isa/trident.h"
+#include "bus/rs232/hlemouse.h"
#include "bus/rs232/rs232.h"
-#include "bus/rs232/ser_mouse.h"
#include "screen.h"
@@ -145,7 +145,7 @@ INPUT_PORTS_END
static void pcat_dyn_com(device_slot_interface &device)
{
- device.option_add("msmouse", MSYSTEM_SERIAL_MOUSE);
+ device.option_add("msmouse", MSYSTEMS_HLE_SERIAL_MOUSE);
}
static void pcat_dyn_isa8_cards(device_slot_interface &device)
diff --git a/src/mame/drivers/pcipc.cpp b/src/mame/drivers/pcipc.cpp
index 8068ba762df..08669a9b8dd 100644
--- a/src/mame/drivers/pcipc.cpp
+++ b/src/mame/drivers/pcipc.cpp
@@ -26,10 +26,11 @@
#include "machine/i82371sb.h"
#include "video/mga2064w.h"
#include "bus/isa/isa_cards.h"
+#include "bus/rs232/hlemouse.h"
+#include "bus/rs232/null_modem.h"
#include "bus/rs232/rs232.h"
-#include "bus/rs232/ser_mouse.h"
+#include "bus/rs232/sun_kbd.h"
#include "bus/rs232/terminal.h"
-#include "bus/rs232/null_modem.h"
#include "machine/fdc37c93x.h"
class pcipc_state : public driver_device
@@ -481,10 +482,14 @@ static void isa_internal_devices(device_slot_interface &device)
static void isa_com(device_slot_interface &device)
{
- device.option_add("microsoft_mouse", MSFT_SERIAL_MOUSE);
- device.option_add("msystems_mouse", MSYSTEM_SERIAL_MOUSE);
+ device.option_add("microsoft_mouse", MSFT_HLE_SERIAL_MOUSE);
+ device.option_add("logitech_mouse", LOGITECH_HLE_SERIAL_MOUSE);
+ device.option_add("wheel_mouse", WHEEL_HLE_SERIAL_MOUSE);
+ device.option_add("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE);
+ device.option_add("rotatable_mouse", ROTATABLE_HLE_SERIAL_MOUSE);
device.option_add("terminal", SERIAL_TERMINAL);
device.option_add("null_modem", NULL_MODEM);
+ device.option_add("sun_kbd", SUN_KBD_ADAPTOR);
}
void pcipc_state::superio_config(device_t *device)
@@ -539,7 +544,7 @@ MACHINE_CONFIG_START(pcipc_state::pcipc)
MCFG_DEVICE_ADD("isa3", ISA16_SLOT, 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false)
MCFG_DEVICE_ADD("isa4", ISA16_SLOT, 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false)
MCFG_DEVICE_ADD("isa5", ISA16_SLOT, 0, "pci:07.0:isabus", pc_isa16_cards, nullptr, false)
- MCFG_DEVICE_ADD("serport0", RS232_PORT, isa_com, "microsoft_mouse")
+ MCFG_DEVICE_ADD("serport0", RS232_PORT, isa_com, "logitech_mouse")
MCFG_RS232_RXD_HANDLER(WRITELINE("board4:fdc37c93x", fdc37c93x_device, rxd1_w))
MCFG_RS232_DCD_HANDLER(WRITELINE("board4:fdc37c93x", fdc37c93x_device, ndcd1_w))
MCFG_RS232_DSR_HANDLER(WRITELINE("board4:fdc37c93x", fdc37c93x_device, ndsr1_w))
diff --git a/src/mame/drivers/pcw16.cpp b/src/mame/drivers/pcw16.cpp
index 822c9dfb5e6..9c6e8b6accf 100644
--- a/src/mame/drivers/pcw16.cpp
+++ b/src/mame/drivers/pcw16.cpp
@@ -91,8 +91,8 @@ TODO:
#include "emu.h"
#include "includes/pcw16.h"
+#include "bus/rs232/hlemouse.h"
#include "bus/rs232/rs232.h"
-#include "bus/rs232/ser_mouse.h"
#include "screen.h"
#include "softlist.h"
#include "speaker.h"
@@ -1007,7 +1007,7 @@ INPUT_PORTS_END
static void pcw16_com(device_slot_interface &device)
{
- device.option_add("msystems_mouse", MSYSTEM_SERIAL_MOUSE);
+ device.option_add("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE);
}
MACHINE_CONFIG_START(pcw16_state::pcw16)
diff --git a/src/mame/drivers/rainbow.cpp b/src/mame/drivers/rainbow.cpp
index df625970c02..37bcfef0172 100644
--- a/src/mame/drivers/rainbow.cpp
+++ b/src/mame/drivers/rainbow.cpp
@@ -356,8 +356,8 @@ W17 pulls J1 serial port pin 1 to GND when set (chassis to logical GND).
#include "bus/rs232/rs232.h"
#include "imagedev/bitbngr.h"
#include "machine/com8116.h"
+#include "bus/rs232/hlemouse.h"
#include "bus/rs232/terminal.h"
-#include "bus/rs232/ser_mouse.h"
#include "machine/i8251.h"
#include "machine/dec_lk201.h"
@@ -3326,9 +3326,10 @@ MACHINE_CONFIG_START(rainbow_state::rainbow)
MCFG_RS232_DCD_HANDLER(WRITELINE(m_mpsc, upd7201_new_device, ctsb_w)) // actually DTR
MCFG_DEVICE_MODIFY("comm")
- MCFG_SLOT_OPTION_ADD("microsoft_mouse", MSFT_SERIAL_MOUSE)
- MCFG_SLOT_OPTION_ADD("mouse_systems_mouse", MSYSTEM_SERIAL_MOUSE)
- MCFG_SLOT_DEFAULT_OPTION("microsoft_mouse")
+ MCFG_SLOT_OPTION_ADD("microsoft_mouse", MSFT_HLE_SERIAL_MOUSE)
+ MCFG_SLOT_OPTION_ADD("logitech_mouse", LOGITECH_HLE_SERIAL_MOUSE)
+ MCFG_SLOT_OPTION_ADD("msystems_mouse", MSYSTEMS_HLE_SERIAL_MOUSE)
+ MCFG_SLOT_DEFAULT_OPTION("logitech_mouse")
MCFG_DEVICE_MODIFY("printer")
MCFG_SLOT_DEFAULT_OPTION("printer")