summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/msx/ctrl/mouse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/msx/ctrl/mouse.cpp')
-rw-r--r--src/devices/bus/msx/ctrl/mouse.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/devices/bus/msx/ctrl/mouse.cpp b/src/devices/bus/msx/ctrl/mouse.cpp
new file mode 100644
index 00000000000..95155e7f421
--- /dev/null
+++ b/src/devices/bus/msx/ctrl/mouse.cpp
@@ -0,0 +1,120 @@
+// license:BSD-3-Clause
+// copyright-holders:Wilbert Pol
+/**********************************************************************
+
+ MSX Mouse emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "mouse.h"
+
+
+namespace {
+
+INPUT_PORTS_START(msx_mouse)
+ PORT_START("BUTTONS")
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_BUTTON1)
+ PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON2)
+ PORT_BIT(0xcf, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("MOUSE_X")
+ PORT_BIT(0xffff, 0, IPT_MOUSE_X) PORT_SENSITIVITY(50)
+
+ PORT_START("MOUSE_Y")
+ PORT_BIT(0xffff, 0, IPT_MOUSE_Y) PORT_SENSITIVITY(50)
+INPUT_PORTS_END
+
+
+class msx_mouse_device : public device_t, public device_msx_general_purpose_port_interface
+{
+public:
+ msx_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ virtual u8 read() override;
+ virtual void pin_8_w(int state) override;
+
+protected:
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(msx_mouse); }
+
+private:
+ required_ioport m_buttons;
+ required_ioport m_port_mouse_x;
+ required_ioport m_port_mouse_y;
+ u16 m_data;
+ u8 m_stat;
+ u8 m_old_pin8;
+ s16 m_mouse_x;
+ s16 m_mouse_y;
+ attotime m_last_pin8_change;
+ attotime m_timeout;
+};
+
+msx_mouse_device::msx_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, MSX_MOUSE, tag, owner, clock)
+ , device_msx_general_purpose_port_interface(mconfig, *this)
+ , m_buttons(*this, "BUTTONS")
+ , m_port_mouse_x(*this, "MOUSE_X")
+ , m_port_mouse_y(*this, "MOUSE_Y")
+{
+}
+
+void msx_mouse_device::device_start()
+{
+ save_item(NAME(m_data));
+ save_item(NAME(m_stat));
+ save_item(NAME(m_old_pin8));
+ save_item(NAME(m_last_pin8_change));
+ save_item(NAME(m_mouse_x));
+ save_item(NAME(m_mouse_y));
+ m_timeout = attotime::from_msec(3);
+}
+
+void msx_mouse_device::device_reset()
+{
+ m_data = 0;
+ m_stat = 3;
+ m_old_pin8 = 0;
+ m_last_pin8_change = attotime::zero;
+ m_mouse_x = 0;
+ m_mouse_y = 0;
+}
+
+u8 msx_mouse_device::read()
+{
+ return (m_buttons->read() & 0xf0) | ((m_data >> (4 * (3 - m_stat))) & 0x0f);
+}
+
+void msx_mouse_device::pin_8_w(int state)
+{
+ if (m_old_pin8 != state)
+ {
+ attotime now = machine().scheduler().time();
+ if (now - m_last_pin8_change > m_timeout)
+ {
+ // force restart
+ m_stat = 3;
+ }
+ m_last_pin8_change = now;
+ m_stat = (m_stat + 1) & 0x03;
+
+ if (m_stat == 0)
+ {
+ s16 mouse_x = m_port_mouse_x->read();
+ s16 mouse_y = m_port_mouse_y->read();
+
+ m_data = (u8(m_mouse_x - mouse_x) << 8) | u8(m_mouse_y - mouse_y);
+ m_mouse_x = mouse_x;
+ m_mouse_y = mouse_y;
+ }
+ }
+ m_old_pin8 = state;
+}
+
+} // anonymous namespace
+
+
+DEFINE_DEVICE_TYPE_PRIVATE(MSX_MOUSE, device_msx_general_purpose_port_interface, msx_mouse_device, "msx_mouse", "MSX Mouse")