diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index ef9a5987072..4774c3e6308 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -3059,12 +3059,14 @@ if CPUS["Z80"] or CPUS["KC80"] or CPUS["Z80N"] then dependency { { MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80.hxx" }, + { MAME_DIR .. "src/devices/cpu/z80/z80.cpp", GEN_DIR .. "emu/cpu/z80/z80_nomrq.hxx" }, { MAME_DIR .. "src/devices/cpu/z80/nsc800.cpp", GEN_DIR .. "emu/cpu/z80/ncs800.hxx" }, { MAME_DIR .. "src/devices/cpu/z80/r800.cpp", GEN_DIR .. "emu/cpu/z80/r800.hxx" }, } custombuildtask { { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 source file...", PYTHON .. " $(1) $(<) $(@)" } }, + { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/z80_nomrq.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating Z80 /NOMRQ source file...", PYTHON .. " $(1) z80_nomrq $(<) $(@)" } }, { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/ncs800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating NSC800 source file...", PYTHON .. " $(1) ncs800 $(<) $(@)" } }, { MAME_DIR .. "src/devices/cpu/z80/z80.lst", GEN_DIR .. "emu/cpu/z80/r800.hxx", { MAME_DIR .. "src/devices/cpu/z80/z80make.py" }, { "@echo Generating R800 source file...", PYTHON .. " $(1) r800 $(<) $(@)" } }, } diff --git a/src/devices/cpu/z80/z80.cpp b/src/devices/cpu/z80/z80.cpp index dec4cfbbd9a..4d3eb1f1c38 100644 --- a/src/devices/cpu/z80/z80.cpp +++ b/src/devices/cpu/z80/z80.cpp @@ -33,6 +33,7 @@ TODO: #define VERBOSE (LOG_UNDOC) #include "logmacro.h" +DEFINE_DEVICE_TYPE(Z80, z80_device, "z80", "Zilog Z80") bool z80_device::tables_initialised = false; u8 z80_device::SZ[] = {}; // zero and sign flags @@ -833,7 +834,6 @@ z80_device::z80_device(const machine_config &mconfig, device_type type, const ch m_io_config("io", ENDIANNESS_LITTLE, 8, 16, 0), m_irqack_cb(*this), m_refresh_cb(*this), - m_nomreq_cb(*this), m_halt_cb(*this), m_busack_cb(*this), m_branch_cb(*this), @@ -862,4 +862,32 @@ device_memory_interface::space_config_vector z80_device::memory_space_config() c } } -DEFINE_DEVICE_TYPE(Z80, z80_device, "z80", "Zilog Z80") +/************************************************************************** + * Z80 flavour(s) which hit performance but required in specific drivers + **************************************************************************/ + +DEFINE_DEVICE_TYPE(Z80_NOMRQ, z80_nomrq_device, "z80_nomrq", "Zilog Z80 (NOMRQ)") + +void z80_nomrq_device::do_op() +{ + #include "cpu/z80/z80_nomrq.hxx" +} + +void z80_nomrq_device::device_validity_check(validity_checker &valid) const +{ + z80_device::device_validity_check(valid); + + if (m_nomreq_cb.isunset()) + osd_printf_error("Wrong z80 flavour: nomreq_cb is not initialized.\n"); +} + +z80_nomrq_device::z80_nomrq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : z80_device(mconfig, type, tag, owner, clock) + , m_nomreq_cb(*this) +{ +} + +z80_nomrq_device::z80_nomrq_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : z80_nomrq_device(mconfig, Z80_NOMRQ, tag, owner, clock) +{ +} diff --git a/src/devices/cpu/z80/z80.h b/src/devices/cpu/z80/z80.h index eadaae4ba07..ae0b6c4e8f0 100644 --- a/src/devices/cpu/z80/z80.h +++ b/src/devices/cpu/z80/z80.h @@ -39,7 +39,6 @@ public: template void set_io_map(T &&... args) { set_addrmap(AS_IO, std::forward(args)...); } auto irqack_cb() { return m_irqack_cb.bind(); } auto refresh_cb() { return m_refresh_cb.bind(); } - auto nomreq_cb() { return m_nomreq_cb.bind(); } auto halt_cb() { return m_halt_cb.bind(); } auto busack_cb() { return m_busack_cb.bind(); } @@ -141,7 +140,6 @@ protected: devcb_write_line m_irqack_cb; devcb_write8 m_refresh_cb; - devcb_write8 m_nomreq_cb; devcb_write_line m_halt_cb; devcb_write_line m_busack_cb; @@ -210,4 +208,20 @@ protected: DECLARE_DEVICE_TYPE(Z80, z80_device) +class z80_nomrq_device : public z80_device +{ +public: + z80_nomrq_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + auto nomreq_cb() { return m_nomreq_cb.bind(); } + +protected: + z80_nomrq_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + virtual void device_validity_check(validity_checker &valid) const override; + virtual void do_op() override; + devcb_write8 m_nomreq_cb; +}; + +DECLARE_DEVICE_TYPE(Z80_NOMRQ, z80_nomrq_device) + #endif // MAME_CPU_Z80_Z80_H diff --git a/src/devices/cpu/z80/z80.lst b/src/devices/cpu/z80/z80.lst index ee62b4d915e..a04e3922e44 100644 --- a/src/devices/cpu/z80/z80.lst +++ b/src/devices/cpu/z80/z80.lst @@ -4,11 +4,16 @@ # macros ########################################################## macro nomreq_addr - if (!m_nomreq_cb.isunset()) - m_nomreq_cb(TADR, 0x00, 0xff); + 1 macro nomreq_ir %cycles + + %cycles + +macro z80_nomrq:nomreq_addr + m_nomreq_cb(TADR, 0x00, 0xff); + + 1 + +macro z80_nomrq:nomreq_ir %cycles TADR = (m_i << 8) | (m_r2 & 0x80) | (m_r & 0x7f); %cycles * call nomreq_addr diff --git a/src/mame/sinclair/atm.cpp b/src/mame/sinclair/atm.cpp index 1a355649658..e17ed6dffd5 100644 --- a/src/mame/sinclair/atm.cpp +++ b/src/mame/sinclair/atm.cpp @@ -503,7 +503,7 @@ void atm_state::atm(machine_config &config) m_maincpu->set_addrmap(AS_IO, &atm_state::atm_io); m_maincpu->set_addrmap(AS_OPCODES, &atm_state::atm_switch); m_maincpu->set_vblank_int("screen", FUNC(atm_state::atm_interrupt)); - m_maincpu->nomreq_cb().set_nop(); + //TODO replace CPU: m_maincpu->nomreq_cb().set_nop(); m_screen->set_raw(X1_128_SINCLAIR / 5, 448, 312, {get_screen_area().left() - 40, get_screen_area().right() + 40, get_screen_area().top() - 40, get_screen_area().bottom() + 40}); subdevice("gfxdecode")->set_info(gfx_atm); diff --git a/src/mame/sinclair/chloe.cpp b/src/mame/sinclair/chloe.cpp index c8af1e9d9e5..12ef3f64f6c 100644 --- a/src/mame/sinclair/chloe.cpp +++ b/src/mame/sinclair/chloe.cpp @@ -930,7 +930,7 @@ void chloe_state::chloe(machine_config &config) m_maincpu->set_memory_map(&chloe_state::map_mem); m_maincpu->set_io_map(&chloe_state::map_io); m_maincpu->set_vblank_int("screen", FUNC(chloe_state::chloe_interrupt)); - m_maincpu->nomreq_cb().set_nop(); + //TODO replace CPU: m_maincpu->nomreq_cb().set_nop(); ADDRESS_MAP_BANK(config, m_regs_map).set_map(&chloe_state::map_regs).set_options(ENDIANNESS_LITTLE, 8, 8, 0); diff --git a/src/mame/sinclair/pentagon.cpp b/src/mame/sinclair/pentagon.cpp index 8cbc4e7daa5..871a262e9ec 100644 --- a/src/mame/sinclair/pentagon.cpp +++ b/src/mame/sinclair/pentagon.cpp @@ -196,7 +196,7 @@ void pentagon_state::pentagon(machine_config &config) m_maincpu->set_addrmap(AS_IO, &pentagon_state::pentagon_io); m_maincpu->set_addrmap(AS_OPCODES, &pentagon_state::pentagon_switch); m_maincpu->set_vblank_int("screen", FUNC(pentagon_state::pentagon_interrupt)); - m_maincpu->nomreq_cb().set_nop(); + //TODO replace CPU: m_maincpu->nomreq_cb().set_nop(); m_screen->set_raw(14_MHz_XTAL / 2, 448, 320, {get_screen_area().left() - 48, get_screen_area().right() + 48, get_screen_area().top() - 48, get_screen_area().bottom() + 48}); subdevice("gfxdecode")->set_info(gfx_pentagon); diff --git a/src/mame/sinclair/scorpion.cpp b/src/mame/sinclair/scorpion.cpp index 901f420beb1..09b6913f3f5 100644 --- a/src/mame/sinclair/scorpion.cpp +++ b/src/mame/sinclair/scorpion.cpp @@ -505,7 +505,7 @@ void scorpion_state::scorpion(machine_config &config) m_maincpu->set_m1_map(&scorpion_state::scorpion_switch); m_maincpu->set_io_map(&scorpion_state::scorpion_io); m_maincpu->set_vblank_int("screen", FUNC(scorpion_state::scorpion_interrupt)); - m_maincpu->nomreq_cb().set_nop(); + //TODO replace CPU: m_maincpu->nomreq_cb().set_nop(); subdevice("gfxdecode")->set_info(gfx_scorpion); diff --git a/src/mame/sinclair/spec128.cpp b/src/mame/sinclair/spec128.cpp index c6a1c4353d2..b9ed24cf3b7 100644 --- a/src/mame/sinclair/spec128.cpp +++ b/src/mame/sinclair/spec128.cpp @@ -413,12 +413,12 @@ void spectrum_128_state::spectrum_128(machine_config &config) { spectrum(config); - Z80(config.replace(), m_maincpu, X1_128_SINCLAIR / 10); - m_maincpu->set_memory_map(&spectrum_128_state::spectrum_128_mem); - m_maincpu->set_io_map(&spectrum_128_state::spectrum_128_io); - m_maincpu->set_m1_map(&spectrum_128_state::spectrum_128_fetch); - m_maincpu->set_vblank_int("screen", FUNC(spectrum_128_state::spec_interrupt)); - m_maincpu->nomreq_cb().set(FUNC(spectrum_128_state::spectrum_nomreq)); + z80_nomrq_device &cpu(Z80_NOMRQ(config.replace(), m_maincpu, X1_128_SINCLAIR / 10)); + cpu.set_memory_map(&spectrum_128_state::spectrum_128_mem); + cpu.set_io_map(&spectrum_128_state::spectrum_128_io); + cpu.set_m1_map(&spectrum_128_state::spectrum_128_fetch); + cpu.set_vblank_int("screen", FUNC(spectrum_128_state::spec_interrupt)); + cpu.nomreq_cb().set(FUNC(spectrum_128_state::spectrum_nomreq)); config.set_maximum_quantum(attotime::from_hz(60)); diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp index 9bfd6a11207..8bfb4e7a79b 100644 --- a/src/mame/sinclair/specnext.cpp +++ b/src/mame/sinclair/specnext.cpp @@ -3445,7 +3445,6 @@ void specnext_state::tbblue(machine_config &config) m_maincpu->out_nextreg_cb().set(FUNC(specnext_state::reg_w)); m_maincpu->in_nextreg_cb().set(FUNC(specnext_state::reg_r)); m_maincpu->out_retn_seen_cb().set(FUNC(specnext_state::leave_nmi)); - m_maincpu->nomreq_cb().set_nop(); m_maincpu->busack_cb().set(m_dma, FUNC(specnext_dma_device::bai_w)); SPECNEXT_CTC(config, m_ctc, 28_MHz_XTAL / 8); diff --git a/src/mame/sinclair/specpls3.cpp b/src/mame/sinclair/specpls3.cpp index 2a0a062a0ca..71ff34463b0 100644 --- a/src/mame/sinclair/specpls3.cpp +++ b/src/mame/sinclair/specpls3.cpp @@ -409,7 +409,7 @@ void specpls3_state::spectrum_plus2(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &specpls3_state::plus3_mem); m_maincpu->set_addrmap(AS_IO, &specpls3_state::plus3_io); - m_maincpu->nomreq_cb().set_nop(); + //TODO replace CPU: m_maincpu->nomreq_cb().set_nop(); subdevice("gfxdecode")->set_info(specpls3); diff --git a/src/mame/sinclair/spectrum.cpp b/src/mame/sinclair/spectrum.cpp index cb92826746d..dec4b10bedf 100644 --- a/src/mame/sinclair/spectrum.cpp +++ b/src/mame/sinclair/spectrum.cpp @@ -734,13 +734,15 @@ INTERRUPT_GEN_MEMBER(spectrum_state::spec_interrupt) void spectrum_state::spectrum_common(machine_config &config) { - /* basic machine hardware */ - Z80(config, m_maincpu, X1 / 4); /* This is verified only for the ZX Spectrum. Other clones are reported to have different clocks */ - m_maincpu->set_m1_map(&spectrum_state::spectrum_opcodes); - m_maincpu->set_memory_map(&spectrum_state::spectrum_data); - m_maincpu->set_io_map(&spectrum_state::spectrum_io); - m_maincpu->set_vblank_int("screen", FUNC(spectrum_state::spec_interrupt)); - m_maincpu->nomreq_cb().set(FUNC(spectrum_state::spectrum_nomreq)); + // basic machine hardware + + // This is verified only for the ZX Spectrum. Other clones are reported to have different clocks + z80_nomrq_device &cpu(Z80_NOMRQ(config, m_maincpu, X1 / 4)); + cpu.set_m1_map(&spectrum_state::spectrum_opcodes); + cpu.set_memory_map(&spectrum_state::spectrum_data); + cpu.set_io_map(&spectrum_state::spectrum_io); + cpu.set_vblank_int("screen", FUNC(spectrum_state::spec_interrupt)); + cpu.nomreq_cb().set(FUNC(spectrum_state::spectrum_nomreq)); ADDRESS_MAP_BANK(config, m_specmem).set_map(&spectrum_state::spectrum_map).set_options(ENDIANNESS_LITTLE, 8, 16, 0x10000); diff --git a/src/mame/sinclair/sprinter.cpp b/src/mame/sinclair/sprinter.cpp index a01a35d525b..c75066d83db 100644 --- a/src/mame/sinclair/sprinter.cpp +++ b/src/mame/sinclair/sprinter.cpp @@ -1883,7 +1883,6 @@ void sprinter_state::sprinter(machine_config &config) m_maincpu->set_m1_map(&sprinter_state::map_fetch); m_maincpu->set_memory_map(&sprinter_state::map_mem); m_maincpu->set_io_map(&sprinter_state::map_io); - m_maincpu->nomreq_cb().set_nop(); m_maincpu->set_irq_acknowledge_callback(NAME([](device_t &, int){ return 0xff; })); m_maincpu->irqack_cb().set(m_irqs, FUNC(input_merger_any_high_device::in_clear<2>)); m_maincpu->irqack_cb().append(m_irqs, FUNC(input_merger_any_high_device::in_clear<1>));