summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/bbc/joyport/mouse.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/bbc/joyport/mouse.cpp')
-rw-r--r--src/devices/bus/bbc/joyport/mouse.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/devices/bus/bbc/joyport/mouse.cpp b/src/devices/bus/bbc/joyport/mouse.cpp
new file mode 100644
index 00000000000..1cd91caeaa5
--- /dev/null
+++ b/src/devices/bus/bbc/joyport/mouse.cpp
@@ -0,0 +1,178 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ BBC Master Compact Mouse
+
+ The New Advanced User Guide (page 371) states the Compact PB assignments are:
+ PB4 Joystick RIGHT / Mouse Y-axis
+ PB3 Joystick UP / Mouse X-axis
+ PB2 Joystick DOWN / Mouse right button
+ PB1 Joystick LEFT / Mouse middle button
+ PB0 Joystick FIRE / Mouse left button
+
+**********************************************************************/
+
+#include "emu.h"
+#include "mouse.h"
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(BBCMC_MOUSE, bbcmc_mouse_device, "bbcmc_mouse", "BBC Master Compact Mouse")
+
+
+//-------------------------------------------------
+// INPUT_PORTS( mouse )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( mouse )
+ PORT_START("mouse_x")
+ PORT_BIT(0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100)
+
+ PORT_START("mouse_y")
+ PORT_BIT(0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100)
+
+ PORT_START("buttons")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Middle mouse button") PORT_CODE(MOUSECODE_BUTTON3)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2)
+INPUT_PORTS_END
+
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor bbcmc_mouse_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( mouse );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// bbcmc_mouse_device - constructor
+//-------------------------------------------------
+
+bbcmc_mouse_device::bbcmc_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, BBCMC_MOUSE, tag, owner, clock)
+ , device_bbc_joyport_interface(mconfig, *this)
+ , m_mouse_x(*this, "mouse_x")
+ , m_mouse_y(*this, "mouse_y")
+ , m_buttons(*this, "buttons")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void bbcmc_mouse_device::device_start()
+{
+ m_mouse_timer = timer_alloc(FUNC(bbcmc_mouse_device::update), this);
+}
+
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void bbcmc_mouse_device::device_reset()
+{
+ m_xdir = 0;
+ m_ydir = 0;
+ m_x = 0;
+ m_y = 0;
+ m_phase_x = 0;
+ m_phase_y = 0;
+
+ m_mouse_timer->adjust(attotime::zero, 0, attotime::from_hz(1400));
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+TIMER_CALLBACK_MEMBER(bbcmc_mouse_device::update)
+{
+ int x = m_mouse_x->read();
+ int y = m_mouse_y->read();
+
+ int dx = x - m_x;
+ int dy = y - m_y;
+
+ // Process X output
+ if (dx)
+ {
+ // Set the output pins according to the current phase
+ switch (m_phase_x)
+ {
+ case 0:
+ m_slot->cb1_w(1); // Set X1 to 1
+ break;
+ case 1:
+ m_xdir = 1; // Set X2 to 1
+ break;
+ case 2:
+ m_slot->cb1_w(0); // Set X1 to 0
+ break;
+ case 3:
+ m_xdir = 0; // Set X2 to 0
+ break;
+ }
+
+ // Change phase
+ if (dx > 0)
+ m_phase_x++;
+ else
+ m_phase_x--;
+
+ // Range check the phase
+ m_phase_x &= 3;
+ }
+
+ // Process Y output
+ if (dy)
+ {
+ // Set the output pins according to the current phase
+ switch (m_phase_y)
+ {
+ case 3:
+ m_slot->cb2_w(0); // Set Y1 to 0
+ break;
+ case 2:
+ m_ydir = 0; // Set Y2 to 0
+ break;
+ case 1:
+ m_slot->cb2_w(1); // Set Y1 to 1
+ break;
+ case 0:
+ m_ydir = 1; // Set Y2 to 1
+ break;
+ }
+
+ // Change phase
+ if (dy > 0)
+ m_phase_y++;
+ else
+ m_phase_y--;
+
+ // Range check the phase
+ m_phase_y &= 3;
+ }
+
+ m_x = x;
+ m_y = y;
+}
+
+uint8_t bbcmc_mouse_device::pb_r()
+{
+ return (m_buttons->read() & 0x07) | (m_xdir << 3) | (m_ydir << 4) | 0xe0;
+}