summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/vcs_ctrl
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/vcs_ctrl')
-rw-r--r--src/devices/bus/vcs_ctrl/ctrl.cpp14
-rw-r--r--src/devices/bus/vcs_ctrl/ctrl.h38
-rw-r--r--src/devices/bus/vcs_ctrl/cx85.cpp126
-rw-r--r--src/devices/bus/vcs_ctrl/cx85.h54
-rw-r--r--src/devices/bus/vcs_ctrl/joybooster.cpp14
-rw-r--r--src/devices/bus/vcs_ctrl/joybooster.h14
-rw-r--r--src/devices/bus/vcs_ctrl/joystick.cpp2
-rw-r--r--src/devices/bus/vcs_ctrl/joystick.h10
-rw-r--r--src/devices/bus/vcs_ctrl/keypad.cpp63
-rw-r--r--src/devices/bus/vcs_ctrl/keypad.h26
-rw-r--r--src/devices/bus/vcs_ctrl/lightpen.cpp2
-rw-r--r--src/devices/bus/vcs_ctrl/lightpen.h10
-rw-r--r--src/devices/bus/vcs_ctrl/mouse.cpp2
-rw-r--r--src/devices/bus/vcs_ctrl/mouse.h14
-rw-r--r--src/devices/bus/vcs_ctrl/paddles.cpp19
-rw-r--r--src/devices/bus/vcs_ctrl/paddles.h16
-rw-r--r--src/devices/bus/vcs_ctrl/trakball.cpp150
-rw-r--r--src/devices/bus/vcs_ctrl/trakball.h53
-rw-r--r--src/devices/bus/vcs_ctrl/wheel.cpp4
-rw-r--r--src/devices/bus/vcs_ctrl/wheel.h10
20 files changed, 506 insertions, 135 deletions
diff --git a/src/devices/bus/vcs_ctrl/ctrl.cpp b/src/devices/bus/vcs_ctrl/ctrl.cpp
index 57cdad8f4ba..8cf51645a55 100644
--- a/src/devices/bus/vcs_ctrl/ctrl.cpp
+++ b/src/devices/bus/vcs_ctrl/ctrl.cpp
@@ -28,7 +28,7 @@ DEFINE_DEVICE_TYPE(VCS_CONTROL_PORT, vcs_control_port_device, "vcs_control_port"
//-------------------------------------------------
device_vcs_control_port_interface::device_vcs_control_port_interface(const machine_config &mconfig, device_t &device) :
- device_slot_card_interface(mconfig, device)
+ device_interface(device, "vcsctrl")
{
m_port = dynamic_cast<vcs_control_port_device *>(device.owner());
}
@@ -58,8 +58,6 @@ vcs_control_port_device::vcs_control_port_device(const machine_config &mconfig,
void vcs_control_port_device::device_start()
{
m_device = dynamic_cast<device_vcs_control_port_interface *>(get_card_device());
-
- m_write_trigger.resolve_safe();
}
@@ -67,12 +65,14 @@ void vcs_control_port_device::device_start()
// SLOT_INTERFACE( vcs_control_port_devices )
//-------------------------------------------------
+#include "cx85.h"
#include "joybooster.h"
#include "joystick.h"
#include "keypad.h"
#include "lightpen.h"
#include "mouse.h"
#include "paddles.h"
+#include "trakball.h"
#include "wheel.h"
void vcs_control_port_devices(device_slot_interface &device)
@@ -84,4 +84,12 @@ void vcs_control_port_devices(device_slot_interface &device)
device.option_add("joybstr", VCS_JOYSTICK_BOOSTER);
device.option_add("wheel", VCS_WHEEL);
device.option_add("keypad", VCS_KEYPAD);
+ device.option_add("cx85", ATARI_CX85);
+ device.option_add("trakball", ATARI_TRAKBALL);
+}
+
+void a800_control_port_devices(device_slot_interface &device)
+{
+ vcs_control_port_devices(device);
+ device.set_option_machine_config("pad", &vcs_paddles_device::reverse_players);
}
diff --git a/src/devices/bus/vcs_ctrl/ctrl.h b/src/devices/bus/vcs_ctrl/ctrl.h
index 574a7dc3ae8..b1ca5fde075 100644
--- a/src/devices/bus/vcs_ctrl/ctrl.h
+++ b/src/devices/bus/vcs_ctrl/ctrl.h
@@ -9,8 +9,8 @@
**********************************************************************/
-#ifndef MAME_BUS_CVS_CTRL_CTRL_H
-#define MAME_BUS_CVS_CTRL_CTRL_H
+#ifndef MAME_BUS_VCS_CTRL_CTRL_H
+#define MAME_BUS_VCS_CTRL_CTRL_H
#pragma once
@@ -24,22 +24,25 @@ class vcs_control_port_device;
// ======================> device_vcs_control_port_interface
-class device_vcs_control_port_interface : public device_slot_card_interface
+class device_vcs_control_port_interface : public device_interface
{
public:
- // construction/destruction
- device_vcs_control_port_interface(const machine_config &mconfig, device_t &device);
virtual ~device_vcs_control_port_interface() { }
- virtual uint8_t vcs_joy_r() { return 0xff; };
- virtual uint8_t vcs_pot_x_r() { return 0xff; };
- virtual uint8_t vcs_pot_y_r() { return 0xff; };
- virtual void vcs_joy_w(uint8_t data) { };
+ virtual uint8_t vcs_joy_r() { return 0xff; }
+ virtual uint8_t vcs_pot_x_r() { return 0xff; }
+ virtual uint8_t vcs_pot_y_r() { return 0xff; }
+ virtual void vcs_joy_w(uint8_t data) { }
virtual bool has_pot_x() { return false; }
virtual bool has_pot_y() { return false; }
+ // FIXME: should be made protected when port definitions become member functions
+ inline void trigger_w(int state);
+
protected:
+ device_vcs_control_port_interface(const machine_config &mconfig, device_t &device);
+
vcs_control_port_device *m_port;
};
@@ -72,18 +75,15 @@ public:
// bit 1 - pin 2 - Down
// bit 2 - pin 3 - Left
// bit 3 - pin 4 - Right
- // bit 4 - pin 5 -
+ // pin 5 - Pot X
// bit 5 - pin 6 - Button
// pin 7 - +5V
// pin 8 - GND
- // bit 6 - pin 9 -
+ // pin 9 - Pot Y
//
uint8_t read_joy() { return exists() ? m_device->vcs_joy_r() : 0xff; }
- DECLARE_READ8_MEMBER( joy_r ) { return read_joy(); }
uint8_t read_pot_x() { return exists() ? m_device->vcs_pot_x_r() : 0xff; }
- DECLARE_READ8_MEMBER( pot_x_r ) { return read_pot_x(); }
uint8_t read_pot_y() { return exists() ? m_device->vcs_pot_y_r() : 0xff; }
- DECLARE_READ8_MEMBER( pot_y_r ) { return read_pot_y(); }
void joy_w(uint8_t data) { if (exists()) m_device->vcs_joy_w(data); }
@@ -95,7 +95,7 @@ public:
protected:
// device-level overrides
- virtual void device_start() override;
+ virtual void device_start() override ATTR_COLD;
device_vcs_control_port_interface *m_device;
@@ -103,10 +103,16 @@ private:
devcb_write_line m_write_trigger;
};
+inline void device_vcs_control_port_interface::trigger_w(int state)
+{
+ m_port->trigger_w(state);
+}
+
// device type definition
DECLARE_DEVICE_TYPE(VCS_CONTROL_PORT, vcs_control_port_device)
void vcs_control_port_devices(device_slot_interface &device);
+void a800_control_port_devices(device_slot_interface &device);
-#endif // MAME_BUS_CVS_CTRL_CTRL_H
+#endif // MAME_BUS_VCS_CTRL_CTRL_H
diff --git a/src/devices/bus/vcs_ctrl/cx85.cpp b/src/devices/bus/vcs_ctrl/cx85.cpp
new file mode 100644
index 00000000000..f4543e6cd34
--- /dev/null
+++ b/src/devices/bus/vcs_ctrl/cx85.cpp
@@ -0,0 +1,126 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/**********************************************************************
+
+ Atari CX85 Numeric Keypad
+
+ Normal Atari 400/800 usage has this connect to controller port 2.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "cx85.h"
+
+#include "machine/rescap.h"
+
+
+//**************************************************************************
+// DEVICE TYPE DEFINITION
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(ATARI_CX85, atari_cx85_device, "atari_cx85", "Atari CX85 Numeric Keypad")
+
+
+//**************************************************************************
+// INPUT PORTS
+//**************************************************************************
+
+static INPUT_PORTS_START(atari_cx85)
+ PORT_START("X1")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad -") PORT_CODE(KEYCODE_PLUS_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 3") PORT_CODE(KEYCODE_3_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 9") PORT_CODE(KEYCODE_9_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 6") PORT_CODE(KEYCODE_6_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("X2")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad + Enter") PORT_CODE(KEYCODE_ENTER_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 2") PORT_CODE(KEYCODE_2_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 8") PORT_CODE(KEYCODE_8_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 5") PORT_CODE(KEYCODE_5_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("X3")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad .") PORT_CODE(KEYCODE_DEL_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 1") PORT_CODE(KEYCODE_1_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 7") PORT_CODE(KEYCODE_7_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 4") PORT_CODE(KEYCODE_4_PAD)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_UNUSED)
+
+ PORT_START("X4")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad 0") PORT_CODE(KEYCODE_0_PAD)
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F4 (Yes)") PORT_CODE(KEYCODE_MINUS_PAD)
+ PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F2 (No)") PORT_CODE(KEYCODE_SLASH_PAD)
+ PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F3 (Delete)") PORT_CODE(KEYCODE_ASTERISK)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Keypad F1 (Escape)") PORT_CODE(KEYCODE_NUMLOCK)
+INPUT_PORTS_END
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// atari_cx85_device - constructor
+//-------------------------------------------------
+
+atari_cx85_device::atari_cx85_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, ATARI_CX85, tag, owner, clock)
+ , device_vcs_control_port_interface(mconfig, *this)
+ , m_encoder(*this, "encoder")
+{
+}
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void atari_cx85_device::device_add_mconfig(machine_config &config)
+{
+ MM74C923(config, m_encoder, 0); // MCM74C923N
+ m_encoder->set_cap_osc(CAP_U(.1));
+ m_encoder->set_cap_debounce(CAP_U(.47));
+ m_encoder->data_tri_callback().set_constant(0);
+ m_encoder->x1_rd_callback().set_ioport("X1");
+ m_encoder->x2_rd_callback().set_ioport("X2");
+ m_encoder->x3_rd_callback().set_ioport("X3");
+ m_encoder->x4_rd_callback().set_ioport("X4");
+ m_encoder->da_wr_callback().set(FUNC(atari_cx85_device::trigger_w)).invert();
+}
+
+//-------------------------------------------------
+// device_input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor atari_cx85_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(atari_cx85);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void atari_cx85_device::device_start()
+{
+}
+
+//-------------------------------------------------
+// vcs_joy_r - read digital inputs
+//-------------------------------------------------
+
+u8 atari_cx85_device::vcs_joy_r()
+{
+ // 74C923 outputs are buffered through 4049B
+ return (~m_encoder->read() & 0x0f) | (m_encoder->da_r() ? 0 : 0x20);
+}
+
+//-------------------------------------------------
+// vcs_pot_x_r - sample B pot
+//-------------------------------------------------
+
+u8 atari_cx85_device::vcs_pot_x_r()
+{
+ // Schematics suggests this should also be inverted through 4049B, but drivers seem to work the opposite way
+ return BIT(m_encoder->read(), 4) ? 0xff : 0;
+}
diff --git a/src/devices/bus/vcs_ctrl/cx85.h b/src/devices/bus/vcs_ctrl/cx85.h
new file mode 100644
index 00000000000..6fb0bf0a316
--- /dev/null
+++ b/src/devices/bus/vcs_ctrl/cx85.h
@@ -0,0 +1,54 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR
+/**********************************************************************
+
+ Atari CX85 Numeric Keypad
+
+**********************************************************************/
+
+#ifndef MAME_BUS_VCS_CTRL_CX85_H
+#define MAME_BUS_VCS_CTRL_CX85_H
+
+#pragma once
+
+#include "ctrl.h"
+#include "machine/mm74c922.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> atari_cx85_device
+
+class atari_cx85_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ atari_cx85_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+
+ // device_vcs_control_port_interface overrides
+ virtual u8 vcs_joy_r() override;
+ virtual u8 vcs_pot_x_r() override;
+
+ virtual bool has_pot_x() override { return true; }
+ virtual bool has_pot_y() override { return false; } // pin 9 not used
+
+private:
+ required_device<mm74c923_device> m_encoder;
+};
+
+
+// device type declaration
+DECLARE_DEVICE_TYPE(ATARI_CX85, atari_cx85_device)
+
+#endif // MAME_BUS_VCS_CTRL_CX85_H
diff --git a/src/devices/bus/vcs_ctrl/joybooster.cpp b/src/devices/bus/vcs_ctrl/joybooster.cpp
index 9ea3b813ac1..b390a158e85 100644
--- a/src/devices/bus/vcs_ctrl/joybooster.cpp
+++ b/src/devices/bus/vcs_ctrl/joybooster.cpp
@@ -2,8 +2,14 @@
// copyright-holders:Curt Coder
/**********************************************************************
- Atari Video Computer System digital joystick emulation with
- boostergrip adapter
+ CBS Electronics Booster-Grip Joystick Adaptor
+
+ This peripheral device, which adds two extra buttons to an
+ ordinary single-button joystick, was packaged with the Atari 2600
+ version of Omega Race. CBS Electronics also advertised it as a
+ pack-in for their unreleased 2600 title Wings (it does not work
+ with the known prototype). The homebrew Thrust games optionally
+ support the Booster-Grip as well.
**********************************************************************/
@@ -16,7 +22,7 @@
// DEVICE DEFINITIONS
//**************************************************************************
-DEFINE_DEVICE_TYPE(VCS_JOYSTICK_BOOSTER, vcs_joystick_booster_device, "vcs_joystick_booster", "Atari / CBM Digital joystick with Boostergrip")
+DEFINE_DEVICE_TYPE(VCS_JOYSTICK_BOOSTER, vcs_joystick_booster_device, "vcs_joystick_booster", "CBS Electronics Booster-Grip Joystick Adaptor")
static INPUT_PORTS_START( vcs_joystick_booster )
@@ -25,7 +31,7 @@ static INPUT_PORTS_START( vcs_joystick_booster )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY // Pin 2
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY // Pin 3
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY // Pin 4
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // Pin 6
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_WRITE_LINE_MEMBER(FUNC(vcs_joystick_booster_device::trigger_w)) // Pin 6
PORT_BIT( 0xd0, IP_ACTIVE_LOW, IPT_UNUSED )
// Pin 5
diff --git a/src/devices/bus/vcs_ctrl/joybooster.h b/src/devices/bus/vcs_ctrl/joybooster.h
index 8b3cf922a1b..4bb0695b47f 100644
--- a/src/devices/bus/vcs_ctrl/joybooster.h
+++ b/src/devices/bus/vcs_ctrl/joybooster.h
@@ -29,13 +29,6 @@ public:
// construction/destruction
vcs_joystick_booster_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
-
// device_vcs_control_port_interface overrides
virtual uint8_t vcs_joy_r() override;
virtual uint8_t vcs_pot_x_r() override;
@@ -44,6 +37,13 @@ protected:
virtual bool has_pot_x() override { return true; }
virtual bool has_pot_y() override { return true; }
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+
private:
required_ioport m_joy;
required_ioport m_potx;
diff --git a/src/devices/bus/vcs_ctrl/joystick.cpp b/src/devices/bus/vcs_ctrl/joystick.cpp
index c911f435a0c..a84e8ddfeaa 100644
--- a/src/devices/bus/vcs_ctrl/joystick.cpp
+++ b/src/devices/bus/vcs_ctrl/joystick.cpp
@@ -24,7 +24,7 @@ static INPUT_PORTS_START( vcs_joystick )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_WRITE_LINE_MEMBER(FUNC(vcs_joystick_device::trigger_w))
PORT_BIT( 0xd0, IP_ACTIVE_LOW, IPT_UNUSED )
INPUT_PORTS_END
diff --git a/src/devices/bus/vcs_ctrl/joystick.h b/src/devices/bus/vcs_ctrl/joystick.h
index dcae27d2965..af82bf5dd77 100644
--- a/src/devices/bus/vcs_ctrl/joystick.h
+++ b/src/devices/bus/vcs_ctrl/joystick.h
@@ -28,15 +28,15 @@ public:
// construction/destruction
vcs_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
+ // device_vcs_control_port_interface overrides
+ virtual uint8_t vcs_joy_r() override;
protected:
// device-level overrides
- virtual void device_start() override;
+ virtual void device_start() override ATTR_COLD;
- // device_vcs_control_port_interface overrides
- virtual uint8_t vcs_joy_r() override;
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
private:
required_ioport m_joy;
diff --git a/src/devices/bus/vcs_ctrl/keypad.cpp b/src/devices/bus/vcs_ctrl/keypad.cpp
index 97a43253c08..888cae738f5 100644
--- a/src/devices/bus/vcs_ctrl/keypad.cpp
+++ b/src/devices/bus/vcs_ctrl/keypad.cpp
@@ -58,7 +58,7 @@ vcs_keypad_device::vcs_keypad_device(const machine_config &mconfig, const char *
device_t(mconfig, VCS_KEYPAD, tag, owner, clock),
device_vcs_control_port_interface(mconfig, *this),
m_keypad(*this, "KEYPAD"),
- m_column(0)
+ m_row(0)
{
}
@@ -69,8 +69,7 @@ vcs_keypad_device::vcs_keypad_device(const machine_config &mconfig, const char *
void vcs_keypad_device::device_start()
{
- m_column = 0;
- save_item(NAME(m_column));
+ save_item(NAME(m_row));
}
@@ -78,64 +77,26 @@ void vcs_keypad_device::device_start()
// vcs_joy_w - joystick write
//-------------------------------------------------
-uint8_t vcs_keypad_device::vcs_joy_r()
+void vcs_keypad_device::vcs_joy_w(uint8_t data)
{
- for ( int i = 0; i < 4; i++ )
- {
- if ( ! ( ( m_column >> i ) & 0x01 ) )
- {
- if ( ( m_keypad->read() >> 3*i ) & 0x04 )
- {
- return 0xff;
- }
- else
- {
- return 0;
- }
- }
- }
- return 0xff;
+ m_row = data & 0x0f;
}
-void vcs_keypad_device::vcs_joy_w( uint8_t data )
+uint8_t vcs_keypad_device::read_keys(uint8_t col)
{
- m_column = data & 0x0F;
-}
+ uint8_t val = 0;
-uint8_t vcs_keypad_device::vcs_pot_x_r()
-{
- for ( int i = 0; i < 4; i++ )
+ for (int row = 0; row < 4; row++)
{
- if ( ! ( ( m_column >> i ) & 0x01 ) )
+ if (!BIT(m_row, row))
{
- if ( ( m_keypad->read() >> 3*i ) & 0x01 )
- {
- return 0;
- }
- else
+ if (!BIT(m_keypad->read(), 3*row + col))
{
- return 0xff;
+ val = 0xff;
}
+ break;
}
}
- return 0;
-}
-uint8_t vcs_keypad_device::vcs_pot_y_r()
-{
- for ( int i = 0; i < 4; i++ )
- {
- if ( ! ( ( m_column >> i ) & 0x01 ) )
- {
- if ( ( m_keypad->read() >> 3*i ) & 0x02 )
- {
- return 0;
- }
- else
- {
- return 0xff;
- }
- }
- }
- return 0;
+ return val;
}
diff --git a/src/devices/bus/vcs_ctrl/keypad.h b/src/devices/bus/vcs_ctrl/keypad.h
index 37733cc135c..83a1f1a904f 100644
--- a/src/devices/bus/vcs_ctrl/keypad.h
+++ b/src/devices/bus/vcs_ctrl/keypad.h
@@ -28,26 +28,28 @@ public:
// construction/destruction
vcs_keypad_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
-
// device_vcs_control_port_interface overrides
- virtual uint8_t vcs_joy_r() override;
- virtual void vcs_joy_w( uint8_t data ) override;
- virtual uint8_t vcs_pot_x_r() override;
- virtual uint8_t vcs_pot_y_r() override;
+ virtual uint8_t vcs_joy_r() override { return ~read_keys(2); }
+ virtual uint8_t vcs_pot_x_r() override { return read_keys(0); }
+ virtual uint8_t vcs_pot_y_r() override { return read_keys(1); }
+ virtual void vcs_joy_w(uint8_t data) override;
virtual bool has_pot_x() override { return true; }
virtual bool has_pot_y() override { return true; }
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+
private:
+ uint8_t read_keys(uint8_t column);
+
required_ioport m_keypad;
- uint8_t m_column;
+ uint8_t m_row;
};
diff --git a/src/devices/bus/vcs_ctrl/lightpen.cpp b/src/devices/bus/vcs_ctrl/lightpen.cpp
index b79f447a809..f0145d50dda 100644
--- a/src/devices/bus/vcs_ctrl/lightpen.cpp
+++ b/src/devices/bus/vcs_ctrl/lightpen.cpp
@@ -27,7 +27,7 @@ INPUT_CHANGED_MEMBER( vcs_lightpen_device::trigger )
static INPUT_PORTS_START( vcs_lightpen )
PORT_START("JOY")
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, vcs_lightpen_device, trigger, 0)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(vcs_lightpen_device::trigger), 0)
PORT_BIT( 0xdf, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("LIGHTX")
diff --git a/src/devices/bus/vcs_ctrl/lightpen.h b/src/devices/bus/vcs_ctrl/lightpen.h
index f0b2805bdd6..bd375b07888 100644
--- a/src/devices/bus/vcs_ctrl/lightpen.h
+++ b/src/devices/bus/vcs_ctrl/lightpen.h
@@ -28,17 +28,17 @@ public:
// construction/destruction
vcs_lightpen_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
+ // device_vcs_control_port_interface overrides
+ virtual uint8_t vcs_joy_r() override;
DECLARE_INPUT_CHANGED_MEMBER( trigger );
protected:
// device-level overrides
- virtual void device_start() override;
+ virtual void device_start() override ATTR_COLD;
- // device_vcs_control_port_interface overrides
- virtual uint8_t vcs_joy_r() override;
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
private:
required_ioport m_joy;
diff --git a/src/devices/bus/vcs_ctrl/mouse.cpp b/src/devices/bus/vcs_ctrl/mouse.cpp
index 611ae081da4..23dabc6c37d 100644
--- a/src/devices/bus/vcs_ctrl/mouse.cpp
+++ b/src/devices/bus/vcs_ctrl/mouse.cpp
@@ -28,7 +28,7 @@ DEFINE_DEVICE_TYPE(VCS_MOUSE, vcs_mouse_device, "vcs_mouse", "Atari / CBM Mouse"
static INPUT_PORTS_START( vcs_mouse )
PORT_START("JOY")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON2 )
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_WRITE_LINE_MEMBER(FUNC(vcs_mouse_device::trigger_w))
PORT_BIT( 0xde, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("POTX")
diff --git a/src/devices/bus/vcs_ctrl/mouse.h b/src/devices/bus/vcs_ctrl/mouse.h
index eab33d64aab..e31000e9180 100644
--- a/src/devices/bus/vcs_ctrl/mouse.h
+++ b/src/devices/bus/vcs_ctrl/mouse.h
@@ -28,13 +28,6 @@ public:
// construction/destruction
vcs_mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
-
// device_vcs_control_port_interface overrides
virtual uint8_t vcs_joy_r() override;
virtual uint8_t vcs_pot_x_r() override;
@@ -43,6 +36,13 @@ protected:
virtual bool has_pot_x() override { return true; }
virtual bool has_pot_y() override { return true; }
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+
private:
required_ioport m_joy;
required_ioport m_potx;
diff --git a/src/devices/bus/vcs_ctrl/paddles.cpp b/src/devices/bus/vcs_ctrl/paddles.cpp
index 09e7a0d26a5..f46478d8e41 100644
--- a/src/devices/bus/vcs_ctrl/paddles.cpp
+++ b/src/devices/bus/vcs_ctrl/paddles.cpp
@@ -20,18 +20,17 @@ DEFINE_DEVICE_TYPE(VCS_PADDLES, vcs_paddles_device, "vcs_paddles", "Atari / CBM
static INPUT_PORTS_START( vcs_paddles )
PORT_START("JOY")
- PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
- PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
+ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) // pin 3
+ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) // pin 4
PORT_BIT( 0xf3, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("POTX")
- PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(1) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255)
+ PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(1) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255) PORT_REVERSE // pin 5
PORT_START("POTY")
- PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(2) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255)
+ PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_PLAYER(2) PORT_SENSITIVITY(30) PORT_KEYDELTA(20) PORT_MINMAX(0, 255) PORT_REVERSE // pin 9
INPUT_PORTS_END
-
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
@@ -56,7 +55,8 @@ vcs_paddles_device::vcs_paddles_device(const machine_config &mconfig, const char
device_vcs_control_port_interface(mconfig, *this),
m_joy(*this, "JOY"),
m_potx(*this, "POTX"),
- m_poty(*this, "POTY")
+ m_poty(*this, "POTY"),
+ m_reverse_players(false)
{
}
@@ -76,7 +76,8 @@ void vcs_paddles_device::device_start()
uint8_t vcs_paddles_device::vcs_joy_r()
{
- return m_joy->read();
+ uint8_t const data = m_joy->read();
+ return m_reverse_players ? bitswap<8>(data, 7, 6, 5, 4, 2, 3, 1, 0) : data;
}
@@ -86,7 +87,7 @@ uint8_t vcs_paddles_device::vcs_joy_r()
uint8_t vcs_paddles_device::vcs_pot_x_r()
{
- return m_potx->read();
+ return m_reverse_players ? m_poty->read() : m_potx->read();
}
@@ -96,5 +97,5 @@ uint8_t vcs_paddles_device::vcs_pot_x_r()
uint8_t vcs_paddles_device::vcs_pot_y_r()
{
- return m_poty->read();
+ return m_reverse_players ? m_potx->read() : m_poty->read();
}
diff --git a/src/devices/bus/vcs_ctrl/paddles.h b/src/devices/bus/vcs_ctrl/paddles.h
index e88084066ee..6e80b632a58 100644
--- a/src/devices/bus/vcs_ctrl/paddles.h
+++ b/src/devices/bus/vcs_ctrl/paddles.h
@@ -28,12 +28,7 @@ public:
// construction/destruction
vcs_paddles_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
-
-protected:
- // device-level overrides
- virtual void device_start() override;
+ static void reverse_players(device_t *device) { downcast<vcs_paddles_device &>(*device).m_reverse_players = true; }
// device_vcs_control_port_interface overrides
virtual uint8_t vcs_joy_r() override;
@@ -43,10 +38,19 @@ protected:
virtual bool has_pot_x() override { return true; }
virtual bool has_pot_y() override { return true; }
+protected:
+ // device-level overrides
+ virtual void device_start() override ATTR_COLD;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
+
private:
required_ioport m_joy;
required_ioport m_potx;
required_ioport m_poty;
+
+ bool m_reverse_players;
};
diff --git a/src/devices/bus/vcs_ctrl/trakball.cpp b/src/devices/bus/vcs_ctrl/trakball.cpp
new file mode 100644
index 00000000000..0da97221762
--- /dev/null
+++ b/src/devices/bus/vcs_ctrl/trakball.cpp
@@ -0,0 +1,150 @@
+// license:BSD-3-Clause
+/**********************************************************************
+
+ Atari CX22/CX80 Trak-Ball
+
+Note: this module only works in trackball mode and not in joystick emulation mode
+
+Reference: Atari, CX22 Trakball Field Service Manual, Rev. 01 (FD100660), November 1983
+
+**********************************************************************/
+
+#include "emu.h"
+#include "trakball.h"
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define TRAKBALL_BUTTON_TAG "trackball_buttons"
+#define TRAKBALL_XAXIS_TAG "trackball_x"
+#define TRAKBALL_YAXIS_TAG "trackball_y"
+
+#define TRAKBALL_POS_UNINIT 0xffffffff /* default out-of-range position */
+
+//**************************************************************************
+// DEVICE TYPE DEFINITION
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(ATARI_TRAKBALL, atari_trakball_device, "atari_trakball", "Atari CX22/CX80 Trak-Ball")
+
+
+//**************************************************************************
+// INPUT PORTS
+//**************************************************************************
+
+static INPUT_PORTS_START(atari_trakball)
+ PORT_START(TRAKBALL_BUTTON_TAG) /* Trak-ball - button */
+ PORT_BIT( 0x0f, IP_ACTIVE_HIGH, IPT_UNUSED )
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_WRITE_LINE_MEMBER(FUNC(atari_trakball_device::trigger_w))
+ PORT_BIT( 0xd0, IP_ACTIVE_LOW, IPT_UNUSED )
+
+ PORT_START(TRAKBALL_XAXIS_TAG) /* Trak-ball - X AXIS */
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X) PORT_SENSITIVITY(80) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(atari_trakball_device::trakball_moved), 0)
+
+ PORT_START(TRAKBALL_YAXIS_TAG) /* Trak-ball - Y AXIS */
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y) PORT_SENSITIVITY(80) PORT_KEYDELTA(0) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, FUNC(atari_trakball_device::trakball_moved), 1)
+INPUT_PORTS_END
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// atari_trakball_device - constructor
+//-------------------------------------------------
+
+atari_trakball_device::atari_trakball_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, ATARI_TRAKBALL, tag, owner, clock)
+ , device_vcs_control_port_interface(mconfig, *this)
+ , m_trakballb(*this, TRAKBALL_BUTTON_TAG)
+ , m_trakballxy(*this, { TRAKBALL_XAXIS_TAG, TRAKBALL_YAXIS_TAG })
+ , m_last_pos{ TRAKBALL_POS_UNINIT, TRAKBALL_POS_UNINIT }
+ , m_last_direction{ 0, 0 }
+{
+}
+
+//-------------------------------------------------
+// device_input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor atari_trakball_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(atari_trakball);
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void atari_trakball_device::device_start()
+{
+ save_item(NAME(m_last_pos));
+ save_item(NAME(m_last_direction));
+}
+
+#define QUADRATURE_ANGLE_RESOLUTION 0x02
+
+//-----------------------------------------------------------------
+// trakbal_pos_and_dir_upd - update tracked position and direction
+//-----------------------------------------------------------------
+
+void atari_trakball_device::trakball_pos_and_dir_upd(int axis)
+{
+ int diff_pos = 0;
+ int cur_pos = 0;
+
+ cur_pos = m_trakballxy[axis]->read();
+ if (m_last_pos[axis] == TRAKBALL_POS_UNINIT) {
+ if (!machine().side_effects_disabled()) {
+ m_last_pos[axis] = cur_pos;
+ }
+ }
+ diff_pos = cur_pos - m_last_pos[axis];
+ // wrap-around the position
+ if (diff_pos > 0x7f) {
+ diff_pos -= 0x100;
+ } else if (diff_pos < -0x80) {
+ diff_pos += 0x100;
+ }
+ if (!machine().side_effects_disabled()) {
+ m_last_pos[axis] = cur_pos;
+ if (diff_pos) {
+ m_last_direction[axis] = diff_pos > 0;
+ }
+ }
+}
+
+//---------------------------------------------------------
+// trakball_moved - called when moved outside of polling
+//---------------------------------------------------------
+
+INPUT_CHANGED_MEMBER( atari_trakball_device::trakball_moved )
+{
+ const int axis(param);
+
+ trakball_pos_and_dir_upd(axis);
+}
+
+//-------------------------------------------------
+// vcs_joy_r - read digital inputs
+//-------------------------------------------------
+
+u8 atari_trakball_device::vcs_joy_r()
+{
+ u8 vcs_joy_return = 0;
+
+ for (int axis = 0; axis < 2; axis++) {
+ trakball_pos_and_dir_upd(axis);
+ }
+
+ vcs_joy_return =
+ m_trakballb->read() |
+ (m_last_direction[0] ? 0x01 : 0x00) |
+ ((m_last_pos[0] & QUADRATURE_ANGLE_RESOLUTION) ? 0x02 : 0x00) |
+ (m_last_direction[1] ? 0x04 : 0x00) |
+ ((m_last_pos[1] & QUADRATURE_ANGLE_RESOLUTION) ? 0x08 : 0x00);
+
+ return vcs_joy_return;
+}
diff --git a/src/devices/bus/vcs_ctrl/trakball.h b/src/devices/bus/vcs_ctrl/trakball.h
new file mode 100644
index 00000000000..8bd357b0466
--- /dev/null
+++ b/src/devices/bus/vcs_ctrl/trakball.h
@@ -0,0 +1,53 @@
+// license:BSD-3-Clause
+/**********************************************************************
+
+ Atari CX22/CX80 Trak-Ball
+
+**********************************************************************/
+
+#ifndef MAME_BUS_VCS_CTRL_TRAKBALL_H
+#define MAME_BUS_VCS_CTRL_TRAKBALL_H
+
+#pragma once
+
+#include "ctrl.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> atari_trakball_device
+
+class atari_trakball_device : public device_t,
+ public device_vcs_control_port_interface
+{
+public:
+ // construction/destruction
+ atari_trakball_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ DECLARE_INPUT_CHANGED_MEMBER( trakball_moved );
+
+protected:
+ // device_t implementation
+ virtual void device_start() override;
+
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override;
+
+ // device_vcs_control_port_interface overrides
+ virtual u8 vcs_joy_r() override;
+
+private:
+ void trakball_pos_and_dir_upd(int axis);
+
+ required_ioport m_trakballb;
+ required_ioport_array<2> m_trakballxy;
+
+ uint32_t m_last_pos[2];
+ uint8_t m_last_direction[2];
+};
+
+
+// device type declaration
+DECLARE_DEVICE_TYPE(ATARI_TRAKBALL, atari_trakball_device)
+
+#endif // MAME_BUS_VCS_CTRL_TRAKBALL_H
diff --git a/src/devices/bus/vcs_ctrl/wheel.cpp b/src/devices/bus/vcs_ctrl/wheel.cpp
index 76e86530cf8..c470f9117ec 100644
--- a/src/devices/bus/vcs_ctrl/wheel.cpp
+++ b/src/devices/bus/vcs_ctrl/wheel.cpp
@@ -20,7 +20,7 @@ DEFINE_DEVICE_TYPE(VCS_WHEEL, vcs_wheel_device, "vcs_wheel", "Atari / CBM Drivin
static INPUT_PORTS_START( vcs_wheel )
PORT_START("JOY")
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // Pin 6
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_WRITE_LINE_MEMBER(FUNC(vcs_wheel_device::trigger_w)) // Pin 6
PORT_BIT( 0xdc, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("WHEEL")
@@ -73,5 +73,5 @@ uint8_t vcs_wheel_device::vcs_joy_r()
{
static const uint8_t driving_lookup[4] = { 0x00, 0x02, 0x03, 0x01 };
- return m_joy->read() | driving_lookup[ ( m_wheel->read() & 0x18 ) >> 3 ];
+ return m_joy->read() | driving_lookup[BIT(m_wheel->read(), 3, 2)];
}
diff --git a/src/devices/bus/vcs_ctrl/wheel.h b/src/devices/bus/vcs_ctrl/wheel.h
index 369afe7c614..6981eaa6b63 100644
--- a/src/devices/bus/vcs_ctrl/wheel.h
+++ b/src/devices/bus/vcs_ctrl/wheel.h
@@ -28,15 +28,15 @@ public:
// construction/destruction
vcs_wheel_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- // optional information overrides
- virtual ioport_constructor device_input_ports() const override;
+ // device_vcs_control_port_interface overrides
+ virtual uint8_t vcs_joy_r() override;
protected:
// device-level overrides
- virtual void device_start() override;
+ virtual void device_start() override ATTR_COLD;
- // device_vcs_control_port_interface overrides
- virtual uint8_t vcs_joy_r() override;
+ // optional information overrides
+ virtual ioport_constructor device_input_ports() const override ATTR_COLD;
private:
required_ioport m_joy;