-astrocde: Slot-ified accessory port and added lightpen device. [Ryan Holtz]

This commit is contained in:
Ryan Holtz 2019-03-22 17:40:22 +01:00
parent 41f23bcc2b
commit 5a09b0feb2
7 changed files with 364 additions and 1 deletions

View File

@ -266,6 +266,10 @@ if (BUSES["ASTROCADE"]~=null) then
MAME_DIR .. "src/devices/bus/astrocde/joy.h",
MAME_DIR .. "src/devices/bus/astrocde/cassette.cpp",
MAME_DIR .. "src/devices/bus/astrocde/cassette.h",
MAME_DIR .. "src/devices/bus/astrocde/accessory.cpp",
MAME_DIR .. "src/devices/bus/astrocde/accessory.h",
MAME_DIR .. "src/devices/bus/astrocde/lightpen.cpp",
MAME_DIR .. "src/devices/bus/astrocde/lightpen.h",
}
end

View File

@ -0,0 +1,112 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#include "emu.h"
#include "accessory.h"
#include <cassert>
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE(ASTROCADE_ACCESSORY_PORT, astrocade_accessory_port_device, "astrocade_accessory_port", "Bally Astrocade Accessory Port")
//**************************************************************************
// Bally Astrocade accessory interface
//**************************************************************************
device_astrocade_accessory_interface::device_astrocade_accessory_interface(const machine_config &mconfig, device_t &device)
: device_slot_card_interface(mconfig, device)
, m_port(dynamic_cast<astrocade_accessory_port_device *>(device.owner()))
{
}
device_astrocade_accessory_interface::~device_astrocade_accessory_interface()
{
}
void device_astrocade_accessory_interface::interface_validity_check(validity_checker &valid) const
{
device_slot_card_interface::interface_validity_check(valid);
if (device().owner() && !m_port)
{
osd_printf_error("Owner device %s (%s) is not an astrocade_accessory_port_device\n", device().owner()->tag(), device().owner()->name());
}
}
void device_astrocade_accessory_interface::interface_pre_start()
{
device_slot_card_interface::interface_pre_start();
if (m_port && !m_port->started())
throw device_missing_dependencies();
}
//**************************************************************************
// Bally Astrocade accessory port
//**************************************************************************
astrocade_accessory_port_device::astrocade_accessory_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ASTROCADE_ACCESSORY_PORT, tag, owner, clock)
, device_slot_interface(mconfig, *this)
, m_ltpen(0)
, m_ltpen_handler(*this)
, m_screen(*this, finder_base::DUMMY_TAG)
, m_device(nullptr)
{
}
astrocade_accessory_port_device::~astrocade_accessory_port_device()
{
}
void astrocade_accessory_port_device::device_validity_check(validity_checker &valid) const
{
device_t *const card(get_card_device());
if (card && !dynamic_cast<device_astrocade_accessory_interface *>(card))
{
osd_printf_error("Card device %s (%s) does not implement device_astrocade_accessory_interface\n", card->tag(), card->name());
}
}
void astrocade_accessory_port_device::device_resolve_objects()
{
device_astrocade_accessory_interface *const card(dynamic_cast<device_astrocade_accessory_interface *>(get_card_device()));
if (card)
{
m_device = card;
m_device->set_screen(m_screen);
}
m_ltpen_handler.resolve_safe();
}
void astrocade_accessory_port_device::device_start()
{
device_t *const card(get_card_device());
if (card)
{
if (!m_device)
{
throw emu_fatalerror("astrocade_accessory_port_device: card device %s (%s) does not implement device_astrocade_accessory_interface\n", card->tag(), card->name());
}
}
save_item(NAME(m_ltpen));
m_ltpen = 0;
m_ltpen_handler(0);
}
#include "lightpen.h"
void astrocade_accessories(device_slot_interface &device)
{
device.option_add("lightpen", ASTROCADE_LIGHTPEN);
}

View File

@ -0,0 +1,99 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#ifndef MAME_BUS_ASTROCDE_ACCESSORY_H
#define MAME_BUS_ASTROCDE_ACCESSORY_H
#pragma once
#include "screen.h"
/***************************************************************************
FORWARD DECLARATIONS
***************************************************************************/
class device_astrocade_accessory_interface;
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
// ======================> astrocade_accessory_port_device
class astrocade_accessory_port_device : public device_t, public device_slot_interface
{
public:
// construction/destruction
template <typename T, typename U>
astrocade_accessory_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&screen_tag, U &&opts, char const *dflt)
: astrocade_accessory_port_device(mconfig, tag, owner, 0U)
{
m_screen.set_tag(std::forward<T>(screen_tag));
option_reset();
opts(*this);
set_default_option(dflt);
set_fixed(false);
}
astrocade_accessory_port_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U);
virtual ~astrocade_accessory_port_device();
auto ltpen_handler() { return m_ltpen_handler.bind(); }
protected:
// device_t implementation
virtual void device_validity_check(validity_checker &valid) const override ATTR_COLD;
virtual void device_resolve_objects() override;
virtual void device_start() override;
int m_ltpen;
devcb_write_line m_ltpen_handler;
required_device<screen_device> m_screen;
private:
device_astrocade_accessory_interface *m_device;
friend class device_astrocade_accessory_interface;
};
// ======================> device_astrocade_accessory_interface
class device_astrocade_accessory_interface : public device_slot_card_interface
{
public:
virtual ~device_astrocade_accessory_interface();
DECLARE_WRITE_LINE_MEMBER( write_ltpen ) { m_port->m_ltpen = state; m_port->m_ltpen_handler(state); }
protected:
device_astrocade_accessory_interface(machine_config const &mconfig, device_t &device);
// device_interface implementation
virtual void interface_validity_check(validity_checker &valid) const override ATTR_COLD;
virtual void interface_pre_start() override;
void set_screen(screen_device *screen) { m_screen = screen; }
screen_device *m_screen;
private:
astrocade_accessory_port_device *const m_port;
friend class astrocade_accessory_port_device;
};
/***************************************************************************
FUNCTIONS
***************************************************************************/
void astrocade_accessories(device_slot_interface &device);
/***************************************************************************
DEVICE TYPES
***************************************************************************/
DECLARE_DEVICE_TYPE(ASTROCADE_ACCESSORY_PORT, astrocade_accessory_port_device)
#endif // MAME_BUS_ASTROCDE_ACCESSORY_H

View File

@ -0,0 +1,87 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#include "emu.h"
#include "lightpen.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
DEFINE_DEVICE_TYPE(ASTROCADE_LIGHTPEN, astrocade_lightpen_device, "astrocade_lightpen", "Bally Astrocade Light Pen")
//**************************************************************************
// Bally Astrocade light pen input
//**************************************************************************
astrocade_lightpen_device::astrocade_lightpen_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, ASTROCADE_LIGHTPEN, tag, owner, clock)
, device_astrocade_accessory_interface(mconfig, *this)
, m_trigger(*this, "TRIGGER")
, m_lightx(*this, "LIGHTX")
, m_lighty(*this, "LIGHTY")
, m_pen_timer(nullptr)
{
}
astrocade_lightpen_device::~astrocade_lightpen_device()
{
}
void astrocade_lightpen_device::device_start()
{
m_pen_timer = timer_alloc(TIMER_TRIGGER);
save_item(NAME(m_retrigger));
}
void astrocade_lightpen_device::device_reset()
{
m_pen_timer->adjust(attotime::never);
m_retrigger = false;
}
void astrocade_lightpen_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (id == TIMER_TRIGGER)
{
write_ltpen(1);
write_ltpen(0);
if (m_retrigger)
m_pen_timer->adjust(m_screen->time_until_pos(m_lighty->read(), m_lightx->read()));
else
m_pen_timer->adjust(attotime::never);
}
}
INPUT_CHANGED_MEMBER( astrocade_lightpen_device::trigger )
{
if (newval)
{
m_retrigger = true;
m_pen_timer->adjust(m_screen->time_until_pos(m_lighty->read(), m_lightx->read()));
}
else
{
m_retrigger = false;
m_pen_timer->adjust(attotime::never);
}
}
static INPUT_PORTS_START( astrocade_lightpen )
PORT_START("TRIGGER")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_MEMBER(DEVICE_SELF, astrocade_lightpen_device, trigger, nullptr)
PORT_BIT( 0xfe, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_START("LIGHTX")
PORT_BIT(0x1ff, 0x000, IPT_LIGHTGUN_X) PORT_MINMAX(0x000, 0x15f) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
PORT_START("LIGHTY")
PORT_BIT(0x0ff, 0x000, IPT_LIGHTGUN_Y) PORT_MINMAX(0x000, 0x0f0) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(45) PORT_KEYDELTA(15)
INPUT_PORTS_END
ioport_constructor astrocade_lightpen_device::device_input_ports() const
{
return INPUT_PORTS_NAME( astrocade_lightpen );
}

View File

@ -0,0 +1,51 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#ifndef MAME_BUS_ASTROCDE_LIGHTPEN_H
#define MAME_BUS_ASTROCDE_LIGHTPEN_H
#pragma once
#include "accessory.h"
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
// ======================> astrocade_lightpen_device
class astrocade_lightpen_device : public device_t,
public device_astrocade_accessory_interface
{
public:
// construction/destruction
astrocade_lightpen_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0U);
virtual ~astrocade_lightpen_device();
DECLARE_INPUT_CHANGED_MEMBER( trigger );
protected:
// device_t implementation
virtual void device_start() override;
virtual void device_reset() override;
virtual ioport_constructor device_input_ports() const override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
static const device_timer_id TIMER_TRIGGER = 0;
private:
required_ioport m_trigger;
required_ioport m_lightx;
required_ioport m_lighty;
emu_timer *m_pen_timer;
bool m_retrigger;
};
/***************************************************************************
DEVICE TYPES
***************************************************************************/
DECLARE_DEVICE_TYPE(ASTROCADE_LIGHTPEN, astrocade_lightpen_device)
#endif // MAME_BUS_ASTROCDE_LIGHTPEN_H

View File

@ -18,6 +18,7 @@
#include "bus/astrocde/exp.h"
#include "bus/astrocde/ram.h"
#include "bus/astrocde/ctrl.h"
#include "bus/astrocde/accessory.h"
#include "softlist.h"
#include "speaker.h"
@ -31,6 +32,7 @@ public:
, m_cart(*this, "cartslot")
, m_exp(*this, "exp")
, m_ctrl(*this, "ctrl%u", 1U)
, m_accessory(*this, "accessory")
, m_keypad(*this, "KEYPAD%u", 0U)
{ }
@ -45,6 +47,7 @@ private:
required_device<astrocade_cart_slot_device> m_cart;
required_device<astrocade_exp_device> m_exp;
required_device_array<astrocade_ctrl_port_device, 4> m_ctrl;
required_device<astrocade_accessory_port_device> m_accessory;
required_ioport_array<4> m_keypad;
};
@ -216,6 +219,10 @@ void astrocde_home_state::astrocde(machine_config &config)
/* cartridge */
ASTROCADE_CART_SLOT(config, m_cart, astrocade_cart, nullptr);
/* cartridge */
ASTROCADE_ACCESSORY_PORT(config, m_accessory, m_screen, astrocade_accessories, nullptr);
m_accessory->ltpen_handler().set(FUNC(astrocde_home_state::lightpen_trigger_w));
/* Software lists */
SOFTWARE_LIST(config, "cart_list").set_original("astrocde");
}

View File

@ -398,7 +398,10 @@ void astrocde_state::device_timer(emu_timer &timer, device_timer_id id, int para
WRITE_LINE_MEMBER(astrocde_state::lightpen_trigger_w)
{
if (state)
astrocade_trigger_lightpen(m_screen->vpos(), m_screen->hpos());
{
uint8_t res_shift = 1 - m_video_mode;
astrocade_trigger_lightpen(mame_vpos_to_astrocade_vpos(m_screen->vpos()) & ~res_shift, (m_screen->hpos() >> res_shift) + 12);
}
}
void astrocde_state::astrocade_trigger_lightpen(uint8_t vfeedback, uint8_t hfeedback)