summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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")