summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Miodrag Milanović <mmicko@gmail.com>2022-05-10 15:03:30 +0200
committer GitHub <noreply@github.com>2022-05-10 15:03:30 +0200
commit437f504eef483f30eebfa2adb9f60687a7bd502a (patch)
tree9da172571fc8b33f882ffa9676d17d587f7b2bde
parent721a1a6417de555efcaec0f65f870f663e25e8f9 (diff)
RC2014 (#9716)
New working machines -------------------- RC2014 Classic [Miodrag Milanovic] RC2014 Pro [Miodrag Milanovic] RC2014 Classic II [Miodrag Milanovic] RC2014 Zed [Miodrag Milanovic] RC2014 Zed Pro [Miodrag Milanovic]
-rw-r--r--scripts/src/bus.lua27
-rw-r--r--scripts/target/mame/mess.lua2
-rw-r--r--src/devices/bus/rc2014/cf.cpp63
-rw-r--r--src/devices/bus/rc2014/cf.h18
-rw-r--r--src/devices/bus/rc2014/clock.cpp230
-rw-r--r--src/devices/bus/rc2014/clock.h20
-rw-r--r--src/devices/bus/rc2014/modules.cpp49
-rw-r--r--src/devices/bus/rc2014/modules.h19
-rw-r--r--src/devices/bus/rc2014/ram.cpp220
-rw-r--r--src/devices/bus/rc2014/ram.h20
-rw-r--r--src/devices/bus/rc2014/rc2014.cpp291
-rw-r--r--src/devices/bus/rc2014/rc2014.h328
-rw-r--r--src/devices/bus/rc2014/rom.cpp217
-rw-r--r--src/devices/bus/rc2014/rom.h19
-rw-r--r--src/devices/bus/rc2014/romram.cpp132
-rw-r--r--src/devices/bus/rc2014/romram.h18
-rw-r--r--src/devices/bus/rc2014/serial.cpp266
-rw-r--r--src/devices/bus/rc2014/serial.h20
-rw-r--r--src/devices/bus/rc2014/z80cpu.cpp143
-rw-r--r--src/devices/bus/rc2014/z80cpu.h19
-rw-r--r--src/mame/drivers/rc2014.cpp188
-rw-r--r--src/mame/mame.lst7
-rw-r--r--src/mame/mess.flt1
23 files changed, 2317 insertions, 0 deletions
diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua
index d3a50bfa2d3..3a97d6e7c52 100644
--- a/scripts/src/bus.lua
+++ b/scripts/src/bus.lua
@@ -2079,6 +2079,33 @@ if (BUSES["POFO"]~=null) then
}
end
+---------------------------------------------------
+--
+--@src/devices/bus/rc2014/rc2014.h,BUSES["RC2014"] = true
+---------------------------------------------------
+
+if (BUSES["RC2014"]~=null) then
+ files {
+ MAME_DIR .. "src/devices/bus/rc2014/rc2014.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/rc2014.h",
+ MAME_DIR .. "src/devices/bus/rc2014/modules.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/modules.h",
+ MAME_DIR .. "src/devices/bus/rc2014/z80cpu.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/z80cpu.h",
+ MAME_DIR .. "src/devices/bus/rc2014/clock.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/clock.h",
+ MAME_DIR .. "src/devices/bus/rc2014/ram.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/ram.h",
+ MAME_DIR .. "src/devices/bus/rc2014/rom.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/rom.h",
+ MAME_DIR .. "src/devices/bus/rc2014/romram.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/romram.h",
+ MAME_DIR .. "src/devices/bus/rc2014/serial.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/serial.h",
+ MAME_DIR .. "src/devices/bus/rc2014/cf.cpp",
+ MAME_DIR .. "src/devices/bus/rc2014/cf.h",
+ }
+end
---------------------------------------------------
--
diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua
index 30879e781c9..3dbc27c7aed 100644
--- a/scripts/target/mame/mess.lua
+++ b/scripts/target/mame/mess.lua
@@ -960,6 +960,7 @@ BUSES["PSX_CONTROLLER"] = true
BUSES["PSX_PARALLEL"] = true
BUSES["QBUS"] = true
BUSES["QL"] = true
+BUSES["RC2014"] = true
BUSES["RS232"] = true
BUSES["PC8801"] = true
BUSES["RTPC_KBD"] = true
@@ -4745,6 +4746,7 @@ files {
MAME_DIR .. "src/mame/drivers/pv9234.cpp",
MAME_DIR .. "src/mame/drivers/pwp14.cpp",
MAME_DIR .. "src/mame/drivers/qtsbc.cpp",
+ MAME_DIR .. "src/mame/drivers/rc2014.cpp",
MAME_DIR .. "src/mame/drivers/rd100.cpp",
MAME_DIR .. "src/mame/drivers/rvoice.cpp",
MAME_DIR .. "src/mame/drivers/sacstate.cpp",
diff --git a/src/devices/bus/rc2014/cf.cpp b/src/devices/bus/rc2014/cf.cpp
new file mode 100644
index 00000000000..b15a20eed70
--- /dev/null
+++ b/src/devices/bus/rc2014/cf.cpp
@@ -0,0 +1,63 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 Compact Flash Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "cf.h"
+#include "bus/ata/ataintf.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 Compact Flash module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class compact_flash_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ compact_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_bus->int_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx_w ) { m_bus->tx_w(state); }
+
+ uint8_t ide_cs0_r(offs_t offset) { return m_ata->cs0_r(offset); }
+ void ide_cs0_w(offs_t offset, uint8_t data) { m_ata->cs0_w(offset, data); }
+private:
+ required_device<ata_interface_device> m_ata;
+};
+
+compact_flash_device::compact_flash_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_COMPACT_FLASH, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+ , m_ata(*this, "ata")
+{
+}
+
+void compact_flash_device::device_start()
+{
+ // A7 not connected
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x10, 0x17, 0, 0x80, 0, read8sm_delegate(*this, FUNC(compact_flash_device::ide_cs0_r)), write8sm_delegate(*this, FUNC(compact_flash_device::ide_cs0_w)));
+}
+
+void compact_flash_device::device_add_mconfig(machine_config &config)
+{
+ ATA_INTERFACE(config, m_ata).options(ata_devices, "hdd", nullptr, false);
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_COMPACT_FLASH, device_rc2014_card_interface, compact_flash_device, "rc2014_cf", "RC2014 Compact Flash module")
diff --git a/src/devices/bus/rc2014/cf.h b/src/devices/bus/rc2014/cf.h
new file mode 100644
index 00000000000..3efc1223c33
--- /dev/null
+++ b/src/devices/bus/rc2014/cf.h
@@ -0,0 +1,18 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 Compact Flash Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_COMPACT_FLASH_H
+#define MAME_BUS_RC2014_COMPACT_FLASH_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_COMPACT_FLASH, device_rc2014_card_interface)
+
+#endif // MAME_BUS_RC2014_COMPACT_FLASH_H
diff --git a/src/devices/bus/rc2014/clock.cpp b/src/devices/bus/rc2014/clock.cpp
new file mode 100644
index 00000000000..00bfd43e4bb
--- /dev/null
+++ b/src/devices/bus/rc2014/clock.cpp
@@ -0,0 +1,230 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 Clock Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "clock.h"
+#include "machine/clock.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 Clock module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class single_clock_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ single_clock_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ DECLARE_WRITE_LINE_MEMBER( clk_w ) { m_bus->clk_w(state); }
+};
+
+single_clock_device::single_clock_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_SINGLE_CLOCK, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+{
+}
+
+void single_clock_device::device_start()
+{
+ m_bus->set_bus_clock(XTAL(7'372'800));
+}
+
+void single_clock_device::device_add_mconfig(machine_config &config)
+{
+ clock_device &clock(CLOCK(config, "clock", XTAL(7'372'800)));
+ clock.signal_handler().set(FUNC(single_clock_device::clk_w));
+}
+
+//**************************************************************************
+// RC2014 Dual Clock module
+// Module author: Spencer Owen
+//**************************************************************************
+
+//**************************************************************************
+// dual_clock_base
+//**************************************************************************
+
+class dual_clock_base : public device_t
+{
+protected:
+ // construction/destruction
+ dual_clock_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual DECLARE_WRITE_LINE_MEMBER( clk_w ) = 0;
+ virtual DECLARE_WRITE_LINE_MEMBER( clk2_w ) = 0;
+
+ // base-class members
+ required_device<clock_device> m_clock_1;
+ required_device<clock_device> m_clock_2;
+ required_ioport m_clk_sel_1;
+ required_ioport m_clk_sel_2;
+};
+
+dual_clock_base::dual_clock_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_clock_1(*this, "clock1")
+ , m_clock_2(*this, "clock2")
+ , m_clk_sel_1(*this, "CLOCK1")
+ , m_clk_sel_2(*this, "CLOCK2")
+{
+}
+
+void dual_clock_base::device_start()
+{
+}
+
+static constexpr u32 clock_mapping[] =
+{
+ 7'372'800/1,
+ 7'372'800/2,
+ 7'372'800/3,
+ 7'372'800/6,
+ 7'372'800/8,
+ 7'372'800/12,
+ 7'372'800/24,
+ 10'000,
+ 0,
+ 0
+};
+
+void dual_clock_base::device_reset()
+{
+ u32 clk1 = clock_mapping[m_clk_sel_1->read()];
+ m_clock_1->set_clock(clk1);
+
+ u32 clk2 = clock_mapping[m_clk_sel_2->read()];
+ m_clock_2->set_clock(clk2);
+
+ notify_clock_changed();
+}
+
+static INPUT_PORTS_START( dual_clock_jumpers )
+ PORT_START("CLOCK1")
+ PORT_CONFNAME( 0xf, 0x0, "Clock 1" )
+ PORT_CONFSETTING( 0x0, "7.3728 MHz" )
+ PORT_CONFSETTING( 0x1, "3.6864 MHz" )
+ PORT_CONFSETTING( 0x2, "2.4576 MHz" )
+ PORT_CONFSETTING( 0x3, "1.2288 MHz" )
+ PORT_CONFSETTING( 0x4, "0.9216 MHz" )
+ PORT_CONFSETTING( 0x5, "0.6144 MHz" )
+ PORT_CONFSETTING( 0x6, "0.3072 MHz" )
+ PORT_CONFSETTING( 0x7, "Slow" )
+ PORT_CONFSETTING( 0x8, "Manual" )
+ PORT_CONFSETTING( 0x9, "External" )
+ PORT_START("CLOCK2")
+ PORT_CONFNAME( 0xf, 0x0, "Clock 2" )
+ PORT_CONFSETTING( 0x0, "7.3728 MHz" )
+ PORT_CONFSETTING( 0x1, "3.6864 MHz" )
+ PORT_CONFSETTING( 0x2, "2.4576 MHz" )
+ PORT_CONFSETTING( 0x3, "1.2288 MHz" )
+ PORT_CONFSETTING( 0x4, "0.9216 MHz" )
+ PORT_CONFSETTING( 0x5, "0.6144 MHz" )
+ PORT_CONFSETTING( 0x6, "0.3072 MHz" )
+ PORT_CONFSETTING( 0x7, "Slow" )
+ PORT_CONFSETTING( 0x8, "Manual" )
+ PORT_CONFSETTING( 0x9, "External" )
+INPUT_PORTS_END
+
+ioport_constructor dual_clock_base::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( dual_clock_jumpers );
+}
+
+void dual_clock_base::device_add_mconfig(machine_config &config)
+{
+ CLOCK(config, m_clock_1, 0);
+ m_clock_1->signal_handler().set(FUNC(dual_clock_base::clk_w));
+
+ CLOCK(config, m_clock_2, 0);
+ m_clock_2->signal_handler().set(FUNC(dual_clock_base::clk2_w));
+}
+
+//**************************************************************************
+// RC2014 Dual Clock module in extended bus
+//**************************************************************************
+
+class dual_clock_device : public dual_clock_base, public device_rc2014_ext_card_interface
+{
+public:
+ // construction/destruction
+ dual_clock_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_reset() override;
+
+ // base-class overrides
+ DECLARE_WRITE_LINE_MEMBER( clk_w ) override { m_bus->clk_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( clk2_w ) override { m_bus->clk2_w(state); }
+};
+
+dual_clock_device::dual_clock_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : dual_clock_base(mconfig, RC2014_DUAL_CLOCK, tag, owner, clock)
+ , device_rc2014_ext_card_interface(mconfig, *this)
+{
+}
+
+void dual_clock_device::device_reset()
+{
+ m_bus->set_bus_clock(clock_mapping[m_clk_sel_1->read()]);
+ dual_clock_base::device_reset();
+}
+
+//**************************************************************************
+// RC2014 Dual Clock module in standard bus
+//**************************************************************************
+
+class dual_clock_device_40pin : public dual_clock_base, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ dual_clock_device_40pin(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_reset() override;
+
+ // base-class overrides
+ DECLARE_WRITE_LINE_MEMBER( clk_w ) override { m_bus->clk_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( clk2_w ) override { }
+};
+
+dual_clock_device_40pin::dual_clock_device_40pin(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : dual_clock_base(mconfig, RC2014_DUAL_CLOCK_40P, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+{
+}
+
+void dual_clock_device_40pin::device_reset()
+{
+ m_bus->set_bus_clock(clock_mapping[m_clk_sel_1->read()]);
+ dual_clock_base::device_reset();
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_SINGLE_CLOCK, device_rc2014_card_interface, single_clock_device, "rc2014_clock", "RC2014 Clock module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_DUAL_CLOCK, device_rc2014_ext_card_interface, dual_clock_device, "rc2014_dual_clock", "RC2014 Dual Clock module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_DUAL_CLOCK_40P, device_rc2014_card_interface, dual_clock_device_40pin, "rc2014_dual_clock_40p", "RC2014 Dual Clock module (40 pin)")
diff --git a/src/devices/bus/rc2014/clock.h b/src/devices/bus/rc2014/clock.h
new file mode 100644
index 00000000000..225a2e09333
--- /dev/null
+++ b/src/devices/bus/rc2014/clock.h
@@ -0,0 +1,20 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 Clock Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_CLOCK_H
+#define MAME_BUS_RC2014_CLOCK_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_SINGLE_CLOCK, device_rc2014_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_DUAL_CLOCK, device_rc2014_ext_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_DUAL_CLOCK_40P, device_rc2014_card_interface)
+
+#endif // MAME_BUS_RC2014_CLOCK_H
diff --git a/src/devices/bus/rc2014/modules.cpp b/src/devices/bus/rc2014/modules.cpp
new file mode 100644
index 00000000000..0429b87d5a1
--- /dev/null
+++ b/src/devices/bus/rc2014/modules.cpp
@@ -0,0 +1,49 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 Modules
+
+**********************************************************************/
+
+#include "emu.h"
+#include "bus/rc2014/rc2014.h"
+
+#include "bus/rc2014/z80cpu.h"
+#include "bus/rc2014/clock.h"
+#include "bus/rc2014/ram.h"
+#include "bus/rc2014/rom.h"
+#include "bus/rc2014/romram.h"
+#include "bus/rc2014/serial.h"
+#include "bus/rc2014/cf.h"
+
+void rc2014_bus_modules(device_slot_interface &device)
+{
+ device.option_add("z80", RC2014_Z80CPU);
+ // Z80 2.1 on standard bus is same as Z80 module
+ device.option_add("z80_21_40p", RC2014_Z80CPU);
+ device.option_add("clock", RC2014_SINGLE_CLOCK);
+ device.option_add("dual_clk_40p", RC2014_DUAL_CLOCK_40P);
+ device.option_add("ram32k", RC2014_RAM_32K);
+ device.option_add("ram64k_40p", RC2014_RAM_64K_40P);
+ device.option_add("sw_rom", RC2014_SWITCHABLE_ROM);
+ device.option_add("serial", RC2014_SERIAL_IO);
+ device.option_add("sio_40p", RC2014_DUAL_SERIAL_40P);
+ device.option_add("cf", RC2014_COMPACT_FLASH);
+ device.option_add("rom_ram", RC2014_ROM_RAM_512);
+}
+
+void rc2014_ext_bus_modules(device_slot_interface &device)
+{
+ rc2014_bus_modules(device);
+ device.option_add("z80_21", RC2014_Z80CPU_21);
+ device.option_add("dual_clk", RC2014_DUAL_CLOCK);
+ device.option_add("sio", RC2014_DUAL_SERIAL);
+ device.option_add("page_rom", RC2014_PAGABLE_ROM);
+ device.option_add("ram64k", RC2014_RAM_64K);
+}
+
+void rc2014_rc80_bus_modules(device_slot_interface &device)
+{
+ rc2014_ext_bus_modules(device);
+}
diff --git a/src/devices/bus/rc2014/modules.h b/src/devices/bus/rc2014/modules.h
new file mode 100644
index 00000000000..0447f81aee7
--- /dev/null
+++ b/src/devices/bus/rc2014/modules.h
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 Modules
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_MODULES_H
+#define MAME_BUS_RC2014_MODULES_H
+
+#pragma once
+
+// supported devices
+void rc2014_bus_modules(device_slot_interface &device);
+void rc2014_ext_bus_modules(device_slot_interface &device);
+void rc2014_rc80_bus_modules(device_slot_interface &device);
+
+#endif // MAME_BUS_RC2014_MODULES_H
diff --git a/src/devices/bus/rc2014/ram.cpp b/src/devices/bus/rc2014/ram.cpp
new file mode 100644
index 00000000000..83790e510df
--- /dev/null
+++ b/src/devices/bus/rc2014/ram.cpp
@@ -0,0 +1,220 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 RAM Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "ram.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 32K RAM module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class ram_32k_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ ram_32k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+private:
+ std::unique_ptr<u8[]> m_ram;
+};
+
+ram_32k_device::ram_32k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_RAM_32K, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+ , m_ram(nullptr)
+{
+}
+
+void ram_32k_device::device_start()
+{
+ m_ram = std::make_unique<u8[]>(0x8000);
+ std::fill_n(m_ram.get(), 0x8000, 0xff);
+ save_pointer(NAME(m_ram), 0x8000);
+
+ m_bus->installer(AS_PROGRAM)->install_ram(0x8000, 0xffff, m_ram.get());
+}
+
+//**************************************************************************
+// RC2014 64K RAM module
+// Module author: Spencer Owen
+//**************************************************************************
+
+//**************************************************************************
+// ram_64k_base
+//**************************************************************************
+
+class ram_64k_base : public device_t
+{
+protected:
+ // construction/destruction
+ ram_64k_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override { update_banks(); }
+
+ virtual ioport_constructor device_input_ports() const override;
+
+ DECLARE_WRITE_LINE_MEMBER( page_w ) { m_bank = state; update_banks(); }
+ void ram_w(offs_t offset, uint8_t data) { m_ram[offset] = data; }
+
+ virtual void update_banks() = 0;
+
+ // base-class members
+ int m_bank;
+ std::unique_ptr<u8[]> m_ram;
+ required_ioport m_start_addr;
+ required_ioport m_paged;
+};
+
+ram_64k_base::ram_64k_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_bank(0)
+ , m_ram(nullptr)
+ , m_start_addr(*this, "START_ADDR")
+ , m_paged(*this, "PAGED")
+{
+}
+
+void ram_64k_base::device_start()
+{
+ m_ram = std::make_unique<u8[]>(0x10000);
+ std::fill_n(m_ram.get(), 0x10000, 0xff);
+ save_pointer(NAME(m_ram), 0x10000);
+ save_item(NAME(m_bank));
+}
+
+void ram_64k_base::device_reset()
+{
+ m_bank = 0;
+ update_banks();
+}
+
+static INPUT_PORTS_START( ram_64k_jumpers )
+ PORT_START("START_ADDR")
+ PORT_CONFNAME( 0x4, 0x0, "Start address" )
+ PORT_CONFSETTING( 0x0, "0x0000" )
+ PORT_CONFSETTING( 0x1, "0x1000" )
+ PORT_CONFSETTING( 0x2, "0x2000" )
+ PORT_CONFSETTING( 0x4, "0x4000" )
+ PORT_START("PAGED")
+ PORT_CONFNAME( 0x1, 0x1, "Paged" )
+ PORT_CONFSETTING( 0x0, DEF_STR( No ) )
+ PORT_CONFSETTING( 0x1, DEF_STR( Yes ) )
+INPUT_PORTS_END
+
+ioport_constructor ram_64k_base::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( ram_64k_jumpers );
+}
+
+//**************************************************************************
+// RC2014 64K RAM module in extended bus
+//**************************************************************************
+
+class ram_64k_device : public ram_64k_base, public device_rc2014_ext_card_interface
+{
+public:
+ // construction/destruction
+ ram_64k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_reset() override;
+ virtual void device_resolve_objects() override;
+
+ // base-class overrides
+ void update_banks() override;
+};
+
+ram_64k_device::ram_64k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : ram_64k_base(mconfig, RC2014_RAM_64K, tag, owner, clock)
+ , device_rc2014_ext_card_interface(mconfig, *this)
+{
+}
+
+void ram_64k_device::device_reset()
+{
+ ram_64k_base::device_reset();
+ if (m_paged->read())
+ m_bus->installer(AS_PROGRAM)->install_ram(0x8000, 0xffff, m_ram.get() + 0x8000);
+ else
+ m_bus->installer(AS_PROGRAM)->install_ram(m_start_addr->read() * 0x1000, 0xffff, m_ram.get() + m_start_addr->read() * 0x1000);
+}
+
+void ram_64k_device::device_resolve_objects()
+{
+ m_bus->page_callback().append(*this, FUNC(ram_64k_device::page_w));
+}
+
+void ram_64k_device::update_banks()
+{
+ if (m_paged->read() == 0) return; // If not paged skip
+
+ if (m_bank == 0) {
+ m_bus->installer(AS_PROGRAM)->install_write_handler(0x0000, 0x7fff, write8sm_delegate(*this, FUNC(ram_64k_device::ram_w)));
+ } else {
+ m_bus->installer(AS_PROGRAM)->install_ram(0x0000, 0x7fff, m_ram.get());
+ }
+}
+
+//**************************************************************************
+// RC2014 64K RAM module in standard bus
+//**************************************************************************
+
+class ram_64k_device_40pin : public ram_64k_base, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ ram_64k_device_40pin(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_reset() override;
+
+ // base-class overrides
+ void update_banks() override {};
+};
+
+ram_64k_device_40pin::ram_64k_device_40pin(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : ram_64k_base(mconfig, RC2014_RAM_64K_40P, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+{
+}
+
+void ram_64k_device_40pin::device_reset()
+{
+ ram_64k_base::device_reset();
+ // page pin not connected so we can set all at once
+ if (m_paged->read())
+ {
+ m_bus->installer(AS_PROGRAM)->install_ram(0x8000, 0xffff, m_ram.get() + 0x8000);
+ m_bus->installer(AS_PROGRAM)->install_write_handler(0x0000, 0x7fff, write8sm_delegate(*this, FUNC(ram_64k_device_40pin::ram_w)));
+ }
+ else
+ {
+ m_bus->installer(AS_PROGRAM)->install_ram(m_start_addr->read() * 0x1000, 0xffff, m_ram.get() + m_start_addr->read() * 0x1000);
+ }
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_RAM_32K, device_rc2014_card_interface, ram_32k_device, "rc2014_ram_32k", "RC2014 32K RAM module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_RAM_64K, device_rc2014_ext_card_interface, ram_64k_device, "rc2014_ram_64k", "RC2014 64K RAM module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_RAM_64K_40P, device_rc2014_card_interface, ram_64k_device_40pin, "rc2014_ram_64k_40p", "RC2014 64K RAM module (40 pin)")
diff --git a/src/devices/bus/rc2014/ram.h b/src/devices/bus/rc2014/ram.h
new file mode 100644
index 00000000000..c55424b7871
--- /dev/null
+++ b/src/devices/bus/rc2014/ram.h
@@ -0,0 +1,20 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 RAM Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_RAM_H
+#define MAME_BUS_RC2014_RAM_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_RAM_32K, device_rc2014_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_RAM_64K, device_rc2014_ext_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_RAM_64K_40P, device_rc2014_card_interface)
+
+#endif // MAME_BUS_RC2014_RAM_H
diff --git a/src/devices/bus/rc2014/rc2014.cpp b/src/devices/bus/rc2014/rc2014.cpp
new file mode 100644
index 00000000000..69d07eb515c
--- /dev/null
+++ b/src/devices/bus/rc2014/rc2014.cpp
@@ -0,0 +1,291 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 Bus Device
+
+***************************************************************************/
+
+#include "emu.h"
+#include "rc2014.h"
+
+//**************************************************************************
+// RC2014 Standard Bus
+//**************************************************************************
+
+//-------------------------------------------------
+// rc2014_bus_device
+//-------------------------------------------------
+
+rc2014_bus_device::rc2014_bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_installer{}
+ , m_clk(*this)
+ , m_int(*this)
+ , m_tx(*this)
+ , m_rx(*this)
+ , m_user1(*this)
+ , m_user2(*this)
+ , m_user3(*this)
+ , m_user4(*this)
+ , m_daisy_chain{}
+{
+}
+
+rc2014_bus_device::rc2014_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_bus_device(mconfig, RC2014_BUS, tag, owner, clock)
+{
+}
+
+rc2014_bus_device::~rc2014_bus_device()
+{
+ for(size_t i = 0; i < m_daisy.size(); i++)
+ delete [] m_daisy_chain[i];
+ delete [] m_daisy_chain;
+}
+
+void rc2014_bus_device::device_start()
+{
+ if (m_installer[AS_PROGRAM] == nullptr)
+ throw emu_fatalerror("Main address installer missing on RC2014 bus !!!");
+ // resolve callbacks
+ m_clk.resolve_safe();
+ m_int.resolve_safe();
+ m_tx.resolve_safe();
+ m_rx.resolve_safe();
+ m_user1.resolve_safe();
+ m_user2.resolve_safe();
+ m_user3.resolve_safe();
+ m_user4.resolve_safe();
+}
+
+void rc2014_bus_device::set_bus_clock(u32 clock)
+{
+ set_clock(clock);
+ notify_clock_changed();
+}
+
+void rc2014_bus_device::assign_installer(int index, address_space_installer *installer)
+{
+ if (m_installer[index] != nullptr )
+ throw emu_fatalerror("Address installer already set on RC2014 bus !!!");
+ m_installer[index] = installer;
+}
+
+address_space_installer *rc2014_bus_device::installer(int index) const
+{
+ assert(index >= 0 && index < 4 && m_installer[index]);
+ return m_installer[index];
+}
+
+const z80_daisy_config* rc2014_bus_device::get_daisy_chain()
+{
+ m_daisy_chain = new char*[m_daisy.size() + 1];
+ for(size_t i = 0; i < m_daisy.size(); i++)
+ {
+ m_daisy_chain[i] = new char[m_daisy[i].size() + 1];
+ strcpy(m_daisy_chain[i], m_daisy[i].c_str());
+ }
+ m_daisy_chain[m_daisy.size()] = nullptr;
+ return (const z80_daisy_config*)m_daisy_chain;
+}
+
+//-------------------------------------------------
+// device_rc2014_card_interface
+//-------------------------------------------------
+
+device_rc2014_card_interface::device_rc2014_card_interface(const machine_config &mconfig, device_t &device)
+ : device_interface(device, "rc2014bus")
+ , m_bus(nullptr)
+{
+}
+
+void device_rc2014_card_interface::set_bus_device(rc2014_bus_device *bus_device)
+{
+ m_bus = bus_device;
+}
+
+//-------------------------------------------------
+// rc2014_slot_device
+//-------------------------------------------------
+
+rc2014_slot_device::rc2014_slot_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_slot_interface(mconfig, *this)
+ , m_bus(*this, finder_base::DUMMY_TAG)
+{
+}
+
+rc2014_slot_device::rc2014_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_slot_device(mconfig, RC2014_SLOT, tag, owner, clock)
+{
+}
+
+void rc2014_slot_device::device_start()
+{
+}
+
+void rc2014_slot_device::device_resolve_objects()
+{
+ device_rc2014_card_interface *const card(dynamic_cast<device_rc2014_card_interface *>(get_card_device()));
+
+ if (card)
+ card->set_bus_device(m_bus);
+}
+
+//**************************************************************************
+// RC2014 Extended Bus
+//**************************************************************************
+
+//-------------------------------------------------
+// rc2014_ext_bus_device
+//-------------------------------------------------
+
+rc2014_ext_bus_device::rc2014_ext_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_ext_bus_device(mconfig, RC2014_EXT_BUS, tag, owner, clock)
+{
+}
+
+rc2014_ext_bus_device::rc2014_ext_bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_bus_device(mconfig, type, tag, owner, clock)
+ , m_clk2(*this)
+ , m_page(*this)
+ , m_nmi(*this)
+ , m_tx2(*this)
+ , m_rx2(*this)
+ , m_user5(*this)
+ , m_user6(*this)
+ , m_user7(*this)
+ , m_user8(*this)
+{
+}
+
+void rc2014_ext_bus_device::device_start()
+{
+ rc2014_bus_device::device_start();
+ m_clk2.resolve_safe();
+ m_page.resolve_safe();
+ m_nmi.resolve_safe();
+ m_tx2.resolve_safe();
+ m_rx2.resolve_safe();
+ m_user5.resolve_safe();
+ m_user6.resolve_safe();
+ m_user7.resolve_safe();
+ m_user8.resolve_safe();
+}
+
+//-------------------------------------------------
+// device_rc2014_ext_card_interface
+//-------------------------------------------------
+
+device_rc2014_ext_card_interface::device_rc2014_ext_card_interface(const machine_config &mconfig, device_t &device)
+ : device_rc2014_card_interface(mconfig,device)
+ , m_bus(nullptr)
+{
+}
+
+void device_rc2014_ext_card_interface::set_bus_device(rc2014_ext_bus_device *bus_device)
+{
+ m_bus = bus_device;
+}
+
+//-------------------------------------------------
+// rc2014_ext_slot_device
+//-------------------------------------------------
+
+rc2014_ext_slot_device::rc2014_ext_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_ext_slot_device(mconfig, RC2014_EXT_SLOT, tag, owner, clock)
+{
+}
+
+rc2014_ext_slot_device::rc2014_ext_slot_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_slot_device(mconfig, type, tag, owner, clock)
+{
+}
+
+void rc2014_ext_slot_device::device_start()
+{
+}
+
+void rc2014_ext_slot_device::device_resolve_objects()
+{
+ rc2014_slot_device::device_resolve_objects();
+ device_rc2014_ext_card_interface *const card(dynamic_cast<device_rc2014_ext_card_interface *>(get_card_device()));
+
+ if (card)
+ card->set_bus_device(dynamic_cast<rc2014_ext_bus_device *>(m_bus.target()));
+}
+
+//**************************************************************************
+// RC2014 RC80 Bus
+//**************************************************************************
+
+//-------------------------------------------------
+// rc2014_rc80_bus_device
+//-------------------------------------------------
+
+rc2014_rc80_bus_device::rc2014_rc80_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_rc80_bus_device(mconfig, RC2014_RC80_BUS, tag, owner, clock)
+{
+}
+
+rc2014_rc80_bus_device::rc2014_rc80_bus_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_ext_bus_device(mconfig, type, tag, owner, clock)
+
+{
+}
+
+void rc2014_rc80_bus_device::device_start()
+{
+ rc2014_ext_bus_device::device_start();
+}
+
+//-------------------------------------------------
+// device_rc2014_rc80_card_interface
+//-------------------------------------------------
+
+device_rc2014_rc80_card_interface::device_rc2014_rc80_card_interface(const machine_config &mconfig, device_t &device)
+ : device_rc2014_ext_card_interface(mconfig,device)
+ , m_bus(nullptr)
+{
+}
+
+void device_rc2014_rc80_card_interface::set_bus_device(rc2014_rc80_bus_device *bus_device)
+{
+ m_bus = bus_device;
+}
+
+//-------------------------------------------------
+// rc2014_rc80_slot_device
+//-------------------------------------------------
+
+rc2014_rc80_slot_device::rc2014_rc80_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : rc2014_ext_slot_device(mconfig, RC2014_RC80_SLOT, tag, owner, clock)
+{
+}
+
+void rc2014_rc80_slot_device::device_start()
+{
+}
+
+void rc2014_rc80_slot_device::device_resolve_objects()
+{
+ rc2014_ext_slot_device::device_resolve_objects();
+ device_rc2014_rc80_card_interface *const card(dynamic_cast<device_rc2014_rc80_card_interface *>(get_card_device()));
+
+ if (card)
+ card->set_bus_device(dynamic_cast<rc2014_rc80_bus_device *>(m_bus.target()));
+}
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(RC2014_BUS, rc2014_bus_device, "rc2014_bus", "RC2014 Standard Bus")
+DEFINE_DEVICE_TYPE(RC2014_SLOT, rc2014_slot_device, "rc2014_slot", "RC2014 Standard Bus Slot")
+
+DEFINE_DEVICE_TYPE(RC2014_EXT_BUS, rc2014_ext_bus_device, "rc2014_ext_bus", "RC2014 Extended Bus")
+DEFINE_DEVICE_TYPE(RC2014_EXT_SLOT, rc2014_ext_slot_device, "rc2014_ext_slot", "RC2014 Extended Bus Slot")
+
+DEFINE_DEVICE_TYPE(RC2014_RC80_BUS, rc2014_rc80_bus_device, "rc2014_rc80_bus", "RC2014 RC80 Bus")
+DEFINE_DEVICE_TYPE(RC2014_RC80_SLOT, rc2014_rc80_slot_device, "rc2014_rc80_slot", "RC2014 RC80 Bus Slot")
diff --git a/src/devices/bus/rc2014/rc2014.h b/src/devices/bus/rc2014/rc2014.h
new file mode 100644
index 00000000000..d6cbd6f5154
--- /dev/null
+++ b/src/devices/bus/rc2014/rc2014.h
@@ -0,0 +1,328 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 Bus Device
+
+===========================================================================
+ Standard Bus| Extended Bus | RC80 RC2014 Bus
+=============|============================|================================
+ Pin Signal |Pin Signal Pin Signal |Pin # Signal Pin Signal
+=============|============================|================================
+ 1 A15 |1 Not used 1 A15 |41 #41 (custom) 1 A15
+ 2 A14 |2 Not used 2 A14 |42 #42 (custom) 2 A14
+ 3 A13 |3 Not used 3 A13 |43 #43 (custom) 3 A13
+ 4 A12 |4 Not used 4 A12 |44 #44 (custom) 4 A12
+ 5 A11 |5 Not used 5 A11 |45 #45 (custom) 5 A11
+ 6 A10 |6 Not used 6 A10 |46 #46 (custom) 6 A10
+ 7 A9 |7 Not used 7 A9 |47 #47 (custom) 7 A9
+ 8 A8 |8 Not used 8 A8 |48 #48 (custom) 8 A8
+ 9 A7 |9 Not used 9 A7 |49 A23 9 A7
+ 10 A6 |10 Not used 10 A6 |50 A22 10 A6
+ 11 A5 |11 Not used 11 A5 |51 A21 11 A5
+ 12 A4 |12 Not used 12 A4 |52 A20 12 A4
+ 13 A3 |13 Not used 13 A3 |53 A19 13 A3
+ 14 A2 |14 Not used 14 A2 |54 A18 14 A2
+ 15 A1 |15 Not used 15 A1 |55 A17 15 A1
+ 16 A0 |16 Not used 16 A0 |56 A16 16 A0
+ 17 GND |17 GND 17 GND |57 GND 17 GND
+ 18 5V |18 5V 18 5V |58 5V 18 5V
+ 19 /M1 |19 /RFSH 19 /M1 |59 /RFSH 19 /M1
+ 20 /RESET |20 PAGE(/RESET2)20 /RESET |60 PAGE 20 /RESET
+ 21 CLK |21 CLK2 21 CLK |61 CLK2 21 CLK
+ 22 /INT |22 /BUSAK 22 /INT |62 /BUSAK 22 /INT
+ 23 /MREQ |23 /HALT 23 /MREQ |63 /HALT 23 /MREQ
+ 24 /WR |24 /BUSRQ 24 /WR |64 /BUSRQ 24 /WR
+ 25 /RD |25 /WAIT 25 /RD |65 /WAIT 25 /RD
+ 26 /IORQ |26 /NMI 26 /IORQ |66 /NMI 26 /IORQ
+ 27 D0 |27 D8 27 D0 |67 #67 (custom) 27 D0
+ 28 D1 |28 D9 28 D1 |68 #68 (custom) 28 D1
+ 29 D2 |29 D10 29 D2 |69 #69 (custom) 29 D2
+ 30 D3 |30 D11 30 D3 |70 #70 (custom) 30 D3
+ 31 D4 |31 D12 31 D4 |71 #71 (custom) 31 D4
+ 32 D5 |32 D13 32 D5 |72 #72 (custom) 32 D5
+ 33 D6 |33 D14 33 D6 |73 #73 (custom) 33 D6
+ 34 D7 |34 D15 34 D7 |74 #74 (custom) 34 D7
+ 35 TX |35 TX2 35 TX |75 TX2 35 TX
+ 36 RX |36 RX2 36 RX |76 RX2 36 RX
+ 37 USER1 |37 USER5 37 USER1 |77 USER5 37 USER1
+ 38 USER2 |38 USER6 38 USER2 |78 USER6 38 USER2
+ 39 USER3 |39 USER7 39 USER3 |79 USER7 39 USER3
+ 40 USER4 |40 USER8 40 USER4 |80 USER8(IEI) 40 USER4(IEO)
+===========================================================================
+
+***************************************************************************/
+
+#ifndef MAME_BUS_RC2014_RC2014_H
+#define MAME_BUS_RC2014_RC2014_H
+
+#pragma once
+
+#include "machine/z80daisy.h"
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+//**************************************************************************
+// RC2014 Standard Bus
+//**************************************************************************
+
+// ======================> rc2014_bus_device
+
+class rc2014_bus_device : public device_t
+{
+public:
+ // construction/destruction
+ rc2014_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+ virtual ~rc2014_bus_device();
+
+ auto clk_callback() { return m_clk.bind(); }
+ auto int_callback() { return m_int.bind(); }
+ auto tx_callback() { return m_tx.bind(); }
+ auto rx_callback() { return m_rx.bind(); }
+ auto user1_callback() { return m_user1.bind(); }
+ auto user2_callback() { return m_user2.bind(); }
+ auto user3_callback() { return m_user3.bind(); }
+ auto user4_callback() { return m_user4.bind(); }
+
+ DECLARE_WRITE_LINE_MEMBER( clk_w ) { m_clk(state); }
+ DECLARE_WRITE_LINE_MEMBER( int_w ) { m_int(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx_w ) { m_tx(state); }
+ DECLARE_WRITE_LINE_MEMBER( rx_w ) { m_rx(state); }
+ DECLARE_WRITE_LINE_MEMBER( user1_w ) { m_user1(state); }
+ DECLARE_WRITE_LINE_MEMBER( user2_w ) { m_user2(state); }
+ DECLARE_WRITE_LINE_MEMBER( user3_w ) { m_user3(state); }
+ DECLARE_WRITE_LINE_MEMBER( user4_w ) { m_user4(state); }
+
+ void set_bus_clock(u32 clock);
+ void set_bus_clock(const XTAL &xtal) { set_bus_clock(xtal.value()); }
+ void assign_installer(int index, address_space_installer *installer);
+ address_space_installer *installer(int index) const;
+ void add_to_daisy_chain(std::string tag) { m_daisy.push_back(tag); }
+ const z80_daisy_config* get_daisy_chain();
+
+protected:
+ rc2014_bus_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;
+
+private:
+ address_space_installer *m_installer[4];
+ devcb_write_line m_clk;
+ devcb_write_line m_int;
+ devcb_write_line m_tx;
+ devcb_write_line m_rx;
+ devcb_write_line m_user1;
+ devcb_write_line m_user2;
+ devcb_write_line m_user3;
+ devcb_write_line m_user4;
+ std::vector<std::string> m_daisy;
+ char **m_daisy_chain;
+};
+
+// ======================> device_rc2014_card_interface
+
+class rc2014_slot_device;
+
+class device_rc2014_card_interface : public device_interface
+{
+ friend class rc2014_slot_device;
+
+public:
+ // construction/destruction
+ device_rc2014_card_interface(const machine_config &mconfig, device_t &device);
+protected:
+ void set_bus_device(rc2014_bus_device *bus_device);
+
+ rc2014_bus_device *m_bus;
+};
+
+// ======================> rc2014_slot_device
+
+class rc2014_slot_device : public device_t, public device_slot_interface
+{
+public:
+ rc2014_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ template <typename T, typename U>
+ rc2014_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&bus_tag, U &&slot_options, char const *default_option)
+ : rc2014_slot_device(mconfig, tag, owner, DERIVED_CLOCK(1,1))
+ {
+ m_bus.set_tag(std::forward<T>(bus_tag));
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(false);
+ }
+
+protected:
+ rc2014_slot_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+
+ required_device<rc2014_bus_device> m_bus;
+};
+
+//**************************************************************************
+// RC2014 Extended Bus
+//**************************************************************************
+
+// ======================> rc2014_ext_bus_device
+
+class rc2014_ext_bus_device : public rc2014_bus_device
+{
+public:
+ // construction/destruction
+ rc2014_ext_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ auto clk2_callback() { return m_clk2.bind(); }
+ auto page_callback() { return m_page.bind(); }
+ auto nmi_callback() { return m_nmi.bind(); }
+ auto tx2_callback() { return m_tx2.bind(); }
+ auto rx2_callback() { return m_rx2.bind(); }
+ auto user5_callback() { return m_user5.bind(); }
+ auto user6_callback() { return m_user6.bind(); }
+ auto user7_callback() { return m_user7.bind(); }
+ auto user8_callback() { return m_user8.bind(); }
+
+ DECLARE_WRITE_LINE_MEMBER( clk2_w ) { m_clk2(state); }
+ DECLARE_WRITE_LINE_MEMBER( page_w ) { m_page(state); }
+ DECLARE_WRITE_LINE_MEMBER( nmi_w ) { m_nmi(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx2_w ) { m_tx2(state); }
+ DECLARE_WRITE_LINE_MEMBER( rx2_w ) { m_rx2(state); }
+ DECLARE_WRITE_LINE_MEMBER( user5_w ) { m_user5(state); }
+ DECLARE_WRITE_LINE_MEMBER( user6_w ) { m_user6(state); }
+ DECLARE_WRITE_LINE_MEMBER( user7_w ) { m_user7(state); }
+ DECLARE_WRITE_LINE_MEMBER( user8_w ) { m_user8(state); }
+
+protected:
+ rc2014_ext_bus_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;
+
+private:
+ devcb_write_line m_clk2;
+ devcb_write_line m_page;
+ devcb_write_line m_nmi;
+ devcb_write_line m_tx2;
+ devcb_write_line m_rx2;
+ devcb_write_line m_user5;
+ devcb_write_line m_user6;
+ devcb_write_line m_user7;
+ devcb_write_line m_user8;
+};
+
+// ======================> device_rc2014_ext_card_interface
+
+class rc2014_ext_slot_device;
+
+class device_rc2014_ext_card_interface : public device_rc2014_card_interface
+{
+ friend class rc2014_ext_slot_device;
+
+protected:
+ // construction/destruction
+ device_rc2014_ext_card_interface(const machine_config &mconfig, device_t &device);
+
+ void set_bus_device(rc2014_ext_bus_device *bus_device);
+
+ rc2014_ext_bus_device *m_bus;
+};
+
+// ======================> rc2014_ext_slot_device
+
+class rc2014_ext_slot_device : public rc2014_slot_device
+{
+public:
+ rc2014_ext_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ template <typename T, typename U>
+ rc2014_ext_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&bus_tag, U &&slot_options, char const *default_option)
+ : rc2014_ext_slot_device(mconfig, tag, owner, DERIVED_CLOCK(1,1))
+ {
+ m_bus.set_tag(std::forward<T>(bus_tag));
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(false);
+ }
+
+protected:
+ rc2014_ext_slot_device(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock);
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+};
+
+//**************************************************************************
+// RC2014 RC80 Bus
+//**************************************************************************
+
+// ======================> rc2014_rc80_bus_device
+
+class rc2014_rc80_bus_device : public rc2014_ext_bus_device
+{
+public:
+ // construction/destruction
+ rc2014_rc80_bus_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ rc2014_rc80_bus_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;
+};
+
+// ======================> device_rc2014_rc80_card_interface
+
+class rc2014_rc80_slot_device;
+
+class device_rc2014_rc80_card_interface : public device_rc2014_ext_card_interface
+{
+ friend class rc2014_rc80_slot_device;
+
+protected:
+ // construction/destruction
+ device_rc2014_rc80_card_interface(const machine_config &mconfig, device_t &device);
+
+ void set_bus_device(rc2014_rc80_bus_device *bus_device);
+
+ rc2014_rc80_bus_device *m_bus;
+};
+
+// ======================> rc2014_rc80_slot_device
+
+class rc2014_rc80_slot_device : public rc2014_ext_slot_device
+{
+public:
+ rc2014_rc80_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ template <typename T, typename U>
+ rc2014_rc80_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&bus_tag, U &&slot_options, char const *default_option)
+ : rc2014_rc80_slot_device(mconfig, tag, owner, DERIVED_CLOCK(1,1))
+ {
+ m_bus.set_tag(std::forward<T>(bus_tag));
+ option_reset();
+ slot_options(*this);
+ set_default_option(default_option);
+ set_fixed(false);
+ }
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+};
+
+// device type definition
+DECLARE_DEVICE_TYPE(RC2014_BUS, rc2014_bus_device)
+DECLARE_DEVICE_TYPE(RC2014_SLOT, rc2014_slot_device)
+
+DECLARE_DEVICE_TYPE(RC2014_EXT_BUS, rc2014_ext_bus_device)
+DECLARE_DEVICE_TYPE(RC2014_EXT_SLOT, rc2014_ext_slot_device)
+
+DECLARE_DEVICE_TYPE(RC2014_RC80_BUS, rc2014_rc80_bus_device)
+DECLARE_DEVICE_TYPE(RC2014_RC80_SLOT, rc2014_rc80_slot_device)
+
+#endif // MAME_BUS_RC2014_RC2014_H
diff --git a/src/devices/bus/rc2014/rom.cpp b/src/devices/bus/rc2014/rom.cpp
new file mode 100644
index 00000000000..9e73cd6084e
--- /dev/null
+++ b/src/devices/bus/rc2014/rom.cpp
@@ -0,0 +1,217 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 ROM Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "rom.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 Switchable ROM module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class switchable_rom_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ switchable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+private:
+ required_memory_region m_rom;
+ required_ioport m_rom_selector;
+};
+
+switchable_rom_device::switchable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_SWITCHABLE_ROM, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+ , m_rom(*this, "rom")
+ , m_rom_selector(*this, "A13-A15")
+{
+}
+
+void switchable_rom_device::device_start()
+{
+}
+
+void switchable_rom_device::device_reset()
+{
+ m_bus->installer(AS_PROGRAM)->install_rom(0x0000, 0x1fff, 0x0000, m_rom->base() + (m_rom_selector->read() & 7) * 0x2000);
+}
+
+static INPUT_PORTS_START( switchable_rom_jumpers )
+ PORT_START("A13-A15") /* jumpers to select ROM region */
+ PORT_CONFNAME( 0x7, 0x7, "ROM Bank" )
+ PORT_CONFSETTING( 0x0, "BASIC" )
+ PORT_CONFSETTING( 0x1, "EMPTY1" )
+ PORT_CONFSETTING( 0x2, "EMPTY2" )
+ PORT_CONFSETTING( 0x3, "EMPTY3" )
+ PORT_CONFSETTING( 0x4, "EMPTY4" )
+ PORT_CONFSETTING( 0x5, "EMPTY5" )
+ PORT_CONFSETTING( 0x6, "EMPTY6" )
+ PORT_CONFSETTING( 0x7, "SCM" )
+INPUT_PORTS_END
+
+ioport_constructor switchable_rom_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( switchable_rom_jumpers );
+}
+
+ROM_START(rc2014_rom)
+ ROM_REGION( 0x10000, "rom",0 )
+ ROM_LOAD( "r0000009.bin", 0x0000, 0x10000, CRC(3fb1ced7) SHA1(40a030b931ebe6cca654ce056c228297f245b057) )
+ROM_END
+
+const tiny_rom_entry *switchable_rom_device::device_rom_region() const
+{
+ return ROM_NAME( rc2014_rom );
+}
+
+//**************************************************************************
+// RC2014 Pageable ROM module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class pagable_rom_device : public device_t, public device_rc2014_ext_card_interface
+{
+public:
+ // construction/destruction
+ pagable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override { update_banks(); }
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ void reset_bank_w(offs_t, uint8_t) { m_bank = 0; update_banks(); m_bus->page_w(CLEAR_LINE);}
+ void toggle_bank_w(offs_t, uint8_t) { m_bank = m_bank ? 0 : 1; update_banks(); m_bus->page_w(m_bank ? ASSERT_LINE : CLEAR_LINE); }
+
+ void update_banks();
+private:
+ int m_bank;
+ u16 m_start_offset;
+ u16 m_end_addr;
+ required_memory_region m_rom;
+ required_ioport m_page_size_conf;
+ required_ioport_array<6> m_page_addr_conf;
+};
+
+pagable_rom_device::pagable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_PAGABLE_ROM, tag, owner, clock)
+ , device_rc2014_ext_card_interface(mconfig, *this)
+ , m_bank(0)
+ , m_rom(*this, "rom")
+ , m_page_size_conf(*this, "PAGE_SIZE")
+ , m_page_addr_conf(*this, "A1%u", 0U)
+{
+}
+
+void pagable_rom_device::device_start()
+{
+ save_item(NAME(m_bank));
+
+ m_bus->installer(AS_IO)->install_write_handler(0x30, 0x30, write8sm_delegate(*this, FUNC(pagable_rom_device::reset_bank_w)));
+ m_bus->installer(AS_IO)->install_write_handler(0x38, 0x38, write8sm_delegate(*this, FUNC(pagable_rom_device::toggle_bank_w)));
+}
+
+void pagable_rom_device::device_reset()
+{
+ static constexpr u16 page_size[] = { 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 };
+ static constexpr u16 page_mask[] = { 0xfc00, 0xf800, 0xf000, 0xe000, 0xc000, 0x8000 };
+
+ int index = 0;
+ m_start_offset = 0x0000;
+ for (auto& addr : m_page_addr_conf)
+ {
+ if (addr->read() != 0)
+ m_start_offset += (addr->read() - 1) * page_size[index];
+ index++;
+ }
+ m_start_offset &= page_mask[m_page_size_conf->read()];
+ m_end_addr = page_size[m_page_size_conf->read()] - 1;
+ reset_bank_w(0,0);
+}
+
+void pagable_rom_device::update_banks()
+{
+ if (m_bank == 0)
+ m_bus->installer(AS_PROGRAM)->install_rom(0x0000, m_end_addr, 0x0000, m_rom->base() + m_start_offset);
+}
+
+static INPUT_PORTS_START( pagable_rom_jumpers )
+ PORT_START("PAGE_SIZE")
+ PORT_CONFNAME( 0x7, 0x4, "Page Size" )
+ PORT_CONFSETTING( 0x0, "1K" )
+ PORT_CONFSETTING( 0x1, "2K" )
+ PORT_CONFSETTING( 0x2, "4K" )
+ PORT_CONFSETTING( 0x3, "8K" )
+ PORT_CONFSETTING( 0x4, "16K" )
+ PORT_CONFSETTING( 0x5, "32K" )
+ PORT_START("A10")
+ PORT_CONFNAME( 0x3, 0x0, "A10" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A11")
+ PORT_CONFNAME( 0x3, 0x0, "A11" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A12")
+ PORT_CONFNAME( 0x3, 0x0, "A12" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A13")
+ PORT_CONFNAME( 0x3, 0x0, "A13" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A14")
+ PORT_CONFNAME( 0x3, 0x2, "A14" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A15")
+ PORT_CONFNAME( 0x3, 0x1, "A15" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+INPUT_PORTS_END
+
+ioport_constructor pagable_rom_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( pagable_rom_jumpers );
+}
+
+ROM_START(rc2014_pagable_rom)
+ ROM_REGION( 0x10000, "rom",0 )
+ ROM_LOAD( "24886009.bin", 0x00000, 0x10000, CRC(2731ca52) SHA1(e9ac663cb85de4e3e041bce444712c00f46b6eb2) )
+ROM_END
+
+const tiny_rom_entry *pagable_rom_device::device_rom_region() const
+{
+ return ROM_NAME( rc2014_pagable_rom );
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_SWITCHABLE_ROM, device_rc2014_card_interface, switchable_rom_device, "rc2014_switchable_rom", "RC2014 Switchable ROM module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_PAGABLE_ROM, device_rc2014_ext_card_interface, pagable_rom_device, "rc2014_pagable_rom", "RC2014 Pageable ROM module")
diff --git a/src/devices/bus/rc2014/rom.h b/src/devices/bus/rc2014/rom.h
new file mode 100644
index 00000000000..e4d92b987e0
--- /dev/null
+++ b/src/devices/bus/rc2014/rom.h
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 ROM Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_ROM_H
+#define MAME_BUS_RC2014_ROM_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_SWITCHABLE_ROM, device_rc2014_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_PAGABLE_ROM, device_rc2014_ext_card_interface)
+
+#endif // MAME_BUS_RC2014_ROM_H
diff --git a/src/devices/bus/rc2014/romram.cpp b/src/devices/bus/rc2014/romram.cpp
new file mode 100644
index 00000000000..6b5c9b7bc66
--- /dev/null
+++ b/src/devices/bus/rc2014/romram.cpp
@@ -0,0 +1,132 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 ROM/RAM Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "romram.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 512K RAM / 512K Flash
+// Module author: Spencer Owen
+//**************************************************************************
+
+class rom_ram_512k_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ rom_ram_512k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_post_load() override { update_banks(); }
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ void page_w(offs_t offset, uint8_t data) { m_page_reg[offset & 3] = data & 0x3f; update_banks(); }
+ void page_en_w(offs_t, uint8_t data) { m_page_en = data & 1; update_banks(); }
+
+ void update_banks();
+private:
+ uint8_t m_page_reg[4];
+ uint8_t m_page_en;
+ std::unique_ptr<u8[]> m_ram;
+ required_memory_region m_romram;
+ memory_bank_array_creator<4> m_bank;
+};
+
+rom_ram_512k_device::rom_ram_512k_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_ROM_RAM_512, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+ , m_page_reg{0,0,0,0}
+ , m_page_en(0)
+ , m_ram(nullptr)
+ , m_romram(*this, "romram")
+ , m_bank(*this, "bank%u", 0U)
+{
+}
+
+void rom_ram_512k_device::device_start()
+{
+ m_ram = std::make_unique<u8[]>(0x80000);
+ std::fill_n(m_ram.get(), 0x80000, 0xff);
+ save_pointer(NAME(m_ram), 0x80000);
+ save_item(NAME(m_page_en));
+ save_item(NAME(m_page_reg));
+
+ // A3 not connected
+ m_bus->installer(AS_IO)->install_write_handler(0x70, 0x73, 0, 0x08, 0, write8sm_delegate(*this, FUNC(rom_ram_512k_device::page_w)));
+ // A3, A1 and A0 not connected
+ m_bus->installer(AS_IO)->install_write_handler(0x74, 0x74, 0, 0x0b, 0, write8sm_delegate(*this, FUNC(rom_ram_512k_device::page_en_w)));
+
+ m_bus->installer(AS_PROGRAM)->install_read_bank(0x0000, 0x3fff, m_bank[0]);
+ m_bus->installer(AS_PROGRAM)->install_read_bank(0x4000, 0x7fff, m_bank[1]);
+ m_bus->installer(AS_PROGRAM)->install_read_bank(0x8000, 0xbfff, m_bank[2]);
+ m_bus->installer(AS_PROGRAM)->install_read_bank(0xc000, 0xffff, m_bank[3]);
+
+ update_banks();
+}
+
+void rom_ram_512k_device::update_banks()
+{
+ if (m_page_en)
+ {
+ if (m_page_reg[0] & 0x20) {
+ m_bank[0]->set_base(m_ram.get() + ((m_page_reg[0] & 0x1f) << 14));
+ m_bus->installer(AS_PROGRAM)->install_write_bank(0x0000, 0x3fff, m_bank[0]);
+ } else {
+ m_bank[0]->set_base(m_romram->base() + (m_page_reg[0] << 14));
+ m_bus->installer(AS_PROGRAM)->unmap_write(0x0000, 0x3fff);
+ }
+ if (m_page_reg[1] & 0x20) {
+ m_bank[1]->set_base(m_ram.get() + ((m_page_reg[1] & 0x1f) << 14));
+ m_bus->installer(AS_PROGRAM)->install_write_bank(0x4000, 0x7fff, m_bank[1]);
+ } else {
+ m_bank[1]->set_base(m_romram->base() + (m_page_reg[1] << 14));
+ m_bus->installer(AS_PROGRAM)->unmap_write(0x4000, 0x7fff);
+ }
+ if (m_page_reg[2] & 0x20) {
+ m_bank[2]->set_base(m_ram.get() + ((m_page_reg[2] & 0x1f) << 14));
+ m_bus->installer(AS_PROGRAM)->install_write_bank(0x8000, 0xbfff, m_bank[2]);
+ } else {
+ m_bank[2]->set_base(m_romram->base() + (m_page_reg[2] << 14));
+ m_bus->installer(AS_PROGRAM)->unmap_write(0x8000, 0xbfff);
+ }
+ if (m_page_reg[3] & 0x20) {
+ m_bank[3]->set_base(m_ram.get() + ((m_page_reg[3] & 0x1f) << 14));
+ m_bus->installer(AS_PROGRAM)->install_write_bank(0xc000, 0xffff, m_bank[3]);
+ } else {
+ m_bank[3]->set_base(m_romram->base() + (m_page_reg[3] << 14));
+ m_bus->installer(AS_PROGRAM)->unmap_write(0xc000, 0xffff);
+ }
+ }
+ else
+ {
+ m_bank[0]->set_base(m_romram->base() + 0x0000);
+ m_bank[1]->set_base(m_romram->base() + 0x4000);
+ m_bank[2]->set_base(m_romram->base() + 0x8000);
+ m_bank[3]->set_base(m_romram->base() + 0xc000);
+ }
+}
+
+ROM_START(rc2014_rom_ram_512k)
+ ROM_REGION( 0x80000, "romram", 0)
+ ROM_LOAD( "rc_2.512k.rom", 0x00000, 0x80000, CRC(c3aefb4e) SHA1(34541851dc781033b00cdfbe445e1d91811da5c2) )
+ROM_END
+
+const tiny_rom_entry *rom_ram_512k_device::device_rom_region() const
+{
+ return ROM_NAME( rc2014_rom_ram_512k );
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_ROM_RAM_512, device_rc2014_card_interface, rom_ram_512k_device, "rc2014_rom_ram_512k", "RC2014 512K RAM / 512K Flash")
diff --git a/src/devices/bus/rc2014/romram.h b/src/devices/bus/rc2014/romram.h
new file mode 100644
index 00000000000..63cf08735fa
--- /dev/null
+++ b/src/devices/bus/rc2014/romram.h
@@ -0,0 +1,18 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 ROM/RAM Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_ROMRAM_H
+#define MAME_BUS_RC2014_ROMRAM_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_ROM_RAM_512, device_rc2014_card_interface)
+
+#endif // MAME_BUS_RC2014_ROMRAM_H
diff --git a/src/devices/bus/rc2014/serial.cpp b/src/devices/bus/rc2014/serial.cpp
new file mode 100644
index 00000000000..80bc984579b
--- /dev/null
+++ b/src/devices/bus/rc2014/serial.cpp
@@ -0,0 +1,266 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 Serial Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "serial.h"
+#include "machine/6850acia.h"
+#include "machine/z80sio.h"
+#include "bus/rs232/rs232.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 Serial I/O module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class serial_io_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ serial_io_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) { m_bus->int_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx_w ) { m_bus->tx_w(state); }
+private:
+ required_device<acia6850_device> m_acia;
+};
+
+serial_io_device::serial_io_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_SERIAL_IO, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+ , m_acia(*this, "acia")
+{
+}
+
+void serial_io_device::device_start()
+{
+ // A5, A4, A3, A2 and A1 not connected
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x80, 0x81, 0, 0x3e, 0, read8sm_delegate(*m_acia, FUNC(acia6850_device::read)), write8sm_delegate(*m_acia, FUNC(acia6850_device::write)));
+}
+
+void serial_io_device::device_resolve_objects()
+{
+ m_bus->clk_callback().append(m_acia, FUNC(acia6850_device::write_txc));
+ m_bus->clk_callback().append(m_acia, FUNC(acia6850_device::write_rxc));
+
+ m_bus->rx_callback().append(m_acia, FUNC(acia6850_device::write_rxd));
+}
+
+static DEVICE_INPUT_DEFAULTS_START( terminal )
+ DEVICE_INPUT_DEFAULTS( "RS232_RXBAUD", 0xff, RS232_BAUD_115200 )
+ DEVICE_INPUT_DEFAULTS( "RS232_TXBAUD", 0xff, RS232_BAUD_115200 )
+ DEVICE_INPUT_DEFAULTS( "RS232_DATABITS", 0xff, RS232_DATABITS_8 )
+ DEVICE_INPUT_DEFAULTS( "RS232_PARITY", 0xff, RS232_PARITY_NONE )
+ DEVICE_INPUT_DEFAULTS( "RS232_STOPBITS", 0xff, RS232_STOPBITS_1 )
+DEVICE_INPUT_DEFAULTS_END
+
+void serial_io_device::device_add_mconfig(machine_config &config)
+{
+ ACIA6850(config, m_acia, 0);
+ m_acia->txd_handler().set("rs232", FUNC(rs232_port_device::write_txd));
+ m_acia->txd_handler().append(FUNC(serial_io_device::tx_w));
+ m_acia->rts_handler().set("rs232", FUNC(rs232_port_device::write_rts));
+ m_acia->irq_handler().set(FUNC(serial_io_device::irq_w));
+
+ rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "terminal"));
+ rs232.rxd_handler().set(m_acia, FUNC(acia6850_device::write_rxd));
+ rs232.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal));
+}
+
+//**************************************************************************
+// RC2014 Dual Serial module SIO/2
+// Module author: Spencer Owen
+//**************************************************************************
+
+//**************************************************************************
+// dual_serial_base
+//**************************************************************************
+
+class dual_serial_base : public device_t
+{
+protected:
+ // construction/destruction
+ dual_serial_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ virtual DECLARE_WRITE_LINE_MEMBER( irq_w ) = 0;
+ virtual DECLARE_WRITE_LINE_MEMBER( tx_w ) = 0;
+ virtual DECLARE_WRITE_LINE_MEMBER( tx2_w ) = 0;
+ DECLARE_WRITE_LINE_MEMBER( clk1_w ) { if (m_clk_portb == 1) { m_sio->txcb_w(state); m_sio->rxcb_w(state); } }
+ DECLARE_WRITE_LINE_MEMBER( clk2_w ) { if (m_clk_portb == 0) { m_sio->txcb_w(state); m_sio->rxcb_w(state); } }
+
+ // base-class members
+ u8 m_clk_portb;
+ required_ioport m_portb;
+ required_device<z80sio_device> m_sio;
+};
+
+dual_serial_base::dual_serial_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_clk_portb(0)
+ , m_portb(*this, "PORTB")
+ , m_sio(*this, "sio")
+{
+}
+
+void dual_serial_base::device_start()
+{
+}
+
+void dual_serial_base::device_reset()
+{
+ m_clk_portb = m_portb->read();
+}
+
+void dual_serial_base::device_add_mconfig(machine_config &config)
+{
+ Z80SIO(config, m_sio, 0);
+ m_sio->out_txda_callback().set("rs232a", FUNC(rs232_port_device::write_txd));
+ m_sio->out_txda_callback().append(FUNC(dual_serial_base::tx_w));
+ m_sio->out_rtsa_callback().set("rs232a", FUNC(rs232_port_device::write_rts));
+ m_sio->out_txdb_callback().set("rs232b", FUNC(rs232_port_device::write_txd));
+ m_sio->out_txdb_callback().append(FUNC(dual_serial_base::tx2_w));
+ m_sio->out_rtsb_callback().set("rs232b", FUNC(rs232_port_device::write_rts));
+ m_sio->out_int_callback().set(FUNC(dual_serial_base::irq_w));
+
+ rs232_port_device &rs232a(RS232_PORT(config, "rs232a", default_rs232_devices, "terminal"));
+ rs232a.rxd_handler().set(m_sio, FUNC(z80sio_device::rxa_w));
+ rs232a.set_option_device_input_defaults("terminal", DEVICE_INPUT_DEFAULTS_NAME(terminal));
+
+ rs232_port_device &rs232b(RS232_PORT(config, "rs232b", default_rs232_devices, nullptr));
+ rs232b.rxd_handler().set(m_sio, FUNC(z80sio_device::rxb_w));
+}
+
+static INPUT_PORTS_START( dual_serial_jumpers )
+ PORT_START("PORTB")
+ PORT_CONFNAME( 0x1, 0x0, "Port B" )
+ PORT_CONFSETTING( 0x0, "CLK2 (Open)" )
+ PORT_CONFSETTING( 0x1, "CLK1 (Closed)" )
+INPUT_PORTS_END
+
+ioport_constructor dual_serial_base::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( dual_serial_jumpers );
+}
+
+//**************************************************************************
+// RC2014 Dual Serial module SIO/2 in extended bus
+//**************************************************************************
+
+class dual_serial_device : public dual_serial_base, public device_rc2014_ext_card_interface
+{
+public:
+ // construction/destruction
+ dual_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+
+ // base-class overrides
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) override { m_bus->int_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx_w ) override { m_bus->tx_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx2_w ) override { m_bus->tx2_w(state); }
+};
+
+dual_serial_device::dual_serial_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : dual_serial_base(mconfig, RC2014_DUAL_SERIAL, tag, owner, clock)
+ , device_rc2014_ext_card_interface(mconfig, *this)
+{
+}
+
+void dual_serial_device::device_start()
+{
+ // A2 not connected
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x80, 0x80, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::ca_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::ca_w)));
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x81, 0x81, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::da_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::da_w)));
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x82, 0x82, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::cb_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::cb_w)));
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x83, 0x83, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::db_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::db_w)));
+}
+
+void dual_serial_device::device_resolve_objects()
+{
+ m_bus->clk_callback().append(m_sio, FUNC(z80sio_device::txca_w));
+ m_bus->clk_callback().append(m_sio, FUNC(z80sio_device::rxca_w));
+ m_bus->clk_callback().append(*this, FUNC(dual_serial_device::clk1_w));
+ m_bus->clk2_callback().append(*this, FUNC(dual_serial_device::clk2_w));
+
+ m_bus->rx_callback().append(m_sio, FUNC(z80sio_device::rxa_w));
+ m_bus->rx2_callback().append(m_sio, FUNC(z80sio_device::rxb_w));
+
+ m_bus->add_to_daisy_chain(m_sio->tag());
+}
+
+//**************************************************************************
+// RC2014 Dual Serial module SIO/2 in standard bus
+//**************************************************************************
+
+class dual_serial_device_40pin : public dual_serial_base, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ dual_serial_device_40pin(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+
+ // base-class overrides
+ DECLARE_WRITE_LINE_MEMBER( irq_w ) override { m_bus->int_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx_w ) override { m_bus->tx_w(state); }
+ DECLARE_WRITE_LINE_MEMBER( tx2_w ) override { }
+};
+
+dual_serial_device_40pin::dual_serial_device_40pin(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : dual_serial_base(mconfig, RC2014_DUAL_SERIAL_40P, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+{
+}
+
+void dual_serial_device_40pin::device_start()
+{
+ // A2 not connected
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x80, 0x80, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::ca_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::ca_w)));
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x81, 0x81, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::da_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::da_w)));
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x82, 0x82, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::cb_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::cb_w)));
+ m_bus->installer(AS_IO)->install_readwrite_handler(0x83, 0x83, 0, 0x04, 0, read8smo_delegate(*m_sio, FUNC(z80sio_device::db_r)), write8smo_delegate(*m_sio, FUNC(z80sio_device::db_w)));
+}
+
+void dual_serial_device_40pin::device_resolve_objects()
+{
+ m_bus->clk_callback().append(m_sio, FUNC(z80sio_device::txca_w));
+ m_bus->clk_callback().append(m_sio, FUNC(z80sio_device::rxca_w));
+ m_bus->clk_callback().append(*this, FUNC(dual_serial_device_40pin::clk1_w));
+
+ m_bus->rx_callback().append(m_sio, FUNC(z80sio_device::rxa_w));
+
+ m_bus->add_to_daisy_chain(m_sio->tag());
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_SERIAL_IO, device_rc2014_card_interface, serial_io_device, "rc2014_serial_io", "RC2014 Serial I/O module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_DUAL_SERIAL, device_rc2014_ext_card_interface, dual_serial_device, "rc2014_dual_serial", "RC2014 Dual Serial module SIO/2")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_DUAL_SERIAL_40P, device_rc2014_card_interface, dual_serial_device_40pin, "rc2014_dual_serial_40p", "RC2014 Dual Serial module SIO/2 (40 pin)")
diff --git a/src/devices/bus/rc2014/serial.h b/src/devices/bus/rc2014/serial.h
new file mode 100644
index 00000000000..60fe94d838f
--- /dev/null
+++ b/src/devices/bus/rc2014/serial.h
@@ -0,0 +1,20 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 Serial Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_SERIAL_H
+#define MAME_BUS_RC2014_SERIAL_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_SERIAL_IO, device_rc2014_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_DUAL_SERIAL, device_rc2014_ext_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_DUAL_SERIAL_40P, device_rc2014_card_interface)
+
+#endif // MAME_BUS_RC2014_SERIAL_H
diff --git a/src/devices/bus/rc2014/z80cpu.cpp b/src/devices/bus/rc2014/z80cpu.cpp
new file mode 100644
index 00000000000..35991f2fad5
--- /dev/null
+++ b/src/devices/bus/rc2014/z80cpu.cpp
@@ -0,0 +1,143 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 Z80 CPU Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "z80cpu.h"
+
+#include "cpu/z80/z80.h"
+
+namespace {
+
+//**************************************************************************
+// Z80 CPU base class
+//**************************************************************************
+
+class z80cpu_base : public device_t
+{
+protected:
+ // construction/destruction
+ z80cpu_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+
+ void addrmap_mem(address_map &map);
+ void addrmap_io(address_map &map);
+
+ // object finders
+ required_device<z80_device> m_maincpu;
+};
+
+z80cpu_base::z80cpu_base(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_maincpu(*this, "maincpu")
+{
+}
+
+void z80cpu_base::device_start()
+{
+}
+
+void z80cpu_base::addrmap_mem(address_map &map)
+{
+ map.unmap_value_high();
+}
+
+void z80cpu_base::addrmap_io(address_map &map)
+{
+ map.unmap_value_high();
+ map.global_mask(0xff);
+}
+
+void z80cpu_base::device_add_mconfig(machine_config &config)
+{
+ Z80(config, m_maincpu, DERIVED_CLOCK(1,1));
+ m_maincpu->set_addrmap(AS_PROGRAM, &z80cpu_base::addrmap_mem);
+ m_maincpu->set_addrmap(AS_IO, &z80cpu_base::addrmap_io);
+}
+
+//**************************************************************************
+// RC2014 Z80 CPU module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class z80cpu_device : public z80cpu_base, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ z80cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+};
+
+z80cpu_device::z80cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : z80cpu_base(mconfig, RC2014_Z80CPU, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+{
+}
+
+void z80cpu_device::device_start()
+{
+ m_maincpu->set_daisy_config(m_bus->get_daisy_chain());
+}
+
+void z80cpu_device::device_resolve_objects()
+{
+ m_bus->assign_installer(AS_PROGRAM, &m_maincpu->space(AS_PROGRAM));
+ m_bus->assign_installer(AS_IO, &m_maincpu->space(AS_IO));
+
+ m_bus->int_callback().append_inputline(m_maincpu, INPUT_LINE_IRQ0);
+}
+
+//**************************************************************************
+// RC2014 Z80 CPU 2.1 module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class z80cpu21_device : public z80cpu_base, public device_rc2014_ext_card_interface
+{
+public:
+ // construction/destruction
+ z80cpu21_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_resolve_objects() override;
+};
+
+z80cpu21_device::z80cpu21_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : z80cpu_base(mconfig, RC2014_Z80CPU_21, tag, owner, clock)
+ , device_rc2014_ext_card_interface(mconfig, *this)
+{
+}
+
+void z80cpu21_device::device_start()
+{
+ m_maincpu->set_daisy_config(m_bus->get_daisy_chain());
+}
+
+void z80cpu21_device::device_resolve_objects()
+{
+ m_bus->assign_installer(AS_PROGRAM, &m_maincpu->space(AS_PROGRAM));
+ m_bus->assign_installer(AS_IO, &m_maincpu->space(AS_IO));
+
+ m_bus->int_callback().append_inputline(m_maincpu, INPUT_LINE_IRQ0);
+ m_bus->nmi_callback().append_inputline(m_maincpu, INPUT_LINE_NMI);
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_Z80CPU, device_rc2014_card_interface, z80cpu_device, "rc2014_z80", "RC2014 Z80 CPU module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_Z80CPU_21, device_rc2014_ext_card_interface, z80cpu21_device, "rc2014_z8021", "RC2014 Z80 CPU 2.1 module")
diff --git a/src/devices/bus/rc2014/z80cpu.h b/src/devices/bus/rc2014/z80cpu.h
new file mode 100644
index 00000000000..1d07b2175ca
--- /dev/null
+++ b/src/devices/bus/rc2014/z80cpu.h
@@ -0,0 +1,19 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**********************************************************************
+
+ RC2014 Z80 CPU Module
+
+**********************************************************************/
+
+#ifndef MAME_BUS_RC2014_Z80CPU_H
+#define MAME_BUS_RC2014_Z80CPU_H
+
+#pragma once
+
+#include "bus/rc2014/rc2014.h"
+
+DECLARE_DEVICE_TYPE(RC2014_Z80CPU, device_rc2014_card_interface)
+DECLARE_DEVICE_TYPE(RC2014_Z80CPU_21, device_rc2014_ext_card_interface)
+
+#endif // MAME_BUS_RC2014_Z80CPU_H
diff --git a/src/mame/drivers/rc2014.cpp b/src/mame/drivers/rc2014.cpp
new file mode 100644
index 00000000000..80af8114c92
--- /dev/null
+++ b/src/mame/drivers/rc2014.cpp
@@ -0,0 +1,188 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/**************************************************************************************
+
+ RC2014 Modular Computer
+
+**************************************************************************************/
+
+#include "emu.h"
+#include "bus/rc2014/rc2014.h"
+#include "bus/rc2014/modules.h"
+
+namespace {
+
+class rc2014_state : public driver_device
+{
+public:
+ rc2014_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_rc2014_bus(*this, "bus")
+ { }
+
+ //
+ // RC2014 Classic
+ //
+ // Z80 CPU module
+ // Clock/Reset
+ // 32K RAM module
+ // Switchable ROM module
+ // Serial I/O
+ //
+ // Backplane-5 - 5 x 40pin slots
+ //
+ void rc2014(machine_config &config)
+ {
+ RC2014_BUS(config, m_rc2014_bus, 0);
+ RC2014_SLOT(config, "bus:1", m_rc2014_bus, rc2014_bus_modules, "z80");
+ RC2014_SLOT(config, "bus:2", m_rc2014_bus, rc2014_bus_modules, "clock");
+ RC2014_SLOT(config, "bus:3", m_rc2014_bus, rc2014_bus_modules, "ram32k");
+ RC2014_SLOT(config, "bus:4", m_rc2014_bus, rc2014_bus_modules, "sw_rom");
+ RC2014_SLOT(config, "bus:5", m_rc2014_bus, rc2014_bus_modules, "serial");
+ }
+
+ //
+ // RC2014 Classic II
+ //
+ // Clock/Reset
+ // Z80 CPU module
+ // 32K RAM module
+ // Switchable ROM module
+ // Serial I/O
+ //
+ // Backplane-8 - 8 x 40pin slots
+ //
+ // all modules are in slightly different form factor
+ //
+ void rc2014cl2(machine_config &config)
+ {
+ RC2014_BUS(config, m_rc2014_bus, 0);
+ RC2014_SLOT(config, "bus:1", m_rc2014_bus, rc2014_bus_modules, "z80");
+ RC2014_SLOT(config, "bus:2", m_rc2014_bus, rc2014_bus_modules, "clock");
+ RC2014_SLOT(config, "bus:3", m_rc2014_bus, rc2014_bus_modules, "ram32k");
+ RC2014_SLOT(config, "bus:4", m_rc2014_bus, rc2014_bus_modules, "sw_rom");
+ RC2014_SLOT(config, "bus:5", m_rc2014_bus, rc2014_bus_modules, "serial");
+ RC2014_SLOT(config, "bus:6", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ RC2014_SLOT(config, "bus:7", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ RC2014_SLOT(config, "bus:8", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ }
+
+
+ //
+ // RC2014 Zed
+ //
+ // Z80 2.1 CPU Module
+ // Dual Clock Module
+ // 512k ROM 512k RAM Module
+ // Dual Serial SIO/2 Module
+ //
+ // Backplane 8 - 8 x 40pin slots
+ //
+ // Some modules are extended bus modules in standard slots
+ //
+ void rc2014zed(machine_config &config)
+ {
+ RC2014_BUS(config, m_rc2014_bus, 0);
+ RC2014_SLOT(config, "bus:1", m_rc2014_bus, rc2014_bus_modules, "z80_21_40p");
+ RC2014_SLOT(config, "bus:2", m_rc2014_bus, rc2014_bus_modules, "dual_clk_40p");
+ RC2014_SLOT(config, "bus:3", m_rc2014_bus, rc2014_bus_modules, "rom_ram");
+ RC2014_SLOT(config, "bus:4", m_rc2014_bus, rc2014_bus_modules, "sio_40p");
+ RC2014_SLOT(config, "bus:5", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ RC2014_SLOT(config, "bus:6", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ RC2014_SLOT(config, "bus:7", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ RC2014_SLOT(config, "bus:8", m_rc2014_bus, rc2014_bus_modules, nullptr);
+ }
+
+private:
+ required_device<rc2014_bus_device> m_rc2014_bus;
+};
+
+ROM_START(rc2014)
+ROM_END
+ROM_START(rc2014cl2)
+ROM_END
+ROM_START(rc2014zed)
+ROM_END
+
+class rc2014pro_state : public driver_device
+{
+public:
+ rc2014pro_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_rc2014_bus(*this, "bus")
+ { }
+
+ //
+ // RC2014 PRo
+ //
+ // Z80 2.1 CPU Module
+ // Dual Clock Module
+ // 64k RAM
+ // Pageable ROM
+ // Dual Serial SIO/2 Module
+ // Compact Flash storage
+ //
+ // Backplane Pro - 12 x extended slots
+ //
+ void rc2014pro(machine_config &config)
+ {
+ RC2014_EXT_BUS(config, m_rc2014_bus, 0);
+ RC2014_EXT_SLOT(config, "bus:1", m_rc2014_bus, rc2014_ext_bus_modules, "z80_21");
+ RC2014_EXT_SLOT(config, "bus:2", m_rc2014_bus, rc2014_ext_bus_modules, "dual_clk");
+ RC2014_EXT_SLOT(config, "bus:3", m_rc2014_bus, rc2014_ext_bus_modules, "ram64k");
+ RC2014_EXT_SLOT(config, "bus:4", m_rc2014_bus, rc2014_ext_bus_modules, "page_rom");
+ RC2014_EXT_SLOT(config, "bus:5", m_rc2014_bus, rc2014_ext_bus_modules, "sio");
+ RC2014_EXT_SLOT(config, "bus:6", m_rc2014_bus, rc2014_ext_bus_modules, "cf");
+ RC2014_EXT_SLOT(config, "bus:7", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:8", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:9", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:10", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:11", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:12", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ }
+
+ //
+ // RC2014 Zed
+ //
+ // Z80 2.1 CPU Module
+ // Dual Clock Module
+ // 512k ROM 512k RAM Module
+ // Dual Serial SIO/2 Module
+ //
+ // Backplane Pro - 12 x extended slots
+ //
+ void rc2014zedp(machine_config &config)
+ {
+ RC2014_EXT_BUS(config, m_rc2014_bus, 0);
+ RC2014_EXT_SLOT(config, "bus:1", m_rc2014_bus, rc2014_ext_bus_modules, "z80_21");
+ RC2014_EXT_SLOT(config, "bus:2", m_rc2014_bus, rc2014_ext_bus_modules, "dual_clk");
+ RC2014_EXT_SLOT(config, "bus:3", m_rc2014_bus, rc2014_ext_bus_modules, "rom_ram");
+ RC2014_EXT_SLOT(config, "bus:4", m_rc2014_bus, rc2014_ext_bus_modules, "sio");
+ RC2014_EXT_SLOT(config, "bus:5", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:6", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:7", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:8", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:9", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:10", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:11", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ RC2014_EXT_SLOT(config, "bus:12", m_rc2014_bus, rc2014_ext_bus_modules, nullptr);
+ }
+private:
+ required_device<rc2014_ext_bus_device> m_rc2014_bus;
+};
+
+ROM_START(rc2014pro)
+ROM_END
+
+ROM_START(rc2014zedp)
+ROM_END
+
+} // anonymous namespace
+
+// This ties everything together
+// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
+COMP( 2016, rc2014, 0, 0, rc2014, 0, rc2014_state, empty_init, "RFC2795 Ltd", "RC2014 Classic", MACHINE_SUPPORTS_SAVE )
+COMP( 2017, rc2014pro, rc2014, 0, rc2014pro, 0, rc2014pro_state, empty_init, "RFC2795 Ltd", "RC2014 Pro", MACHINE_SUPPORTS_SAVE )
+COMP( 2020, rc2014cl2, rc2014, 0, rc2014cl2, 0, rc2014_state, empty_init, "RFC2795 Ltd", "RC2014 Classic II", MACHINE_SUPPORTS_SAVE )
+COMP( 2018, rc2014zed , rc2014, 0, rc2014zed ,0, rc2014_state, empty_init, "RFC2795 Ltd", "RC2014 Zed", MACHINE_SUPPORTS_SAVE )
+COMP( 2018, rc2014zedp, rc2014, 0, rc2014zedp,0, rc2014pro_state, empty_init, "RFC2795 Ltd", "RC2014 Zed Pro", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index a4cfc4462a6..364c9c827d8 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -44557,3 +44557,10 @@ gs6809 // Grant Searle's Simple 6809 Machine
@source:ultim809.cpp
ultim809
+
+@source:rc2014.cpp
+rc2014 // RC2014 Classic
+rc2014pro // RC2014 Pro
+rc2014cl2 // RC2014 Classic II
+rc2014zed // RC2014 Zed
+rc2014zedp // RC2014 Zed Pro
diff --git a/src/mame/mess.flt b/src/mame/mess.flt
index 76456ecece3..30bfc685e68 100644
--- a/src/mame/mess.flt
+++ b/src/mame/mess.flt
@@ -878,6 +878,7 @@ radionic.cpp
rainbow.cpp
rambo.cpp
ravens.cpp
+rc2014.cpp
rc702.cpp
rc759.cpp
rd100.cpp