summaryrefslogtreecommitdiffstats
path: root/src/devices/bus/spectrum
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/spectrum')
-rw-r--r--src/devices/bus/spectrum/beta.cpp256
-rw-r--r--src/devices/bus/spectrum/beta.h64
-rw-r--r--src/devices/bus/spectrum/exp.cpp63
-rw-r--r--src/devices/bus/spectrum/exp.h22
-rw-r--r--src/devices/bus/spectrum/fuller.cpp65
-rw-r--r--src/devices/bus/spectrum/fuller.h11
-rw-r--r--src/devices/bus/spectrum/intf1.cpp47
-rw-r--r--src/devices/bus/spectrum/intf1.h8
-rw-r--r--src/devices/bus/spectrum/intf2.cpp19
-rw-r--r--src/devices/bus/spectrum/intf2.h4
-rw-r--r--src/devices/bus/spectrum/kempjoy.cpp20
-rw-r--r--src/devices/bus/spectrum/kempjoy.h5
-rw-r--r--src/devices/bus/spectrum/melodik.cpp55
-rw-r--r--src/devices/bus/spectrum/melodik.h9
-rw-r--r--src/devices/bus/spectrum/mface.cpp321
-rw-r--r--src/devices/bus/spectrum/mface.h100
-rw-r--r--src/devices/bus/spectrum/mikroplus.cpp22
-rw-r--r--src/devices/bus/spectrum/mikroplus.h6
-rw-r--r--src/devices/bus/spectrum/opus.cpp289
-rw-r--r--src/devices/bus/spectrum/opus.h75
-rw-r--r--src/devices/bus/spectrum/plus2test.cpp2
-rw-r--r--src/devices/bus/spectrum/plus2test.h2
-rw-r--r--src/devices/bus/spectrum/protek.cpp17
-rw-r--r--src/devices/bus/spectrum/protek.h2
-rw-r--r--src/devices/bus/spectrum/specdrum.cpp73
-rw-r--r--src/devices/bus/spectrum/specdrum.h51
-rw-r--r--src/devices/bus/spectrum/uslot.cpp38
-rw-r--r--src/devices/bus/spectrum/uslot.h8
-rw-r--r--src/devices/bus/spectrum/usource.cpp13
-rw-r--r--src/devices/bus/spectrum/usource.h3
-rw-r--r--src/devices/bus/spectrum/uspeech.cpp40
-rw-r--r--src/devices/bus/spectrum/uspeech.h6
32 files changed, 1508 insertions, 208 deletions
diff --git a/src/devices/bus/spectrum/beta.cpp b/src/devices/bus/spectrum/beta.cpp
new file mode 100644
index 00000000000..e48bed34e52
--- /dev/null
+++ b/src/devices/bus/spectrum/beta.cpp
@@ -0,0 +1,256 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/*********************************************************************
+
+ Technology Research Beta 128 Disk interface
+
+*********************************************************************/
+
+#include "emu.h"
+#include "beta.h"
+
+
+/***************************************************************************
+ DEVICE DEFINITIONS
+***************************************************************************/
+
+DEFINE_DEVICE_TYPE(SPECTRUM_BETA128, spectrum_beta128_device, "spectrum_beta128", "TR Beta 128 Disk Interface")
+
+
+//-------------------------------------------------
+// INPUT_PORTS( beta128 )
+//-------------------------------------------------
+
+INPUT_PORTS_START(beta128)
+ PORT_START("BUTTON")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Magic Button") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_beta128_device, magic_button, nullptr)
+
+ PORT_START("SWITCH")
+ PORT_CONFNAME(0x03, 0x01, "System Switch") //PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_beta128_device, switch_changed, 0)
+ PORT_CONFSETTING(0x00, "Off (128)")
+ PORT_CONFSETTING(0x01, "Normal (auto-boot)")
+ //PORT_CONFSETTING(0x02, "Reset") // TODO: implement RESET callback
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor spectrum_beta128_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(beta128);
+}
+
+//-------------------------------------------------
+// SLOT_INTERFACE( beta_floppies )
+//-------------------------------------------------
+
+static void beta_floppies(device_slot_interface &device)
+{
+ device.option_add("525qd", FLOPPY_525_QD);
+}
+
+//-------------------------------------------------
+// floppy_format_type floppy_formats
+//-------------------------------------------------
+
+FLOPPY_FORMATS_MEMBER(spectrum_beta128_device::floppy_formats)
+ FLOPPY_TRD_FORMAT
+FLOPPY_FORMATS_END
+
+//-------------------------------------------------
+// ROM( beta )
+//-------------------------------------------------
+
+ROM_START(beta128)
+ ROM_REGION(0x4000, "rom", 0)
+ ROM_DEFAULT_BIOS("trd504")
+ ROM_SYSTEM_BIOS(0, "trd501", "TR-DOS v5.01")
+ ROMX_LOAD("trd501.rom", 0x0000, 0x4000, CRC(3e3cdd4c) SHA1(8303ba0cc79daa6c04cd1e6ce27e8b6886a3f0de), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "trd503", "TR-DOS v5.03")
+ ROMX_LOAD("trd503.rom", 0x0000, 0x4000, CRC(10751aba) SHA1(21695e3f2a8f796386ce66eea8a246b0ac44810c), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(2, "trd504", "TR-DOS v5.04")
+ ROMX_LOAD("trd504.rom", 0x0000, 0x4000, CRC(ba310874) SHA1(05e55e37df8eee6c68601ba9cf6c92195852ce3f), ROM_BIOS(2))
+ROM_END
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void spectrum_beta128_device::device_add_mconfig(machine_config &config)
+{
+ FD1793(config, m_fdc, 4_MHz_XTAL / 4);
+ FLOPPY_CONNECTOR(config, "fdc:0", beta_floppies, "525qd", spectrum_beta128_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:1", beta_floppies, "525qd", spectrum_beta128_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:2", beta_floppies, nullptr, spectrum_beta128_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:3", beta_floppies, nullptr, spectrum_beta128_device::floppy_formats).enable_sound(true);
+
+ // passthru
+ SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
+ m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
+ m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
+}
+
+const tiny_rom_entry *spectrum_beta128_device::device_rom_region() const
+{
+ return ROM_NAME(beta128);
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spectrum_beta128_device - constructor
+//-------------------------------------------------
+
+spectrum_beta128_device::spectrum_beta128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SPECTRUM_BETA128, tag, owner, clock)
+ , device_spectrum_expansion_interface(mconfig, *this)
+ , m_rom(*this, "rom")
+ , m_fdc(*this, "fdc")
+ , m_floppy(*this, "fdc:%u", 0)
+ , m_exp(*this, "exp")
+ , m_switch(*this, "SWITCH")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spectrum_beta128_device::device_start()
+{
+ save_item(NAME(m_romcs));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void spectrum_beta128_device::device_reset()
+{
+ // Page in the ROM if auto-boot is selected
+ if (m_switch->read() == 0x01)
+ m_romcs = 1;
+ else
+ m_romcs = 0;
+}
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ_LINE_MEMBER(spectrum_beta128_device::romcs)
+{
+ return m_romcs | m_exp->romcs();
+}
+
+
+void spectrum_beta128_device::opcode_fetch(offs_t offset)
+{
+ m_exp->opcode_fetch(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ if ((offset == 0x0066) || (offset & 0xff00) == 0x3d00)
+ m_romcs = 1;
+ else if (offset >= 0x4000)
+ m_romcs = 0;
+ }
+}
+
+uint8_t spectrum_beta128_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ if (m_romcs)
+ {
+ switch (offset & 0xff)
+ {
+ case 0x1f: case 0x3f: case 0x5f: case 0x7f:
+ data = m_fdc->read((offset >> 5) & 0x03);
+ break;
+
+ case 0xff:
+ data &= 0x3f; // actually open bus
+ data |= m_fdc->drq_r() ? 0x40 : 0;
+ data |= m_fdc->intrq_r() ? 0x80 : 0;
+ break;
+ }
+ }
+ return data;
+}
+
+void spectrum_beta128_device::iorq_w(offs_t offset, uint8_t data)
+{
+ if (m_romcs)
+ {
+ switch (offset & 0xff)
+ {
+ case 0x1f: case 0x3f: case 0x5f: case 0x7f:
+ m_fdc->write((offset >> 5) & 0x03, data);
+ break;
+
+ case 0xff:
+ floppy_image_device* floppy = m_floppy[data & 3]->get_device();
+
+ m_fdc->set_floppy(floppy);
+ if (floppy)
+ floppy->ss_w(BIT(data, 4) ? 0 : 1);
+ m_fdc->dden_w(BIT(data, 6));
+
+ // bit 3 connected to pin 23 "HLT" of FDC and via diode to INDEX
+ //m_fdc->hlt_w(BIT(data, 3)); // not handled in current wd_fdc
+
+ if (BIT(data, 2) == 0) // reset
+ {
+ m_fdc->reset();
+ if (floppy)
+ floppy->mon_w(ASSERT_LINE);
+ }
+ else
+ {
+ // TODO: implement correct motor control, FDD motor and RDY FDC pin controlled by HLD pin of FDC
+ if (floppy)
+ floppy->mon_w(CLEAR_LINE);
+ }
+ break;
+ }
+ }
+ m_exp->iorq_w(offset, data);
+}
+
+uint8_t spectrum_beta128_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ if (m_romcs)
+ {
+ data = m_rom->base()[offset & 0x3fff];
+ }
+
+ if (m_exp->romcs())
+ data &= m_exp->mreq_r(offset);
+
+ return data;
+}
+
+void spectrum_beta128_device::mreq_w(offs_t offset, uint8_t data)
+{
+ if (m_exp->romcs())
+ m_exp->mreq_w(offset, data);
+}
+
+INPUT_CHANGED_MEMBER(spectrum_beta128_device::magic_button)
+{
+ if (newval && !oldval)
+ {
+ m_slot->nmi_w(ASSERT_LINE);
+ }
+ else
+ {
+ m_slot->nmi_w(CLEAR_LINE);
+ }
+}
diff --git a/src/devices/bus/spectrum/beta.h b/src/devices/bus/spectrum/beta.h
new file mode 100644
index 00000000000..b759201d35d
--- /dev/null
+++ b/src/devices/bus/spectrum/beta.h
@@ -0,0 +1,64 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/*********************************************************************
+
+ Technology Research Beta 128 Disk interface
+
+*********************************************************************/
+#ifndef MAME_BUS_SPECTRUM_BETA_H
+#define MAME_BUS_SPECTRUM_BETA_H
+
+#include "exp.h"
+#include "softlist.h"
+#include "imagedev/floppy.h"
+#include "machine/wd_fdc.h"
+#include "formats/trd_dsk.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class spectrum_beta128_device :
+ public device_t,
+ public device_spectrum_expansion_interface
+
+{
+public:
+ // construction/destruction
+ spectrum_beta128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_FLOPPY_FORMATS(floppy_formats);
+ DECLARE_INPUT_CHANGED_MEMBER(magic_button);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ_LINE_MEMBER(romcs) override;
+
+ required_memory_region m_rom;
+ required_device<fd1793_device> m_fdc;
+ required_device_array<floppy_connector, 4> m_floppy;
+ required_device<spectrum_expansion_slot_device> m_exp;
+ required_ioport m_switch;
+
+ int m_romcs;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SPECTRUM_BETA128, spectrum_beta128_device)
+
+
+#endif // MAME_BUS_SPECTRUM_BETA_H
diff --git a/src/devices/bus/spectrum/exp.cpp b/src/devices/bus/spectrum/exp.cpp
index 73e1d4a3a9a..850b9f88384 100644
--- a/src/devices/bus/spectrum/exp.cpp
+++ b/src/devices/bus/spectrum/exp.cpp
@@ -43,7 +43,6 @@ device_spectrum_expansion_interface::device_spectrum_expansion_interface(const m
spectrum_expansion_slot_device::spectrum_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SPECTRUM_EXPANSION_SLOT, tag, owner, clock),
device_slot_interface(mconfig, *this),
- m_io(nullptr),
m_card(nullptr),
m_irq_handler(*this),
m_nmi_handler(*this)
@@ -87,46 +86,57 @@ void spectrum_expansion_slot_device::device_reset()
}
//-------------------------------------------------
-// set_io_space - set address space we are attached to
+// romcs
+//-------------------------------------------------
+
+READ_LINE_MEMBER(spectrum_expansion_slot_device::romcs)
+{
+ if (m_card)
+ return m_card->romcs();
+ else
+ return 0;
+}
+
+//-------------------------------------------------
+// fetch_r
//-------------------------------------------------
-void spectrum_expansion_slot_device::set_io_space(address_space *io)
+void spectrum_expansion_slot_device::opcode_fetch(offs_t offset)
{
- m_io = io;
+ if (m_card)
+ m_card->opcode_fetch(offset);
}
//-------------------------------------------------
-// port_fe_r
+// iorq_r
//-------------------------------------------------
-READ8_MEMBER(spectrum_expansion_slot_device::port_fe_r)
+uint8_t spectrum_expansion_slot_device::iorq_r(offs_t offset)
{
if (m_card)
- return m_card->port_fe_r(space, offset);
+ return m_card->iorq_r(offset);
else
return 0xff;
}
//-------------------------------------------------
-// romcs
+// iorq_w
//-------------------------------------------------
-READ_LINE_MEMBER(spectrum_expansion_slot_device::romcs)
+void spectrum_expansion_slot_device::iorq_w(offs_t offset, uint8_t data)
{
if (m_card)
- return m_card->romcs();
- else
- return 0;
+ m_card->iorq_w(offset, data);
}
//-------------------------------------------------
// mreq_r
//-------------------------------------------------
-READ8_MEMBER(spectrum_expansion_slot_device::mreq_r)
+uint8_t spectrum_expansion_slot_device::mreq_r(offs_t offset)
{
if (m_card)
- return m_card->mreq_r(space, offset);
+ return m_card->mreq_r(offset);
else
return 0xff;
}
@@ -135,10 +145,10 @@ READ8_MEMBER(spectrum_expansion_slot_device::mreq_r)
// mreq_w
//-------------------------------------------------
-WRITE8_MEMBER(spectrum_expansion_slot_device::mreq_w)
+void spectrum_expansion_slot_device::mreq_w(offs_t offset, uint8_t data)
{
if (m_card)
- m_card->mreq_w(space, offset, data);
+ m_card->mreq_w(offset, data);
}
@@ -148,14 +158,20 @@ WRITE8_MEMBER(spectrum_expansion_slot_device::mreq_w)
// slot devices
+#include "beta.h"
+//#include "disciple.h"
#include "intf1.h"
#include "intf2.h"
#include "fuller.h"
#include "kempjoy.h"
#include "melodik.h"
+#include "mface.h"
#include "mikroplus.h"
+#include "opus.h"
#include "plus2test.h"
+//#include "plusd.h"
#include "protek.h"
+#include "specdrum.h"
#include "uslot.h"
#include "usource.h"
#include "uspeech.h"
@@ -163,13 +179,21 @@ WRITE8_MEMBER(spectrum_expansion_slot_device::mreq_w)
void spectrum_expansion_devices(device_slot_interface &device)
{
+ device.option_add("beta128", SPECTRUM_BETA128);
+ //device.option_add("disciple", SPECTRUM_DISCIPLE);
device.option_add("intf1", SPECTRUM_INTF1);
device.option_add("intf2", SPECTRUM_INTF2);
device.option_add("fuller", SPECTRUM_FULLER);
device.option_add("kempjoy", SPECTRUM_KEMPJOY);
device.option_add("melodik", SPECTRUM_MELODIK);
+ device.option_add("mface1", SPECTRUM_MFACE1);
+ device.option_add("mface128", SPECTRUM_MFACE128);
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
+ device.option_add("mprint", SPECTRUM_MPRINT);
+ device.option_add("opus", SPECTRUM_OPUS);
+ //device.option_add("plusd", SPECTRUM_PLUSD);
device.option_add("protek", SPECTRUM_PROTEK);
+ device.option_add("specdrum", SPECTRUM_SPECDRUM);
device.option_add("uslot", SPECTRUM_USLOT);
device.option_add("usource", SPECTRUM_USOURCE);
device.option_add("uspeech", SPECTRUM_USPEECH);
@@ -177,15 +201,22 @@ void spectrum_expansion_devices(device_slot_interface &device)
void spec128_expansion_devices(device_slot_interface &device)
{
+ device.option_add("beta128", SPECTRUM_BETA128);
+ //device.option_add("disciple", SPECTRUM_DISCIPLE);
device.option_add("intf1", SPECTRUM_INTF1);
device.option_add("intf2", SPECTRUM_INTF2);
device.option_add("kempjoy", SPECTRUM_KEMPJOY);
+ device.option_add("mface128", SPECTRUM_MFACE128);
device.option_add("mikroplus", SPECTRUM_MIKROPLUS);
+ device.option_add("mprint", SPECTRUM_MPRINT);
+ device.option_add("opus", SPECTRUM_OPUS);
device.option_add("plus2test", SPECTRUM_PLUS2TEST);
device.option_add("protek", SPECTRUM_PROTEK);
+ device.option_add("specdrum", SPECTRUM_SPECDRUM);
}
void specpls3_expansion_devices(device_slot_interface &device)
{
+ device.option_add("mface3", SPECTRUM_MFACE3);
}
diff --git a/src/devices/bus/spectrum/exp.h b/src/devices/bus/spectrum/exp.h
index 1d8eb5f21f2..aee398d1ab4 100644
--- a/src/devices/bus/spectrum/exp.h
+++ b/src/devices/bus/spectrum/exp.h
@@ -69,22 +69,20 @@ public:
spectrum_expansion_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock = 0);
- void set_io_space(address_space *io);
-
// callbacks
auto irq_handler() { return m_irq_handler.bind(); }
auto nmi_handler() { return m_nmi_handler.bind(); }
- DECLARE_READ8_MEMBER( mreq_r );
- DECLARE_WRITE8_MEMBER( mreq_w );
- DECLARE_READ8_MEMBER( port_fe_r );
+ void opcode_fetch(offs_t offset);
+ uint8_t mreq_r(offs_t offset);
+ void mreq_w(offs_t offset, uint8_t data);
+ uint8_t iorq_r(offs_t offset);
+ void iorq_w(offs_t offset, uint8_t data);
DECLARE_READ_LINE_MEMBER( romcs );
DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_irq_handler(state); }
DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi_handler(state); }
- address_space *m_io;
-
protected:
// device-level overrides
virtual void device_validity_check(validity_checker &valid) const override;
@@ -108,14 +106,14 @@ public:
device_spectrum_expansion_interface(const machine_config &mconfig, device_t &device);
// reading and writing
- virtual DECLARE_READ8_MEMBER(mreq_r) { return 0xff; }
- virtual DECLARE_WRITE8_MEMBER(mreq_w) { }
- virtual DECLARE_READ8_MEMBER(port_fe_r) { return 0xff; }
+ virtual void opcode_fetch(offs_t offset) { };
+ virtual uint8_t mreq_r(offs_t offset) { return 0xff; }
+ virtual void mreq_w(offs_t offset, uint8_t data) { }
+ virtual uint8_t iorq_r(offs_t offset) { return 0xff; }
+ virtual void iorq_w(offs_t offset, uint8_t data) { }
virtual DECLARE_READ_LINE_MEMBER(romcs) { return 0; }
protected:
- address_space &io_space() { return *m_slot->m_io; }
-
spectrum_expansion_slot_device *m_slot;
};
diff --git a/src/devices/bus/spectrum/fuller.cpp b/src/devices/bus/spectrum/fuller.cpp
index 36275ccc4cd..636967cbdd6 100644
--- a/src/devices/bus/spectrum/fuller.cpp
+++ b/src/devices/bus/spectrum/fuller.cpp
@@ -84,51 +84,62 @@ void spectrum_fuller_device::device_start()
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void spectrum_fuller_device::device_reset()
-{
- m_exp->set_io_space(&io_space());
-
- io_space().install_write_handler(0x3f, 0x3f, 0, 0xff00, 0, write8_delegate(FUNC(ay8910_device::address_w), m_psg.target()));
- io_space().install_readwrite_handler(0x5f, 0x5f, 0, 0xff00, 0, read8_delegate(FUNC(ay8910_device::data_r), m_psg.target()), write8_delegate(FUNC(ay8910_device::data_w), m_psg.target()));
- io_space().install_read_handler(0x7f, 0x7f, 0, 0xff00, 0, read8_delegate(FUNC(spectrum_fuller_device::joystick_r), this));
-}
-
-
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
-READ8_MEMBER(spectrum_fuller_device::joystick_r)
-{
- return m_joy->read() | (0xff ^ 0x8f);
-}
-
READ_LINE_MEMBER(spectrum_fuller_device::romcs)
{
return m_exp->romcs();
}
-READ8_MEMBER(spectrum_fuller_device::mreq_r)
+void spectrum_fuller_device::opcode_fetch(offs_t offset)
{
- return m_exp->mreq_r(space, offset);
+ m_exp->opcode_fetch(offset);
}
-WRITE8_MEMBER(spectrum_fuller_device::mreq_w)
+uint8_t spectrum_fuller_device::mreq_r(offs_t offset)
{
+ uint8_t data = 0xff;
+
if (m_exp->romcs())
- m_exp->mreq_w(space, offset, data);
+ data &= m_exp->mreq_r(offset);
+
+ return data;
}
-READ8_MEMBER(spectrum_fuller_device::port_fe_r)
+void spectrum_fuller_device::mreq_w(offs_t offset, uint8_t data)
{
- uint8_t data = 0xff;
-
if (m_exp->romcs())
- data &= m_exp->port_fe_r(space, offset);
+ m_exp->mreq_w(offset, data);
+}
+uint8_t spectrum_fuller_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ switch (offset & 0xff)
+ {
+ case 0x5f:
+ data &= m_psg->data_r();
+ break;
+ case 0x7f:
+ data &= m_joy->read() | (0xff ^ 0x8f);
+ break;
+ }
return data;
}
+
+void spectrum_fuller_device::iorq_w(offs_t offset, uint8_t data)
+{
+ switch (offset & 0xff)
+ {
+ case 0x3f:
+ m_psg->address_w(data);
+ break;
+ case 0x5f:
+ m_psg->data_w(data);
+ break;
+ }
+ m_exp->iorq_w(offset, data);
+}
diff --git a/src/devices/bus/spectrum/fuller.h b/src/devices/bus/spectrum/fuller.h
index b0431121424..12f7805eff0 100644
--- a/src/devices/bus/spectrum/fuller.h
+++ b/src/devices/bus/spectrum/fuller.h
@@ -32,20 +32,19 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void device_reset() override;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
- virtual DECLARE_WRITE8_MEMBER(mreq_w) override;
- virtual DECLARE_READ8_MEMBER(port_fe_r) override;
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:
- DECLARE_READ8_MEMBER(joystick_r);
-
required_device<spectrum_expansion_slot_device> m_exp;
required_device<ay8910_device> m_psg;
required_ioport m_joy;
diff --git a/src/devices/bus/spectrum/intf1.cpp b/src/devices/bus/spectrum/intf1.cpp
index d324e931e2c..344aaf61841 100644
--- a/src/devices/bus/spectrum/intf1.cpp
+++ b/src/devices/bus/spectrum/intf1.cpp
@@ -85,6 +85,7 @@ spectrum_intf1_device::spectrum_intf1_device(const machine_config &mconfig, cons
void spectrum_intf1_device::device_start()
{
+ save_item(NAME(m_romcs));
}
//-------------------------------------------------
@@ -93,8 +94,6 @@ void spectrum_intf1_device::device_start()
void spectrum_intf1_device::device_reset()
{
- m_exp->set_io_space(&io_space());
-
m_romcs = 0;
}
@@ -107,45 +106,49 @@ READ_LINE_MEMBER(spectrum_intf1_device::romcs)
return m_romcs | m_exp->romcs();
}
-READ8_MEMBER(spectrum_intf1_device::mreq_r)
+void spectrum_intf1_device::opcode_fetch(offs_t offset)
{
- uint8_t temp;
- uint8_t data = 0xff;
+ m_exp->opcode_fetch(offset);
if (!machine().side_effects_disabled())
{
- if (offset == 0x0008 || offset == 0x1708)
+ switch (offset)
+ {
+ case 0x0008: case 0x1708:
m_romcs = 1;
+ break;
+ case 0x0700:
+ m_romcs = 0;
+ break;
+ }
}
+}
- temp = m_exp->mreq_r(space, offset);
- if (m_exp->romcs())
- data &= temp;
+uint8_t spectrum_intf1_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
if (m_romcs)
data &= m_rom->base()[offset & 0x1fff];
- if (!machine().side_effects_disabled())
- {
- if (offset == 0x0700)
- m_romcs = 0;
- }
+ if (m_exp->romcs())
+ data &= m_exp->mreq_r(offset);
return data;
}
-WRITE8_MEMBER(spectrum_intf1_device::mreq_w)
+void spectrum_intf1_device::mreq_w(offs_t offset, uint8_t data)
{
if (m_exp->romcs())
- m_exp->mreq_w(space, offset, data);
+ m_exp->mreq_w(offset, data);
}
-READ8_MEMBER(spectrum_intf1_device::port_fe_r)
+uint8_t spectrum_intf1_device::iorq_r(offs_t offset)
{
- uint8_t data = 0xff;
-
- if (m_exp->romcs())
- data &= m_exp->port_fe_r(space, offset);
+ return m_exp->iorq_r(offset);
+}
- return data;
+void spectrum_intf1_device::iorq_w(offs_t offset, uint8_t data)
+{
+ m_exp->iorq_w(offset, data);
}
diff --git a/src/devices/bus/spectrum/intf1.h b/src/devices/bus/spectrum/intf1.h
index 5a21cd9927d..6b0ddb32804 100644
--- a/src/devices/bus/spectrum/intf1.h
+++ b/src/devices/bus/spectrum/intf1.h
@@ -36,9 +36,11 @@ protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual const tiny_rom_entry *device_rom_region() const override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
- virtual DECLARE_WRITE8_MEMBER(mreq_w) override;
- virtual DECLARE_READ8_MEMBER(port_fe_r) override;
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:
diff --git a/src/devices/bus/spectrum/intf2.cpp b/src/devices/bus/spectrum/intf2.cpp
index 2700c2787d0..789be29717d 100644
--- a/src/devices/bus/spectrum/intf2.cpp
+++ b/src/devices/bus/spectrum/intf2.cpp
@@ -117,7 +117,7 @@ READ_LINE_MEMBER(spectrum_intf2_device::romcs)
return 0;
}
-READ8_MEMBER(spectrum_intf2_device::mreq_r)
+uint8_t spectrum_intf2_device::mreq_r(offs_t offset)
{
if (m_cart && m_cart->exists())
return m_cart->get_rom_base()[offset & 0x3fff];
@@ -125,17 +125,20 @@ READ8_MEMBER(spectrum_intf2_device::mreq_r)
return 0xff;
}
-READ8_MEMBER(spectrum_intf2_device::port_fe_r)
+uint8_t spectrum_intf2_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
- uint8_t lines = offset >> 8;
-
- if ((lines & 8) == 0)
- data = m_exp_line3->read() | (0xff ^ 0x1f);
+ switch (offset & 0xff)
+ {
+ case 0xfe:
+ if (((offset >> 8) & 8) == 0)
+ data = m_exp_line3->read() | (0xff ^ 0x1f);
- if ((lines & 16) == 0)
- data = m_exp_line4->read() | (0xff ^ 0x1f);
+ if (((offset >> 8) & 16) == 0)
+ data = m_exp_line4->read() | (0xff ^ 0x1f);
+ break;
+ }
return data;
}
diff --git a/src/devices/bus/spectrum/intf2.h b/src/devices/bus/spectrum/intf2.h
index 826e4b8fb3e..fd131112a3c 100644
--- a/src/devices/bus/spectrum/intf2.h
+++ b/src/devices/bus/spectrum/intf2.h
@@ -35,8 +35,8 @@ protected:
virtual ioport_constructor device_input_ports() const override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
- virtual DECLARE_READ8_MEMBER(port_fe_r) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
private:
image_init_result load_cart(device_image_interface &image, generic_slot_device *slot);
diff --git a/src/devices/bus/spectrum/kempjoy.cpp b/src/devices/bus/spectrum/kempjoy.cpp
index ac7d5698bd7..a433d615e8c 100644
--- a/src/devices/bus/spectrum/kempjoy.cpp
+++ b/src/devices/bus/spectrum/kempjoy.cpp
@@ -65,21 +65,17 @@ void spectrum_kempjoy_device::device_start()
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void spectrum_kempjoy_device::device_reset()
-{
- io_space().install_read_handler(0x1f, 0x1f, 0, 0xff00, 0, read8_delegate(FUNC(spectrum_kempjoy_device::joystick_r), this));
-}
-
-
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
-READ8_MEMBER(spectrum_kempjoy_device::joystick_r)
+uint8_t spectrum_kempjoy_device::iorq_r(offs_t offset)
{
- return m_joy->read() & 0x1f;
+ uint8_t data = 0xff;
+
+ if (offset == 0x1f)
+ {
+ data = m_joy->read() & 0x1f;
+ }
+ return data;
}
diff --git a/src/devices/bus/spectrum/kempjoy.h b/src/devices/bus/spectrum/kempjoy.h
index 555fb67643a..466dceb7517 100644
--- a/src/devices/bus/spectrum/kempjoy.h
+++ b/src/devices/bus/spectrum/kempjoy.h
@@ -31,14 +31,13 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void device_reset() override;
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
-private:
- DECLARE_READ8_MEMBER(joystick_r);
+ virtual uint8_t iorq_r(offs_t offset) override;
+private:
required_ioport m_joy;
};
diff --git a/src/devices/bus/spectrum/melodik.cpp b/src/devices/bus/spectrum/melodik.cpp
index 8303d4c436c..f6abc0f98d6 100644
--- a/src/devices/bus/spectrum/melodik.cpp
+++ b/src/devices/bus/spectrum/melodik.cpp
@@ -60,18 +60,6 @@ void spectrum_melodik_device::device_start()
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void spectrum_melodik_device::device_reset()
-{
- m_exp->set_io_space(&io_space());
-
- io_space().install_write_handler(0x8000, 0x8000, 0, 0x3ffd, 0, write8_delegate(FUNC(ay8910_device::address_w), m_psg.target()));
- io_space().install_readwrite_handler(0xc000, 0xc000, 0, 0x3ffd, 0, read8_delegate(FUNC(ay8910_device::data_r), m_psg.target()), write8_delegate(FUNC(ay8910_device::data_w), m_psg.target()));
-}
-
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
@@ -81,23 +69,50 @@ READ_LINE_MEMBER(spectrum_melodik_device::romcs)
return m_exp->romcs();
}
-READ8_MEMBER(spectrum_melodik_device::mreq_r)
+void spectrum_melodik_device::opcode_fetch(offs_t offset)
{
- return m_exp->mreq_r(space, offset);
+ m_exp->opcode_fetch(offset);
}
-WRITE8_MEMBER(spectrum_melodik_device::mreq_w)
+uint8_t spectrum_melodik_device::mreq_r(offs_t offset)
{
+ uint8_t data = 0xff;
+
if (m_exp->romcs())
- m_exp->mreq_w(space, offset, data);
+ data &= m_exp->mreq_r(offset);
+
+ return data;
}
-READ8_MEMBER(spectrum_melodik_device::port_fe_r)
+void spectrum_melodik_device::mreq_w(offs_t offset, uint8_t data)
{
- uint8_t data = 0xff;
-
if (m_exp->romcs())
- data &= m_exp->port_fe_r(space, offset);
+ m_exp->mreq_w(offset, data);
+}
+uint8_t spectrum_melodik_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ switch (offset & 0xc002)
+ {
+ case 0xc000:
+ data &= m_psg->data_r();
+ break;
+ }
return data;
}
+
+void spectrum_melodik_device::iorq_w(offs_t offset, uint8_t data)
+{
+ switch (offset & 0xc002)
+ {
+ case 0x8000:
+ m_psg->address_w(data);
+ break;
+ case 0xc000:
+ m_psg->data_w(data);
+ break;
+ }
+ m_exp->iorq_w(offset, data);
+}
diff --git a/src/devices/bus/spectrum/melodik.h b/src/devices/bus/spectrum/melodik.h
index 2dc3c547836..4300d946cd4 100644
--- a/src/devices/bus/spectrum/melodik.h
+++ b/src/devices/bus/spectrum/melodik.h
@@ -32,14 +32,15 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void device_reset() override;
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
- virtual DECLARE_WRITE8_MEMBER(mreq_w) override;
- virtual DECLARE_READ8_MEMBER(port_fe_r) override;
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:
diff --git a/src/devices/bus/spectrum/mface.cpp b/src/devices/bus/spectrum/mface.cpp
new file mode 100644
index 00000000000..559dd9ae1e6
--- /dev/null
+++ b/src/devices/bus/spectrum/mface.cpp
@@ -0,0 +1,321 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/*********************************************************************
+
+ Romantic Robot Multiface One/128/3
+
+*********************************************************************/
+
+#include "emu.h"
+#include "mface.h"
+
+
+/***************************************************************************
+ DEVICE DEFINITIONS
+***************************************************************************/
+
+DEFINE_DEVICE_TYPE(SPECTRUM_MFACE1, spectrum_mface1_device, "spectrum_mface1", "Multiface One")
+DEFINE_DEVICE_TYPE(SPECTRUM_MFACE128, spectrum_mface128_device, "spectrum_mface128", "Multiface 128")
+DEFINE_DEVICE_TYPE(SPECTRUM_MFACE3, spectrum_mface3_device, "spectrum_mface3", "Multiface 3")
+DEFINE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device, "spectrum_mprint", "MultiPrint")
+
+
+//-------------------------------------------------
+// INPUT_PORTS( mface )
+//-------------------------------------------------
+
+INPUT_PORTS_START(mface)
+ PORT_START("BUTTON")
+ PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Multiface") PORT_CODE(KEYCODE_F12) PORT_CHANGED_MEMBER(DEVICE_SELF, spectrum_mface1_device, magic_button, nullptr)
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor spectrum_mface1_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(mface);
+}
+
+//-------------------------------------------------
+// ROM( mface1 )
+//-------------------------------------------------
+
+ROM_START(mface1)
+ ROM_REGION(0x2000, "rom", 0)
+ ROM_DEFAULT_BIOS("mu21e7")
+ ROM_SYSTEM_BIOS(0, "mu20fe", "MU 2.0 FE")
+ ROMX_LOAD("mf1_20_fe.rom", 0x0000, 0x2000, CRC(fa1b8b0d) SHA1(20cd508b0143166558a7238c7a9ccfbe37b90b0d), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "mu2167", "MU 2.1 67")
+ ROMX_LOAD("mf1_21_67.rom", 0x0000, 0x2000, CRC(d720ec1b) SHA1(91a40d8f503ef825df3e2ed712897dbf4ca3671d), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(2, "mu21e4", "MU 2.1 E4")
+ ROMX_LOAD("mf1_21_e4.rom", 0x0000, 0x2000, CRC(4b31a971) SHA1(ba28754a3cc31a4ca579829ed4310c313409cf5d), ROM_BIOS(2))
+ ROM_SYSTEM_BIOS(3, "mu21e7", "MU 2.1 E7")
+ ROMX_LOAD("mf1_21_e7.rom", 0x0000, 0x2000, CRC(670f0ec2) SHA1(50fba2d628f3a2e9219f72980e4efd62fc9ec1f8), ROM_BIOS(3))
+ROM_END
+
+ROM_START(mface128)
+ ROM_REGION(0x2000, "rom", 0)
+ ROM_DEFAULT_BIOS("v363c")
+ ROM_SYSTEM_BIOS(0, "v363c", "87.2 V36 3C")
+ ROMX_LOAD("mf128_36_3c.rom", 0x0000, 0x2000, CRC(78ec8cfd) SHA1(8df204ab490b87c389971ce0c7fb5f9cbd281f14), ROM_BIOS(0))
+ROM_END
+
+ROM_START(mface3)
+ ROM_REGION(0x2000, "rom", 0)
+ ROM_DEFAULT_BIOS("v50fe")
+ ROM_SYSTEM_BIOS(0, "v5013", "V50 13")
+ ROMX_LOAD("mf3_50_13.rom", 0x0000, 0x2000, CRC(2d594640) SHA1(5d74d2e2e5a537639da92ff120f8a6d86f474495), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "v50fe", "V50 FE")
+ ROMX_LOAD("mf3_50_fe.rom", 0x0000, 0x2000, CRC(b5c00f28) SHA1(983699a07665186f498f5827f9b35c442c2178ba), ROM_BIOS(1))
+ROM_END
+
+ROM_START(mprint)
+ ROM_REGION(0x2000, "rom", 0)
+ ROM_DEFAULT_BIOS("mpa8")
+ ROM_SYSTEM_BIOS(0, "mp5a", "MP 5A")
+ ROMX_LOAD("mprint_5a.rom", 0x0000, 0x2000, CRC(3a26e84b) SHA1(4714469bf25f69291f61188f52bfb11fbb8d0b33), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "mpa8", "MP A8")
+ ROMX_LOAD("mprint_a8.rom", 0x0000, 0x2000, CRC(a5c58022) SHA1(1356bfae3264b952f83a33e25af536c0f13f50e7), ROM_BIOS(1))
+ROM_END
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void spectrum_mface1_device::device_add_mconfig(machine_config &config)
+{
+ /* passthru */
+ SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
+ m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
+ m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
+}
+
+const tiny_rom_entry *spectrum_mface1_device::device_rom_region() const
+{
+ return ROM_NAME(mface1);
+}
+
+const tiny_rom_entry *spectrum_mface128_device::device_rom_region() const
+{
+ return ROM_NAME(mface128);
+}
+
+const tiny_rom_entry *spectrum_mface3_device::device_rom_region() const
+{
+ return ROM_NAME(mface3);
+}
+
+const tiny_rom_entry *spectrum_mprint_device::device_rom_region() const
+{
+ return ROM_NAME(mprint);
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spectrum_opus_device - constructor
+//-------------------------------------------------
+
+spectrum_mface1_device::spectrum_mface1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , device_spectrum_expansion_interface(mconfig, *this)
+ , m_rom(*this, "rom")
+ , m_exp(*this, "exp")
+{
+}
+
+spectrum_mface1_device::spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spectrum_mface1_device(mconfig, SPECTRUM_MFACE1, tag, owner, clock)
+{
+}
+
+spectrum_mface128_device::spectrum_mface128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spectrum_mface1_device(mconfig, SPECTRUM_MFACE128, tag, owner, clock)
+{
+}
+
+spectrum_mface3_device::spectrum_mface3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spectrum_mface1_device(mconfig, SPECTRUM_MFACE3, tag, owner, clock)
+{
+}
+
+spectrum_mprint_device::spectrum_mprint_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : spectrum_mface1_device(mconfig, SPECTRUM_MPRINT, tag, owner, clock)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spectrum_mface1_device::device_start()
+{
+ save_item(NAME(m_romcs));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void spectrum_mface1_device::device_reset()
+{
+ m_romcs = 0;
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ_LINE_MEMBER(spectrum_mface1_device::romcs)
+{
+ return m_romcs | m_exp->romcs();
+}
+
+void spectrum_mface1_device::opcode_fetch(offs_t offset)
+{
+ m_exp->opcode_fetch(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ if (offset == 0x0066)
+ m_romcs = 1;
+ }
+}
+
+uint8_t spectrum_mface1_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ switch (offset & 0xff)
+ {
+ case 0x1f:
+ m_romcs = 0;
+ break;
+ case 0x9f:
+ m_romcs = 1;
+ break;
+ }
+ }
+ return data;
+}
+
+uint8_t spectrum_mface128_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ switch (offset & 0xff)
+ {
+ case 0xbf:
+ m_romcs = 1;
+ break;
+ case 0x3f:
+ m_romcs = 0;
+ break;
+ }
+ }
+ return data;
+}
+
+uint8_t spectrum_mface3_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ switch (offset & 0xff)
+ {
+ case 0x3f:
+ m_romcs = 1;
+ break;
+ case 0xbf:
+ m_romcs = 0;
+ break;
+ }
+ }
+ return data;
+}
+
+uint8_t spectrum_mprint_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ switch (offset & 0xff)
+ {
+ case 0xbb:
+ m_romcs = 1;
+ break;
+ case 0xbf:
+ m_romcs = 0;
+ break;
+ }
+ }
+ return data;
+}
+
+void spectrum_mface1_device::iorq_w(offs_t offset, uint8_t data)
+{
+ m_exp->iorq_w(offset, data);
+}
+
+uint8_t spectrum_mface1_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ if (m_romcs)
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x0000:
+ data = m_rom->base()[offset & 0x1fff];
+ break;
+ case 0x2000:
+ data = m_ram[offset & 0x1fff];
+ break;
+ }
+ }
+
+ if (m_exp->romcs())
+ data &= m_exp->mreq_r(offset);
+
+ return data;
+}
+
+void spectrum_mface1_device::mreq_w(offs_t offset, uint8_t data)
+{
+ if (m_romcs)
+ {
+ switch (offset & 0xe000)
+ {
+ case 0x2000:
+ m_ram[offset & 0x1fff] = data;
+ break;
+ }
+ }
+
+ if (m_exp->romcs())
+ m_exp->mreq_w(offset, data);
+}
+
+INPUT_CHANGED_MEMBER(spectrum_mface1_device::magic_button)
+{
+ if (newval && !oldval)
+ {
+ m_slot->nmi_w(ASSERT_LINE);
+ }
+ else
+ {
+ m_slot->nmi_w(CLEAR_LINE);
+ }
+}
diff --git a/src/devices/bus/spectrum/mface.h b/src/devices/bus/spectrum/mface.h
new file mode 100644
index 00000000000..bbe8311808c
--- /dev/null
+++ b/src/devices/bus/spectrum/mface.h
@@ -0,0 +1,100 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/*********************************************************************
+
+ Romantic Robot Multiface One/128/3
+
+*********************************************************************/
+#ifndef MAME_BUS_SPECTRUM_MFACE_H
+#define MAME_BUS_SPECTRUM_MFACE_H
+
+#include "exp.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class spectrum_mface1_device :
+ public device_t,
+ public device_spectrum_expansion_interface
+
+{
+public:
+ // construction/destruction
+ spectrum_mface1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_INPUT_CHANGED_MEMBER(magic_button);
+
+protected:
+ spectrum_mface1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ_LINE_MEMBER(romcs) override;
+
+ required_memory_region m_rom;
+ required_device<spectrum_expansion_slot_device> m_exp;
+
+ uint8_t m_ram[8 * 1024];
+ int m_romcs;
+};
+
+class spectrum_mface128_device : public spectrum_mface1_device
+{
+public:
+ spectrum_mface128_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // optional information overrides
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual uint8_t iorq_r(offs_t offset) override;
+};
+
+class spectrum_mface3_device : public spectrum_mface1_device
+{
+public:
+ spectrum_mface3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // optional information overrides
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual uint8_t iorq_r(offs_t offset) override;
+};
+
+class spectrum_mprint_device : public spectrum_mface1_device
+{
+public:
+ spectrum_mprint_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // optional information overrides
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual uint8_t iorq_r(offs_t offset) override;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SPECTRUM_MFACE1, spectrum_mface1_device)
+DECLARE_DEVICE_TYPE(SPECTRUM_MFACE128, spectrum_mface128_device)
+DECLARE_DEVICE_TYPE(SPECTRUM_MFACE3, spectrum_mface3_device)
+DECLARE_DEVICE_TYPE(SPECTRUM_MPRINT, spectrum_mprint_device)
+
+
+
+#endif // MAME_BUS_SPECTRUM_MFACE_H
diff --git a/src/devices/bus/spectrum/mikroplus.cpp b/src/devices/bus/spectrum/mikroplus.cpp
index b0f0676aaee..87552f79bf3 100644
--- a/src/devices/bus/spectrum/mikroplus.cpp
+++ b/src/devices/bus/spectrum/mikroplus.cpp
@@ -85,23 +85,19 @@ void spectrum_mikroplus_device::device_start()
}
-//-------------------------------------------------
-// device_reset - device-specific reset
-//-------------------------------------------------
-
-void spectrum_mikroplus_device::device_reset()
-{
- io_space().install_read_handler(0xdf, 0xdf, 0, 0xff00, 0, read8_delegate(FUNC(spectrum_mikroplus_device::joystick_r), this));
-}
-
-
//**************************************************************************
// IMPLEMENTATION
//**************************************************************************
-READ8_MEMBER(spectrum_mikroplus_device::joystick_r)
+uint8_t spectrum_mikroplus_device::iorq_r(offs_t offset)
{
- return m_joy->read() | (0xff ^ 0x1f);
+ uint8_t data = 0xff;
+
+ if (offset == 0xdf)
+ {
+ data = m_joy->read() | (0xff ^ 0x1f);
+ }
+ return data;
}
READ_LINE_MEMBER(spectrum_mikroplus_device::romcs)
@@ -109,7 +105,7 @@ READ_LINE_MEMBER(spectrum_mikroplus_device::romcs)
return 1;
}
-READ8_MEMBER(spectrum_mikroplus_device::mreq_r)
+uint8_t spectrum_mikroplus_device::mreq_r(offs_t offset)
{
return m_rom->base()[offset & 0x3fff];
}
diff --git a/src/devices/bus/spectrum/mikroplus.h b/src/devices/bus/spectrum/mikroplus.h
index 927cff5f56a..e06cb38bb2c 100644
--- a/src/devices/bus/spectrum/mikroplus.h
+++ b/src/devices/bus/spectrum/mikroplus.h
@@ -31,18 +31,16 @@ public:
protected:
// device-level overrides
virtual void device_start() override;
- virtual void device_reset() override;
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
virtual ioport_constructor device_input_ports() const override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
private:
- DECLARE_READ8_MEMBER(joystick_r);
-
required_memory_region m_rom;
required_ioport m_joy;
};
diff --git a/src/devices/bus/spectrum/opus.cpp b/src/devices/bus/spectrum/opus.cpp
new file mode 100644
index 00000000000..be73ef01e92
--- /dev/null
+++ b/src/devices/bus/spectrum/opus.cpp
@@ -0,0 +1,289 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ Opus Discovery disc system
+
+**********************************************************************/
+
+
+#include "emu.h"
+#include "opus.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(SPECTRUM_OPUS, spectrum_opus_device, "spectrum_opus", "Opus Discovery")
+
+
+//-------------------------------------------------
+// INPUT_PORTS( opus )
+//-------------------------------------------------
+
+static INPUT_PORTS_START( opus )
+ PORT_START("JOY")
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT) PORT_8WAY
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT) PORT_8WAY
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN) PORT_8WAY
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP) PORT_8WAY
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON1)
+INPUT_PORTS_END
+
+//-------------------------------------------------
+// input_ports - device-specific input ports
+//-------------------------------------------------
+
+ioport_constructor spectrum_opus_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( opus );
+}
+
+//-------------------------------------------------
+// MACHINE_DRIVER( opus )
+//-------------------------------------------------
+
+FLOPPY_FORMATS_MEMBER( spectrum_opus_device::floppy_formats )
+ FLOPPY_OPD_FORMAT
+FLOPPY_FORMATS_END
+
+static void spectrum_floppies(device_slot_interface &device)
+{
+ device.option_add("35ssdd", FLOPPY_35_SSDD);
+ device.option_add("35dd", FLOPPY_35_DD);
+}
+
+ROM_START(opus)
+ ROM_REGION(0x2000, "rom", 0)
+ ROM_DEFAULT_BIOS("opus22")
+ ROM_SYSTEM_BIOS(0, "opus22", "Opus v2.2")
+ ROMX_LOAD("opus-22.rom", 0x0000, 0x2000, CRC(50f0eae0) SHA1(0eee1c503f71709fce8b7560dadc2d07d15edb80), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "opus21", "Opus v2.1")
+ ROMX_LOAD("opus-21.rom", 0x0000, 0x2000, CRC(619973f9) SHA1(31999a68901392bba907cf5a15e264b6759f1a29), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(2, "opus222", "Opus v2.22")
+ ROMX_LOAD("opus-222.rom", 0x0000, 0x2000, CRC(08ce9949) SHA1(71f1c8a8b923f7751d1ff48d30b8e18a15b92591), ROM_BIOS(2))
+ ROM_SYSTEM_BIOS(3, "quickdos", "QuickDOS v2.31") // MegaSoft
+ ROMX_LOAD("quickdos-231.rom", 0x0000, 0x2000, CRC(d042b32a) SHA1(2975f7eb61d44e898cdd6e3196893e95637f17ff), ROM_BIOS(3))
+ ROM_SYSTEM_BIOS(4, "excom", "EXCOM v2.28") // Paul Cheffings
+ ROMX_LOAD("excom-228.rom", 0x0000, 0x2000, CRC(29257418) SHA1(098a812c4707251f647553a2abc1436afa38f43c), ROM_BIOS(4))
+ROM_END
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void spectrum_opus_device::device_add_mconfig(machine_config &config)
+{
+ WD1770(config, m_fdc, 16_MHz_XTAL / 2);
+ m_fdc->drq_wr_callback().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::nmi_w));
+
+ FLOPPY_CONNECTOR(config, "fdc:0", spectrum_floppies, "35dd", spectrum_opus_device::floppy_formats).enable_sound(true);
+ FLOPPY_CONNECTOR(config, "fdc:1", spectrum_floppies, "35dd", spectrum_opus_device::floppy_formats).enable_sound(true);
+
+ /* parallel printer port */
+ CENTRONICS(config, m_centronics, centronics_devices, "printer");
+ m_centronics->ack_handler().set(m_pia, FUNC(pia6821_device::ca2_w));
+ m_centronics->busy_handler().set(FUNC(spectrum_opus_device::busy_w));
+
+ /* pia */
+ PIA6821(config, m_pia, 0);
+ m_pia->writepa_handler().set(FUNC(spectrum_opus_device::pia_out_a));
+ m_pia->writepb_handler().set(FUNC(spectrum_opus_device::pia_out_b));
+ m_pia->cb2_handler().set("centronics", FUNC(centronics_device::write_strobe));
+
+ /* software list */
+ SOFTWARE_LIST(config, "flop_list").set_original("spectrum_flop_opus");
+
+ /* passthru without NMI */
+ SPECTRUM_EXPANSION_SLOT(config, m_exp, spectrum_expansion_devices, nullptr);
+ m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(spectrum_expansion_slot_device::irq_w));
+}
+
+const tiny_rom_entry *spectrum_opus_device::device_rom_region() const
+{
+ return ROM_NAME( opus );
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spectrum_opus_device - constructor
+//-------------------------------------------------
+
+spectrum_opus_device::spectrum_opus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SPECTRUM_OPUS, tag, owner, clock)
+ , device_spectrum_expansion_interface(mconfig, *this)
+ , m_joy(*this, "JOY")
+ , m_rom(*this, "rom")
+ , m_pia(*this, "pia")
+ , m_fdc(*this, "fdc")
+ , m_floppy0(*this, "fdc:0")
+ , m_floppy1(*this, "fdc:1")
+ , m_centronics(*this, "centronics")
+ , m_exp(*this, "exp")
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spectrum_opus_device::device_start()
+{
+ memset(m_ram, 0, sizeof(m_ram));
+
+ save_item(NAME(m_romcs));
+ save_item(NAME(m_ram));
+ save_item(NAME(m_last_pc));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void spectrum_opus_device::device_reset()
+{
+ m_romcs = 0;
+ m_last_pc = 0x0000;
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+READ_LINE_MEMBER(spectrum_opus_device::romcs)
+{
+ return m_romcs | m_exp->romcs();
+}
+
+void spectrum_opus_device::opcode_fetch(offs_t offset)
+{
+ m_exp->opcode_fetch(offset);
+
+ if (!machine().side_effects_disabled())
+ {
+ switch (m_last_pc)
+ {
+ case 0x0008: case 0x0048: case 0x1708:
+ m_romcs = 1;
+ break;
+ case 0x1748:
+ m_romcs = 0;
+ break;
+ }
+ }
+ m_last_pc = offset;
+}
+
+uint8_t spectrum_opus_device::iorq_r(offs_t offset)
+{
+ uint8_t data = m_exp->iorq_r(offset);
+
+ // PIA bit 7 is enable joystick and selected on A5 only
+ if (!BIT(m_pia->a_output(), 7) && (~offset & 0x20))
+ {
+ data &= m_joy->read() & 0x1f;
+ }
+ return data;
+}
+
+void spectrum_opus_device::iorq_w(offs_t offset, uint8_t data)
+{
+ m_exp->iorq_w(offset, data);
+}
+
+uint8_t spectrum_opus_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ if (m_romcs)
+ {
+ switch (offset & 0xf800)
+ {
+ case 0x0000: case 0x0800: case 0x1000: case 0x1800:
+ data = m_rom->base()[offset & 0x1fff];
+ break;
+ case 0x2000:
+ data = m_ram[offset & 0x7ff];
+ break;
+ case 0x2800:
+ data = m_fdc->read(offset & 0x03);
+ break;
+ case 0x3000:
+ data = m_pia->read(offset & 0x03);
+ break;
+ case 0x3800: // Extra 2K described in QuickDOS manual - not used
+ data = m_ram[offset & 0xfff];
+ break;
+ }
+ }
+
+ if (m_exp->romcs())
+ data &= m_exp->mreq_r(offset);
+
+ return data;
+}
+
+void spectrum_opus_device::mreq_w(offs_t offset, uint8_t data)
+{
+ if (m_romcs)
+ {
+ switch (offset & 0xf800)
+ {
+ case 0x2000:
+ m_ram[offset & 0x7ff] = data;
+ break;
+ case 0x2800:
+ m_fdc->write(offset & 0x03, data);
+ break;
+ case 0x3000:
+ m_pia->write(offset & 0x03, data);
+ break;
+ case 0x3800: // Extra 2K described in QuickDOS manual - not used
+ m_ram[offset & 0xfff] = data;
+ break;
+ }
+ }
+
+ if (m_exp->romcs())
+ m_exp->mreq_w(offset, data);
+}
+
+WRITE8_MEMBER(spectrum_opus_device::pia_out_a)
+{
+ floppy_image_device *floppy = nullptr;
+
+ // bit 0, 1: drive select
+ if (!BIT(data, 0)) floppy = m_floppy1->get_device();
+ if (!BIT(data, 1)) floppy = m_floppy0->get_device();
+ m_fdc->set_floppy(floppy);
+
+ // bit 4: side select
+ if (floppy)
+ floppy->ss_w(BIT(data, 4));
+
+ // bit 5: density
+ m_fdc->dden_w(BIT(data, 5));
+}
+
+WRITE8_MEMBER(spectrum_opus_device::pia_out_b)
+{
+ m_centronics->write_data1(BIT(data, 1));
+ m_centronics->write_data2(BIT(data, 2));
+ m_centronics->write_data3(BIT(data, 3));
+ m_centronics->write_data4(BIT(data, 4));
+ m_centronics->write_data5(BIT(data, 5));
+ m_centronics->write_data6(BIT(data, 6));
+ m_centronics->write_data7(BIT(data, 7));
+}
+
+WRITE_LINE_MEMBER(spectrum_opus_device::busy_w)
+{
+ m_pia->set_a_input(state << 6, 0xbf);
+}
diff --git a/src/devices/bus/spectrum/opus.h b/src/devices/bus/spectrum/opus.h
new file mode 100644
index 00000000000..8d72d8be94b
--- /dev/null
+++ b/src/devices/bus/spectrum/opus.h
@@ -0,0 +1,75 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ Opus Discovery disc system
+
+**********************************************************************/
+
+#ifndef MAME_BUS_SPECTRUM_OPUS_H
+#define MAME_BUS_SPECTRUM_OPUS_H
+
+#include "exp.h"
+#include "softlist.h"
+#include "imagedev/floppy.h"
+#include "machine/wd_fdc.h"
+#include "machine/6821pia.h"
+#include "bus/centronics/ctronics.h"
+#include "formats/opd_dsk.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class spectrum_opus_device:
+ public device_t,
+ public device_spectrum_expansion_interface
+
+{
+public:
+ // construction/destruction
+ spectrum_opus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_FLOPPY_FORMATS(floppy_formats);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
+ virtual DECLARE_READ_LINE_MEMBER(romcs) override;
+
+private:
+ DECLARE_WRITE8_MEMBER(pia_out_a);
+ DECLARE_WRITE8_MEMBER(pia_out_b);
+ DECLARE_WRITE_LINE_MEMBER(busy_w);
+
+ required_ioport m_joy;
+ required_memory_region m_rom;
+ required_device<pia6821_device> m_pia;
+ required_device<wd_fdc_device_base> m_fdc;
+ required_device<floppy_connector> m_floppy0;
+ required_device<floppy_connector> m_floppy1;
+ required_device<centronics_device> m_centronics;
+ required_device<spectrum_expansion_slot_device> m_exp;
+
+ int m_romcs;
+ uint8_t m_ram[4 * 1024];
+ offs_t m_last_pc;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SPECTRUM_OPUS, spectrum_opus_device)
+
+#endif // MAME_BUS_SPECTRUM_OPUS_H
diff --git a/src/devices/bus/spectrum/plus2test.cpp b/src/devices/bus/spectrum/plus2test.cpp
index a734a76f775..3d90ed4dee3 100644
--- a/src/devices/bus/spectrum/plus2test.cpp
+++ b/src/devices/bus/spectrum/plus2test.cpp
@@ -68,7 +68,7 @@ READ_LINE_MEMBER(spectrum_plus2test_device::romcs)
return 1;
}
-READ8_MEMBER(spectrum_plus2test_device::mreq_r)
+uint8_t spectrum_plus2test_device::mreq_r(offs_t offset)
{
return m_rom->base()[offset & 0x3fff];
}
diff --git a/src/devices/bus/spectrum/plus2test.h b/src/devices/bus/spectrum/plus2test.h
index 234e82a95f0..f8caad2fa26 100644
--- a/src/devices/bus/spectrum/plus2test.h
+++ b/src/devices/bus/spectrum/plus2test.h
@@ -36,7 +36,7 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
private:
required_memory_region m_rom;
diff --git a/src/devices/bus/spectrum/protek.cpp b/src/devices/bus/spectrum/protek.cpp
index a3f3a1838f8..d1e122d8dbb 100644
--- a/src/devices/bus/spectrum/protek.cpp
+++ b/src/devices/bus/spectrum/protek.cpp
@@ -72,17 +72,20 @@ void spectrum_protek_device::device_start()
// IMPLEMENTATION
//**************************************************************************
-READ8_MEMBER(spectrum_protek_device::port_fe_r)
+uint8_t spectrum_protek_device::iorq_r(offs_t offset)
{
uint8_t data = 0xff;
- uint8_t lines = offset >> 8;
+ switch (offset & 0xff)
+ {
+ case 0xfe:
+ if (((offset >> 8) & 8) == 0)
+ data = m_exp_line3->read() | (0xff ^ 0x10);
- if ((lines & 8) == 0)
- data = m_exp_line3->read() | (0xff ^ 0x10);
-
- if ((lines & 16) == 0)
- data = m_exp_line4->read() | (0xff ^ 0x1d);
+ if (((offset >> 8) & 16) == 0)
+ data = m_exp_line4->read() | (0xff ^ 0x1d);
+ break;
+ }
return data;
}
diff --git a/src/devices/bus/spectrum/protek.h b/src/devices/bus/spectrum/protek.h
index 503a041a0d3..9edd5a82f29 100644
--- a/src/devices/bus/spectrum/protek.h
+++ b/src/devices/bus/spectrum/protek.h
@@ -35,7 +35,7 @@ protected:
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
- virtual DECLARE_READ8_MEMBER(port_fe_r) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
private:
required_ioport m_exp_line3;
diff --git a/src/devices/bus/spectrum/specdrum.cpp b/src/devices/bus/spectrum/specdrum.cpp
new file mode 100644
index 00000000000..9c809a1b36a
--- /dev/null
+++ b/src/devices/bus/spectrum/specdrum.cpp
@@ -0,0 +1,73 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ Cheetah Marketing SpecDrum emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "specdrum.h"
+#include "sound/volt_reg.h"
+#include "speaker.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(SPECTRUM_SPECDRUM, spectrum_specdrum_device, "spectrum_specdrum", "SpecDrum")
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void spectrum_specdrum_device::device_add_mconfig(machine_config &config)
+{
+ SPEAKER(config, "speaker").front_center();
+ ZN428E(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.5);
+ voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref"));
+ vref.add_route(0, "dac", 1.0, DAC_VREF_POS_INPUT);
+ vref.add_route(0, "dac", -1.0, DAC_VREF_NEG_INPUT);
+}
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// spectrum_specdrum_device - constructor
+//-------------------------------------------------
+
+spectrum_specdrum_device::spectrum_specdrum_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SPECTRUM_SPECDRUM, tag, owner, clock)
+ , device_spectrum_expansion_interface(mconfig, *this)
+ , m_dac(*this, "dac")
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void spectrum_specdrum_device::device_start()
+{
+}
+
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+void spectrum_specdrum_device::iorq_w(offs_t offset, uint8_t data)
+{
+ switch (offset & 0x00ff)
+ {
+ case 0xdf:
+ m_dac->write(data);
+ break;
+ }
+}
diff --git a/src/devices/bus/spectrum/specdrum.h b/src/devices/bus/spectrum/specdrum.h
new file mode 100644
index 00000000000..7412a8509c0
--- /dev/null
+++ b/src/devices/bus/spectrum/specdrum.h
@@ -0,0 +1,51 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ Cheetah Marketing SpecDrum emulation
+
+**********************************************************************/
+
+#ifndef MAME_BUS_SPECTRUM_SPECDRUM_H
+#define MAME_BUS_SPECTRUM_SPECDRUM_H
+
+#pragma once
+
+
+#include "exp.h"
+#include "sound/dac.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> spectrum_specdrum_device
+
+class spectrum_specdrum_device :
+ public device_t,
+ public device_spectrum_expansion_interface
+{
+public:
+ // construction/destruction
+ spectrum_specdrum_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
+
+private:
+ required_device<dac_byte_interface> m_dac;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(SPECTRUM_SPECDRUM, spectrum_specdrum_device)
+
+
+#endif // MAME_BUS_SPECTRUM_SPECDRUM_H
diff --git a/src/devices/bus/spectrum/uslot.cpp b/src/devices/bus/spectrum/uslot.cpp
index d2d75d6a72c..d27f1ec572d 100644
--- a/src/devices/bus/spectrum/uslot.cpp
+++ b/src/devices/bus/spectrum/uslot.cpp
@@ -64,8 +64,6 @@ void spectrum_uslot_device::device_start()
void spectrum_uslot_device::device_reset()
{
- m_exp1->set_io_space(&io_space());
- m_exp2->set_io_space(&io_space());
}
@@ -78,41 +76,41 @@ READ_LINE_MEMBER(spectrum_uslot_device::romcs)
return m_exp1->romcs() | m_exp2->romcs();
}
+void spectrum_uslot_device::opcode_fetch(offs_t offset)
+{
+ m_exp1->opcode_fetch(offset);
+ m_exp2->opcode_fetch(offset);
+}
-READ8_MEMBER(spectrum_uslot_device::mreq_r)
+uint8_t spectrum_uslot_device::mreq_r(offs_t offset)
{
- uint8_t temp;
uint8_t data = 0xff;
- temp = m_exp1->mreq_r(space, offset);
if (m_exp1->romcs())
- data &= temp;
+ data &= m_exp1->mreq_r(offset);
- temp = m_exp2->mreq_r(space, offset);
if (m_exp2->romcs())
- data &= temp;
+ data &= m_exp2->mreq_r(offset);
return data;
}
-WRITE8_MEMBER(spectrum_uslot_device::mreq_w)
+void spectrum_uslot_device::mreq_w(offs_t offset, uint8_t data)
{
if (m_exp1->romcs())
- m_exp1->mreq_w(space, offset, data);
+ m_exp1->mreq_w(offset, data);
if (m_exp2->romcs())
- m_exp2->mreq_w(space, offset, data);
+ m_exp2->mreq_w(offset, data);
}
-READ8_MEMBER(spectrum_uslot_device::port_fe_r)
+uint8_t spectrum_uslot_device::iorq_r(offs_t offset)
{
- uint8_t data = 0xff;
-
- if (m_exp1->romcs())
- data &= m_exp1->port_fe_r(space, offset);
-
- if (m_exp2->romcs())
- data &= m_exp2->port_fe_r(space, offset);
+ return m_exp1->iorq_r(offset) & m_exp2->iorq_r(offset);
+}
- return data;
+void spectrum_uslot_device::iorq_w(offs_t offset, uint8_t data)
+{
+ m_exp1->iorq_w(offset, data);
+ m_exp2->iorq_w(offset, data);
}
diff --git a/src/devices/bus/spectrum/uslot.h b/src/devices/bus/spectrum/uslot.h
index 536f7c75bc4..6cfa90c45e9 100644
--- a/src/devices/bus/spectrum/uslot.h
+++ b/src/devices/bus/spectrum/uslot.h
@@ -36,9 +36,11 @@ protected:
// optional information overrides
virtual void device_add_mconfig(machine_config &config) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
- virtual DECLARE_WRITE8_MEMBER(mreq_w) override;
- virtual DECLARE_READ8_MEMBER(port_fe_r) override;
+ virtual void opcode_fetch(offs_t offset) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
+ virtual void iorq_w(offs_t offset, uint8_t data) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
private:
diff --git a/src/devices/bus/spectrum/usource.cpp b/src/devices/bus/spectrum/usource.cpp
index b4fb9c5797a..13f302b14c5 100644
--- a/src/devices/bus/spectrum/usource.cpp
+++ b/src/devices/bus/spectrum/usource.cpp
@@ -60,6 +60,7 @@ spectrum_usource_device::spectrum_usource_device(const machine_config &mconfig,
void spectrum_usource_device::device_start()
{
+ save_item(NAME(m_romcs));
}
@@ -82,17 +83,15 @@ READ_LINE_MEMBER(spectrum_usource_device::romcs)
return m_romcs;
}
-
-READ8_MEMBER(spectrum_usource_device::mreq_r)
+void spectrum_usource_device::opcode_fetch(offs_t offset)
{
- uint8_t data;
-
if (!machine().side_effects_disabled() && (offset == 0x2bae))
{
m_romcs = !m_romcs;
}
+}
- data = m_rom->base()[offset & 0x1fff];
-
- return data;
+uint8_t spectrum_usource_device::mreq_r(offs_t offset)
+{
+ return m_rom->base()[offset & 0x1fff];
}
diff --git a/src/devices/bus/spectrum/usource.h b/src/devices/bus/spectrum/usource.h
index 607cf0737a6..daf792f076f 100644
--- a/src/devices/bus/spectrum/usource.h
+++ b/src/devices/bus/spectrum/usource.h
@@ -38,8 +38,9 @@ protected:
// optional information overrides
virtual const tiny_rom_entry *device_rom_region() const override;
+ virtual void opcode_fetch(offs_t offset) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
private:
required_memory_region m_rom;
diff --git a/src/devices/bus/spectrum/uspeech.cpp b/src/devices/bus/spectrum/uspeech.cpp
index 87f66ca0182..60374fd3c2c 100644
--- a/src/devices/bus/spectrum/uspeech.cpp
+++ b/src/devices/bus/spectrum/uspeech.cpp
@@ -76,6 +76,7 @@ spectrum_uspeech_device::spectrum_uspeech_device(const machine_config &mconfig,
void spectrum_uspeech_device::device_start()
{
+ save_item(NAME(m_romcs));
}
@@ -98,46 +99,59 @@ READ_LINE_MEMBER(spectrum_uspeech_device::romcs)
return m_romcs;
}
-
-READ8_MEMBER(spectrum_uspeech_device::mreq_r)
+void spectrum_uspeech_device::opcode_fetch(offs_t offset)
{
- uint8_t data;
+ if (!machine().side_effects_disabled() && (offset == 0x0038))
+ {
+ m_romcs = !m_romcs;
+ }
+}
- if (!machine().side_effects_disabled() && (offset == 0x38))
+uint8_t spectrum_uspeech_device::iorq_r(offs_t offset)
+{
+ if (!machine().side_effects_disabled() && (offset == 0x0038))
{
m_romcs = !m_romcs;
}
- switch (offset)
+ return 0xff;
+}
+
+uint8_t spectrum_uspeech_device::mreq_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ switch (offset & 0xf000)
{
- case 0x1000:
- data = !m_nsp->lrq_r(); // (m_nsp->lrq_r() && (m_nsp->sby_r() != 0)) ? 0x00 : 0x01;
- break;
- default:
+ case 0x0000:
data = m_rom->base()[offset & 0x7ff];
break;
+ case 0x1000:
+ data = !m_nsp->lrq_r();
+ break;
}
return data;
}
-WRITE8_MEMBER(spectrum_uspeech_device::mreq_w)
+void spectrum_uspeech_device::mreq_w(offs_t offset, uint8_t data)
{
- switch (offset)
+ switch (offset & 0xf001)
{
case 0x1000:
+ case 0x1001:
// allophone
m_nsp->ald_w(data & 0x3f);
break;
case 0x3000:
// intonation low
- m_nsp->set_clock(3500000); // CK / 4 ??
+ m_nsp->set_clock(3050000); // oscillator frequency read from hardware
break;
case 0x3001:
// intonation high
- m_nsp->set_clock(3800000); // TODO: the exact frequency is unknown
+ m_nsp->set_clock(3260000); // oscillator frequency read from hardware
break;
}
}
diff --git a/src/devices/bus/spectrum/uspeech.h b/src/devices/bus/spectrum/uspeech.h
index b3209f80331..8013abf9222 100644
--- a/src/devices/bus/spectrum/uspeech.h
+++ b/src/devices/bus/spectrum/uspeech.h
@@ -40,9 +40,11 @@ protected:
virtual const tiny_rom_entry *device_rom_region() const override;
virtual void device_add_mconfig(machine_config &config) override;
+ virtual void opcode_fetch(offs_t offset) override;
virtual DECLARE_READ_LINE_MEMBER(romcs) override;
- virtual DECLARE_READ8_MEMBER(mreq_r) override;
- virtual DECLARE_WRITE8_MEMBER(mreq_w) override;
+ virtual uint8_t mreq_r(offs_t offset) override;
+ virtual void mreq_w(offs_t offset, uint8_t data) override;
+ virtual uint8_t iorq_r(offs_t offset) override;
private:
required_device<sp0256_device> m_nsp;