From 9ca073b15974f894e12cdae46ce8f8d8607720a3 Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Tue, 13 Jun 2023 23:15:00 +1000 Subject: emu/devdelegate.h: Added resolve_safe and resolve_all_safe helpers. Uses decay rules, so if a delegate returns a reference and you want to supply a referene to an object you don't want copied as the default result, remember to use std::ref. Updated a few devices to use resolve_safe on device delegates to streamline code. --- src/devices/bus/psx/ctlrport.cpp | 7 +- src/devices/bus/psx/ctlrport.h | 13 +- src/devices/bus/psx/multitap.cpp | 8 +- src/devices/bus/snes_ctrl/ctrl.cpp | 4 +- src/devices/bus/snes_ctrl/ctrl.h | 4 +- src/devices/cpu/ccpu/ccpu.cpp | 3 +- src/devices/cpu/diablo/diablo1300.h | 9 - src/devices/cpu/i8085/i8085.cpp | 8 +- src/devices/cpu/i86/i186.cpp | 8 +- src/devices/cpu/i86/i286.cpp | 5 +- src/devices/cpu/i86/i286.h | 6 +- src/devices/cpu/lc8670/lc8670.cpp | 6 +- src/devices/cpu/mcs40/mcs40.cpp | 26 +-- src/devices/cpu/patinhofeio/patinho_feio.cpp | 8 +- src/devices/machine/at.cpp | 3 +- src/devices/machine/i3001.cpp | 14 +- src/devices/machine/i3002.cpp | 42 +++-- src/devices/machine/keyboard.cpp | 3 +- src/devices/machine/mc68328.cpp | 12 +- src/devices/machine/microtch.cpp | 4 +- src/devices/machine/microtch.h | 4 +- src/devices/machine/myb3k_kbd.cpp | 3 +- src/devices/machine/tc009xlvc.cpp | 16 +- src/devices/machine/terminal.cpp | 2 +- src/devices/machine/terminal.h | 2 +- src/devices/machine/upd7002.cpp | 6 +- src/devices/sound/bsmt2000.cpp | 5 +- src/devices/sound/lynx.cpp | 7 +- src/devices/video/i8275.cpp | 25 ++- src/devices/video/mc6845.cpp | 14 +- src/devices/video/scn2674.cpp | 4 +- src/devices/video/tmap038.cpp | 8 +- src/devices/video/upd7220.cpp | 13 +- src/emu/devdelegate.h | 245 +++++++++++++++++++-------- src/mame/nec/pc9801.cpp | 4 +- 35 files changed, 300 insertions(+), 251 deletions(-) diff --git a/src/devices/bus/psx/ctlrport.cpp b/src/devices/bus/psx/ctlrport.cpp index dc9a6ae392a..ab2c9db7722 100644 --- a/src/devices/bus/psx/ctlrport.cpp +++ b/src/devices/bus/psx/ctlrport.cpp @@ -4,9 +4,11 @@ #include "emu.h" #include "ctlrport.h" + #include "analogue.h" #include "multitap.h" + DEFINE_DEVICE_TYPE(PSX_CONTROLLER_PORT, psx_controller_port_device, "psx_controller_port", "Playstation Controller Port") DEFINE_DEVICE_TYPE(PSXCONTROLLERPORTS, psxcontrollerports_device, "psxcontrollerports", "Playstation Controller Bus") DEFINE_DEVICE_TYPE(PSX_STANDARD_CONTROLLER, psx_standard_controller_device, "psx_standard_controller", "Playstation Standard Controller") @@ -14,6 +16,7 @@ DEFINE_DEVICE_TYPE(PSX_STANDARD_CONTROLLER, psx_standard_controller_device, "psx psx_controller_port_device::psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, PSX_CONTROLLER_PORT, tag, owner, clock), device_single_card_slot_interface(mconfig, *this), + m_ack_cb(*this), m_tx(false), m_dev(nullptr), m_card(*this, "card") @@ -52,8 +55,8 @@ void psxcontrollerports_device::device_start() m_dsr_handler.resolve_safe(); m_rxd_handler.resolve_safe(); - m_port0->setup_ack_cb(psx_controller_port_device::void_cb(&psxcontrollerports_device::ack, this)); - m_port1->setup_ack_cb(psx_controller_port_device::void_cb(&psxcontrollerports_device::ack, this)); + m_port0->set_ack_cb(*this, FUNC(psxcontrollerports_device::ack)); + m_port1->set_ack_cb(*this, FUNC(psxcontrollerports_device::ack)); } // add controllers to define so they can be connected to the multitap diff --git a/src/devices/bus/psx/ctlrport.h b/src/devices/bus/psx/ctlrport.h index ff6859b1d72..0fc7fba52d7 100644 --- a/src/devices/bus/psx/ctlrport.h +++ b/src/devices/bus/psx/ctlrport.h @@ -108,6 +108,8 @@ class psx_controller_port_device : public device_t, public device_single_card_slot_interface { public: + typedef device_delegate void_cb; + template psx_controller_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt) : psx_controller_port_device(mconfig, tag, owner, (uint32_t)0) @@ -119,9 +121,10 @@ public: } psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - typedef delegate void_cb; - void ack() { if(!ack_cb.isnull()) ack_cb(); } - void setup_ack_cb(void_cb cb) { ack_cb = cb; } + template + void set_ack_cb(T &&... args) { m_ack_cb.set(std::forward(args)...); } + + void ack() { m_ack_cb(); } void tx_w(int state) { m_tx = state; } void sel_w(int state) { if(m_dev) m_dev->sel_w(state); m_card->sel_w(state); } @@ -134,14 +137,14 @@ public: void disable_card(bool status); protected: - virtual void device_start() override {} + virtual void device_start() override { m_ack_cb.resolve_safe(); } virtual void device_reset() override { m_tx = true; } virtual void device_config_complete() override; virtual void device_add_mconfig(machine_config &config) override; private: - void_cb ack_cb; + void_cb m_ack_cb; bool m_tx; device_psx_controller_interface *m_dev; diff --git a/src/devices/bus/psx/multitap.cpp b/src/devices/bus/psx/multitap.cpp index 5de09102287..4cbeba57c96 100644 --- a/src/devices/bus/psx/multitap.cpp +++ b/src/devices/bus/psx/multitap.cpp @@ -31,10 +31,10 @@ void psx_multitap_device::device_add_mconfig(machine_config &config) void psx_multitap_device::device_start() { - m_porta->setup_ack_cb(psx_controller_port_device::void_cb(&psx_multitap_device::ack, this)); - m_portb->setup_ack_cb(psx_controller_port_device::void_cb(&psx_multitap_device::ack, this)); - m_portc->setup_ack_cb(psx_controller_port_device::void_cb(&psx_multitap_device::ack, this)); - m_portd->setup_ack_cb(psx_controller_port_device::void_cb(&psx_multitap_device::ack, this)); + m_porta->set_ack_cb(*this, FUNC(psx_multitap_device::ack)); + m_portb->set_ack_cb(*this, FUNC(psx_multitap_device::ack)); + m_portc->set_ack_cb(*this, FUNC(psx_multitap_device::ack)); + m_portd->set_ack_cb(*this, FUNC(psx_multitap_device::ack)); m_nextmode = false; save_item(NAME(m_activeport)); diff --git a/src/devices/bus/snes_ctrl/ctrl.cpp b/src/devices/bus/snes_ctrl/ctrl.cpp index 68e69ee0a8b..69fe2554725 100644 --- a/src/devices/bus/snes_ctrl/ctrl.cpp +++ b/src/devices/bus/snes_ctrl/ctrl.cpp @@ -85,8 +85,8 @@ snes_control_port_device::~snes_control_port_device() void snes_control_port_device::device_start() { m_device = get_card_device(); - m_onscreen_cb.resolve(); - m_gunlatch_cb.resolve(); + m_onscreen_cb.resolve_safe(true); + m_gunlatch_cb.resolve_safe(); } diff --git a/src/devices/bus/snes_ctrl/ctrl.h b/src/devices/bus/snes_ctrl/ctrl.h index b6e6ddc869e..30169d8a7dd 100644 --- a/src/devices/bus/snes_ctrl/ctrl.h +++ b/src/devices/bus/snes_ctrl/ctrl.h @@ -71,8 +71,8 @@ public: void write_strobe(uint8_t data); void port_poll(); - bool onscreen_cb(int16_t x, int16_t y) { return m_onscreen_cb.isnull() ? true : m_onscreen_cb(x, y); } - void gunlatch_cb(int16_t x, int16_t y) { if (!m_gunlatch_cb.isnull()) m_gunlatch_cb(x, y); } + bool onscreen_cb(int16_t x, int16_t y) { return m_onscreen_cb(x, y); } + void gunlatch_cb(int16_t x, int16_t y) { m_gunlatch_cb(x, y); } protected: // device-level overrides diff --git a/src/devices/cpu/ccpu/ccpu.cpp b/src/devices/cpu/ccpu/ccpu.cpp index f39de3fe1fe..00a210a6c23 100644 --- a/src/devices/cpu/ccpu/ccpu.cpp +++ b/src/devices/cpu/ccpu/ccpu.cpp @@ -105,8 +105,7 @@ void ccpu_cpu_device::device_start() { /* copy input params */ m_external_input.resolve_safe(0); - m_vector_callback.resolve(); - assert(!m_vector_callback.isnull()); + m_vector_callback.resolve_safe(); space(AS_PROGRAM).cache(m_cache); space(AS_PROGRAM).specific(m_program); diff --git a/src/devices/cpu/diablo/diablo1300.h b/src/devices/cpu/diablo/diablo1300.h index 753d2f7b2b1..f706938f2a0 100644 --- a/src/devices/cpu/diablo/diablo1300.h +++ b/src/devices/cpu/diablo/diablo1300.h @@ -79,15 +79,6 @@ protected: // rom regions memory_region *m_table; - -#if 0 - // Callbacks and set methods - write_line_delegate m_xxx_cb; // Called when xxx happens in CPU - void call_xxx_cb(int state){ if (!m_xxx.cb.isnull()) (m_xxx_cb)(state); -public: - void set_xxx_callback( write_line_delegate callback ){ m_xxx_cb = callback; } - void set_line_yyy(int state){ m_yyy = state; } -#endif }; // device type definition diff --git a/src/devices/cpu/i8085/i8085.cpp b/src/devices/cpu/i8085/i8085.cpp index 09b739c76d0..992f89d4427 100644 --- a/src/devices/cpu/i8085/i8085.cpp +++ b/src/devices/cpu/i8085/i8085.cpp @@ -250,16 +250,14 @@ device_memory_interface::space_config_vector i8085a_cpu_device::memory_space_con void i8085a_cpu_device::device_config_complete() { - m_clk_out_func.resolve(); - if (!m_clk_out_func.isnull()) - m_clk_out_func(clock() / 2); + m_clk_out_func.resolve_safe(); + m_clk_out_func(clock() / 2); } void i8085a_cpu_device::device_clock_changed() { - if (!m_clk_out_func.isnull()) - m_clk_out_func(clock() / 2); + m_clk_out_func(clock() / 2); } diff --git a/src/devices/cpu/i86/i186.cpp b/src/devices/cpu/i86/i186.cpp index 1bfd4820c5e..6114a8ec1af 100644 --- a/src/devices/cpu/i86/i186.cpp +++ b/src/devices/cpu/i86/i186.cpp @@ -739,7 +739,7 @@ void i80186_cpu_device::device_start() m_out_chip_select_func.resolve_safe(); m_irmx_irq_cb.resolve_safe(); m_irqa_cb.resolve_safe(); - m_irmx_irq_ack.resolve(); + m_irmx_irq_ack.resolve_safe(0); } void i80186_cpu_device::device_reset() @@ -907,11 +907,7 @@ IRQ_CALLBACK_MEMBER(i80186_cpu_device::inta_callback) m_irqa_cb(CLEAR_LINE); } if (BIT(m_reloc, 14)) - { - if (!m_irmx_irq_ack.isnull()) - return m_irmx_irq_ack(device, irqline); - return 0; - } + return m_irmx_irq_ack(device, irqline); return int_callback(device, irqline); } diff --git a/src/devices/cpu/i86/i286.cpp b/src/devices/cpu/i86/i286.cpp index 2562dcc85b9..c13985bf2eb 100644 --- a/src/devices/cpu/i86/i286.cpp +++ b/src/devices/cpu/i86/i286.cpp @@ -171,6 +171,7 @@ i80286_cpu_device::i80286_cpu_device(const machine_config &mconfig, const char * , m_program_config("program", ENDIANNESS_LITTLE, 16, 24, 0) , m_opcodes_config("opcodes", ENDIANNESS_LITTLE, 16, 24, 0) , m_io_config("io", ENDIANNESS_LITTLE, 16, 16, 0) + , m_a20_callback(*this) , m_out_shutdown_func(*this) { memcpy(m_timing, m_i80286_timing, sizeof(m_i80286_timing)); @@ -221,6 +222,7 @@ void i80286_cpu_device::device_reset() void i80286_cpu_device::device_start() { i8086_common_cpu_device::device_start(); + save_item(NAME(m_trap_level)); save_item(NAME(m_msw)); save_item(NAME(m_base)); @@ -277,6 +279,7 @@ void i80286_cpu_device::device_start() state_add( STATE_GENPCBASE, "CURPC", [this] { return m_base[CS] + m_prev_ip; }).mask(0xffffff).noshow(); state_add( I8086_HALT, "HALT", m_halt ).mask(1); + m_a20_callback.resolve_safe(0xffffff); m_out_shutdown_func.resolve_safe(); } @@ -393,7 +396,7 @@ void i80286_cpu_device::execute_set_input(int inptnum, int state) } } else if(inptnum == INPUT_LINE_A20) - m_amask = m_a20_callback.isnull() ? 0xffffff : m_a20_callback(state); + m_amask = m_a20_callback(state); else { m_irq_state = state; diff --git a/src/devices/cpu/i86/i286.h b/src/devices/cpu/i86/i286.h index 4adf6cbb4a3..78b1f1d6b03 100644 --- a/src/devices/cpu/i86/i286.h +++ b/src/devices/cpu/i86/i286.h @@ -81,12 +81,14 @@ public: // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; - typedef delegate a20_cb; - template void set_a20_callback(Object &&cb) { m_a20_callback = std::forward(cb); } + template + void set_a20_callback(T &&... args) { m_a20_callback.set(std::forward(args)...); } auto shutdown_callback() { return m_out_shutdown_func.bind(); } protected: + typedef device_delegate a20_cb; + virtual void execute_run() override; virtual void device_reset() override; virtual void device_start() override; diff --git a/src/devices/cpu/lc8670/lc8670.cpp b/src/devices/cpu/lc8670/lc8670.cpp index 01c8bc8873a..14bb12714c7 100644 --- a/src/devices/cpu/lc8670/lc8670.cpp +++ b/src/devices/cpu/lc8670/lc8670.cpp @@ -202,7 +202,7 @@ void lc8670_cpu_device::device_start() // resolve callbacks m_bankswitch_func.resolve(); - m_lcd_update_func.resolve(); + m_lcd_update_func.resolve_safe(0); // setup timers m_basetimer = timer_alloc(FUNC(lc8670_cpu_device::base_timer_update), this); @@ -560,9 +560,7 @@ void lc8670_cpu_device::execute_set_input(int inputnum, int state) uint32_t lc8670_cpu_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - if (!m_lcd_update_func.isnull()) - return m_lcd_update_func(bitmap, cliprect, m_xram, (REG_MCR & 0x08) && (REG_VCCR & 0x80), REG_STAD); - return 0; + return m_lcd_update_func(bitmap, cliprect, m_xram, (REG_MCR & 0x08) && (REG_VCCR & 0x80), REG_STAD); } diff --git a/src/devices/cpu/mcs40/mcs40.cpp b/src/devices/cpu/mcs40/mcs40.cpp index 0b9b80c719f..138850c69c9 100644 --- a/src/devices/cpu/mcs40/mcs40.cpp +++ b/src/devices/cpu/mcs40/mcs40.cpp @@ -142,7 +142,7 @@ void mcs40_cpu_device_base::device_start() m_spaces[AS_PROGRAM_MEMORY] = &space(AS_PROGRAM_MEMORY); m_spaces[AS_ROM]->cache(m_cache); - m_bus_cycle_cb.resolve(); + m_bus_cycle_cb.resolve_safe(); m_sync_cb.resolve_safe(); m_cm_rom_cb.resolve_all_safe(); m_cm_ram_cb.resolve_all_safe(); @@ -603,15 +603,13 @@ inline void mcs40_cpu_device_base::do_a1() m_sync_cb(1); update_4289_pm(1U); update_4289_f_l(1U); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::A1, 1U, m_rom_addr & 0x000fU); + m_bus_cycle_cb(phase::A1, 1U, m_rom_addr & 0x000fU); } inline void mcs40_cpu_device_base::do_a2() { m_4289_a = (m_4289_a & 0x0fU) | (m_rom_addr & 0xf0U); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::A2, 1U, (m_rom_addr >> 4) & 0x000fU); + m_bus_cycle_cb(phase::A2, 1U, (m_rom_addr >> 4) & 0x000fU); } inline void mcs40_cpu_device_base::do_a3() @@ -619,8 +617,7 @@ inline void mcs40_cpu_device_base::do_a3() m_4289_c = (m_rom_addr >> 8) & 0x0fU; update_cm_rom(BIT(m_cr, 3) ? 0x01U : 0x02U); update_cm_ram(f_cm_ram_table[m_cr & 0x07U]); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::A3, 1U, (m_rom_addr >> 8) & 0x000fU); + m_bus_cycle_cb(phase::A3, 1U, (m_rom_addr >> 8) & 0x000fU); } inline void mcs40_cpu_device_base::do_m1() @@ -642,8 +639,7 @@ inline void mcs40_cpu_device_base::do_m1() m_arg = read; } m_decoded_halt = false; - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::M1, 1U, (read >> 4) & 0x0fU); + m_bus_cycle_cb(phase::M1, 1U, (read >> 4) & 0x0fU); } inline void mcs40_cpu_device_base::do_m2() @@ -664,8 +660,7 @@ inline void mcs40_cpu_device_base::do_m2() if (!m_stop_ff && (cycle::IN != m_cycle)) pc() = (pc() + 1) & 0x0fff; m_rom_addr = pc(); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::M2, 1U, read & 0x0fU); + m_bus_cycle_cb(phase::M2, 1U, read & 0x0fU); } inline void mcs40_cpu_device_base::do_x1() @@ -702,8 +697,7 @@ inline void mcs40_cpu_device_base::do_x1() else assert(pmem::WRITE == m_program_op); } - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::X1, 1U, output); + m_bus_cycle_cb(phase::X1, 1U, output); } void mcs40_cpu_device_base::do_x2() @@ -732,8 +726,7 @@ void mcs40_cpu_device_base::do_x2() set_a(output = m_arg & 0x0fU); else if (pmem::WRITE == m_program_op) output = get_a(); - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::X2, 1U, output); + m_bus_cycle_cb(phase::X2, 1U, output); } void mcs40_cpu_device_base::do_x3() @@ -763,8 +756,7 @@ void mcs40_cpu_device_base::do_x3() m_stp_ack_cb(1U); } m_resume = false; - if (!m_bus_cycle_cb.isnull()) - m_bus_cycle_cb(phase::X3, 0U, m_new_rc & 0x0fU); // FIXME: what appears on the bus if it isn't SRC? + m_bus_cycle_cb(phase::X3, 0U, m_new_rc & 0x0fU); // FIXME: what appears on the bus if it isn't SRC? } diff --git a/src/devices/cpu/patinhofeio/patinho_feio.cpp b/src/devices/cpu/patinhofeio/patinho_feio.cpp index d017ff8a318..8757ab29f5f 100644 --- a/src/devices/cpu/patinhofeio/patinho_feio.cpp +++ b/src/devices/cpu/patinhofeio/patinho_feio.cpp @@ -94,7 +94,7 @@ void patinho_feio_cpu_device::transfer_byte_from_external_device(uint8_t channel void patinho_feio_cpu_device::device_start() { m_program = &space(AS_PROGRAM); - m_update_panel_cb.resolve(); + m_update_panel_cb.resolve_safe(); //TODO: implement handling of these special purpose registers // which are also mapped to the first few main memory positions: @@ -159,8 +159,7 @@ void patinho_feio_cpu_device::device_reset() m_addr = 0; m_opcode = 0; m_mode = ADDRESSING_MODE; - if (!m_update_panel_cb.isnull()) - m_update_panel_cb(ACC, m_opcode, READ_BYTE_PATINHO(m_addr), m_addr, PC, FLAGS, RC, m_mode); + m_update_panel_cb(ACC, m_opcode, READ_BYTE_PATINHO(m_addr), m_addr, PC, FLAGS, RC, m_mode); } /* execute instructions on this CPU until icount expires */ @@ -169,8 +168,7 @@ void patinho_feio_cpu_device::execute_run() { read_panel_keys_register(); m_ext = READ_ACC_EXTENSION_REG(); m_idx = READ_INDEX_REG(); - if (!m_update_panel_cb.isnull()) - m_update_panel_cb(ACC, READ_BYTE_PATINHO(PC), READ_BYTE_PATINHO(m_addr), m_addr, PC, FLAGS, RC, m_mode); + m_update_panel_cb(ACC, READ_BYTE_PATINHO(PC), READ_BYTE_PATINHO(m_addr), m_addr, PC, FLAGS, RC, m_mode); debugger_instruction_hook(PC); if (!m_run){ diff --git a/src/devices/machine/at.cpp b/src/devices/machine/at.cpp index c1ddc37699c..f88a65688d0 100644 --- a/src/devices/machine/at.cpp +++ b/src/devices/machine/at.cpp @@ -43,8 +43,9 @@ void at_mb_device::device_reset() void at_mb_device::device_start() { + // FIXME: this is gross and should be done in machine configuration if(!strncmp(m_maincpu->shortname(), "i80286", 6)) - downcast(m_maincpu.target())->set_a20_callback(i80286_cpu_device::a20_cb(&at_mb_device::a20_286, this)); + downcast(m_maincpu.target())->set_a20_callback(*this, FUNC(at_mb_device::a20_286)); } void at_mb_device::at_softlists(machine_config &config) diff --git a/src/devices/machine/i3001.cpp b/src/devices/machine/i3001.cpp index e6207805d43..2f607c4ff0c 100644 --- a/src/devices/machine/i3001.cpp +++ b/src/devices/machine/i3001.cpp @@ -47,9 +47,7 @@ void i3001_device::fc_w(uint8_t fc) m_fo = true; break; } - if (!m_fo_handler.isnull()) { - m_fo_handler(m_fo); - } + m_fo_handler(m_fo); } void i3001_device::clk_w(int state) @@ -59,9 +57,9 @@ void i3001_device::clk_w(int state) void i3001_device::device_start() { - m_fo_handler.resolve(); - m_px_handler.resolve(); - m_sx_handler.resolve(); + m_fo_handler.resolve_safe(); + m_px_handler.resolve_safe(0); + m_sx_handler.resolve_safe(0); save_item(NAME(m_addr)); save_item(NAME(m_pr)); @@ -132,8 +130,8 @@ void i3001_device::update() m_addr = pack_row_col((get_row(m_addr) & 0b11000) | 0b00100 | (m_ac & 0b00011) , 0b1100 | (m_pr & 0b0011)); } else { // JPX - uint8_t px = !m_px_handler.isnull() ? m_px_handler() & 0b1111 : 0; - m_pr = !m_sx_handler.isnull() ? m_sx_handler() & 0b1111 : 0; + uint8_t px = m_px_handler() & 0b1111; + m_pr = m_sx_handler() & 0b1111; m_addr = pack_row_col((get_row(m_addr) & 0b11100) | (m_ac & 0b00011) , px); } } diff --git a/src/devices/machine/i3002.cpp b/src/devices/machine/i3002.cpp index d0ef79794f0..932646f1114 100644 --- a/src/devices/machine/i3002.cpp +++ b/src/devices/machine/i3002.cpp @@ -136,10 +136,10 @@ bool i3002_device::update_ro() void i3002_device::device_start() { - m_co_handler.resolve(); - m_ro_handler.resolve(); - m_ibus_handler.resolve(); - m_mbus_handler.resolve(); + m_co_handler.resolve_safe(); + m_ro_handler.resolve_safe(); + m_ibus_handler.resolve_safe(0); + m_mbus_handler.resolve_safe(0); save_item(NAME(m_reg)); save_item(NAME(m_fc)); @@ -173,7 +173,7 @@ void i3002_device::update() case 1: // FC 0 RG II { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; uint8_t tmp = (m_reg[ REG_AC ] & m_kbus) + m + m_ci; m_reg[ reg ] = tmp & WORD_MASK; set_co(BIT(tmp , SLICE_SIZE)); @@ -184,7 +184,7 @@ void i3002_device::update() // FC 0 RG III { // Who designed this mess??? - uint8_t ik = !m_ibus_handler.isnull() ? m_ibus_handler() & WORD_MASK & m_kbus : 0; + uint8_t ik = m_ibus_handler() & WORD_MASK & m_kbus; uint8_t at = m_reg[ reg ]; m_reg[ reg ] = 0; set_ro(BIT(at , 0) && !BIT(ik , 0)); @@ -214,7 +214,7 @@ void i3002_device::update() case 1: // FC 1 RG II { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; m_reg[ REG_MAR ] = m_kbus | m; uint8_t tmp = m + m_kbus + m_ci; m_reg[ reg ] = tmp & WORD_MASK; @@ -249,7 +249,7 @@ void i3002_device::update() case 2: // FC 2 RG III { - uint8_t i = !m_ibus_handler.isnull() ? m_ibus_handler() & WORD_MASK : 0; + uint8_t i = m_ibus_handler() & WORD_MASK; uint8_t tmp = (i & m_kbus) + WORD_MASK + m_ci; m_reg[ reg ] = tmp & WORD_MASK; set_co(BIT(tmp , SLICE_SIZE)); @@ -272,7 +272,7 @@ void i3002_device::update() case 1: // FC 3 RG II (== FC 0 RG II) { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; uint8_t tmp = (m_reg[ REG_AC ] & m_kbus) + m + m_ci; m_reg[ reg ] = tmp & WORD_MASK; set_co(BIT(tmp , SLICE_SIZE)); @@ -282,7 +282,7 @@ void i3002_device::update() case 2: // FC 3 RG III { - uint8_t i = !m_ibus_handler.isnull() ? m_ibus_handler() & WORD_MASK : 0; + uint8_t i = m_ibus_handler() & WORD_MASK; uint8_t tmp = (i & m_kbus) + m_reg[ reg ] + m_ci; m_reg[ reg ] = tmp & WORD_MASK; set_co(BIT(tmp , SLICE_SIZE)); @@ -305,7 +305,7 @@ void i3002_device::update() case 1: // FC 4 RG II { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; uint8_t tmp = m & m_reg[ REG_AC ] & m_kbus; m_reg[ reg ] = tmp; set_co(m_ci || tmp != 0); @@ -315,7 +315,7 @@ void i3002_device::update() case 2: // FC 4 RG III { - uint8_t i = !m_ibus_handler.isnull() ? m_ibus_handler() & WORD_MASK : 0; + uint8_t i = m_ibus_handler() & WORD_MASK; uint8_t tmp = i & m_reg[ reg ] & m_kbus; m_reg[ reg ] = tmp; set_co(m_ci || tmp != 0); @@ -340,7 +340,7 @@ void i3002_device::update() case 1: // FC 5 RG II { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; uint8_t tmp = m & m_kbus; m_reg[ reg ] = tmp; set_co(m_ci || tmp != 0); @@ -363,7 +363,7 @@ void i3002_device::update() case 1: // FC 6 RG II { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; uint8_t tmp = m_reg[ REG_AC ] & m_kbus; m_reg[ reg ] = m | tmp; set_co(m_ci || tmp != 0); @@ -373,7 +373,7 @@ void i3002_device::update() case 2: // FC 6 RG III { - uint8_t ik = !m_ibus_handler.isnull() ? m_ibus_handler() & WORD_MASK & m_kbus : 0; + uint8_t ik = m_ibus_handler() & WORD_MASK & m_kbus; m_reg[ reg ] |= ik; set_co(m_ci || ik != 0); } @@ -395,7 +395,7 @@ void i3002_device::update() case 1: // FC 7 RG II { - uint8_t m = !m_mbus_handler.isnull() ? m_mbus_handler() & WORD_MASK : 0; + uint8_t m = m_mbus_handler() & WORD_MASK; uint8_t tmp = m_reg[ REG_AC ] & m_kbus; set_co(m_ci || (m & tmp) != 0); m_reg[ reg ] = m ^ tmp ^ WORD_MASK; @@ -405,7 +405,7 @@ void i3002_device::update() case 2: // FC 7 RG III { - uint8_t ik = !m_ibus_handler.isnull() ? m_ibus_handler() & WORD_MASK & m_kbus : 0; + uint8_t ik = m_ibus_handler() & WORD_MASK & m_kbus; set_co(m_ci || (m_reg[ reg ] & ik) != 0); m_reg[ reg ] = m_reg[ reg ] ^ ik ^ WORD_MASK; } @@ -418,15 +418,11 @@ void i3002_device::update() void i3002_device::set_co(bool co) { m_co = co; - if (!m_co_handler.isnull()) { - m_co_handler(m_co); - } + m_co_handler(m_co); } void i3002_device::set_ro(bool ro) { m_ro = ro; - if (!m_ro_handler.isnull()) { - m_ro_handler(m_ro); - } + m_ro_handler(m_ro); } diff --git a/src/devices/machine/keyboard.cpp b/src/devices/machine/keyboard.cpp index eac7263c82c..d307d637d27 100644 --- a/src/devices/machine/keyboard.cpp +++ b/src/devices/machine/keyboard.cpp @@ -276,7 +276,7 @@ ioport_constructor generic_keyboard_device::device_input_ports() const void generic_keyboard_device::device_start() { - m_keyboard_cb.resolve(); + m_keyboard_cb.resolve_safe(); save_item(NAME(m_last_modifiers)); } @@ -307,7 +307,6 @@ void generic_keyboard_device::key_repeat(u8 row, u8 column) void generic_keyboard_device::send_key(u8 code) { - assert(!m_keyboard_cb.isnull()); m_keyboard_cb(code); } diff --git a/src/devices/machine/mc68328.cpp b/src/devices/machine/mc68328.cpp index e8b86833ace..99475c5c1ad 100644 --- a/src/devices/machine/mc68328.cpp +++ b/src/devices/machine/mc68328.cpp @@ -353,7 +353,7 @@ void mc68328_base_device::device_resolve_objects() m_out_lsclk_cb.resolve_safe(); m_out_ld_cb.resolve_safe(); - m_lcd_info_changed_cb.resolve(); + m_lcd_info_changed_cb.resolve_safe(); } void mc68328_device::device_resolve_objects() @@ -3115,10 +3115,7 @@ void mc68328_device::lcd_update_info() LOGMASKED(LOG_LCD, "lxmax %d, lymax %d, divisor %d, lrra %02x, lpxcd %02x\n", m_lxmax, m_lymax + 1, sysclk_divisor, m_lpxcd + 1); constexpr u8 BIT_WIDTHS[4] = { 1, 2, 4, 0xff }; - if (!m_lcd_info_changed_cb.isnull()) - { - m_lcd_info_changed_cb(lcd_frame_duration.as_hz(), lcd_get_width(), m_lymax + 1, BIT_WIDTHS[(m_lpicf & LPICF_PBSIZ) >> LPICF_PBSIZ_SHIFT], BIT_WIDTHS[m_lpicf & LPICF_GS]); - } + m_lcd_info_changed_cb(lcd_frame_duration.as_hz(), lcd_get_width(), m_lymax + 1, BIT_WIDTHS[(m_lpicf & LPICF_PBSIZ) >> LPICF_PBSIZ_SHIFT], BIT_WIDTHS[m_lpicf & LPICF_GS]); m_lcd_update_pending = false; } @@ -3574,10 +3571,7 @@ void mc68ez328_device::lcd_update_info() attotime lcd_frame_duration = (lcd_scan_duration + lcd_dma_duration) * (m_lymax + 1) * 2; constexpr u8 BIT_WIDTHS[4] = { 1, 2, 4, 0xff }; - if (!m_lcd_info_changed_cb.isnull()) - { - m_lcd_info_changed_cb(lcd_frame_duration.as_hz(), lcd_get_width(), m_lymax + 1, BIT_WIDTHS[(m_lpicf & LPICF_PBSIZ) >> LPICF_PBSIZ_SHIFT], BIT_WIDTHS[m_lpicf & LPICF_GS]); - } + m_lcd_info_changed_cb(lcd_frame_duration.as_hz(), lcd_get_width(), m_lymax + 1, BIT_WIDTHS[(m_lpicf & LPICF_PBSIZ) >> LPICF_PBSIZ_SHIFT], BIT_WIDTHS[m_lpicf & LPICF_GS]); m_lcd_update_pending = false; } diff --git a/src/devices/machine/microtch.cpp b/src/devices/machine/microtch.cpp index 7f4562f02f1..4f0cacb8d77 100644 --- a/src/devices/machine/microtch.cpp +++ b/src/devices/machine/microtch.cpp @@ -138,7 +138,7 @@ void microtouch_device::send_touch_packet() int tx = m_touchx->read(); int ty = m_touchy->read(); - if (m_out_touch_cb.isnull() || m_out_touch_cb(&tx, &ty) != 0) + if (m_out_touch_cb(&tx, &ty) != 0) { ty = 0x4000 - ty; @@ -241,7 +241,7 @@ void microtouch_device::device_start() set_data_frame(1, 8, PARITY_NONE, STOP_BITS_1); //8N1? set_tra_rate(clock()); set_rcv_rate(clock()); - m_out_touch_cb.resolve(); + m_out_touch_cb.resolve_safe(1); m_out_stx_func.resolve_safe(); m_output_valid = false; diff --git a/src/devices/machine/microtch.h b/src/devices/machine/microtch.h index 5aea58ed4f8..67656f93b49 100644 --- a/src/devices/machine/microtch.h +++ b/src/devices/machine/microtch.h @@ -15,13 +15,13 @@ public: typedef device_delegate touch_cb; microtouch_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + auto stx() { return m_out_stx_func.bind(); } + template void set_touch_callback(T &&... args) { m_out_touch_cb.set(std::forward(args)...); } void rx(int state) { device_serial_interface::rx_w(state); } DECLARE_INPUT_CHANGED_MEMBER(touch); - template void set_touch_callback(T &&... args) { m_out_touch_cb.set(std::forward(args)...); } - protected: // device_t implementation virtual ioport_constructor device_input_ports() const override; diff --git a/src/devices/machine/myb3k_kbd.cpp b/src/devices/machine/myb3k_kbd.cpp index 768ae3bda91..0eb63868aff 100644 --- a/src/devices/machine/myb3k_kbd.cpp +++ b/src/devices/machine/myb3k_kbd.cpp @@ -354,7 +354,7 @@ ioport_constructor myb3k_keyboard_device::device_input_ports() const void myb3k_keyboard_device::device_start() { - m_keyboard_cb.resolve(); + m_keyboard_cb.resolve_safe(); m_scan_timer = timer_alloc(FUNC(myb3k_keyboard_device::scan_keys), this); m_first_byte_timer = timer_alloc(FUNC(myb3k_keyboard_device::send_first_byte), this); m_second_byte_timer = timer_alloc(FUNC(myb3k_keyboard_device::send_second_byte), this); @@ -370,7 +370,6 @@ void myb3k_keyboard_device::device_reset() void myb3k_keyboard_device::send_byte(u8 code) { - assert(!m_keyboard_cb.isnull()); m_keyboard_cb(code); } diff --git a/src/devices/machine/tc009xlvc.cpp b/src/devices/machine/tc009xlvc.cpp index 8d4b762f53a..12260976822 100644 --- a/src/devices/machine/tc009xlvc.cpp +++ b/src/devices/machine/tc009xlvc.cpp @@ -165,8 +165,7 @@ TILE_GET_INFO_MEMBER(tc0090lvc_device::get_tile_info) | ((attr & 0x03) << 8) | ((tilebank((attr & 0xc) >> 2)) << 10); - if (!m_tile_cb.isnull()) - m_tile_cb(code); + m_tile_cb(code); tileinfo.set(0, code, @@ -218,7 +217,7 @@ void tc0090lvc_device::device_start() space(AS_DATA).specific(m_vram_space); - m_tile_cb.resolve(); + m_tile_cb.resolve_safe(); std::fill_n(&m_vram[0], m_vram.bytes(), 0); std::fill_n(&m_bitmap_ram[0], m_bitmap_ram.bytes(), 0); @@ -310,13 +309,10 @@ void tc0090lvc_device::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, int fx = m_sprram_buffer[count + 3] & 0x1; int fy = m_sprram_buffer[count + 3] & 0x2; - if (!m_tile_cb.isnull()) - { - // each sprite is 4 8x8 tile group, actually tile number for each tile is << 2 of real address - code <<= 2; - m_tile_cb(code); - code >>= 2; - } + // each sprite is 4 8x8 tile group, actually tile number for each tile is << 2 of real address + code <<= 2; + m_tile_cb(code); + code >>= 2; if (global_flip()) { diff --git a/src/devices/machine/terminal.cpp b/src/devices/machine/terminal.cpp index fc1b5cf3092..31ec127a31f 100644 --- a/src/devices/machine/terminal.cpp +++ b/src/devices/machine/terminal.cpp @@ -347,7 +347,7 @@ void generic_terminal_device::device_start() { m_buffer = std::make_unique(m_width * m_height); m_bell_timer = timer_alloc(FUNC(generic_terminal_device::bell_off), this); - m_keyboard_cb.resolve(); + m_keyboard_cb.resolve_safe(); save_pointer(NAME(m_buffer), m_width * m_height); save_item(NAME(m_x_pos)); save_item(NAME(m_framecnt)); diff --git a/src/devices/machine/terminal.h b/src/devices/machine/terminal.h index 5ebf1468b22..098d776e5e0 100644 --- a/src/devices/machine/terminal.h +++ b/src/devices/machine/terminal.h @@ -41,7 +41,7 @@ protected: virtual void device_reset() override; virtual ioport_constructor device_input_ports() const override; virtual void device_add_mconfig(machine_config &config) override; - virtual void send_key(uint8_t code) { if (!m_keyboard_cb.isnull()) m_keyboard_cb(code); } + virtual void send_key(uint8_t code) { m_keyboard_cb(code); } TIMER_CALLBACK_MEMBER(bell_off); diff --git a/src/devices/machine/upd7002.cpp b/src/devices/machine/upd7002.cpp index b1aa3d7cba3..ab97f46b4b3 100644 --- a/src/devices/machine/upd7002.cpp +++ b/src/devices/machine/upd7002.cpp @@ -34,7 +34,7 @@ void upd7002_device::device_start() { m_conversion_timer = timer_alloc(FUNC(upd7002_device::conversion_complete), this); m_get_analogue_cb.resolve(); - m_eoc_cb.resolve(); + m_eoc_cb.resolve_safe(); // register for state saving save_item(NAME(m_status)); @@ -82,7 +82,7 @@ TIMER_CALLBACK_MEMBER(upd7002_device::conversion_complete) // call the EOC function with EOC from status // eoc_r(0) this has just been set to 0 - if (!m_eoc_cb.isnull()) m_eoc_cb(0); + m_eoc_cb(0); m_conversion_counter = 0; } } @@ -132,7 +132,7 @@ void upd7002_device::write(offs_t offset, uint8_t data) // call the EOC function with EOC from status // eoc_r(0) this has just been set to 1 - if (!m_eoc_cb.isnull()) m_eoc_cb(1); + m_eoc_cb(1); /* the uPD7002 works by sampling the analogue value at the start of the conversion so it is read hear and stored until the end of the A to D conversion */ diff --git a/src/devices/sound/bsmt2000.cpp b/src/devices/sound/bsmt2000.cpp index d48452ca136..428009b1fc2 100644 --- a/src/devices/sound/bsmt2000.cpp +++ b/src/devices/sound/bsmt2000.cpp @@ -110,7 +110,7 @@ void bsmt2000_device::device_add_mconfig(machine_config &config) void bsmt2000_device::device_start() { - m_ready_callback.resolve(); + m_ready_callback.resolve_safe(); // create the stream; BSMT typically runs at 24MHz and writes to a DAC, so // in theory we should generate a 24MHz stream, but that's certainly overkill @@ -261,8 +261,7 @@ uint16_t bsmt2000_device::tms_data_r() { // also implicitly clear the write pending flag m_write_pending = false; - if (!m_ready_callback.isnull()) - m_ready_callback(); + m_ready_callback(); return m_write_data; } diff --git a/src/devices/sound/lynx.cpp b/src/devices/sound/lynx.cpp index d546e4ce00c..1a1f20d0bda 100644 --- a/src/devices/sound/lynx.cpp +++ b/src/devices/sound/lynx.cpp @@ -177,7 +177,7 @@ void lynx_sound_device::init() void lynx_sound_device::device_start() { m_mixer_channel = stream_alloc(0, 1, clock() / 16); - m_timer_delegate.resolve(); + m_timer_delegate.resolve_safe(); init(); register_save(); } @@ -186,7 +186,7 @@ void lynx_sound_device::device_start() void lynx2_sound_device::device_start() { m_mixer_channel = stream_alloc(0, 2, clock() / 16); - m_timer_delegate.resolve(); + m_timer_delegate.resolve_safe(); init(); register_save(); } @@ -279,8 +279,7 @@ void lynx_sound_device::shift(int chan_nr) case 1: count_down(2); break; case 2: count_down(3); break; case 3: - if (!m_timer_delegate.isnull()) - m_timer_delegate(); + m_timer_delegate(); break; } } diff --git a/src/devices/video/i8275.cpp b/src/devices/video/i8275.cpp index 48700508527..0f371d8edf9 100644 --- a/src/devices/video/i8275.cpp +++ b/src/devices/video/i8275.cpp @@ -155,7 +155,7 @@ void i8275_device::device_start() m_write_hrtc.resolve_safe(); m_write_vrtc.resolve_safe(); m_write_lc.resolve_safe(); - m_display_cb.resolve(); + m_display_cb.resolve_safe(); // allocate timers m_hrtc_on_timer = timer_alloc(FUNC(i8275_device::hrtc_on), this); @@ -431,19 +431,18 @@ TIMER_CALLBACK_MEMBER(i8275_device::scanline_tick) } } - if (!m_display_cb.isnull()) m_display_cb(m_bitmap, - sx * m_hpixels_per_column, // x position on screen of starting point - m_scanline, // y position on screen - line_counter, // current line of char - (data & 0x7f), // char code to be displayed - lineattr, // line attribute code - (attr & FAC_U) ? 1 : 0, // light enable signal - (attr & FAC_R) ? 1 : 0, // reverse video signal - (attr & FAC_B) ? 1 : 0, // video suppression - (attr & FAC_GG) >> 2, // general purpose attribute code - (attr & FAC_H) ? 1 : 0 // highlight - ); + sx * m_hpixels_per_column, // x position on screen of starting point + m_scanline, // y position on screen + line_counter, // current line of char + (data & 0x7f), // char code to be displayed + lineattr, // line attribute code + (attr & FAC_U) ? 1 : 0, // light enable signal + (attr & FAC_R) ? 1 : 0, // reverse video signal + (attr & FAC_B) ? 1 : 0, // video suppression + (attr & FAC_GG) >> 2, // general purpose attribute code + (attr & FAC_H) ? 1 : 0 // highlight + ); } if ((SCANLINES_PER_ROW - lc) == 1) diff --git a/src/devices/video/mc6845.cpp b/src/devices/video/mc6845.cpp index 09efa3c22ca..a95eacb3755 100644 --- a/src/devices/video/mc6845.cpp +++ b/src/devices/video/mc6845.cpp @@ -976,8 +976,6 @@ uint32_t mc6845_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma if (m_has_valid_parameters) { - assert(!m_update_row_cb.isnull()); - if (m_display_disabled_msg_shown == true) { logerror("M6845: Valid screen parameters - display reenabled!!!\n"); @@ -985,8 +983,7 @@ uint32_t mc6845_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma } /* call the set up function if any */ - if (!m_begin_update_cb.isnull()) - m_begin_update_cb(bitmap, cliprect); + m_begin_update_cb(bitmap, cliprect); if (cliprect.min_y == 0) { @@ -1001,8 +998,7 @@ uint32_t mc6845_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma } /* call the tear down function if any */ - if (!m_end_update_cb.isnull()) - m_end_update_cb(bitmap, cliprect); + m_end_update_cb(bitmap, cliprect); } else { @@ -1024,9 +1020,9 @@ void mc6845_device::device_start() /* bind delegates */ m_reconfigure_cb.resolve(); - m_begin_update_cb.resolve(); - m_update_row_cb.resolve(); - m_end_update_cb.resolve(); + m_begin_update_cb.resolve_safe(); + m_update_row_cb.resolve_safe(); + m_end_update_cb.resolve_safe(); m_on_update_addr_changed_cb.resolve(); /* resolve callbacks */ diff --git a/src/devices/video/scn2674.cpp b/src/devices/video/scn2674.cpp index 4f82e048c2a..375dbf4d636 100644 --- a/src/devices/video/scn2674.cpp +++ b/src/devices/video/scn2674.cpp @@ -106,7 +106,7 @@ device_memory_interface::space_config_vector scn2674_device::memory_space_config void scn2674_device::device_start() { // resolve callbacks - m_display_cb.resolve(); + m_display_cb.resolve_safe(); m_intr_cb.resolve_safe(); m_breq_cb.resolve_safe(); m_mbc_cb.resolve_safe(); @@ -1149,7 +1149,7 @@ TIMER_CALLBACK_MEMBER(scn2674_device::scanline_timer) attrcode = m_attr_space->read_byte(address); } - if (m_display_enabled && !m_display_cb.isnull()) + if (m_display_enabled) { bool cursor_on = ((address & 0x3fff) == m_cursor_address) && m_cursor_enabled diff --git a/src/devices/video/tmap038.cpp b/src/devices/video/tmap038.cpp index 9b007e28a2c..9446678fe35 100644 --- a/src/devices/video/tmap038.cpp +++ b/src/devices/video/tmap038.cpp @@ -161,8 +161,7 @@ TILE_GET_INFO_MEMBER(tilemap038_device::get_tile_info) code ^= tile_index & 1; code ^= ((tile_index / (512 / 8)) & 1) * 2; - if (!m_038_cb.isnull()) - m_038_cb(true, color, pri, code); + m_038_cb(true, color, pri, code); } else if (tile_is_8x8()) { @@ -172,8 +171,7 @@ TILE_GET_INFO_MEMBER(tilemap038_device::get_tile_info) pri = (tile & 0xc0000000) >> (32 - 2); code = (tile & 0x0003ffff); - if (!m_038_cb.isnull()) - m_038_cb(false, color, pri, code); + m_038_cb(false, color, pri, code); } tileinfo.set(m_gfxno, code, color, 0); @@ -183,7 +181,7 @@ TILE_GET_INFO_MEMBER(tilemap038_device::get_tile_info) void tilemap038_device::device_start() { - m_038_cb.resolve(); + m_038_cb.resolve_safe(); m_vregs = make_unique_clear(0x6/2); if (m_vram_16x16 == nullptr && m_vram_8x8 == nullptr) diff --git a/src/devices/video/upd7220.cpp b/src/devices/video/upd7220.cpp index 957eab0f31a..f593f182f40 100644 --- a/src/devices/video/upd7220.cpp +++ b/src/devices/video/upd7220.cpp @@ -665,8 +665,8 @@ upd7220_device::upd7220_device(const machine_config &mconfig, const char *tag, d void upd7220_device::device_start() { // resolve callbacks - m_display_cb.resolve(); - m_draw_text_cb.resolve(); + m_display_cb.resolve_safe(); + m_draw_text_cb.resolve_safe(); m_write_drq.resolve_safe(); m_write_hsync.resolve_safe(); @@ -1707,9 +1707,7 @@ void upd7220_device::update_text(bitmap_rgb32 &bitmap, const rectangle &cliprect for (y = sy; y < sy + len; y++) { uint32_t const addr = sad + (y * m_pitch); - - if (!m_draw_text_cb.isnull()) - m_draw_text_cb(bitmap, addr, (y * m_lr) + m_vbp, wd, m_pitch, m_lr, m_dc, m_ead); + m_draw_text_cb(bitmap, addr, (y * m_lr) + m_vbp, wd, m_pitch, m_lr, m_dc, m_ead); } sy = y + 1; @@ -1782,7 +1780,7 @@ void upd7220_device::update_graphics(bitmap_rgb32 &bitmap, const rectangle &clip for(int z = 0; z <= m_disp; ++z) { int yval = (y*zoom)+z + (bsy + m_vbp); - if(!m_display_cb.isnull() && yval <= cliprect.bottom()) + if(yval <= cliprect.bottom()) draw_graphics_line(bitmap, addr, yval, wd, (m_pitch >> (mixed ? 1 : 0))); } } @@ -1795,8 +1793,7 @@ void upd7220_device::update_graphics(bitmap_rgb32 &bitmap, const rectangle &clip { uint32_t const addr = (sad & 0x3ffff) + ((y / m_lr) * m_pitch); int yval = y * zoom + (tsy + m_vbp); - if (!m_draw_text_cb.isnull() && yval <= cliprect.bottom()) - m_draw_text_cb(bitmap, addr, yval, wd, m_pitch, m_lr, m_dc, m_ead); + m_draw_text_cb(bitmap, addr, yval, wd, m_pitch, m_lr, m_dc, m_ead); } } } diff --git a/src/emu/devdelegate.h b/src/emu/devdelegate.h index 6b405ee0303..3a63c874d92 100644 --- a/src/emu/devdelegate.h +++ b/src/emu/devdelegate.h @@ -43,41 +43,6 @@ template class device_delegate_array; // TYPE DEFINITIONS //************************************************************************** -namespace detail { - -// ======================> device_delegate_helper - -// device_delegate_helper does non-template work -class device_delegate_helper -{ -public: - // accessors - char const *finder_tag() const { return m_tag; } - std::pair finder_target() const { return std::make_pair(m_base, m_tag); } - -protected: - // construct/assign - device_delegate_helper(device_t &owner, char const *tag = nullptr) : m_base(owner), m_tag(tag) { } - template device_delegate_helper(device_finder const &finder); - device_delegate_helper(device_delegate_helper const &) = default; - device_delegate_helper &operator=(device_delegate_helper const &) = default; - - // internal helpers - delegate_late_bind &bound_object() const; - void set_tag(device_t &object) { m_base = object; m_tag = nullptr; } - void set_tag(device_t &base, char const *tag) { m_base = base; m_tag = tag; } - void set_tag(char const *tag); - template void set_tag(device_finder const &finder); - -private: - std::reference_wrapper m_base; - char const *m_tag; -}; - -} // namespace detail - - -// ======================> named_delegate template class named_delegate : public delegate { @@ -104,8 +69,8 @@ public: template named_delegate(T &&funcptr, std::enable_if_t::value, char const *> name) : basetype(std::forward(funcptr)), m_name(name) { } // allow assignment - named_delegate &operator=(named_delegate const &src) = default; - named_delegate &operator=(named_delegate &&src) = default; + named_delegate &operator=(named_delegate const &) = default; + named_delegate &operator=(named_delegate &&) = default; named_delegate &operator=(std::nullptr_t) noexcept { reset(); return *this; } // getters @@ -125,14 +90,43 @@ template named_delegate(ReturnType (*)(FunctionClass &, Params...), char const *, FunctionClass *) -> named_delegate; -// ======================> device_delegate +namespace detail { -// 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; +// device_delegate_helper does non-template work + +class device_delegate_helper +{ +public: + // accessors + char const *finder_tag() const { return m_tag; } + std::pair finder_target() const { return std::make_pair(m_base, m_tag); } + +protected: + // construct/assign + device_delegate_helper(device_t &owner, char const *tag = nullptr) : m_base(owner), m_tag(tag) { } + template device_delegate_helper(device_finder const &finder); + device_delegate_helper(device_delegate_helper const &) = default; + device_delegate_helper &operator=(device_delegate_helper const &) = default; + + // internal helpers + delegate_late_bind &bound_object() const; + void set_tag(device_t &object) { m_base = object; m_tag = nullptr; } + void set_tag(device_t &base, char const *tag) { m_base = base; m_tag = tag; } + void set_tag(char const *tag); + template void set_tag(device_finder const &finder); + +private: + std::reference_wrapper m_base; + char const *m_tag; +}; + + +// device_delegate_base doesn't need to be specialised on return type + +template class device_delegate_base; template -class device_delegate : protected named_delegate, public detail::device_delegate_helper +class device_delegate_base : protected named_delegate, public device_delegate_helper { private: using basetype = named_delegate; @@ -151,76 +145,71 @@ private: template static std::enable_if_t::value, device_t &> get_device(T &object) { return object.device(); } public: - template using array = device_delegate_array; - - template - using supports_callback = std::bool_constant >; - // construct/assign - explicit device_delegate(device_t &owner) : basetype(), detail::device_delegate_helper(owner) { } - device_delegate(device_delegate const &) = default; - device_delegate &operator=(device_delegate const &) = default; + explicit device_delegate_base(device_t &owner) : basetype(), device_delegate_helper(owner) { } + device_delegate_base(device_delegate_base const &) = default; + device_delegate_base &operator=(device_delegate_base const &) = default; // construct with prototype and target - device_delegate(basetype const &proto, device_t &object) : basetype(proto, object), detail::device_delegate_helper(object) { } - device_delegate(device_delegate const &proto, device_t &object) : basetype(proto, object), detail::device_delegate_helper(object) { } + device_delegate_base(basetype const &proto, device_t &object) : basetype(proto, object), device_delegate_helper(object) { } + device_delegate_base(device_delegate_base const &proto, device_t &object) : basetype(proto, object), device_delegate_helper(object) { } // construct with base and tag template - device_delegate(device_t &base, char const *tag, ReturnType (D::*funcptr)(Params...), char const *name) + device_delegate_base(device_t &base, char const *tag, ReturnType (D::*funcptr)(Params...), char const *name) : basetype(funcptr, name, static_cast(nullptr)) - , detail::device_delegate_helper(base, tag) + , device_delegate_helper(base, tag) { } template - device_delegate(device_t &base, char const *tag, ReturnType (D::*funcptr)(Params...) const, char const *name) + device_delegate_base(device_t &base, char const *tag, ReturnType (D::*funcptr)(Params...) const, char const *name) : basetype(funcptr, name, static_cast(nullptr)) - , detail::device_delegate_helper(base, tag) + , device_delegate_helper(base, tag) { } template - device_delegate(device_t &base, char const *tag, ReturnType (*funcptr)(D &, Params...), char const *name) + device_delegate_base(device_t &base, char const *tag, ReturnType (*funcptr)(D &, Params...), char const *name) : basetype(funcptr, name, static_cast(nullptr)) - , detail::device_delegate_helper(base, tag) + , device_delegate_helper(base, tag) { } // construct with device finder template - device_delegate(device_finder const &finder, ReturnType (E::*funcptr)(Params...), char const *name) + device_delegate_base(device_finder const &finder, ReturnType (E::*funcptr)(Params...), char const *name) : basetype(funcptr, name, static_cast(nullptr)) - , detail::device_delegate_helper(finder) + , device_delegate_helper(finder) { } template - device_delegate(device_finder const &finder, ReturnType (E::*funcptr)(Params...) const, char const *name) + device_delegate_base(device_finder const &finder, ReturnType (E::*funcptr)(Params...) const, char const *name) : basetype(funcptr, name, static_cast(nullptr)) - , detail::device_delegate_helper(finder) + , device_delegate_helper(finder) { } template - device_delegate(device_finder const &finder, ReturnType (*funcptr)(E &, Params...), char const *name) + device_delegate_base(device_finder const &finder, ReturnType (*funcptr)(E &, Params...), char const *name) : basetype(funcptr, name, static_cast(nullptr)) - , detail::device_delegate_helper(finder) + , device_delegate_helper(finder) { } // construct with target object template - device_delegate(T &object, ReturnType (D::*funcptr)(Params...), std::enable_if_t::value, char const *> name) + device_delegate_base(T &object, ReturnType (D::*funcptr)(Params...), std::enable_if_t::value, char const *> name) : basetype(funcptr, name, static_cast(&object)) - , detail::device_delegate_helper(get_device(object)) + , device_delegate_helper(get_device(object)) { } template - device_delegate(T &object, ReturnType (D::*funcptr)(Params...) const, std::enable_if_t::value, char const *> name) + device_delegate_base(T &object, ReturnType (D::*funcptr)(Params...) const, std::enable_if_t::value, char const *> name) : basetype(funcptr, name, static_cast(&object)) - , detail::device_delegate_helper(get_device(object)) + , device_delegate_helper(get_device(object)) { } template - device_delegate(T &object, ReturnType (*funcptr)(D &, Params...), std::enable_if_t::value, char const *> name) + device_delegate_base(T &object, ReturnType (*funcptr)(D &, Params...), std::enable_if_t::value, char const *> name) : basetype(funcptr, name, static_cast(&object)) - , detail::device_delegate_helper(get_device(object)) + , device_delegate_helper(get_device(object)) { } // construct with callable object template - device_delegate(device_t &owner, T &&funcptr, std::enable_if_t::value, char const *> name) + device_delegate_base(device_t &owner, T &&funcptr, std::enable_if_t::value, char const *> name) : basetype(std::forward(funcptr), name) - , detail::device_delegate_helper(owner) + , device_delegate_helper(owner) { } // setters that implicitly bind to the current device @@ -257,18 +246,117 @@ public: void reset() { basetype::reset(); set_tag(finder_target().first); } - // perform the binding - void resolve() { if (!basetype::isnull() && !basetype::has_object()) basetype::late_bind(bound_object()); } - // accessors using basetype::operator(); using basetype::isnull; using basetype::has_object; using basetype::name; + + // perform the binding + void resolve() + { + if (!this->isnull() && !this->has_object()) + this->late_bind(bound_object()); + } +}; + +} // namespace detail + + +// device_delegate is a delegate that can be late bound to a device specification + +template class device_delegate; + +template +class device_delegate : protected detail::device_delegate_base +{ +public: + template using array = device_delegate_array; + + template + using supports_callback = std::bool_constant >; + + // constructors + using detail::device_delegate_base::device_delegate_base; + device_delegate(device_delegate const &) = default; + device_delegate(device_delegate const &proto, device_t &object) : detail::device_delegate_base(proto, object) { } + + // assignment + device_delegate &operator=(device_delegate const &) = default; + device_delegate &operator=(std::nullptr_t) { this->reset(); } + + // setters/unsetters + void set(device_delegate const &src) { operator=(src); } + using detail::device_delegate_base::set; + using detail::device_delegate_base::reset; + + // accessors + using detail::device_delegate_base::operator(); + using detail::device_delegate_base::isnull; + using detail::device_delegate_base::has_object; + using detail::device_delegate_base::name; + using detail::device_delegate_base::finder_tag; + using detail::device_delegate_base::finder_target; + + // perform the binding + using detail::device_delegate_base::resolve; + + template + void resolve_safe(T &&dflt) + { + if (this->isnull()) + this->set([result = std::decay_t(std::forward(dflt))] (Params...) { return ReturnType(result); }, "default"); + else if (!this->has_object()) + this->late_bind(this->bound_object()); + } +}; + +template +class device_delegate : protected detail::device_delegate_base +{ +public: + template using array = device_delegate_array; + + template + using supports_callback = std::bool_constant >; + + // constructors + using detail::device_delegate_base::device_delegate_base; + device_delegate(device_delegate const &) = default; + device_delegate(device_delegate const &proto, device_t &object) : detail::device_delegate_base(proto, object) { } + + // assignment + device_delegate &operator=(device_delegate const &) = default; + device_delegate &operator=(std::nullptr_t) { this->reset(); } + + // setters/unsetters + void set(device_delegate const &src) { operator=(src); } + using detail::device_delegate_base::set; + using detail::device_delegate_base::reset; + + // accessors + using detail::device_delegate_base::operator(); + using detail::device_delegate_base::isnull; + using detail::device_delegate_base::has_object; + using detail::device_delegate_base::name; + using detail::device_delegate_base::finder_tag; + using detail::device_delegate_base::finder_target; + + // perform the binding + using detail::device_delegate_base::resolve; + + void resolve_safe() + { + if (this->isnull()) + this->set([] (Params...) { }, "default"); + else if (!this->has_object()) + this->late_bind(this->bound_object()); + } }; // simplifies constructing an array of delegates with a single owner + template class device_delegate_array : public std::array, Count> { @@ -298,6 +386,13 @@ public: for (device_delegate &elem : *this) elem.resolve(); } + + template + void resolve_all_safe(T &&... args) + { + for (device_delegate &elem : *this) + elem.resolve_safe(args...); + } }; template diff --git a/src/mame/nec/pc9801.cpp b/src/mame/nec/pc9801.cpp index 56e56c4debd..68dfba147ab 100644 --- a/src/mame/nec/pc9801.cpp +++ b/src/mame/nec/pc9801.cpp @@ -2354,7 +2354,7 @@ void pc9801vm_state::pc9801ux(machine_config &config) i80286_cpu_device &maincpu(I80286(config.replace(), m_maincpu, 10000000)); maincpu.set_addrmap(AS_PROGRAM, &pc9801vm_state::pc9801ux_map); maincpu.set_addrmap(AS_IO, &pc9801vm_state::pc9801ux_io); - maincpu.set_a20_callback(i80286_cpu_device::a20_cb(&pc9801vm_state::a20_286, this)); + maincpu.set_a20_callback(FUNC(pc9801vm_state::a20_286)); maincpu.set_irq_acknowledge_callback("pic8259_master", FUNC(pic8259_device::inta_cb)); config_floppy_35hd(config); @@ -2367,7 +2367,7 @@ void pc9801vm_state::pc9801dx(machine_config &config) i80286_cpu_device &maincpu(I80286(config.replace(), m_maincpu, 12000000)); maincpu.set_addrmap(AS_PROGRAM, &pc9801vm_state::pc9801ux_map); maincpu.set_addrmap(AS_IO, &pc9801vm_state::pc9801ux_io); - maincpu.set_a20_callback(i80286_cpu_device::a20_cb(&pc9801vm_state::a20_286, this)); + maincpu.set_a20_callback(FUNC(pc9801vm_state::a20_286)); maincpu.set_irq_acknowledge_callback("pic8259_master", FUNC(pic8259_device::inta_cb)); config_floppy_525hd(config); -- cgit v1.2.3