From 524062b83986309a403a4e333559c46565919f5b Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Fri, 27 Jun 2025 12:36:17 -0400 Subject: [PATCH 1/2] z80dma.cpp: Added UA858D variant sinclair/spectrum.cpp: Added configurable DMA slot --- scripts/src/bus.lua | 14 +++ src/devices/bus/spectrum/dma/cards.cpp | 113 +++++++++++++++++++++++ src/devices/bus/spectrum/dma/cards.h | 17 ++++ src/devices/bus/spectrum/dma/slot.cpp | 118 +++++++++++++++++++++++++ src/devices/bus/spectrum/dma/slot.h | 101 +++++++++++++++++++++ src/devices/machine/z80dma.cpp | 27 +++++- src/devices/machine/z80dma.h | 18 +++- src/mame/sinclair/chloe.cpp | 15 ++-- src/mame/sinclair/spec128.cpp | 14 ++- src/mame/sinclair/spec128.h | 2 - src/mame/sinclair/specnext.cpp | 1 + src/mame/sinclair/spectrum.cpp | 15 +++- src/mame/sinclair/spectrum.h | 3 + src/mame/sinclair/sprinter.cpp | 2 + src/mame/sinclair/timex.cpp | 2 + src/mame/sinclair/tsconf.cpp | 1 + 16 files changed, 447 insertions(+), 16 deletions(-) create mode 100644 src/devices/bus/spectrum/dma/cards.cpp create mode 100644 src/devices/bus/spectrum/dma/cards.h create mode 100644 src/devices/bus/spectrum/dma/slot.cpp create mode 100644 src/devices/bus/spectrum/dma/slot.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index ec9498f29768d..950b26a8e583d 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4996,6 +4996,20 @@ if (BUSES["AY_SLOT"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/bus/spectrum/dma/slot.h,BUSES["DMA"] = true +--------------------------------------------------- + +if (BUSES["DMA"]~=null) then + files { + MAME_DIR .. "src/devices/bus/spectrum/dma/slot.cpp", + MAME_DIR .. "src/devices/bus/spectrum/dma/slot.h", + MAME_DIR .. "src/devices/bus/spectrum/dma/cards.cpp", + MAME_DIR .. "src/devices/bus/spectrum/dma/cards.h", + } +end + --------------------------------------------------- -- --@src/devices/bus/spectrum/zxbus/bus.h,BUSES["ZXBUS"] = true diff --git a/src/devices/bus/spectrum/dma/cards.cpp b/src/devices/bus/spectrum/dma/cards.cpp new file mode 100644 index 0000000000000..7adf0d7bcc491 --- /dev/null +++ b/src/devices/bus/spectrum/dma/cards.cpp @@ -0,0 +1,113 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub + +#include "emu.h" +#include "cards.h" + +namespace bus::spectrum::dma_slot { + +namespace { + +/********************************************************************** + DATAGEAR: UA858D, Port 0x6b +**********************************************************************/ +class datagear_device : public dma_device +{ +public: + datagear_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : dma_device(mconfig, DMA_SLOT_DATAGEAR, tag, owner, clock) + { } + +protected: + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; +}; + +void datagear_device::device_add_mconfig(machine_config &config) +{ + UA858D(config, m_dma, clock()); + m_dma_port = 0x6b; + + dma_device::device_add_mconfig(config); +} + + +/********************************************************************** + DATAGEAR: ZILOG, Port 0x6b +**********************************************************************/ +class datagear_zilog_device : public dma_device +{ +public: + datagear_zilog_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : dma_device(mconfig, DMA_SLOT_DATAGEAR_ZILOG, tag, owner, clock) + { } + +protected: + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; +}; + + +/********************************************************************** + DATAGEAR: UA858D, Port 0x6b +**********************************************************************/ +void datagear_zilog_device::device_add_mconfig(machine_config &config) +{ + Z80DMA(config, m_dma, clock()); + m_dma_port = 0x6b; + + dma_device::device_add_mconfig(config); +} + + +/********************************************************************** + MB02+: UA858D, Port 0x0b +**********************************************************************/ +class mb02p_device : public dma_device +{ +public: + mb02p_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : dma_device(mconfig, DMA_SLOT_MB02P, tag, owner, clock) + { } + +protected: + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; +}; + +void mb02p_device::device_add_mconfig(machine_config &config) +{ + UA858D(config, m_dma, clock()); + m_dma_port = 0x0b; + + dma_device::device_add_mconfig(config); +} + + +/********************************************************************** + MB02+: ZILOG, Port 0x0b +**********************************************************************/ +class mb02p_zilog_device : public dma_device +{ +public: + mb02p_zilog_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : dma_device(mconfig, DMA_SLOT_MB02P_ZILOG, tag, owner, clock) + { } + +protected: + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; +}; + +void mb02p_zilog_device::device_add_mconfig(machine_config &config) +{ + Z80DMA(config, m_dma, clock()); + m_dma_port = 0x0b; + + dma_device::device_add_mconfig(config); +} + +} // anonymous namespace + +} // namespace bus::spectrum::dma_slot + +DEFINE_DEVICE_TYPE_PRIVATE(DMA_SLOT_DATAGEAR, device_dma_card_interface, bus::spectrum::dma_slot::datagear_device, "dma_datagear", "DATEGEAR 107(#6b) UA858D") +DEFINE_DEVICE_TYPE_PRIVATE(DMA_SLOT_DATAGEAR_ZILOG, device_dma_card_interface, bus::spectrum::dma_slot::datagear_zilog_device, "dma_datagear_zilog", "DATEGEAR 107(#6b) ZILOG") +DEFINE_DEVICE_TYPE_PRIVATE(DMA_SLOT_MB02P, device_dma_card_interface, bus::spectrum::dma_slot::mb02p_device, "dma_mb02p", "MB02+ 11(#0b) UA858D") +DEFINE_DEVICE_TYPE_PRIVATE(DMA_SLOT_MB02P_ZILOG, device_dma_card_interface, bus::spectrum::dma_slot::mb02p_zilog_device, "dma_mb02p_zilog", "MB02+ 11(#0b) ZILOG") diff --git a/src/devices/bus/spectrum/dma/cards.h b/src/devices/bus/spectrum/dma/cards.h new file mode 100644 index 0000000000000..9b3293a98c2f1 --- /dev/null +++ b/src/devices/bus/spectrum/dma/cards.h @@ -0,0 +1,17 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub + +#ifndef MAME_BUS_SPECTRUM_DMA_CARDS_H +#define MAME_BUS_SPECTRUM_DMA_CARDS_H + +#pragma once + +#include "slot.h" + + +DECLARE_DEVICE_TYPE(DMA_SLOT_DATAGEAR, device_dma_card_interface) +DECLARE_DEVICE_TYPE(DMA_SLOT_DATAGEAR_ZILOG, device_dma_card_interface) +DECLARE_DEVICE_TYPE(DMA_SLOT_MB02P, device_dma_card_interface) +DECLARE_DEVICE_TYPE(DMA_SLOT_MB02P_ZILOG, device_dma_card_interface) + +#endif // MAME_BUS_SPECTRUM_DMA_CARDS_H diff --git a/src/devices/bus/spectrum/dma/slot.cpp b/src/devices/bus/spectrum/dma/slot.cpp new file mode 100644 index 0000000000000..8ad55fafab8a9 --- /dev/null +++ b/src/devices/bus/spectrum/dma/slot.cpp @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +/********************************************************************** + DMA Slot for ZX Spectrum + +DMA Controller mod is available in two variants: +- Data-Gear: uses I/O port 107 (0x6B) +- MB-02+: uses I/O port 11 (0x0B) + +The most commonly used implementation was based on the UA858D chip, which differs in behavior from +the original Zilog DMA controller. +For example, several source code examples published in Czech magazines were written for the UA858D +and did not account for differences in control logic?such as the lack of automatic transfer enable +via WR3, a feature that is present in the Zilog chip. +As a result, there are two versions of the "DMA DEMO LEVEL 3" by Busysoft: +- The original, compatible with the UA858D +- A fixed version, modified to support the Zilog DMA controller + +ref: https://web.archive.org/web/20250524155336/https://velesoft.speccy.cz/data-gear.htm + +**********************************************************************/ + +#include "emu.h" +#include "slot.h" + +DEFINE_DEVICE_TYPE(DMA_SLOT, dma_slot_device, "dma_slot", "Spectrum DMA Slot") + +dma_slot_device::dma_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, DMA_SLOT, tag, owner, clock) + , device_single_card_slot_interface(mconfig, *this) + , m_io(*this, finder_base::DUMMY_TAG, -1) + , m_out_busreq_cb(*this) + , m_out_int_cb(*this) + , m_in_mreq_cb(*this, 0) + , m_out_mreq_cb(*this) + , m_in_iorq_cb(*this, 0) + , m_out_iorq_cb(*this) + , m_card(nullptr) +{ +} + +dma_slot_device::~dma_slot_device() +{ +} + +void dma_slot_device::device_start() +{ + m_card = get_card_device(); +} + +void dma_slot_device::busreq_w(int state) { m_out_busreq_cb(state); } +void dma_slot_device::int_w(int state) { m_out_int_cb(state); } +void dma_slot_device::mreq_w(int state) { m_out_mreq_cb(state); } +u8 dma_slot_device::mreq_r(offs_t offset) { return m_in_mreq_cb(offset); } +void dma_slot_device::iorq_w(int state) { m_out_iorq_cb(state); } +u8 dma_slot_device::iorq_r(offs_t offset) { return m_in_iorq_cb(offset); } +void dma_slot_device::bai_w(int state) { if(m_card) m_card->bai_w(state); }; + + +device_dma_card_interface::device_dma_card_interface(const machine_config &mconfig, device_t &device) + : device_interface(device, "dma") +{ + m_slot = dynamic_cast(device.owner()); +} + +device_dma_card_interface::~device_dma_card_interface() +{ +} + + +dma_device::dma_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock) + , device_dma_card_interface(mconfig, *this) + , m_dma(*this, "dma") + , m_dma_port(0) +{ +} + +void dma_device::bai_w(int state) +{ + m_dma->bai_w(state); +} + +void dma_device::device_validity_check(validity_checker &valid) const +{ + if (!m_dma_port) + osd_printf_error("DMA port is not configured\n"); +} + +void dma_device::device_add_mconfig(machine_config &config) +{ + m_dma->out_busreq_callback().set([this](int state) { m_slot->busreq_w(state); } ); + m_dma->out_int_callback().set([this](int state) { m_slot->int_w(state); } ); + m_dma->in_mreq_callback().set([this](offs_t offset) { return m_slot->mreq_r(offset); }); + m_dma->out_mreq_callback().set([this](int state) { m_slot->mreq_w(state); } ); + m_dma->in_iorq_callback().set([this](offs_t offset) { return m_slot->iorq_r(offset); }); + m_dma->out_iorq_callback().set([this](int state) { m_slot->iorq_w(state); } ); +} + + +void dma_device::device_start() +{ + m_slot->io().install_readwrite_handler(m_dma_port, m_dma_port, 0, 0xff00, 0, emu::rw_delegate(*m_dma, FUNC(z80dma_device::read)), emu::rw_delegate(*m_dma, FUNC(z80dma_device::write))); +} + + +#include "cards.h" + +template class device_finder; +template class device_finder; + +void default_dma_slot_devices(device_slot_interface &device) +{ + device.option_add("datagear", DMA_SLOT_DATAGEAR); + device.option_add("datagear_zilog", DMA_SLOT_DATAGEAR_ZILOG); + device.option_add("mb02p", DMA_SLOT_MB02P); + device.option_add("mb02p_zilog", DMA_SLOT_MB02P_ZILOG); +} diff --git a/src/devices/bus/spectrum/dma/slot.h b/src/devices/bus/spectrum/dma/slot.h new file mode 100644 index 0000000000000..f517265d67214 --- /dev/null +++ b/src/devices/bus/spectrum/dma/slot.h @@ -0,0 +1,101 @@ +// license:BSD-3-Clause +// copyright-holders:Andrei I. Holub +#ifndef MAME_BUS_SPECTRUM_DMA_SLOT_H +#define MAME_BUS_SPECTRUM_DMA_SLOT_H + +#include "emu.h" +#include "osdcomm.h" +#pragma once + +#include "cpu/z80/z80.h" +#include "machine/z80dma.h" + +class device_dma_card_interface; + +class dma_slot_device : public device_t + , public device_single_card_slot_interface +{ + friend class device_dma_card_interface; + +public: + dma_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + template + dma_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&opts, const char *dflt) + : dma_slot_device(mconfig, tag, owner, clock) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(false); + } + virtual ~dma_slot_device(); + + template void set_io_space(T &&tag, int spacenum) { m_io.set_tag(std::forward(tag), spacenum); } + + auto out_busreq_callback() { return m_out_busreq_cb.bind(); } + auto out_int_callback() { return m_out_int_cb.bind(); } + auto in_mreq_callback() { return m_in_mreq_cb.bind(); } + auto out_mreq_callback() { return m_out_mreq_cb.bind(); } + auto in_iorq_callback() { return m_in_iorq_cb.bind(); } + auto out_iorq_callback() { return m_out_iorq_cb.bind(); } + + void busreq_w(int state); + void int_w(int state); + void mreq_w(int state); + u8 mreq_r(offs_t offset); + void iorq_w(int state); + u8 iorq_r(offs_t offset); + + void bai_w(int state); + + address_space &io() const { return *m_io; } + +protected: + virtual void device_start() override ATTR_COLD; + + required_address_space m_io; + + devcb_write_line m_out_busreq_cb; + devcb_write_line m_out_int_cb; + devcb_read8 m_in_mreq_cb; + devcb_write8 m_out_mreq_cb; + devcb_read8 m_in_iorq_cb; + devcb_write8 m_out_iorq_cb; + + device_dma_card_interface *m_card; +}; + +class device_dma_card_interface : public device_interface +{ +public: + virtual ~device_dma_card_interface(); + + virtual void bai_w(int state) {}; + +protected: + device_dma_card_interface(const machine_config &mconfig, device_t &device); + + dma_slot_device *m_slot; +}; + +class dma_device : public device_t, public device_dma_card_interface +{ +public: + virtual void bai_w(int state) override; + +protected: + dma_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 ATTR_COLD; + virtual void device_add_mconfig(machine_config &config) override ATTR_COLD; + virtual void device_start() override ATTR_COLD; + + required_device m_dma; + u8 m_dma_port; +}; + +DECLARE_DEVICE_TYPE(DMA_SLOT, dma_slot_device) + +void default_dma_slot_devices(device_slot_interface &device); + +#endif // MAME_BUS_SPECTRUM_DMA_SLOT_H diff --git a/src/devices/machine/z80dma.cpp b/src/devices/machine/z80dma.cpp index 1e6ce280b0fa3..e349d2796fd69 100644 --- a/src/devices/machine/z80dma.cpp +++ b/src/devices/machine/z80dma.cpp @@ -875,7 +875,7 @@ TIMER_CALLBACK_MEMBER(z80dma_device::rdy_write_callback) void z80dma_device::rdy_w(int state) { LOG("Z80DMA RDY: %d Active High: %d\n", state, READY_ACTIVE_HIGH); - machine().scheduler().synchronize(timer_expired_delegate(FUNC(z80dma_device::rdy_write_callback),this), state); + machine().scheduler().synchronize(timer_expired_delegate(FUNC(z80dma_device::rdy_write_callback) ,this), state); } /**************************************************************************** @@ -885,3 +885,28 @@ void z80dma_device::bai_w(int state) { m_busrq_ack = state; } + + +DEFINE_DEVICE_TYPE(UA858D, ua858d_device, "ua858d", "UA858D DMA Controller") + +ua858d_device::ua858d_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : z80dma_device(mconfig, UA858D, tag, owner, clock) +{ +} + +void ua858d_device::write(u8 data) +{ + if ((m_num_follow == 0) && ((data & 0x83) == 0x80)) // WR3 + { + LOG("UA858D WR3 %02x\n", data); + WR3 = data; + if (data & 0x08) + m_regs_follow[m_num_follow++] = GET_REGNUM(MASK_BYTE); + if (data & 0x10) + m_regs_follow[m_num_follow++] = GET_REGNUM(MATCH_BYTE); + } + else + { + z80dma_device::write(data); + } +} \ No newline at end of file diff --git a/src/devices/machine/z80dma.h b/src/devices/machine/z80dma.h index b461330eab027..687e6a4ff3d06 100644 --- a/src/devices/machine/z80dma.h +++ b/src/devices/machine/z80dma.h @@ -117,6 +117,10 @@ class z80dma_device : public device_t, u16 m_count; u16 m_byte_counter; + u8 m_num_follow; + u8 m_regs_follow[5]; + u8 m_read_num_follow; + private: // device_z80daisy_interface implementation virtual int z80daisy_irq_state() override; @@ -139,10 +143,7 @@ class z80dma_device : public device_t, emu_timer *m_timer; u16 m_regs[(6 << 3) + 1 + 1]; - u8 m_num_follow; u8 m_cur_follow; - u8 m_regs_follow[5]; - u8 m_read_num_follow; u8 m_read_cur_follow; u8 m_read_regs_follow[7]; u8 m_status; @@ -164,8 +165,19 @@ class z80dma_device : public device_t, u8 m_vector; // interrupt vector }; +// ======================> ua858d_device + +class ua858d_device : public z80dma_device +{ +public: + ua858d_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual void write(u8 data) override; +}; + // device type definition DECLARE_DEVICE_TYPE(Z80DMA, z80dma_device) +DECLARE_DEVICE_TYPE(UA858D, ua858d_device) #endif // MAME_MACHINE_Z80DMA_H diff --git a/src/mame/sinclair/chloe.cpp b/src/mame/sinclair/chloe.cpp index 7ed51f0072ed8..01330eafef456 100644 --- a/src/mame/sinclair/chloe.cpp +++ b/src/mame/sinclair/chloe.cpp @@ -908,16 +908,19 @@ 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->busack_cb().set("dma", FUNC(dma_slot_device::bai_w)); ADDRESS_MAP_BANK(config, m_regs_map).set_map(&chloe_state::map_regs).set_options(ENDIANNESS_LITTLE, 8, 8, 0); /* - ???DMA(config, m_dma, 28_MHz_XTAL / 8); - m_dma->out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ); - m_dma->in_mreq_callback().set([this](offs_t offset) { return m_program.read_byte(offset); }); - m_dma->out_mreq_callback().set([this](offs_t offset, u8 data) { m_program.write_byte(offset, data); }); - m_dma->in_iorq_callback().set([this](offs_t offset) { return m_io.read_byte(offset); }); - m_dma->out_iorq_callback().set([this](offs_t offset, u8 data) { m_io.write_byte(offset, data); }); + ???dma_slot_device &dma(DMA_SLOT(config.replace(), "dma", 28_MHz_XTAL / 8, default_dma_slot_devices, nullptr)); + dma.set_io_space(m_maincpu, AS_IO); + dma.out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ); + dma.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + dma.in_mreq_callback().set([this](offs_t offset) { return m_program.read_byte(offset); }); + dma.out_mreq_callback().set([this](offs_t offset, u8 data) { m_program.write_byte(offset, data); }); + dma.in_iorq_callback().set([this](offs_t offset) { return m_io.read_byte(offset); }); + dma.out_iorq_callback().set([this](offs_t offset, u8 data) { m_io.write_byte(offset, data); }); */ SPI_SDCARD(config, m_sdcard, 0); diff --git a/src/mame/sinclair/spec128.cpp b/src/mame/sinclair/spec128.cpp index 7c7ff9ced70a0..cc64d858d47ee 100644 --- a/src/mame/sinclair/spec128.cpp +++ b/src/mame/sinclair/spec128.cpp @@ -154,6 +154,7 @@ resulting mess can be seen in the F4 viewer display. #include "spec128.h" #include "bus/spectrum/ay/slot.h" +#include "bus/spectrum/dma/slot.h" #include "cpu/z80/z80.h" #include "screen.h" @@ -352,9 +353,6 @@ void spectrum_128_state::machine_start() save_item(NAME(m_port_7ffd_data)); - m_maincpu->space(AS_PROGRAM).specific(m_program); - m_maincpu->space(AS_IO).specific(m_io); - // rom 0 is 128K rom, rom 1 is 48 BASIC memory_region *rom = memregion("maincpu"); m_bank_rom[0]->configure_entries(0, 2, rom->base() + 0x10000, 0x4000); @@ -419,6 +417,7 @@ void spectrum_128_state::spectrum_128(machine_config &config) 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)); + m_maincpu->busack_cb().set("dma", FUNC(dma_slot_device::bai_w)); config.set_maximum_quantum(attotime::from_hz(60)); @@ -439,6 +438,15 @@ void spectrum_128_state::spectrum_128(machine_config &config) m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI); m_exp->fb_r_handler().set(FUNC(spectrum_128_state::floating_bus_r)); + dma_slot_device &dma(DMA_SLOT(config.replace(), "dma", X1_128_SINCLAIR / 10, default_dma_slot_devices, nullptr)); + dma.set_io_space(m_maincpu, AS_IO); + dma.out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ); + dma.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + dma.in_mreq_callback().set([this](offs_t offset) { return m_program.read_byte(offset); }); + dma.out_mreq_callback().set([this](offs_t offset, u8 data) { m_program.write_byte(offset, data); }); + dma.in_iorq_callback().set([this](offs_t offset) { return m_io.read_byte(offset); }); + dma.out_iorq_callback().set([this](offs_t offset, u8 data) { m_io.write_byte(offset, data); }); + // internal ram m_ram->set_default_size("128K"); } diff --git a/src/mame/sinclair/spec128.h b/src/mame/sinclair/spec128.h index 1422c3d74db5e..f96dd69801c39 100644 --- a/src/mame/sinclair/spec128.h +++ b/src/mame/sinclair/spec128.h @@ -28,8 +28,6 @@ class spectrum_128_state : public spectrum_state protected: memory_bank_array_creator<1> m_bank_rom; memory_bank_array_creator<4> m_bank_ram; - memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program; - memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_io; virtual void video_start() override ATTR_COLD; virtual void machine_start() override ATTR_COLD; diff --git a/src/mame/sinclair/specnext.cpp b/src/mame/sinclair/specnext.cpp index b005d2a34a4b3..d15494d2ad228 100644 --- a/src/mame/sinclair/specnext.cpp +++ b/src/mame/sinclair/specnext.cpp @@ -3432,6 +3432,7 @@ void specnext_state::tbblue(machine_config &config) { spectrum_128(config); config.device_remove("exp"); + config.device_remove("dma"); // m_ram->set_default_size("1M").set_extra_options("2M"); m_ram->set_default_size("2M").set_default_value(0); diff --git a/src/mame/sinclair/spectrum.cpp b/src/mame/sinclair/spectrum.cpp index cb92826746d8d..ef9adecdc2e1a 100644 --- a/src/mame/sinclair/spectrum.cpp +++ b/src/mame/sinclair/spectrum.cpp @@ -278,6 +278,7 @@ SamRam #include "emu.h" #include "spectrum.h" +#include "bus/spectrum/dma/slot.h" #include "cpu/z80/z80.h" #include "spec_snqk.h" @@ -685,6 +686,9 @@ void spectrum_state::machine_start() { save_item(NAME(m_port_fe_data)); save_item(NAME(m_int_at)); + + m_maincpu->space(AS_PROGRAM).specific(m_program); + m_maincpu->space(AS_IO).specific(m_io); } void spectrum_state::machine_reset() @@ -741,6 +745,7 @@ void spectrum_state::spectrum_common(machine_config &config) 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)); + m_maincpu->busack_cb().set("dma", FUNC(dma_slot_device::bai_w)); ADDRESS_MAP_BANK(config, m_specmem).set_map(&spectrum_state::spectrum_map).set_options(ENDIANNESS_LITTLE, 8, 16, 0x10000); @@ -774,7 +779,15 @@ void spectrum_state::spectrum_common(machine_config &config) m_exp->nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI); m_exp->fb_r_handler().set(FUNC(spectrum_state::floating_bus_r)); - /* devices */ + dma_slot_device &dma(DMA_SLOT(config, "dma", X1 / 4, default_dma_slot_devices, nullptr)); + dma.set_io_space(m_maincpu, AS_IO); + dma.out_busreq_callback().set_inputline(m_maincpu, Z80_INPUT_LINE_BUSRQ); + dma.out_int_callback().set_inputline(m_maincpu, INPUT_LINE_IRQ0); + dma.in_mreq_callback().set([this](offs_t offset) { return m_program.read_byte(offset); }); + dma.out_mreq_callback().set([this](offs_t offset, u8 data) { m_program.write_byte(offset, data); }); + dma.in_iorq_callback().set([this](offs_t offset) { return m_io.read_byte(offset); }); + dma.out_iorq_callback().set([this](offs_t offset, u8 data) { m_io.write_byte(offset, data); }); + SNAPSHOT(config, "snapshot", "ach,frz,plusd,prg,sem,sit,sna,snp,snx,sp,z80,zx").set_load_callback(FUNC(spectrum_state::snapshot_cb)); QUICKLOAD(config, "quickload", "raw,scr", attotime::from_seconds(2)).set_load_callback(FUNC(spectrum_state::quickload_cb)); // The delay prevents the screen from being cleared by the RAM test at boot diff --git a/src/mame/sinclair/spectrum.h b/src/mame/sinclair/spectrum.h index 980d13be69428..e1dcbeb433e81 100644 --- a/src/mame/sinclair/spectrum.h +++ b/src/mame/sinclair/spectrum.h @@ -86,6 +86,9 @@ class spectrum_state : public driver_device void init_spectrum(); protected: + memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program; + memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_io; + virtual void machine_start() override ATTR_COLD; virtual void machine_reset() override ATTR_COLD; virtual void video_start() override ATTR_COLD; diff --git a/src/mame/sinclair/sprinter.cpp b/src/mame/sinclair/sprinter.cpp index fda5027ed7e8b..f620616ba1538 100644 --- a/src/mame/sinclair/sprinter.cpp +++ b/src/mame/sinclair/sprinter.cpp @@ -1873,6 +1873,8 @@ void sprinter_state::sprinter(machine_config &config) { spectrum_128(config); config.device_remove("palette"); + config.device_remove("exp"); + config.device_remove("dma"); config.set_default_layout(layout_sprinter); m_ram->set_default_size("64M"); diff --git a/src/mame/sinclair/timex.cpp b/src/mame/sinclair/timex.cpp index c5c2ff07e1d25..f647edd10300a 100644 --- a/src/mame/sinclair/timex.cpp +++ b/src/mame/sinclair/timex.cpp @@ -681,6 +681,8 @@ void ts2068_state::ts2068(machine_config &config) { spectrum_128(config); + config.device_remove("dma"); + Z80(config.replace(), m_maincpu, XTAL(14'112'000) / 4); // From Schematic; 3.528 MHz m_maincpu->set_addrmap(AS_PROGRAM, &ts2068_state::ts2068_mem); m_maincpu->set_addrmap(AS_IO, &ts2068_state::ts2068_io); diff --git a/src/mame/sinclair/tsconf.cpp b/src/mame/sinclair/tsconf.cpp index a8c83e05e7fd0..b2e14797714b3 100644 --- a/src/mame/sinclair/tsconf.cpp +++ b/src/mame/sinclair/tsconf.cpp @@ -267,6 +267,7 @@ void tsconf_state::tsconf(machine_config &config) spectrum_128(config); config.device_remove("exp"); + config.device_remove("dma"); config.device_remove("palette"); Z80(config.replace(), m_maincpu, 14_MHz_XTAL / 4); From 9387b6651c01dda5b5fe07316b4ea1e0c94b0a34 Mon Sep 17 00:00:00 2001 From: Andrei Holub Date: Sun, 29 Jun 2025 19:18:19 -0400 Subject: [PATCH 2/2] review comments --- scripts/src/bus.lua | 12 ++++++------ src/devices/machine/z80dma.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 950b26a8e583d..c454abfeed13e 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4984,10 +4984,10 @@ end --------------------------------------------------- -- ---@src/devices/bus/spectrum/ay/slot.h,BUSES["AY_SLOT"] = true +--@src/devices/bus/spectrum/ay/slot.h,BUSES["SPECTRUM_AY"] = true --------------------------------------------------- -if (BUSES["AY_SLOT"]~=null) then +if (BUSES["SPECTRUM_AY"]~=null) then files { MAME_DIR .. "src/devices/bus/spectrum/ay/slot.cpp", MAME_DIR .. "src/devices/bus/spectrum/ay/slot.h", @@ -4998,10 +4998,10 @@ end --------------------------------------------------- -- ---@src/devices/bus/spectrum/dma/slot.h,BUSES["DMA"] = true +--@src/devices/bus/spectrum/dma/slot.h,BUSES["SPECTRUM_DMA"] = true --------------------------------------------------- -if (BUSES["DMA"]~=null) then +if (BUSES["SPECTRUM_DMA"]~=null) then files { MAME_DIR .. "src/devices/bus/spectrum/dma/slot.cpp", MAME_DIR .. "src/devices/bus/spectrum/dma/slot.h", @@ -5012,10 +5012,10 @@ end --------------------------------------------------- -- ---@src/devices/bus/spectrum/zxbus/bus.h,BUSES["ZXBUS"] = true +--@src/devices/bus/spectrum/zxbus/bus.h,BUSES["SPECTRUM_ZXBUS"] = true --------------------------------------------------- -if (BUSES["ZXBUS"]~=null) then +if (BUSES["SPECTRUM_ZXBUS"]~=null) then files { MAME_DIR .. "src/devices/bus/spectrum/zxbus/bus.cpp", MAME_DIR .. "src/devices/bus/spectrum/zxbus/bus.h", diff --git a/src/devices/machine/z80dma.cpp b/src/devices/machine/z80dma.cpp index e349d2796fd69..bf144dcb984e0 100644 --- a/src/devices/machine/z80dma.cpp +++ b/src/devices/machine/z80dma.cpp @@ -909,4 +909,4 @@ void ua858d_device::write(u8 data) { z80dma_device::write(data); } -} \ No newline at end of file +}