summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/pce_ctrl/mouse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/pce_ctrl/mouse.cpp')
-rw-r--r--src/devices/bus/pce_ctrl/mouse.cpp137
1 files changed, 137 insertions, 0 deletions
diff --git a/src/devices/bus/pce_ctrl/mouse.cpp b/src/devices/bus/pce_ctrl/mouse.cpp
new file mode 100644
index 00000000000..5f0fd47625f
--- /dev/null
+++ b/src/devices/bus/pce_ctrl/mouse.cpp
@@ -0,0 +1,137 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/***********************************************************************
+
+ NEC PC Engine/TurboGrafx-16 Mouse emulation
+
+***********************************************************************/
+
+#include "emu.h"
+#include "mouse.h"
+
+#include <algorithm>
+#include <iterator>
+
+//#define VERBOSE 1
+//#define LOG_OUTPUT_FUNC osd_printf_info
+#include "logmacro.h"
+
+
+namespace {
+
+INPUT_PORTS_START( pce_mouse )
+ PORT_START("BUTTONS")
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("%p Button I (right)")
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("%p Button II (left)")
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SELECT )
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) PORT_NAME("%p Run")
+
+ PORT_START("X")
+ PORT_BIT( 0xff, 0x00, IPT_MOUSE_X ) PORT_SENSITIVITY(20) PORT_KEYDELTA(1) PORT_REVERSE
+
+ PORT_START("Y")
+ PORT_BIT( 0xff, 0x00, IPT_MOUSE_Y ) PORT_SENSITIVITY(20) PORT_KEYDELTA(1) PORT_REVERSE
+INPUT_PORTS_END
+
+
+class pce_mouse_device : public device_t, public device_pce_control_port_interface
+{
+public:
+ pce_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ virtual u8 peripheral_r() override;
+ virtual void sel_w(int state) override { m_sel_in = state ? 1 : 0; }
+ virtual void clr_w(int state) override;
+
+protected:
+ virtual ioport_constructor device_input_ports() const override { return INPUT_PORTS_NAME(pce_mouse); }
+ virtual void device_start() override ATTR_COLD;
+
+private:
+ required_ioport m_buttons;
+ required_ioport_array<2> m_axes;
+
+ attotime m_squeak;
+ u16 m_data;
+ u8 m_base[2];
+ u8 m_sel_in;
+ u8 m_clr_in;
+};
+
+
+pce_mouse_device::pce_mouse_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, PCE_MOUSE, tag, owner, clock),
+ device_pce_control_port_interface(mconfig, *this),
+ m_buttons(*this, "BUTTONS"),
+ m_axes(*this, "%c", 'X'),
+ m_squeak(),
+ m_data(0),
+ m_sel_in(1),
+ m_clr_in(1)
+{
+}
+
+
+u8 pce_mouse_device::peripheral_r()
+{
+ if (m_clr_in)
+ return 0x0f;
+ else if (!m_sel_in)
+ return m_buttons->read();
+ else
+ return BIT(m_data, 12, 4);
+}
+
+
+void pce_mouse_device::clr_w(int state)
+{
+ u8 const clr = state ? 1 : 0;
+ if (clr != m_clr_in)
+ {
+ m_clr_in = clr;
+ if (clr)
+ {
+ attotime const now = machine().time();
+ if ((now - m_squeak) > attotime::from_usec(550))
+ {
+ LOG("%s: CLR rising, latch count\n", machine().describe_context());
+ m_squeak = now;
+ for (unsigned i = 0; m_axes.size() > i; ++i)
+ {
+ uint8_t const count = m_axes[i]->read();
+ m_data <<= 8;
+ m_data |= (count - m_base[i]) & 0x00ff;
+ m_base[i] = count;
+ }
+ }
+ else
+ {
+ LOG("%s: CLR rising, shift count\n", machine().describe_context());
+ m_data <<= 4;
+ }
+ }
+ else
+ {
+ LOG("%s: CLR falling\n", machine().describe_context());
+ }
+ }
+}
+
+
+void pce_mouse_device::device_start()
+{
+ m_squeak = machine().time();
+ m_data = 0;
+ std::fill(std::begin(m_base), std::end(m_base), 0);
+
+ save_item(NAME(m_squeak));
+ save_item(NAME(m_data));
+ save_item(NAME(m_base));
+ save_item(NAME(m_sel_in));
+ save_item(NAME(m_clr_in));
+}
+
+} // anonymous namespace
+
+
+DEFINE_DEVICE_TYPE_PRIVATE(PCE_MOUSE, device_pce_control_port_interface, pce_mouse_device, "pce_mouse", "NEC PC Engine Mouse")