bbc: Added various pointer devices on userport:

- AMX Mouse
- Acorn Master 512 Mouse
- Marconi RB2 Tracker Ball
This commit is contained in:
Nigel Barnes 2018-05-04 12:41:01 +01:00
parent 0b17c32492
commit 1e76d5fd5e
4 changed files with 388 additions and 4 deletions

View File

@ -333,6 +333,8 @@ if (BUSES["BBC_USERPORT"]~=null) then
files {
MAME_DIR .. "src/devices/bus/bbc/userport/userport.cpp",
MAME_DIR .. "src/devices/bus/bbc/userport/userport.h",
MAME_DIR .. "src/devices/bus/bbc/userport/pointer.cpp",
MAME_DIR .. "src/devices/bus/bbc/userport/pointer.h",
MAME_DIR .. "src/devices/bus/bbc/userport/cfa3000kbd.cpp",
MAME_DIR .. "src/devices/bus/bbc/userport/cfa3000kbd.h",
}

View File

@ -0,0 +1,277 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
AMX Mouse
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/AMX_Mouse.html
Marconi RB2 Tracker Ball
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Marconi_MarcusRB2.html
http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Acorn_Trackerball.html
The Tracker Ball outputs are fed directly into the user port with the port defined as
an input. The CB1 and CB2 lines are used in conjunction with PB3 and PB4 for
sensing pulses and determining the direction of rotation of the ball.
The connections are:
CB1 X1
CB2 Y2
PB0 Left switch button
PB1 Middle switch button
PB2 Right switch button
PB3 X2
PB4 Y1
Quadrature implementation derived from SmallyMouse2,
see https://github.com/simoninns/SmallyMouse2
**********************************************************************/
#include "emu.h"
#include "pointer.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(BBC_AMXMOUSE, bbc_amxmouse_device, "bbc_amxmouse", "AMX Mouse (BBC Micro)")
DEFINE_DEVICE_TYPE(BBC_M512MOUSE, bbc_m512mouse_device, "bbc_m512mouse", "Acorn Master 512 Mouse")
DEFINE_DEVICE_TYPE(BBC_TRACKER, bbc_tracker_device, "bbc_tracker", "Marconi RB2 Tracker Ball")
//-------------------------------------------------
// INPUT_PORTS( amxmouse )
//-------------------------------------------------
static INPUT_PORTS_START( amxmouse )
PORT_START("POINTER_X")
PORT_BIT(0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_pointer_device, pointer_changed, 0) PORT_RESET
PORT_START("POINTER_Y")
PORT_BIT(0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_pointer_device, pointer_changed, 0) PORT_RESET
PORT_START("BUTTONS")
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Mouse Left Button (Execute)") PORT_CODE(MOUSECODE_BUTTON1)
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Mouse Middle Button (Move)") PORT_CODE(MOUSECODE_BUTTON3)
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Mouse Right Button (Cancel)") PORT_CODE(MOUSECODE_BUTTON2)
INPUT_PORTS_END
//-------------------------------------------------
// INPUT_PORTS( m512mouse )
//-------------------------------------------------
static INPUT_PORTS_START( m512mouse )
PORT_START("POINTER_X")
PORT_BIT(0xff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_pointer_device, pointer_changed, 0) PORT_RESET
PORT_START("POINTER_Y")
PORT_BIT(0xff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_pointer_device, pointer_changed, 0) PORT_RESET
PORT_START("BUTTONS")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Mouse Left Button") PORT_CODE(MOUSECODE_BUTTON1)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_UNUSED)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Mouse Right Button") PORT_CODE(MOUSECODE_BUTTON2)
INPUT_PORTS_END
//-------------------------------------------------
// INPUT_PORTS( tracker )
//-------------------------------------------------
static INPUT_PORTS_START( tracker )
PORT_START("POINTER_X")
PORT_BIT(0xff, 0x00, IPT_TRACKBALL_X) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_pointer_device, pointer_changed, 0) PORT_RESET
PORT_START("POINTER_Y")
PORT_BIT(0xff, 0x00, IPT_TRACKBALL_Y) PORT_SENSITIVITY(100) PORT_KEYDELTA(5) PORT_CHANGED_MEMBER(DEVICE_SELF, bbc_pointer_device, pointer_changed, 0) PORT_RESET
PORT_START("BUTTONS")
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Left Button") PORT_CODE(MOUSECODE_BUTTON1)
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON3) PORT_NAME("Middle Button") PORT_CODE(MOUSECODE_BUTTON3)
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON2) PORT_NAME("Right Button") PORT_CODE(MOUSECODE_BUTTON2)
INPUT_PORTS_END
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
ioport_constructor bbc_amxmouse_device::device_input_ports() const
{
return INPUT_PORTS_NAME( amxmouse );
}
ioport_constructor bbc_m512mouse_device::device_input_ports() const
{
return INPUT_PORTS_NAME( m512mouse );
}
ioport_constructor bbc_tracker_device::device_input_ports() const
{
return INPUT_PORTS_NAME( tracker );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// bbc_pointer_device - constructor
//-------------------------------------------------
bbc_pointer_device::bbc_pointer_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_bbc_userport_interface(mconfig, *this)
, m_pointer_x(*this, "POINTER_X")
, m_pointer_y(*this, "POINTER_Y")
, m_buttons(*this, "BUTTONS")
{
}
bbc_amxmouse_device::bbc_amxmouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bbc_pointer_device(mconfig, BBC_AMXMOUSE, tag, owner, clock)
{
}
bbc_m512mouse_device::bbc_m512mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bbc_pointer_device(mconfig, BBC_M512MOUSE, tag, owner, clock)
{
}
bbc_tracker_device::bbc_tracker_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: bbc_pointer_device(mconfig, BBC_TRACKER, tag, owner, clock)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void bbc_pointer_device::device_start()
{
m_pointer_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bbc_pointer_device::pointer_poll), this));
m_pointer_timer->adjust(attotime::zero, 0, attotime::from_hz(1400));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void bbc_pointer_device::device_reset()
{
m_xdir = 0;
m_ydir = 0;
m_direction_x = 0;
m_direction_y = 0;
m_distance_x = 0;
m_distance_y = 0;
m_phase_x = 0;
m_phase_y = 0;
}
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
INPUT_CHANGED_MEMBER(bbc_pointer_device::pointer_changed)
{
int x = m_pointer_x->read();
int y = m_pointer_y->read();
x -= (x & 0x80) ? 0x100 : 0;
y -= (y & 0x80) ? 0x100 : 0;
// Set the mouse movement direction and record the movement units
m_direction_x = (x > 0) ? 1 : 0;
m_distance_x = abs(x);
m_direction_y = (y > 0) ? 1 : 0;
m_distance_y = abs(y);
}
TIMER_CALLBACK_MEMBER(bbc_pointer_device::pointer_poll)
{
// Process X output
if (m_distance_x)
{
// 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 (m_direction_x == 0)
m_phase_x--;
else
m_phase_x++;
// Decrement the distance left to move
m_distance_x--;
// Range check the phase
m_phase_x &= 3;
}
// Process Y output
if (m_distance_y)
{
// 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 (m_direction_y == 0)
m_phase_y--;
else
m_phase_y++;
// Decrement the distance left to move
m_distance_y--;
// Range check the phase
m_phase_y &= 3;
}
}
READ8_MEMBER(bbc_amxmouse_device::pb_r)
{
return (m_buttons->read() & 0xe0) | (m_xdir << 0) | (m_ydir << 2) | 0x1a;
}
READ8_MEMBER(bbc_m512mouse_device::pb_r)
{
return (m_buttons->read() & 0x07) | (m_xdir << 3) | (m_ydir << 4) | 0xe0;
}
READ8_MEMBER(bbc_tracker_device::pb_r)
{
return (m_buttons->read() & 0x07) | (m_xdir << 3) | (m_ydir << 4) | 0xe0;
}

View File

@ -0,0 +1,104 @@
// license:BSD-3-Clause
// copyright-holders:Nigel Barnes
/**********************************************************************
Mouse emulation
**********************************************************************/
#ifndef MAME_BUS_BBC_USERPORT_POINTER_H
#define MAME_BUS_BBC_USERPORT_POINTER_H
#pragma once
#include "userport.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class bbc_pointer_device :
public device_t,
public device_bbc_userport_interface
{
public:
DECLARE_INPUT_CHANGED_MEMBER(pointer_changed);
protected:
// construction/destruction
bbc_pointer_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
required_ioport m_pointer_x;
required_ioport m_pointer_y;
required_ioport m_buttons;
// quadrature output
int m_xdir, m_ydir;
// internal quadrature state
int m_direction_x, m_direction_y;
int m_distance_x, m_distance_y;
int m_phase_x, m_phase_y;
TIMER_CALLBACK_MEMBER(pointer_poll);
emu_timer *m_pointer_timer;
};
// ======================> bbc_amxmouse_device
class bbc_amxmouse_device : public bbc_pointer_device
{
public:
// construction/destruction
bbc_amxmouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(pb_r) override;
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
};
// ======================> bbc_m512mouse_device
class bbc_m512mouse_device : public bbc_pointer_device
{
public:
// construction/destruction
bbc_m512mouse_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(pb_r) override;
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
};
// ======================> bbc_tracker_device
class bbc_tracker_device : public bbc_pointer_device
{
public:
// construction/destruction
bbc_tracker_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
DECLARE_READ8_MEMBER(pb_r) override;
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
};
// device type definition
DECLARE_DEVICE_TYPE(BBC_AMXMOUSE, bbc_amxmouse_device)
DECLARE_DEVICE_TYPE(BBC_M512MOUSE, bbc_m512mouse_device)
DECLARE_DEVICE_TYPE(BBC_TRACKER, bbc_tracker_device)
#endif // MAME_BUS_BBC_USERPORT_POINTER_H

View File

@ -115,15 +115,16 @@ WRITE8_MEMBER(bbc_userport_slot_device::pb_w)
// slot devices
//#include "mouse.h"
#include "pointer.h"
#include "cfa3000kbd.h"
void bbc_userport_devices(device_slot_interface &device)
{
// device.option_add("amxmouse", BBC_AMXMOUSE); /* AMX Mouse */
// device.option_add("m512mouse", BBC_M512MOUSE); /* Acorn Mouse (provided with Master 512) */
// device.option_add("tracker", BBC_TRACKER); /* Marconi RB2 Tracker Ball / Acorn Tracker Ball */
device.option_add("amxmouse", BBC_AMXMOUSE); /* AMX Mouse */
// device.option_add("beebsynth", BBC_BEEBSYNTH); /* Beeb Speech Synthesiser (Watford) */
device.option_add("m512mouse", BBC_M512MOUSE); /* Acorn Mouse (provided with Master 512) */
device.option_add("tracker", BBC_TRACKER); /* Marconi RB2 Tracker Ball / Acorn Tracker Ball */
// device.option_add("music4000", BBC_MUSIC4000); /* Hybrid Music 4000 Keyboard */
device.option_add("cfa3000kbd", CFA3000_KBD); /* Henson CFA 3000 Keyboard */
}