Allow devcb to be bound to a device/mixin or the target of a device

finder.  This works outside machine configuration context so the
workarounds in ATA HLE and MSX slots are no longer necessary.  It also
allows reduction in tag repetition in machine configuration (see
converted osborne1.cpp, zorba.cpp or the more extreme tranz330.cpp).

Allow reimagined device instantiation to take a device finder based on
current device being configured to reduce repetition (see tranz330.cpp).
This commit is contained in:
Vas Crabb 2018-05-02 14:43:01 +10:00
parent 7c8d486909
commit 8795d80808
27 changed files with 426 additions and 264 deletions

View File

@ -44,8 +44,8 @@ public:
virtual ~epson_sio_device();
// callbacks
template<class _rx> devcb_base &set_rx_callback(_rx rx) { return m_write_rx.set_callback(rx); }
template<class _pin> devcb_base &set_pin_callback(_pin pin) { return m_write_pin.set_callback(pin); }
template <class Object> devcb_base &set_rx_callback(Object &&rx) { return m_write_rx.set_callback(std::forward<Object>(rx)); }
template <class Object> devcb_base &set_pin_callback(Object &&pin) { return m_write_pin.set_callback(std::forward<Object>(pin)); }
// called from owner
DECLARE_WRITE_LINE_MEMBER( tx_w );

View File

@ -169,11 +169,7 @@ image_init_result msx_slot_cartridge_device::call_load()
}
}
// FIXME: do this is a less horrid way
{
machine_config::token const tok(const_cast<machine_config &>(mconfig()).begin_configuration(*this));
m_cartridge->set_out_irq_cb(DEVCB_WRITELINE(msx_slot_cartridge_device, irq_out));
}
m_cartridge->set_out_irq_cb(DEVCB_DEVWRITELINE(*this, msx_slot_cartridge_device, irq_out));
m_cartridge->initialize_cartridge();
if (m_cartridge->get_sram_size() > 0)
@ -367,9 +363,5 @@ void msx_slot_yamaha_expansion_device::device_start()
m_irq_handler.resolve_safe();
m_cartridge = dynamic_cast<msx_cart_interface *>(get_card_device());
if (m_cartridge)
{
// FIXME: do this is a less horrid way
machine_config::token const tok(const_cast<machine_config &>(mconfig()).begin_configuration(*this));
m_cartridge->set_out_irq_cb(DEVCB_WRITELINE(msx_slot_cartridge_device, irq_out));
}
m_cartridge->set_out_irq_cb(DEVCB_DEVWRITELINE(*this, msx_slot_cartridge_device, irq_out));
}

View File

@ -37,9 +37,9 @@ void msx_slot_rom_device::device_start()
READ8_MEMBER(msx_slot_rom_device::read)
{
if ( offset >= m_start_address && offset < m_end_address )
if (offset >= m_start_address && offset < m_end_address)
{
return m_rom[ offset - m_start_address ];
return m_rom[offset - m_start_address];
}
return 0xFF;
}

View File

@ -54,9 +54,9 @@ public:
pet_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ~pet_expansion_slot_device();
template<class _read, class _write> void set_callbacks(_read rd, _write wr) {
m_read_dma.set_callback(rd);
m_write_dma.set_callback(wr);
template <class Read, class Write> void set_callbacks(Read &&rd, Write &&wr) {
m_read_dma.set_callback(std::forward<Read>(rd));
m_write_dma.set_callback(std::forward<Write>(wr));
}
// computer interface

View File

@ -72,7 +72,7 @@ public:
// construction/destruction
vip_byteio_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _inst> void set_inst_callback(_inst inst) { m_write_inst.set_callback(inst); }
template <class Object> void set_inst_callback(Object &&inst) { m_write_inst.set_callback(std::forward<Object>(inst)); }
// computer interface
uint8_t in_r();

View File

@ -62,44 +62,44 @@ public:
const address_space_config m_program_config;
template<class _read, class _write> void set_p3_callbacks(_read rd, _write wr)
template <class Read, class Write> void set_p3_callbacks(Read &&rd, Write &&wr)
{
read_p3.set_callback(rd);
write_p3.set_callback(wr);
read_p3.set_callback(std::forward<Read>(rd));
write_p3.set_callback(std::forward<Write>(wr));
}
template<class _read, class _write> void set_p4_callbacks(_read rd, _write wr)
template <class Read, class Write> void set_p4_callbacks(Read &&rd, Write &&wr)
{
read_p4.set_callback(rd);
write_p4.set_callback(wr);
read_p4.set_callback(std::forward<Read>(rd));
write_p4.set_callback(std::forward<Write>(wr));
}
template<class _read, class _write> void set_p5_callbacks(_read rd, _write wr)
template <class Read, class Write> void set_p5_callbacks(Read &&rd, Write &&wr)
{
read_p5.set_callback(rd);
write_p5.set_callback(wr);
read_p5.set_callback(std::forward<Read>(rd));
write_p5.set_callback(std::forward<Write>(wr));
}
template<class _read, class _write> void set_p6_callbacks(_read rd, _write wr)
template <class Read, class Write> void set_p6_callbacks(Read &&rd, Write &&wr)
{
read_p6.set_callback(rd);
write_p6.set_callback(wr);
read_p6.set_callback(std::forward<Read>(rd));
write_p6.set_callback(std::forward<Write>(wr));
}
template<class _read, class _read2, class _read3, class _read4> void set_ad14_callbacks(_read rd, _read2 rd2, _read3 rd3, _read4 rd4)
template <class Read, class Read2, class Read3, class Read4> void set_ad14_callbacks(Read &&rd, Read2 &&rd2, Read3 &&rd3, Read4 &&rd4)
{
read_ad_0.set_callback(rd);
read_ad_1.set_callback(rd2);
read_ad_2.set_callback(rd3);
read_ad_3.set_callback(rd4);
read_ad_0.set_callback(std::forward<Read>(rd));
read_ad_1.set_callback(std::forward<Read2>(rd2));
read_ad_2.set_callback(std::forward<Read3>(rd3));
read_ad_3.set_callback(std::forward<Read4>(rd4));
}
template<class _read, class _read2, class _read3, class _read4> void set_ad58_callbacks(_read rd, _read2 rd2, _read3 rd3, _read4 rd4)
template <class Read, class Read2, class Read3, class Read4> void set_ad58_callbacks(Read &&rd, Read2 &&rd2, Read3 &&rd3, Read4 &&rd4)
{
read_ad_4.set_callback(rd);
read_ad_5.set_callback(rd2);
read_ad_6.set_callback(rd3);
read_ad_7.set_callback(rd4);
read_ad_4.set_callback(std::forward<Read>(rd));
read_ad_5.set_callback(std::forward<Read2>(rd2));
read_ad_6.set_callback(std::forward<Read3>(rd3));
read_ad_7.set_callback(std::forward<Read4>(rd4));
}
devcb_read8 read_p3, read_p4, read_p5, read_p6;

View File

@ -27,9 +27,9 @@ public:
uint8_t get_port();
void set_pulls(uint8_t pullup, uint8_t pulldown);
template<class _read, class _write> void set_callbacks(_read rd, _write wr) {
read_port.set_callback(rd);
write_port.set_callback(wr);
template <class Read, class Write> void set_callbacks(Read &&rd, Write &&wr) {
read_port.set_callback(std::forward<Read>(rd));
write_port.set_callback(std::forward<Write>(wr));
}
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;

View File

@ -30,7 +30,7 @@ public:
// construction/destruction
midiin_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _Object> devcb_base &set_input_callback(_Object object) { return m_input_cb.set_callback(object); }
template <class Object> devcb_base &set_input_callback(Object &&cb) { return m_input_cb.set_callback(std::forward<Object>(cb)); }
// image-level overrides
virtual image_init_result call_load() override;

View File

@ -29,7 +29,7 @@ public:
// construction/destruction
printer_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _Object> devcb_base &set_online_callback(_Object object) { return m_online_cb.set_callback(object); }
template <class Object> devcb_base &set_online_callback(Object &&cb) { return m_online_cb.set_callback(std::forward<Object>(cb)); }
// image-level overrides
virtual image_init_result call_load() override;

View File

@ -248,21 +248,19 @@ void abstract_ata_interface_device::device_start()
device_ata_interface *dev = m_slot[i]->dev();
if (dev)
{
// FIXME: the const_cast is nasty, need a better way that bypasses the tag lookup
machine_config::token const tok(const_cast<machine_config &>(mconfig()).begin_configuration(*this));
if (i == 0)
{
dev->m_irq_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, irq0_write_line));
dev->m_dmarq_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, dmarq0_write_line));
dev->m_dasp_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, dasp0_write_line));
dev->m_pdiag_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, pdiag0_write_line));
dev->m_irq_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, irq0_write_line));
dev->m_dmarq_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, dmarq0_write_line));
dev->m_dasp_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, dasp0_write_line));
dev->m_pdiag_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, pdiag0_write_line));
}
else
{
dev->m_irq_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, irq1_write_line));
dev->m_dmarq_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, dmarq1_write_line));
dev->m_dasp_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, dasp1_write_line));
dev->m_pdiag_handler.set_callback(DEVCB_WRITELINE(abstract_ata_interface_device, pdiag1_write_line));
dev->m_irq_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, irq1_write_line));
dev->m_dmarq_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, dmarq1_write_line));
dev->m_dasp_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, dasp1_write_line));
dev->m_pdiag_handler.set_callback(DEVCB_DEVWRITELINE(*this, abstract_ata_interface_device, pdiag1_write_line));
}
dev->write_csel(i);

View File

@ -76,9 +76,9 @@ template<typename T> void generic_fifo_device_base<T>::device_timer(emu_timer &t
// Adjust devcb lines as needed
if(was_empty && !is_empty())
set_empty_cb(false);
m_empty_cb(false);
if(!was_full && is_full())
set_full_cb(true);
m_full_cb(true);
// Are there still values that don't fit?
if(!m_extra_values.empty()) {

View File

@ -18,53 +18,125 @@
#define MAME_EMU_DEVCB_H
#include <functional>
#include <type_traits>
#include <utility>
namespace emu { namespace detail {
template <typename Delegate> struct devcb_delegate_initialiser
{
template <typename T> struct is_device_implementation
{ static constexpr bool value = std::is_base_of<device_t, T>::value; };
template <typename T> struct is_device_interface
{ static constexpr bool value = std::is_base_of<device_interface, T>::value && !is_device_implementation<T>::value; };
devcb_delegate_initialiser(char const *tag, Delegate &&delegate) : m_base(nullptr), m_delegate(std::move(delegate))
{
}
template <typename T>
devcb_delegate_initialiser(T &device, std::enable_if_t<is_device_implementation<T>::value, Delegate &&> delegate) : m_base(&device), m_delegate(std::move(delegate))
{
}
template <typename T>
devcb_delegate_initialiser(T &interface, std::enable_if_t<is_device_interface<T>::value, Delegate &&> delegate) : m_base(&interface.device()), m_delegate(std::move(delegate))
{
}
template <typename DeviceClass, bool Required>
devcb_delegate_initialiser(device_finder<DeviceClass, Required> const &finder, Delegate &&delegate) : m_base(&finder.finder_target().first), m_delegate(std::move(delegate))
{
}
device_t *m_base;
Delegate &&m_delegate;
};
inline char const *devcb_delegate_get_tag(char const *tag) { return tag; }
template <typename T>
inline std::enable_if_t<devcb_delegate_initialiser<bool>::is_device_implementation<T>::value, char const *> devcb_delegate_get_tag(T &device) { return DEVICE_SELF; }
template <typename T>
inline std::enable_if_t<devcb_delegate_initialiser<bool>::is_device_interface<T>::value, char const *> devcb_delegate_get_tag(T &interface) { return DEVICE_SELF; }
template <typename DeviceClass, bool Required>
inline char const *devcb_delegate_get_tag(device_finder<DeviceClass, Required> const &finder) { return finder.finder_tag(); }
template <typename DescType> struct devcb_tag_desc_creator
{
static DescType create(char const *tag)
{
return DescType{ nullptr, tag };
}
static DescType create(device_t &device)
{
return DescType{ &device, DEVICE_SELF };
}
static DescType create(device_interface &interface)
{
return DescType{ &interface.device(), DEVICE_SELF };
}
template <typename DeviceClass, bool Required>
static DescType create(device_finder<DeviceClass, Required> const &finder)
{
std::pair<device_t &, char const *> const target(finder.finder_target());
return DescType{ &target.first, target.second };
}
};
template <typename DescType> struct devcb_line_desc_creator
{
static DescType create(char const *tag, int inputnum)
{
return DescType{ nullptr, tag, inputnum };
}
static DescType create(device_t &device, int inputnum)
{
return DescType{ &device, DEVICE_SELF, inputnum };
}
static DescType create(device_interface &interface, int inputnum)
{
return DescType{ &interface.device(), DEVICE_SELF, inputnum };
}
template <typename DeviceClass, bool Required>
static DescType create(device_finder<DeviceClass, Required> const &finder, int inputnum)
{
std::pair<device_t &, char const *> const target(finder.finder_target());
return DescType{ &target.first, target.second, inputnum };
}
};
} } // namespace emu::detail
//**************************************************************************
// MACROS
//**************************************************************************
// wrappers for ioports, constants, and loggers
#define DEVCB_NOOP devcb_base::null_desc()
#define DEVCB_IOPORT(_tag) devcb_base::ioport_desc(_tag)
#define DEVCB_MEMBANK(_tag) devcb_base::membank_desc(_tag)
#define DEVCB_OUTPUT(_tag) devcb_base::output_desc(_tag)
#define DEVCB_CONSTANT(_value) devcb_base::constant_desc(_value)
#define DEVCB_LOGGER(_string) devcb_base::logger_desc(_string)
#define DEVCB_INPUTLINE(_tag, _line) devcb_base::inputline_desc(_tag, _line)
#define DEVCB_ASSERTLINE(_tag, _line) devcb_base::assertline_desc(_tag, _line)
#define DEVCB_CLEARLINE(_tag, _line) devcb_base::clearline_desc(_tag, _line)
#define DEVCB_HOLDLINE(_tag, _line) devcb_base::holdline_desc(_tag, _line)
#define DEVCB_VCC DEVCB_CONSTANT(1)
#define DEVCB_GND DEVCB_CONSTANT(0)
// wrappers for read callbacks into the owner device
#define DEVCB_READLINE(_class, _func) read_line_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_READ8(_class, _func) read8_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_READ16(_class, _func) read16_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_READ32(_class, _func) read32_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_READ64(_class, _func) read64_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_READLINE(_class, _func) (emu::detail::devcb_delegate_initialiser<read_line_delegate>(DEVICE_SELF, read_line_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_READ8(_class, _func) (emu::detail::devcb_delegate_initialiser<read8_delegate>(DEVICE_SELF, read8_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_READ16(_class, _func) (emu::detail::devcb_delegate_initialiser<read16_delegate>(DEVICE_SELF, read16_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_READ32(_class, _func) (emu::detail::devcb_delegate_initialiser<read32_delegate>(DEVICE_SELF, read32_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_READ64(_class, _func) (emu::detail::devcb_delegate_initialiser<read64_delegate>(DEVICE_SELF, read64_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
// wrappers for read callbacks into any tagged device
#define DEVCB_DEVREADLINE(tag, _class, _func) read_line_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVREAD8(tag, _class, _func) read8_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVREAD16(tag, _class, _func) read16_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVREAD32(tag, _class, _func) read32_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVREAD64(tag, _class, _func) read64_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVREADLINE(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<read_line_delegate>((tag), read_line_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVREAD8(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<read8_delegate>((tag), read8_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVREAD16(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<read16_delegate>((tag), read16_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVREAD32(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<read32_delegate>((tag), read32_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVREAD64(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<read64_delegate>((tag), read64_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
// wrappers for write callbacks into the owner device
#define DEVCB_WRITELINE(_class, _func) write_line_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_WRITE8(_class, _func) write8_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_WRITE16(_class, _func) write16_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_WRITE32(_class, _func) write32_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_WRITE64(_class, _func) write64_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)
#define DEVCB_WRITELINE(_class, _func) (emu::detail::devcb_delegate_initialiser<write_line_delegate>(DEVICE_SELF, write_line_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_WRITE8(_class, _func) (emu::detail::devcb_delegate_initialiser<write8_delegate>(DEVICE_SELF, write8_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_WRITE16(_class, _func) (emu::detail::devcb_delegate_initialiser<write16_delegate>(DEVICE_SELF, write16_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_WRITE32(_class, _func) (emu::detail::devcb_delegate_initialiser<write32_delegate>(DEVICE_SELF, write32_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
#define DEVCB_WRITE64(_class, _func) (emu::detail::devcb_delegate_initialiser<write64_delegate>(DEVICE_SELF, write64_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr)))
// wrappers for write callbacks into any tagged device
#define DEVCB_DEVWRITELINE(tag, _class, _func) write_line_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVWRITE8(tag, _class, _func) write8_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVWRITE16(tag, _class, _func) write16_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVWRITE32(tag, _class, _func) write32_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVWRITE64(tag, _class, _func) write64_delegate(&_class::_func, #_class "::" #_func, tag, (_class *)nullptr)
#define DEVCB_DEVWRITELINE(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<write_line_delegate>((tag), write_line_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVWRITE8(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<write8_delegate>((tag), write8_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVWRITE16(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<write16_delegate>((tag), write16_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVWRITE32(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<write32_delegate>((tag), write32_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
#define DEVCB_DEVWRITE64(tag, _class, _func) (emu::detail::devcb_delegate_initialiser<write64_delegate>((tag), write64_delegate(&_class::_func, #_class "::" #_func, emu::detail::devcb_delegate_get_tag(tag), (_class *)nullptr)))
// machine config helpers to add shift, mask, or address space configuration
#define MCFG_DEVCB_RSHIFT(_shift) devcb->set_rshift(_shift);
@ -117,6 +189,21 @@ protected:
devcb_base(device_t &device, u64 defmask);
virtual ~devcb_base();
template <callback_type Type> struct tag_desc
{
constexpr tag_desc(device_t *base, char const *tag) : m_base(base), m_tag(tag) { }
device_t *m_base;
char const *m_tag;
};
template <callback_type Type> struct line_desc
{
constexpr line_desc(device_t *base, char const *tag, int inputnum) : m_base(base), m_tag(tag), m_inputnum(inputnum) { }
device_t *m_base;
char const *m_tag;
int m_inputnum;
};
public:
// getters
bool isnull() const { return (m_type == CALLBACK_NONE); }
@ -128,84 +215,38 @@ public:
devcb_base &set_xor(u64 xorval) { m_xor = xorval; return *this; }
// construction helper classes
class null_desc
struct null_desc
{
public:
null_desc() { }
};
class ioport_desc
{
public:
ioport_desc(const char *tag) { m_tag = tag; }
const char *m_tag;
};
using ioport_desc = tag_desc<CALLBACK_IOPORT>;
using membank_desc = tag_desc<CALLBACK_MEMBANK>;
using output_desc = tag_desc<CALLBACK_OUTPUT>;
class membank_desc
struct constant_desc
{
public:
membank_desc(const char *tag) { m_tag = tag; }
const char *m_tag;
};
class output_desc
{
public:
output_desc(const char *tag) { m_tag = tag; }
const char *m_tag;
};
class constant_desc
{
public:
constant_desc(u64 value) { m_value = value; }
u64 m_value;
};
class logger_desc
struct logger_desc
{
public:
logger_desc(const char *string) { m_string = string; }
const char *m_string;
};
class inputline_desc
{
public:
inputline_desc(const char *tag, int inputnum) { m_tag = tag; m_inputnum = inputnum; }
const char *m_tag;
int m_inputnum;
};
class assertline_desc
{
public:
assertline_desc(const char *tag, int inputnum) { m_tag = tag; m_inputnum = inputnum; }
const char *m_tag;
int m_inputnum;
};
class clearline_desc
{
public:
clearline_desc(const char *tag, int inputnum) { m_tag = tag; m_inputnum = inputnum; }
const char *m_tag;
int m_inputnum;
};
class holdline_desc
{
public:
holdline_desc(const char *tag, int inputnum) { m_tag = tag; m_inputnum = inputnum; }
const char *m_tag;
int m_inputnum;
};
using inputline_desc = line_desc<CALLBACK_INPUTLINE>;
using assertline_desc = line_desc<CALLBACK_ASSERTLINE>;
using clearline_desc = line_desc<CALLBACK_CLEARLINE>;
using holdline_desc = line_desc<CALLBACK_HOLDLINE>;
// shared callback setters
devcb_base &set_callback(null_desc null) { reset(CALLBACK_NONE); return *this; }
devcb_base &set_callback(ioport_desc ioport) { reset(CALLBACK_IOPORT); m_target_tag = ioport.m_tag; return *this; }
devcb_base &set_callback(membank_desc membank) { reset(CALLBACK_MEMBANK); m_target_tag = membank.m_tag; return *this; }
devcb_base &set_callback(output_desc output) { reset(CALLBACK_OUTPUT); m_target_tag = output.m_tag; return *this; }
template <callback_type Type> devcb_base &set_callback(tag_desc<Type> desc)
{
if (desc.m_base) reset(*desc.m_base, Type);
else reset(Type);
m_target_tag = desc.m_tag;
return *this;
}
devcb_base &set_callback(constant_desc constant) { reset(CALLBACK_CONSTANT); m_target_int = constant.m_value; return *this; }
devcb_base &set_callback(logger_desc logger) { reset(CALLBACK_LOG); m_target_tag = logger.m_string; return *this; }
void reset() { reset(m_owner, CALLBACK_NONE); }
@ -262,14 +303,52 @@ protected:
// construction/destruction
devcb_read_base(device_t &device, u64 defmask, bool chained = false);
template <typename Delegate, typename Dummy> struct set_helper
{
static constexpr bool valid = false;
};
template <typename Dummy> struct set_helper<read_line_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_LINE;
static void apply(devcb_read_base &devcb, read_line_delegate &&delegate) { devcb.m_readline = std::move(delegate); }
};
template <typename Dummy> struct set_helper<read8_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_8;
static void apply(devcb_read_base &devcb, read8_delegate &&delegate) { devcb.m_read8 = std::move(delegate); }
};
template <typename Dummy> struct set_helper<read16_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_16;
static void apply(devcb_read_base &devcb, read16_delegate &&delegate) { devcb.m_read16 = std::move(delegate); }
};
template <typename Dummy> struct set_helper<read32_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_32;
static void apply(devcb_read_base &devcb, read32_delegate &&delegate) { devcb.m_read32 = std::move(delegate); }
};
template <typename Dummy> struct set_helper<read64_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_64;
static void apply(devcb_read_base &devcb, read64_delegate &&delegate) { devcb.m_read64 = std::move(delegate); }
};
public:
// callback configuration
using devcb_base::set_callback;
devcb_base &set_callback(read_line_delegate func) { reset(CALLBACK_LINE); m_readline = func; return *this; }
devcb_base &set_callback(read8_delegate func) { reset(CALLBACK_8); m_read8 = func; return *this; }
devcb_base &set_callback(read16_delegate func) { reset(CALLBACK_16); m_read16 = func; return *this; }
devcb_base &set_callback(read32_delegate func) { reset(CALLBACK_32); m_read32 = func; return *this; }
devcb_base &set_callback(read64_delegate func) { reset(CALLBACK_64); m_read64 = func; return *this; }
template <typename Delegate>
std::enable_if_t<set_helper<Delegate, void>::valid, devcb_base &> set_callback(emu::detail::devcb_delegate_initialiser<Delegate> &&desc)
{
if (desc.m_base) reset(*desc.m_base, set_helper<Delegate, void>::type);
else reset(set_helper<Delegate, void>::type);
set_helper<Delegate, void>::apply(*this, std::move(desc.m_delegate));
return *this;
}
devcb_read_base &chain_alloc();
// resolution
@ -318,18 +397,60 @@ protected:
// construction/destruction
devcb_write_base(device_t &device, u64 defmask, bool chained = false);
template <typename Delegate, typename Dummy> struct set_helper
{
static constexpr bool valid = false;
};
template <typename Dummy> struct set_helper<write_line_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_LINE;
static void apply(devcb_write_base &devcb, write_line_delegate &&delegate) { devcb.m_writeline = std::move(delegate); }
};
template <typename Dummy> struct set_helper<write8_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_8;
static void apply(devcb_write_base &devcb, write8_delegate &&delegate) { devcb.m_write8 = std::move(delegate); }
};
template <typename Dummy> struct set_helper<write16_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_16;
static void apply(devcb_write_base &devcb, write16_delegate &&delegate) { devcb.m_write16 = std::move(delegate); }
};
template <typename Dummy> struct set_helper<write32_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_32;
static void apply(devcb_write_base &devcb, write32_delegate &&delegate) { devcb.m_write32 = std::move(delegate); }
};
template <typename Dummy> struct set_helper<write64_delegate, Dummy>
{
static constexpr bool valid = true;
static constexpr callback_type type = CALLBACK_64;
static void apply(devcb_write_base &devcb, write64_delegate &&delegate) { devcb.m_write64 = std::move(delegate); }
};
public:
// callback configuration
using devcb_base::set_callback;
devcb_base &set_callback(write_line_delegate func) { reset(CALLBACK_LINE); m_writeline = func; return *this; }
devcb_base &set_callback(write8_delegate func) { reset(CALLBACK_8); m_write8 = func; return *this; }
devcb_base &set_callback(write16_delegate func) { reset(CALLBACK_16); m_write16 = func; return *this; }
devcb_base &set_callback(write32_delegate func) { reset(CALLBACK_32); m_write32 = func; return *this; }
devcb_base &set_callback(write64_delegate func) { reset(CALLBACK_64); m_write64 = func; return *this; }
devcb_base &set_callback(inputline_desc inputline) { reset(CALLBACK_INPUTLINE); m_target_tag = inputline.m_tag; m_target_int = inputline.m_inputnum; return *this; }
devcb_base &set_callback(assertline_desc inputline) { reset(CALLBACK_ASSERTLINE); m_target_tag = inputline.m_tag; m_target_int = inputline.m_inputnum; return *this; }
devcb_base &set_callback(clearline_desc inputline) { reset(CALLBACK_CLEARLINE); m_target_tag = inputline.m_tag; m_target_int = inputline.m_inputnum; return *this; }
devcb_base &set_callback(holdline_desc inputline) { reset(CALLBACK_HOLDLINE); m_target_tag = inputline.m_tag; m_target_int = inputline.m_inputnum; return *this; }
template <typename Delegate>
std::enable_if_t<set_helper<Delegate, void>::valid, devcb_base &> set_callback(emu::detail::devcb_delegate_initialiser<Delegate> &&desc)
{
if (desc.m_base) reset(*desc.m_base, set_helper<Delegate, void>::type);
else reset(set_helper<Delegate, void>::type);
set_helper<Delegate, void>::apply(*this, std::move(desc.m_delegate));
return *this;
}
template <callback_type Type> devcb_base &set_callback(line_desc<Type> desc)
{
if (desc.m_base) reset(*desc.m_base, Type);
else reset(Type);
m_target_tag = desc.m_tag;
m_target_int = desc.m_inputnum;
return *this;
}
devcb_write_base &chain_alloc();
// resolution
@ -520,4 +641,21 @@ inline void devcb_write_base::write(address_space &space, offs_t offset, u64 dat
}
#endif /* MAME_EMU_DEVCB_H */
//-------------------------------------------------
// wrappers for ioports, constants, and loggers
//-------------------------------------------------
#define DEVCB_NOOP devcb_base::null_desc{ }
template <typename... Params> inline devcb_base::ioport_desc DEVCB_IOPORT(Params &&... args) { return emu::detail::devcb_tag_desc_creator<devcb_base::ioport_desc>::create(std::forward<Params>(args)...); }
template <typename... Params> inline devcb_base::membank_desc DEVCB_MEMBANK(Params &&... args) { return emu::detail::devcb_tag_desc_creator<devcb_base::membank_desc>::create(std::forward<Params>(args)...); }
template <typename... Params> inline devcb_base::output_desc DEVCB_OUTPUT(Params &&... args) { return emu::detail::devcb_tag_desc_creator<devcb_base::output_desc>::create(std::forward<Params>(args)...); }
inline devcb_base::constant_desc DEVCB_CONSTANT(u64 value) { return devcb_base::constant_desc{ value }; }
inline devcb_base::logger_desc DEVCB_LOGGER(char const *string) { return devcb_base::logger_desc{ string }; }
template <typename... Params> inline devcb_base::inputline_desc DEVCB_INPUTLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator<devcb_base::inputline_desc>::create(std::forward<Params>(args)...); }
template <typename... Params> inline devcb_base::assertline_desc DEVCB_ASSERTLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator<devcb_base::assertline_desc>::create(std::forward<Params>(args)...); }
template <typename... Params> inline devcb_base::clearline_desc DEVCB_CLEARLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator<devcb_base::clearline_desc>::create(std::forward<Params>(args)...); }
template <typename... Params> inline devcb_base::holdline_desc DEVCB_HOLDLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator<devcb_base::holdline_desc>::create(std::forward<Params>(args)...); }
#define DEVCB_VCC DEVCB_CONSTANT(1)
#define DEVCB_GND DEVCB_CONSTANT(0)
#endif // MAME_EMU_DEVCB_H

View File

@ -39,24 +39,30 @@ protected:
// ======================> named_delegate
template<typename _Signature>
class named_delegate : public delegate<_Signature>
template <typename Signature>
class named_delegate : public delegate<Signature>
{
typedef delegate<_Signature> basetype;
protected:
using basetype = delegate<Signature>;
template <class FunctionClass> using member_func_type = typename basetype::template traits<FunctionClass>::member_func_type;
template <class FunctionClass> using const_member_func_type = typename basetype::template traits<FunctionClass>::const_member_func_type;
template <class FunctionClass> using static_func_type = typename basetype::template traits<FunctionClass>::static_func_type;
template <class FunctionClass> using static_ref_func_type = typename basetype::template traits<FunctionClass>::static_ref_func_type;
public:
// create a standard set of constructors
named_delegate() : basetype(), m_name(nullptr) { }
explicit named_delegate(const basetype &src) : basetype(src), m_name(src.m_name) { }
named_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), m_name(src.m_name) { }
template<class _FunctionClass> named_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
template<class _FunctionClass> named_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
explicit named_delegate(std::function<_Signature> funcptr, const char *name) : basetype(funcptr), m_name(name) { }
template<class _FunctionClass> named_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
template<class _FunctionClass> named_delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
named_delegate &operator=(const basetype &src) { *static_cast<basetype *>(this) = src; m_name = src.m_name; return *this; }
template <class FunctionClass> named_delegate(member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
template <class FunctionClass> named_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
explicit named_delegate(std::function<Signature> funcptr, const char *name) : basetype(funcptr), m_name(name) { }
template <class FunctionClass> named_delegate(static_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
template <class FunctionClass> named_delegate(static_ref_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { }
named_delegate &operator=(const basetype &src) { basetype::operator=(src); m_name = src.m_name; return *this; }
const char *name() const { return m_name; }
private:
const char * m_name; // name string
};
@ -65,33 +71,37 @@ private:
// device_delegate is a delegate that wraps with a device tag and can be easily
// late bound without replicating logic everywhere
template<typename _Signature>
class device_delegate : public named_delegate<_Signature>, public device_delegate_helper
template <typename Signature>
class device_delegate : public named_delegate<Signature>, public device_delegate_helper
{
typedef device_delegate<_Signature> thistype;
typedef named_delegate<_Signature> basetype;
using thistype = device_delegate<Signature>;
using basetype = named_delegate<Signature>;
template <class FunctionClass> using member_func_type = typename basetype::template member_func_type<FunctionClass>;
template <class FunctionClass> using const_member_func_type = typename basetype::template const_member_func_type<FunctionClass>;
template <class FunctionClass> using static_func_type = typename basetype::template static_func_type<FunctionClass>;
template <class FunctionClass> using static_ref_func_type = typename basetype::template static_ref_func_type<FunctionClass>;
public:
// provide the same constructors as the base class
device_delegate() : basetype(), device_delegate_helper(nullptr) { }
device_delegate(const basetype &src) : basetype(src), device_delegate_helper(src.m_device_name) { }
device_delegate(const basetype &src, delegate_late_bind &object) : basetype(src, object), device_delegate_helper(src.m_device_name) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
device_delegate(std::function<_Signature> funcptr, const char *name) : basetype(funcptr,name), device_delegate_helper(nullptr) { }
device_delegate &operator=(const thistype &src) { *static_cast<basetype *>(this) = src; m_device_name = src.m_device_name; return *this; }
template <class FunctionClass> device_delegate(member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
template <class FunctionClass> device_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
template <class FunctionClass> device_delegate(static_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
template <class FunctionClass> device_delegate(static_ref_func_type<FunctionClass> funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast<device_t *>(object))) { }
device_delegate(std::function<Signature> funcptr, const char *name) : basetype(funcptr, name), device_delegate_helper(nullptr) { }
device_delegate &operator=(const thistype &src) { basetype::operator=(src); m_device_name = src.m_device_name; return *this; }
// provide additional constructors that take a device name string
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::const_member_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template<class _FunctionClass> device_delegate(typename basetype::template traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, const char *devname, _FunctionClass *) : basetype(funcptr, name, static_cast<_FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
device_delegate(typename basetype::template traits<device_t>::static_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { }
device_delegate(typename basetype::template traits<device_t>::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { }
template <class FunctionClass> device_delegate(member_func_type<FunctionClass> funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template <class FunctionClass> device_delegate(member_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template <class FunctionClass> device_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template <class FunctionClass> device_delegate(const_member_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template <class FunctionClass> device_delegate(static_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
template <class FunctionClass> device_delegate(static_ref_func_type<FunctionClass> funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast<FunctionClass *>(nullptr)), device_delegate_helper(devname) { }
device_delegate(static_func_type<device_t> funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { }
device_delegate(static_ref_func_type<device_t> funcptr, const char *name) : basetype(funcptr, name, static_cast<device_t *>(nullptr)), device_delegate_helper(nullptr) { }
// and constructors that provide a search root
device_delegate(const thistype &src, device_t &search_root) : basetype(src), device_delegate_helper(src.m_device_name) { bind_relative_to(search_root); }
@ -104,4 +114,4 @@ public:
};
#endif /* MAME_EMU_DEVDELEGATE_H */
#endif // MAME_EMU_DEVDELEGATE_H

View File

@ -22,6 +22,7 @@
#include <stdexcept>
#include <string>
#include <type_traits>
#include <utility>
//**************************************************************************
// TYPE DEFINITIONS
@ -263,7 +264,14 @@ public:
///
/// Returns the search tag.
/// \return The object tag this helper will search for.
const char *finder_tag() const { return m_tag; }
char const *finder_tag() const { return m_tag; }
/// \brief Get search target
///
/// Returns the search base device and tag.
/// \return a pair consisting of a reference to the device to search
/// relative to and the relative tag.
std::pair<device_t &, char const *> finder_target() const { return std::make_pair(m_base, m_tag); }
/// \brief Set search tag
///
@ -519,7 +527,7 @@ public:
/// During configuration, device_finder instances may be assigned
/// a reference to the anticipated target device to avoid the need
/// for tempories during configuration. Normal resolution will
/// still happen after machine configuration is completed to ensure
/// still happen after machine configuration is completed to ensure
/// device removal/replacement is handled properly.
/// \param [in] device Reference to anticipated target device.
/// \return The same reference supplied by the caller.

View File

@ -265,6 +265,7 @@ class device_type_impl : public device_type_impl_base
public:
using device_type_impl_base::device_type_impl_base;
template <typename... Params> DeviceClass &operator()(machine_config &config, char const *tag, Params &&... args) const;
template <typename Exposed, bool Required, typename... Params> DeviceClass &operator()(machine_config &config, device_finder<Exposed, Required> &finder, Params &&... args) const;
};

View File

@ -14,8 +14,8 @@
#error Dont include this file directly; include emu.h instead.
#endif
#ifndef __DEVICE_IPP__
#define __DEVICE_IPP__
#ifndef MAME_EMU_DEVICE_IPP
#define MAME_EMU_DEVICE_IPP
//**************************************************************************
// TYPE DEFINITIONS
@ -23,10 +23,31 @@
typedef device_delegate<void (u32)> clock_update_delegate;
//**************************************************************************
// MEMBER TEMPLATES
//**************************************************************************
namespace emu { namespace detail {
template <class DeviceClass> template <typename... Params>
DeviceClass &device_type_impl<DeviceClass>::operator()(machine_config &config, char const *tag, Params &&... args) const
{
return dynamic_cast<DeviceClass &>(*config.device_add(tag, *this, std::forward<Params>(args)...));
}
template <class DeviceClass> template <typename Exposed, bool Required, typename... Params>
DeviceClass &device_type_impl<DeviceClass>::operator()(machine_config &config, device_finder<Exposed, Required> &finder, Params &&... args) const
{
std::pair<device_t &, char const *> const target(finder.finder_target());
assert(&config.current_device() == &target.first);
DeviceClass &result(dynamic_cast<DeviceClass &>(*config.device_add(target.second, *this, std::forward<Params>(args)...)));
return finder = result;
}
} } // namespace emu::detail
template <typename Format, typename... Params>
inline void device_t::popmessage(Format &&fmt, Params &&... args) const
{
@ -54,4 +75,4 @@ inline void device_t::logerror(Format &&fmt, Params &&... args) const
}
}
#endif // __DEVICE_IPP__
#endif // MAME_EMU_DEVICE_IPP

View File

@ -111,4 +111,4 @@ class address_map; // Forward declaration
// member templates that don't like incomplete types
#include "device.ipp"
#endif /* __EMU_H__ */
#endif // __EMU_H__

View File

@ -103,6 +103,7 @@ class devcb_write_base;
// declared in devfind.h
class finder_base;
template <class DeviceClass, bool Required> class device_finder;
// declared in device.h
class device_interface;

View File

@ -128,17 +128,6 @@ private:
};
namespace emu { namespace detail {
template <class DeviceClass> template <typename... Params>
DeviceClass &device_type_impl<DeviceClass>::operator()(machine_config &config, char const *tag, Params &&... args) const
{
return dynamic_cast<DeviceClass &>(*config.device_add(tag, *this, std::forward<Params>(args)...));
}
} } // namespace emu::detail
//*************************************************************************/
/** @name Machine config start/end macros */
//*************************************************************************/

View File

@ -291,7 +291,7 @@ MACHINE_CONFIG_START(osborne1_state::osborne1)
MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::green())
MCFG_SCREEN_UPDATE_DRIVER(osborne1_state, screen_update)
MCFG_SCREEN_RAW_PARAMS( MAIN_CLOCK, 1024, 0, 104*8, 260, 0, 24*10 )
MCFG_SCREEN_RAW_PARAMS(MAIN_CLOCK, 1024, 0, 104*8, 260, 0, 24*10)
MCFG_SCREEN_PALETTE("palette")
MCFG_GFXDECODE_ADD("gfxdecode", "palette", osborne1)
MCFG_PALETTE_ADD_MONOCHROME_HIGHLIGHT("palette")
@ -301,12 +301,12 @@ MACHINE_CONFIG_START(osborne1_state::osborne1)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
MCFG_DEVICE_ADD("pia_0", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(DEVREAD8(IEEE488_TAG, ieee488_device, dio_r))
MCFG_PIA_READPA_HANDLER(DEVREAD8(m_ieee, ieee488_device, dio_r))
MCFG_PIA_READPB_HANDLER(READ8(osborne1_state, ieee_pia_pb_r))
MCFG_PIA_WRITEPA_HANDLER(DEVWRITE8(IEEE488_TAG, ieee488_device, dio_w))
MCFG_PIA_WRITEPA_HANDLER(DEVWRITE8(m_ieee, ieee488_device, dio_w))
MCFG_PIA_WRITEPB_HANDLER(WRITE8(osborne1_state, ieee_pia_pb_w))
MCFG_PIA_CA2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ifc_w))
MCFG_PIA_CB2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ren_w))
MCFG_PIA_CA2_HANDLER(DEVWRITELINE(m_ieee, ieee488_device, ifc_w))
MCFG_PIA_CB2_HANDLER(DEVWRITELINE(m_ieee, ieee488_device, ren_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(osborne1_state, ieee_pia_irq_a_func))
MCFG_IEEE488_BUS_ADD()
@ -324,10 +324,10 @@ MACHINE_CONFIG_START(osborne1_state::osborne1)
MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(osborne1_state, serial_acia_irq_func))
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_rxd))
MCFG_RS232_DCD_HANDLER(DEVWRITELINE("acia", acia6850_device, write_dcd))
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("acia", acia6850_device, write_cts))
MCFG_RS232_RI_HANDLER(DEVWRITELINE("pia_1", pia6821_device, ca2_w))
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(m_acia, acia6850_device, write_rxd))
MCFG_RS232_DCD_HANDLER(DEVWRITELINE(m_acia, acia6850_device, write_dcd))
MCFG_RS232_CTS_HANDLER(DEVWRITELINE(m_acia, acia6850_device, write_cts))
MCFG_RS232_RI_HANDLER(DEVWRITELINE(m_pia1, pia6821_device, ca2_w))
MCFG_DEVICE_ADD("mb8877", MB8877, MAIN_CLOCK/16)
MCFG_WD_FDC_FORCE_READY

View File

@ -724,7 +724,7 @@ void seta2_state::telpacfl_map(address_map &map)
MCFG_DEVICE_ADD( _tag, FUNCUBE_TOUCHSCREEN, _clock )
#define MCFG_FUNCUBE_TOUCHSCREEN_TX_CALLBACK(_devcb) \
devcb = &funcube_touchscreen_device::set_tx_cb(*device, DEVCB_##_devcb);
devcb = &downcast<funcube_touchscreen_device &>(*device).set_tx_cb(DEVCB_##_devcb);
class funcube_touchscreen_device : public device_t,
public device_serial_interface
@ -733,7 +733,7 @@ public:
funcube_touchscreen_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual ioport_constructor device_input_ports() const override;
template<class _Object> static devcb_base &set_tx_cb(device_t &device, _Object object) { return downcast<funcube_touchscreen_device &>(device).m_tx_cb.set_callback(object); }
template <class Object> devcb_base &set_tx_cb(Object &&cb) { return m_tx_cb.set_callback(std::forward<Object>(cb)); }
protected:
virtual void device_start() override;

View File

@ -23,6 +23,7 @@
#include "emu.h"
#include "includes/tranz330.h"
#include "machine/input_merger.h"
#include "speaker.h"
#include "tranz330.lh"
@ -141,7 +142,7 @@ static const z80_daisy_config tranz330_daisy_chain[] =
// ? - check purported RS232 hookup, inconsistent information found at the relevant webpage vs. user-submitted errata
void tranz330_state::tranz330(machine_config &config)
{
m_cpu = Z80(config, CPU_TAG, XTAL(7'159'090)/2); //*
Z80(config, m_cpu, XTAL(7'159'090)/2); //*
m_cpu->set_addrmap(AS_PROGRAM, address_map_constructor(&tranz330_state::tranz330_mem, tag(), this));
m_cpu->set_addrmap(AS_IO, address_map_constructor(&tranz330_state::tranz330_io, tag(), this));
m_cpu->set_daisy_config(tranz330_daisy_chain);
@ -151,31 +152,34 @@ void tranz330_state::tranz330(machine_config &config)
MSM6242(config, RTC_TAG, XTAL(32'768));
m_pio = Z80PIO(config, PIO_TAG, XTAL(7'159'090)/2); //*
m_pio->set_out_int_callback(DEVCB_INPUTLINE(CPU_TAG, INPUT_LINE_IRQ0)); //*
INPUT_MERGER_ANY_HIGH(config, "irq", 0)
.set_output_handler(DEVCB_INPUTLINE(m_cpu, INPUT_LINE_IRQ0));
Z80PIO(config, m_pio, XTAL(7'159'090)/2); //*
m_pio->set_out_int_callback(DEVCB_DEVWRITELINE("irq", input_merger_device, in_w<0>)); //*
m_pio->set_out_pa_callback(DEVCB_WRITE8(tranz330_state, pio_a_w));
m_pio->set_in_pa_callback(DEVCB_READ8(tranz330_state, card_r));
m_pio->set_in_pb_callback(DEVCB_READ8(tranz330_state, pio_b_r));
m_dart = Z80DART(config, DART_TAG, XTAL(7'159'090)/2); //*
Z80DART(config, m_dart, XTAL(7'159'090)/2); //*
m_dart->set_out_syncb_callback(DEVCB_WRITELINE(tranz330_state, syncb_w));
m_dart->set_out_txdb_callback(DEVCB_DEVWRITELINE(RS232_TAG, rs232_port_device, write_txd)); //?
m_dart->set_out_dtrb_callback(DEVCB_DEVWRITELINE(RS232_TAG, rs232_port_device, write_dtr)); //?
m_dart->set_out_rtsb_callback(DEVCB_DEVWRITELINE(RS232_TAG, rs232_port_device, write_rts)); //?
m_dart->set_out_int_callback(DEVCB_INPUTLINE(CPU_TAG, INPUT_LINE_IRQ0));
m_dart->set_out_txdb_callback(DEVCB_DEVWRITELINE(m_rs232, rs232_port_device, write_txd)); //?
m_dart->set_out_dtrb_callback(DEVCB_DEVWRITELINE(m_rs232, rs232_port_device, write_dtr)); //?
m_dart->set_out_rtsb_callback(DEVCB_DEVWRITELINE(m_rs232, rs232_port_device, write_rts)); //?
m_dart->set_out_int_callback(DEVCB_DEVWRITELINE("irq", input_merger_device, in_w<1>));
m_ctc = Z80CTC(config, CTC_TAG, XTAL(7'159'090)/2); //*
Z80CTC(config, m_ctc, XTAL(7'159'090)/2); //*
m_ctc->set_zc_callback<2>(DEVCB_WRITELINE(tranz330_state, sound_w));
m_ctc->set_intr_callback(DEVCB_INPUTLINE(CPU_TAG, INPUT_LINE_IRQ0));
m_ctc->set_intr_callback(DEVCB_DEVWRITELINE("irq", input_merger_device, in_w<2>));
m_rs232 = RS232_PORT(config, RS232_TAG, 0);
RS232_PORT(config, m_rs232, 0);
m_rs232->option_reset();
slot_options_default_rs232_devices(m_rs232);
m_rs232->set_default_option(nullptr);
m_rs232->set_fixed(false);
m_rs232->set_rxd_handler(DEVCB_DEVWRITELINE(DART_TAG, z80dart_device, rxb_w));
m_rs232->set_dcd_handler(DEVCB_DEVWRITELINE(DART_TAG, z80dart_device, dcdb_w));
m_rs232->set_cts_handler(DEVCB_DEVWRITELINE(DART_TAG, z80dart_device, ctsb_w));
m_rs232->set_rxd_handler(DEVCB_DEVWRITELINE(m_dart, z80dart_device, rxb_w));
m_rs232->set_dcd_handler(DEVCB_DEVWRITELINE(m_dart, z80dart_device, dcdb_w));
m_rs232->set_cts_handler(DEVCB_DEVWRITELINE(m_dart, z80dart_device, ctsb_w));
// video
MIC10937(config, VFD_TAG, 60).set_port_value(0);

View File

@ -197,12 +197,12 @@ MACHINE_CONFIG_START(zorba_state::zorba)
// IEEE488 interface
MCFG_DEVICE_ADD("pia1", PIA6821, 0)
MCFG_PIA_READPA_HANDLER(DEVREAD8(IEEE488_TAG, ieee488_device, dio_r)) // TODO: gated with PB1
MCFG_PIA_WRITEPA_HANDLER(DEVWRITE8(IEEE488_TAG, ieee488_device, dio_w)) // TODO: gated with PB1
MCFG_PIA_READPA_HANDLER(DEVREAD8(m_ieee, ieee488_device, dio_r)) // TODO: gated with PB1
MCFG_PIA_WRITEPA_HANDLER(DEVWRITE8(m_ieee, ieee488_device, dio_w)) // TODO: gated with PB1
MCFG_PIA_READPB_HANDLER(READ8(zorba_state, pia1_portb_r))
MCFG_PIA_WRITEPB_HANDLER(WRITE8(zorba_state, pia1_portb_w))
MCFG_PIA_CA2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ifc_w))
MCFG_PIA_CB2_HANDLER(DEVWRITELINE(IEEE488_TAG, ieee488_device, ren_w))
MCFG_PIA_CA2_HANDLER(DEVWRITELINE(m_ieee, ieee488_device, ifc_w))
MCFG_PIA_CB2_HANDLER(DEVWRITELINE(m_ieee, ieee488_device, ren_w))
MCFG_PIA_IRQA_HANDLER(DEVWRITELINE("irq1", input_merger_device, in_w<0>))
MCFG_PIA_IRQB_HANDLER(DEVWRITELINE("irq1", input_merger_device, in_w<1>))
@ -212,16 +212,16 @@ MACHINE_CONFIG_START(zorba_state::zorba)
MCFG_PIT8253_CLK1(24_MHz_XTAL / 3)
MCFG_PIT8253_CLK2(24_MHz_XTAL / 3)
MCFG_PIT8253_OUT0_HANDLER(WRITELINE(zorba_state, br1_w))
MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE("uart1", i8251_device, write_txc))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_rxc))
MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE("uart2", i8251_device, write_txc))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart2", i8251_device, write_rxc))
MCFG_PIT8253_OUT1_HANDLER(DEVWRITELINE(m_uart1, i8251_device, write_txc))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(m_uart1, i8251_device, write_rxc))
MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE(m_uart2, i8251_device, write_txc))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(m_uart2, i8251_device, write_rxc))
// CRTC
MCFG_DEVICE_ADD("crtc", I8275, 14.318'181_MHz_XTAL / 7)
MCFG_I8275_CHARACTER_WIDTH(8)
MCFG_I8275_DRAW_CHARACTER_CALLBACK_OWNER(zorba_state, zorba_update_chr)
MCFG_I8275_DRQ_CALLBACK(DEVWRITELINE("dma", z80dma_device, rdy_w))
MCFG_I8275_DRQ_CALLBACK(DEVWRITELINE(m_dma, z80dma_device, rdy_w))
MCFG_I8275_IRQ_CALLBACK(DEVWRITELINE("irq0", input_merger_device, in_w<1>))
MCFG_VIDEO_SET_SCREEN("screen")
@ -236,30 +236,30 @@ MACHINE_CONFIG_START(zorba_state::zorba)
// J1 IEEE-488
MCFG_IEEE488_BUS_ADD()
MCFG_IEEE488_SRQ_CALLBACK(DEVWRITELINE("pia1", pia6821_device, ca2_w)) // TODO: gated with PB1 from PIA
MCFG_IEEE488_SRQ_CALLBACK(DEVWRITELINE(m_pia1, pia6821_device, ca2_w)) // TODO: gated with PB1 from PIA
// J2 EIA RS232/internal modem
// TODO: this has additional lines compared to a regular RS232 port (TxC in, RxC in, RxC out, speaker in, power)
MCFG_RS232_PORT_ADD("rs232", default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart0", i8251_device, write_rxd)) // TODO: this line has a LED attached
MCFG_RS232_CTS_HANDLER(DEVWRITELINE("uart0", i8251_device, write_cts)) // TODO: this line has a LED attached
MCFG_RS232_DSR_HANDLER(DEVWRITELINE("uart0", i8251_device, write_dsr))
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(m_uart0, i8251_device, write_rxd)) // TODO: this line has a LED attached
MCFG_RS232_CTS_HANDLER(DEVWRITELINE(m_uart0, i8251_device, write_cts)) // TODO: this line has a LED attached
MCFG_RS232_DSR_HANDLER(DEVWRITELINE(m_uart0, i8251_device, write_dsr))
// J3 Parallel printer
MCFG_CENTRONICS_OUTPUT_LATCH_ADD("parprndata", "parprn")
MCFG_CENTRONICS_ADD("parprn", centronics_devices, "printer")
MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE("uart1", i8251_device, write_cts))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("uart1", i8251_device, write_dsr)) // TODO: shared with serial CTS
MCFG_CENTRONICS_BUSY_HANDLER(DEVWRITELINE(m_uart1, i8251_device, write_cts))
MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE(m_uart1, i8251_device, write_dsr)) // TODO: shared with serial CTS
MCFG_CENTRONICS_FAULT_HANDLER(WRITELINE(zorba_state, printer_fault_w))
MCFG_CENTRONICS_SELECT_HANDLER(WRITELINE(zorba_state, printer_select_w))
// J3 Serial printer
MCFG_RS232_PORT_ADD("serprn", default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(DEVWRITELINE("uart1", i8251_device, write_rxd)) // TODO: this line has a LED attached
MCFG_RS232_RXD_HANDLER(DEVWRITELINE(m_uart1, i8251_device, write_rxd)) // TODO: this line has a LED attached
// J6 TTL-level serial keyboard
MCFG_DEVICE_ADD("keyboard", ZORBA_KEYBOARD, 0)
MCFG_ZORBA_KEYBOARD_RXD_CB(DEVWRITELINE("uart2", i8251_device, write_rxd))
MCFG_ZORBA_KEYBOARD_RXD_CB(DEVWRITELINE(m_uart2, i8251_device, write_rxd))
MCFG_SOFTWARE_LIST_ADD("flop_list", "zorba")
MACHINE_CONFIG_END

View File

@ -94,10 +94,10 @@ public:
int rom_offset;
template<class _Object> devcb_base &set_reset_cb(_Object wr) { return write_reset.set_callback(wr); }
template<class _Object> devcb_base &set_linechange_cb(_Object wr) { return write_linechange.set_callback(wr); }
template<class _Object> devcb_base &set_via_clock_cb(_Object wr) { return write_via_clock.set_callback(wr); }
template<class _Object> devcb_base &set_via_data_cb(_Object wr) { return write_via_data.set_callback(wr); }
template <class Object> devcb_base &set_reset_cb(Object &&wr) { return write_reset.set_callback(std::forward<Object>(wr)); }
template <class Object> devcb_base &set_linechange_cb(Object &&wr) { return write_linechange.set_callback(std::forward<Object>(wr)); }
template <class Object> devcb_base &set_via_clock_cb(Object &&wr) { return write_via_clock.set_callback(std::forward<Object>(wr)); }
template <class Object> devcb_base &set_via_data_cb(Object &&wr) { return write_via_data.set_callback(std::forward<Object>(wr)); }
devcb_write_line write_reset, write_linechange, write_via_clock, write_via_data;

View File

@ -19,9 +19,9 @@ class k573dio_device : public device_t
public:
k573dio_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _write> void set_output_cb(_write _output_cb)
template <class Write> void set_output_cb(Write &&_output_cb)
{
output_cb.set_callback(_output_cb);
output_cb.set_callback(std::forward<Write>(_output_cb));
}
required_device<mas3507d_device> mas3507d;

View File

@ -75,7 +75,7 @@ public:
// construction/destruction
nick_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _Object> devcb_base &set_virq_wr_callback(_Object object) { return m_write_virq.set_callback(object); }
template <class Object> devcb_base &set_virq_wr_callback(Object &&cb) { return m_write_virq.set_callback(std::forward<Object>(cb)); }
virtual void vram_map(address_map &map);
virtual void vio_map(address_map &map);

View File

@ -141,7 +141,7 @@ public:
int next_y;
powervr2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
template<class _cb> void set_irq_cb(_cb cb) { irq_cb.set_callback(cb); }
template <class Object> void set_irq_cb(Object &&cb) { irq_cb.set_callback(std::forward<Object>(cb)); }
DECLARE_READ32_MEMBER( id_r );
DECLARE_READ32_MEMBER( revision_r );