From 8795d808087298025e66c818482f9d9b68968f1f Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Wed, 2 May 2018 14:43:01 +1000 Subject: [PATCH] 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). --- src/devices/bus/epson_sio/epson_sio.h | 4 +- src/devices/bus/msx_slot/cartridge.cpp | 12 +- src/devices/bus/msx_slot/rom.cpp | 4 +- src/devices/bus/pet/exp.h | 6 +- src/devices/bus/vip/byteio.h | 2 +- src/devices/cpu/m6502/m3745x.h | 44 +-- src/devices/cpu/m6502/m6510.h | 6 +- src/devices/imagedev/midiin.h | 2 +- src/devices/imagedev/printer.h | 2 +- src/devices/machine/ataintf.cpp | 18 +- src/devices/machine/gen_fifo.cpp | 4 +- src/emu/devcb.h | 362 +++++++++++++++++-------- src/emu/devdelegate.h | 66 +++-- src/emu/devfind.h | 12 +- src/emu/device.h | 1 + src/emu/device.ipp | 27 +- src/emu/emu.h | 2 +- src/emu/emufwd.h | 1 + src/emu/mconfig.h | 11 - src/mame/drivers/osborne1.cpp | 18 +- src/mame/drivers/seta2.cpp | 4 +- src/mame/drivers/tranz330.cpp | 32 ++- src/mame/drivers/zorba.cpp | 34 +-- src/mame/machine/egret.h | 8 +- src/mame/machine/k573dio.h | 4 +- src/mame/video/nick.h | 2 +- src/mame/video/powervr2.h | 2 +- 27 files changed, 426 insertions(+), 264 deletions(-) diff --git a/src/devices/bus/epson_sio/epson_sio.h b/src/devices/bus/epson_sio/epson_sio.h index 7e1a001c8b1..814dbf6d5fd 100644 --- a/src/devices/bus/epson_sio/epson_sio.h +++ b/src/devices/bus/epson_sio/epson_sio.h @@ -44,8 +44,8 @@ public: virtual ~epson_sio_device(); // callbacks - template devcb_base &set_rx_callback(_rx rx) { return m_write_rx.set_callback(rx); } - template devcb_base &set_pin_callback(_pin pin) { return m_write_pin.set_callback(pin); } + template devcb_base &set_rx_callback(Object &&rx) { return m_write_rx.set_callback(std::forward(rx)); } + template devcb_base &set_pin_callback(Object &&pin) { return m_write_pin.set_callback(std::forward(pin)); } // called from owner DECLARE_WRITE_LINE_MEMBER( tx_w ); diff --git a/src/devices/bus/msx_slot/cartridge.cpp b/src/devices/bus/msx_slot/cartridge.cpp index dd1e591eefd..848cacbcf65 100644 --- a/src/devices/bus/msx_slot/cartridge.cpp +++ b/src/devices/bus/msx_slot/cartridge.cpp @@ -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(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(get_card_device()); if (m_cartridge) - { - // FIXME: do this is a less horrid way - machine_config::token const tok(const_cast(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)); } diff --git a/src/devices/bus/msx_slot/rom.cpp b/src/devices/bus/msx_slot/rom.cpp index 6e80b9551d1..186077edb55 100644 --- a/src/devices/bus/msx_slot/rom.cpp +++ b/src/devices/bus/msx_slot/rom.cpp @@ -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; } diff --git a/src/devices/bus/pet/exp.h b/src/devices/bus/pet/exp.h index 5a61a7653ae..3e941985b16 100644 --- a/src/devices/bus/pet/exp.h +++ b/src/devices/bus/pet/exp.h @@ -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 void set_callbacks(_read rd, _write wr) { - m_read_dma.set_callback(rd); - m_write_dma.set_callback(wr); + template void set_callbacks(Read &&rd, Write &&wr) { + m_read_dma.set_callback(std::forward(rd)); + m_write_dma.set_callback(std::forward(wr)); } // computer interface diff --git a/src/devices/bus/vip/byteio.h b/src/devices/bus/vip/byteio.h index 5c0ebc29afd..08b435ac705 100644 --- a/src/devices/bus/vip/byteio.h +++ b/src/devices/bus/vip/byteio.h @@ -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 void set_inst_callback(_inst inst) { m_write_inst.set_callback(inst); } + template void set_inst_callback(Object &&inst) { m_write_inst.set_callback(std::forward(inst)); } // computer interface uint8_t in_r(); diff --git a/src/devices/cpu/m6502/m3745x.h b/src/devices/cpu/m6502/m3745x.h index 872d8d842ad..ca868f09a66 100644 --- a/src/devices/cpu/m6502/m3745x.h +++ b/src/devices/cpu/m6502/m3745x.h @@ -62,44 +62,44 @@ public: const address_space_config m_program_config; - template void set_p3_callbacks(_read rd, _write wr) + template void set_p3_callbacks(Read &&rd, Write &&wr) { - read_p3.set_callback(rd); - write_p3.set_callback(wr); + read_p3.set_callback(std::forward(rd)); + write_p3.set_callback(std::forward(wr)); } - template void set_p4_callbacks(_read rd, _write wr) + template void set_p4_callbacks(Read &&rd, Write &&wr) { - read_p4.set_callback(rd); - write_p4.set_callback(wr); + read_p4.set_callback(std::forward(rd)); + write_p4.set_callback(std::forward(wr)); } - template void set_p5_callbacks(_read rd, _write wr) + template void set_p5_callbacks(Read &&rd, Write &&wr) { - read_p5.set_callback(rd); - write_p5.set_callback(wr); + read_p5.set_callback(std::forward(rd)); + write_p5.set_callback(std::forward(wr)); } - template void set_p6_callbacks(_read rd, _write wr) + template void set_p6_callbacks(Read &&rd, Write &&wr) { - read_p6.set_callback(rd); - write_p6.set_callback(wr); + read_p6.set_callback(std::forward(rd)); + write_p6.set_callback(std::forward(wr)); } - template void set_ad14_callbacks(_read rd, _read2 rd2, _read3 rd3, _read4 rd4) + template 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(rd)); + read_ad_1.set_callback(std::forward(rd2)); + read_ad_2.set_callback(std::forward(rd3)); + read_ad_3.set_callback(std::forward(rd4)); } - template void set_ad58_callbacks(_read rd, _read2 rd2, _read3 rd3, _read4 rd4) + template 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(rd)); + read_ad_5.set_callback(std::forward(rd2)); + read_ad_6.set_callback(std::forward(rd3)); + read_ad_7.set_callback(std::forward(rd4)); } devcb_read8 read_p3, read_p4, read_p5, read_p6; diff --git a/src/devices/cpu/m6502/m6510.h b/src/devices/cpu/m6502/m6510.h index 033813cd9ad..bedcb78a224 100644 --- a/src/devices/cpu/m6502/m6510.h +++ b/src/devices/cpu/m6502/m6510.h @@ -27,9 +27,9 @@ public: uint8_t get_port(); void set_pulls(uint8_t pullup, uint8_t pulldown); - template void set_callbacks(_read rd, _write wr) { - read_port.set_callback(rd); - write_port.set_callback(wr); + template void set_callbacks(Read &&rd, Write &&wr) { + read_port.set_callback(std::forward(rd)); + write_port.set_callback(std::forward(wr)); } virtual std::unique_ptr create_disassembler() override; diff --git a/src/devices/imagedev/midiin.h b/src/devices/imagedev/midiin.h index d11339e7160..776112b2625 100644 --- a/src/devices/imagedev/midiin.h +++ b/src/devices/imagedev/midiin.h @@ -30,7 +30,7 @@ public: // construction/destruction midiin_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template devcb_base &set_input_callback(_Object object) { return m_input_cb.set_callback(object); } + template devcb_base &set_input_callback(Object &&cb) { return m_input_cb.set_callback(std::forward(cb)); } // image-level overrides virtual image_init_result call_load() override; diff --git a/src/devices/imagedev/printer.h b/src/devices/imagedev/printer.h index 3ee9db01571..41f2dbb03cd 100644 --- a/src/devices/imagedev/printer.h +++ b/src/devices/imagedev/printer.h @@ -29,7 +29,7 @@ public: // construction/destruction printer_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template devcb_base &set_online_callback(_Object object) { return m_online_cb.set_callback(object); } + template devcb_base &set_online_callback(Object &&cb) { return m_online_cb.set_callback(std::forward(cb)); } // image-level overrides virtual image_init_result call_load() override; diff --git a/src/devices/machine/ataintf.cpp b/src/devices/machine/ataintf.cpp index e4fde0e87af..a6d075217ec 100644 --- a/src/devices/machine/ataintf.cpp +++ b/src/devices/machine/ataintf.cpp @@ -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(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); diff --git a/src/devices/machine/gen_fifo.cpp b/src/devices/machine/gen_fifo.cpp index 862626a2db7..bcbd3f54201 100644 --- a/src/devices/machine/gen_fifo.cpp +++ b/src/devices/machine/gen_fifo.cpp @@ -76,9 +76,9 @@ template void generic_fifo_device_base::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()) { diff --git a/src/emu/devcb.h b/src/emu/devcb.h index f884dc7a517..fee31ce1ca4 100644 --- a/src/emu/devcb.h +++ b/src/emu/devcb.h @@ -18,53 +18,125 @@ #define MAME_EMU_DEVCB_H #include +#include +#include + + +namespace emu { namespace detail { + +template struct devcb_delegate_initialiser +{ + template struct is_device_implementation + { static constexpr bool value = std::is_base_of::value; }; + template struct is_device_interface + { static constexpr bool value = std::is_base_of::value && !is_device_implementation::value; }; + + devcb_delegate_initialiser(char const *tag, Delegate &&delegate) : m_base(nullptr), m_delegate(std::move(delegate)) + { + } + template + devcb_delegate_initialiser(T &device, std::enable_if_t::value, Delegate &&> delegate) : m_base(&device), m_delegate(std::move(delegate)) + { + } + template + devcb_delegate_initialiser(T &interface, std::enable_if_t::value, Delegate &&> delegate) : m_base(&interface.device()), m_delegate(std::move(delegate)) + { + } + template + devcb_delegate_initialiser(device_finder 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 +inline std::enable_if_t::is_device_implementation::value, char const *> devcb_delegate_get_tag(T &device) { return DEVICE_SELF; } +template +inline std::enable_if_t::is_device_interface::value, char const *> devcb_delegate_get_tag(T &interface) { return DEVICE_SELF; } +template +inline char const *devcb_delegate_get_tag(device_finder const &finder) { return finder.finder_tag(); } + +template 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 + static DescType create(device_finder const &finder) + { + std::pair const target(finder.finder_target()); + return DescType{ &target.first, target.second }; + } +}; + +template 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 + static DescType create(device_finder const &finder, int inputnum) + { + std::pair 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(DEVICE_SELF, read_line_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_READ8(_class, _func) (emu::detail::devcb_delegate_initialiser(DEVICE_SELF, read8_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_READ16(_class, _func) (emu::detail::devcb_delegate_initialiser(DEVICE_SELF, read16_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_READ32(_class, _func) (emu::detail::devcb_delegate_initialiser(DEVICE_SELF, read32_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_READ64(_class, _func) (emu::detail::devcb_delegate_initialiser(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((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((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((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((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((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(DEVICE_SELF, write_line_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_WRITE8(_class, _func) (emu::detail::devcb_delegate_initialiser(DEVICE_SELF, write8_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_WRITE16(_class, _func) (emu::detail::devcb_delegate_initialiser(DEVICE_SELF, write16_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_WRITE32(_class, _func) (emu::detail::devcb_delegate_initialiser(DEVICE_SELF, write32_delegate(&_class::_func, #_class "::" #_func, DEVICE_SELF, (_class *)nullptr))) +#define DEVCB_WRITE64(_class, _func) (emu::detail::devcb_delegate_initialiser(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((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((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((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((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((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 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 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; + using membank_desc = tag_desc; + using output_desc = tag_desc; - 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; + using assertline_desc = line_desc; + using clearline_desc = line_desc; + using holdline_desc = line_desc; // 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 devcb_base &set_callback(tag_desc 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 struct set_helper + { + static constexpr bool valid = false; + }; + template struct set_helper + { + 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 struct set_helper + { + 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 struct set_helper + { + 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 struct set_helper + { + 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 struct set_helper + { + 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 + std::enable_if_t::valid, devcb_base &> set_callback(emu::detail::devcb_delegate_initialiser &&desc) + { + if (desc.m_base) reset(*desc.m_base, set_helper::type); + else reset(set_helper::type); + set_helper::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 struct set_helper + { + static constexpr bool valid = false; + }; + template struct set_helper + { + 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 struct set_helper + { + 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 struct set_helper + { + 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 struct set_helper + { + 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 struct set_helper + { + 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 + std::enable_if_t::valid, devcb_base &> set_callback(emu::detail::devcb_delegate_initialiser &&desc) + { + if (desc.m_base) reset(*desc.m_base, set_helper::type); + else reset(set_helper::type); + set_helper::apply(*this, std::move(desc.m_delegate)); + return *this; + } + template devcb_base &set_callback(line_desc 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 inline devcb_base::ioport_desc DEVCB_IOPORT(Params &&... args) { return emu::detail::devcb_tag_desc_creator::create(std::forward(args)...); } +template inline devcb_base::membank_desc DEVCB_MEMBANK(Params &&... args) { return emu::detail::devcb_tag_desc_creator::create(std::forward(args)...); } +template inline devcb_base::output_desc DEVCB_OUTPUT(Params &&... args) { return emu::detail::devcb_tag_desc_creator::create(std::forward(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 inline devcb_base::inputline_desc DEVCB_INPUTLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator::create(std::forward(args)...); } +template inline devcb_base::assertline_desc DEVCB_ASSERTLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator::create(std::forward(args)...); } +template inline devcb_base::clearline_desc DEVCB_CLEARLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator::create(std::forward(args)...); } +template inline devcb_base::holdline_desc DEVCB_HOLDLINE(Params &&... args) { return emu::detail::devcb_line_desc_creator::create(std::forward(args)...); } +#define DEVCB_VCC DEVCB_CONSTANT(1) +#define DEVCB_GND DEVCB_CONSTANT(0) + +#endif // MAME_EMU_DEVCB_H diff --git a/src/emu/devdelegate.h b/src/emu/devdelegate.h index 96d9512d79b..544253ecfda 100644 --- a/src/emu/devdelegate.h +++ b/src/emu/devdelegate.h @@ -39,24 +39,30 @@ protected: // ======================> named_delegate -template -class named_delegate : public delegate<_Signature> +template +class named_delegate : public delegate { - typedef delegate<_Signature> basetype; +protected: + using basetype = delegate; + template using member_func_type = typename basetype::template traits::member_func_type; + template using const_member_func_type = typename basetype::template traits::const_member_func_type; + template using static_func_type = typename basetype::template traits::static_func_type; + template using static_ref_func_type = typename basetype::template traits::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 named_delegate(typename basetype::template traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, object), m_name(name) { } - template 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 named_delegate(typename basetype::template traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) : basetype(funcptr, object), m_name(name) { } - template 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(this) = src; m_name = src.m_name; return *this; } + template named_delegate(member_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { } + template named_delegate(const_member_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { } + explicit named_delegate(std::function funcptr, const char *name) : basetype(funcptr), m_name(name) { } + template named_delegate(static_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, object), m_name(name) { } + template named_delegate(static_ref_func_type 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 -class device_delegate : public named_delegate<_Signature>, public device_delegate_helper +template +class device_delegate : public named_delegate, public device_delegate_helper { - typedef device_delegate<_Signature> thistype; - typedef named_delegate<_Signature> basetype; + using thistype = device_delegate; + using basetype = named_delegate; + template using member_func_type = typename basetype::template member_func_type; + template using const_member_func_type = typename basetype::template const_member_func_type; + template using static_func_type = typename basetype::template static_func_type; + template using static_ref_func_type = typename basetype::template static_ref_func_type; 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 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(object))) { } - template 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(object))) { } - template 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(object))) { } - template 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(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(this) = src; m_device_name = src.m_device_name; return *this; } + template device_delegate(member_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast(object))) { } + template device_delegate(const_member_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast(object))) { } + template device_delegate(static_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast(object))) { } + template device_delegate(static_ref_func_type funcptr, const char *name, FunctionClass *object) : basetype(funcptr, name, object), device_delegate_helper(safe_tag(dynamic_cast(object))) { } + device_delegate(std::function 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 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 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 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 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 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 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::static_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(nullptr) { } - device_delegate(typename basetype::template traits::static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(nullptr) { } + template device_delegate(member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(devname) { } + template device_delegate(member_func_type funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(devname) { } + template device_delegate(const_member_func_type funcptr, const char *name, const char *devname) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(devname) { } + template device_delegate(const_member_func_type funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(devname) { } + template device_delegate(static_func_type funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(devname) { } + template device_delegate(static_ref_func_type funcptr, const char *name, const char *devname, FunctionClass *) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(devname) { } + device_delegate(static_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast(nullptr)), device_delegate_helper(nullptr) { } + device_delegate(static_ref_func_type funcptr, const char *name) : basetype(funcptr, name, static_cast(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 diff --git a/src/emu/devfind.h b/src/emu/devfind.h index cc15c201af9..1e61ad1c866 100644 --- a/src/emu/devfind.h +++ b/src/emu/devfind.h @@ -22,6 +22,7 @@ #include #include #include +#include //************************************************************************** // 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 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. diff --git a/src/emu/device.h b/src/emu/device.h index 8ff57dcc83f..3dbaa5f4e37 100644 --- a/src/emu/device.h +++ b/src/emu/device.h @@ -265,6 +265,7 @@ class device_type_impl : public device_type_impl_base public: using device_type_impl_base::device_type_impl_base; template DeviceClass &operator()(machine_config &config, char const *tag, Params &&... args) const; + template DeviceClass &operator()(machine_config &config, device_finder &finder, Params &&... args) const; }; diff --git a/src/emu/device.ipp b/src/emu/device.ipp index c5c97568313..848223dd0c7 100644 --- a/src/emu/device.ipp +++ b/src/emu/device.ipp @@ -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 clock_update_delegate; + //************************************************************************** // MEMBER TEMPLATES //************************************************************************** +namespace emu { namespace detail { + +template template +DeviceClass &device_type_impl::operator()(machine_config &config, char const *tag, Params &&... args) const +{ + return dynamic_cast(*config.device_add(tag, *this, std::forward(args)...)); +} + +template template +DeviceClass &device_type_impl::operator()(machine_config &config, device_finder &finder, Params &&... args) const +{ + std::pair const target(finder.finder_target()); + assert(&config.current_device() == &target.first); + DeviceClass &result(dynamic_cast(*config.device_add(target.second, *this, std::forward(args)...))); + return finder = result; +} + +} } // namespace emu::detail + + template 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 diff --git a/src/emu/emu.h b/src/emu/emu.h index a1f72c051f3..642bc65ad54 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -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__ diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h index f5de6232f05..41e725e7a58 100644 --- a/src/emu/emufwd.h +++ b/src/emu/emufwd.h @@ -103,6 +103,7 @@ class devcb_write_base; // declared in devfind.h class finder_base; +template class device_finder; // declared in device.h class device_interface; diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h index 86902c4b525..0c09f4b69ab 100644 --- a/src/emu/mconfig.h +++ b/src/emu/mconfig.h @@ -128,17 +128,6 @@ private: }; -namespace emu { namespace detail { - -template template -DeviceClass &device_type_impl::operator()(machine_config &config, char const *tag, Params &&... args) const -{ - return dynamic_cast(*config.device_add(tag, *this, std::forward(args)...)); -} - -} } // namespace emu::detail - - //*************************************************************************/ /** @name Machine config start/end macros */ //*************************************************************************/ diff --git a/src/mame/drivers/osborne1.cpp b/src/mame/drivers/osborne1.cpp index 1e98a1af636..528bc0a0f85 100644 --- a/src/mame/drivers/osborne1.cpp +++ b/src/mame/drivers/osborne1.cpp @@ -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 diff --git a/src/mame/drivers/seta2.cpp b/src/mame/drivers/seta2.cpp index 6d66a44cdc3..b2da542dac8 100644 --- a/src/mame/drivers/seta2.cpp +++ b/src/mame/drivers/seta2.cpp @@ -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(*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 static devcb_base &set_tx_cb(device_t &device, _Object object) { return downcast(device).m_tx_cb.set_callback(object); } + template devcb_base &set_tx_cb(Object &&cb) { return m_tx_cb.set_callback(std::forward(cb)); } protected: virtual void device_start() override; diff --git a/src/mame/drivers/tranz330.cpp b/src/mame/drivers/tranz330.cpp index 9b6357cc10d..8eaaebf2ab1 100644 --- a/src/mame/drivers/tranz330.cpp +++ b/src/mame/drivers/tranz330.cpp @@ -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); diff --git a/src/mame/drivers/zorba.cpp b/src/mame/drivers/zorba.cpp index 90419732203..01e5ead77be 100644 --- a/src/mame/drivers/zorba.cpp +++ b/src/mame/drivers/zorba.cpp @@ -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 diff --git a/src/mame/machine/egret.h b/src/mame/machine/egret.h index 1cb7e59090a..a6bb3bc6fc8 100644 --- a/src/mame/machine/egret.h +++ b/src/mame/machine/egret.h @@ -94,10 +94,10 @@ public: int rom_offset; - template devcb_base &set_reset_cb(_Object wr) { return write_reset.set_callback(wr); } - template devcb_base &set_linechange_cb(_Object wr) { return write_linechange.set_callback(wr); } - template devcb_base &set_via_clock_cb(_Object wr) { return write_via_clock.set_callback(wr); } - template devcb_base &set_via_data_cb(_Object wr) { return write_via_data.set_callback(wr); } + template devcb_base &set_reset_cb(Object &&wr) { return write_reset.set_callback(std::forward(wr)); } + template devcb_base &set_linechange_cb(Object &&wr) { return write_linechange.set_callback(std::forward(wr)); } + template devcb_base &set_via_clock_cb(Object &&wr) { return write_via_clock.set_callback(std::forward(wr)); } + template devcb_base &set_via_data_cb(Object &&wr) { return write_via_data.set_callback(std::forward(wr)); } devcb_write_line write_reset, write_linechange, write_via_clock, write_via_data; diff --git a/src/mame/machine/k573dio.h b/src/mame/machine/k573dio.h index 39a5a7da87c..bf4d90afbcd 100644 --- a/src/mame/machine/k573dio.h +++ b/src/mame/machine/k573dio.h @@ -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 void set_output_cb(_write _output_cb) + template void set_output_cb(Write &&_output_cb) { - output_cb.set_callback(_output_cb); + output_cb.set_callback(std::forward(_output_cb)); } required_device mas3507d; diff --git a/src/mame/video/nick.h b/src/mame/video/nick.h index d3fd53bf110..a57258309c7 100644 --- a/src/mame/video/nick.h +++ b/src/mame/video/nick.h @@ -75,7 +75,7 @@ public: // construction/destruction nick_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template devcb_base &set_virq_wr_callback(_Object object) { return m_write_virq.set_callback(object); } + template devcb_base &set_virq_wr_callback(Object &&cb) { return m_write_virq.set_callback(std::forward(cb)); } virtual void vram_map(address_map &map); virtual void vio_map(address_map &map); diff --git a/src/mame/video/powervr2.h b/src/mame/video/powervr2.h index 12ce9c6e248..553bcc04281 100644 --- a/src/mame/video/powervr2.h +++ b/src/mame/video/powervr2.h @@ -141,7 +141,7 @@ public: int next_y; powervr2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - template void set_irq_cb(_cb cb) { irq_cb.set_callback(cb); } + template void set_irq_cb(Object &&cb) { irq_cb.set_callback(std::forward(cb)); } DECLARE_READ32_MEMBER( id_r ); DECLARE_READ32_MEMBER( revision_r );