From 4143172f7cec26b32db0146e385717e041ff0711 Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Fri, 26 Jan 2018 19:28:41 +0000 Subject: electron: Re-implemented cartridge slot device, and added cartridge devices: - Standard cartridge (2x16K ROM) - Advanced Battery-Backed RAM (ABR) - Slogger Click - Slogger Pegasus 400 --- scripts/src/bus.lua | 21 +++ scripts/target/mame/mess.lua | 1 + src/devices/bus/electron/cart/abr.cpp | 96 +++++++++++ src/devices/bus/electron/cart/abr.h | 45 +++++ src/devices/bus/electron/cart/click.cpp | 171 +++++++++++++++++++ src/devices/bus/electron/cart/click.h | 58 +++++++ src/devices/bus/electron/cart/peg400.cpp | 178 +++++++++++++++++++ src/devices/bus/electron/cart/peg400.h | 57 +++++++ src/devices/bus/electron/cart/slot.cpp | 284 +++++++++++++++++++++++++++++++ src/devices/bus/electron/cart/slot.h | 221 ++++++++++++++++++++++++ src/devices/bus/electron/cart/std.cpp | 56 ++++++ src/devices/bus/electron/cart/std.h | 40 +++++ src/devices/bus/electron/exp.cpp | 4 - src/devices/bus/electron/plus1.cpp | 126 +++++++------- src/devices/bus/electron/plus1.h | 13 +- src/devices/bus/electron/plus3.cpp | 2 +- src/devices/bus/electron/rombox.cpp | 8 +- src/devices/bus/electron/romboxp.cpp | 132 +++++++------- src/devices/bus/electron/romboxp.h | 11 +- src/mame/includes/electron.h | 2 + src/mame/machine/electron.cpp | 12 +- 21 files changed, 1397 insertions(+), 141 deletions(-) create mode 100644 src/devices/bus/electron/cart/abr.cpp create mode 100644 src/devices/bus/electron/cart/abr.h create mode 100644 src/devices/bus/electron/cart/click.cpp create mode 100644 src/devices/bus/electron/cart/click.h create mode 100644 src/devices/bus/electron/cart/peg400.cpp create mode 100644 src/devices/bus/electron/cart/peg400.h create mode 100644 src/devices/bus/electron/cart/slot.cpp create mode 100644 src/devices/bus/electron/cart/slot.h create mode 100644 src/devices/bus/electron/cart/std.cpp create mode 100644 src/devices/bus/electron/cart/std.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index ae488168330..804db83c2d1 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -738,6 +738,27 @@ if (BUSES["ELECTRON"]~=null) then end +--------------------------------------------------- +-- +--@src/devices/bus/electron/cart/slot.h,BUSES["ELECTRON_CART"] = true +--------------------------------------------------- + +if (BUSES["ELECTRON_CART"]~=null) then + files { + MAME_DIR .. "src/devices/bus/electron/cart/slot.cpp", + MAME_DIR .. "src/devices/bus/electron/cart/slot.h", + MAME_DIR .. "src/devices/bus/electron/cart/abr.cpp", + MAME_DIR .. "src/devices/bus/electron/cart/abr.h", + MAME_DIR .. "src/devices/bus/electron/cart/click.cpp", + MAME_DIR .. "src/devices/bus/electron/cart/click.h", + MAME_DIR .. "src/devices/bus/electron/cart/peg400.cpp", + MAME_DIR .. "src/devices/bus/electron/cart/peg400.h", + MAME_DIR .. "src/devices/bus/electron/cart/std.cpp", + MAME_DIR .. "src/devices/bus/electron/cart/std.h", + } +end + + --------------------------------------------------- -- --@src/devices/bus/ep64/exp.h,BUSES["EP64"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index dd08d15198f..8dd090657ae 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -671,6 +671,7 @@ BUSES["ECBBUS"] = true BUSES["ECONET"] = true BUSES["EINSTEIN_USERPORT"] = true BUSES["ELECTRON"] = true +BUSES["ELECTRON_CART"] = true BUSES["EP64"] = true BUSES["EPSON_SIO"] = true BUSES["GAMATE"] = true diff --git a/src/devices/bus/electron/cart/abr.cpp b/src/devices/bus/electron/cart/abr.cpp new file mode 100644 index 00000000000..6f7354451af --- /dev/null +++ b/src/devices/bus/electron/cart/abr.cpp @@ -0,0 +1,96 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Advanced Battery-Backed RAM + +***************************************************************************/ + +#include "emu.h" +#include "abr.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_ABR, electron_abr_device, "electron_abr", "Electron Advanced Battery-Backed RAM cartridge") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_abr_device - constructor +//------------------------------------------------- + +electron_abr_device::electron_abr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ELECTRON_ABR, tag, owner, clock) + , device_electron_cart_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_abr_device::device_start() +{ + m_bank_locked[0] = false; + m_bank_locked[1] = false; +} + + +//------------------------------------------------- +// read - cartridge data read +//------------------------------------------------- + +uint8_t electron_abr_device::read(address_space &space, offs_t offset, int infc, int infd, int romqa) +{ + uint8_t data = 0xff; + + if (!infc && !infd) + { + if (offset >= 0x0000 && offset < 0x4000) + { + data = m_nvram[(offset & 0x3fff) + (romqa * 0x4000)]; + } + } + + return data; +} + +//------------------------------------------------- +// write - cartridge data write +//------------------------------------------------- + +void electron_abr_device::write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) +{ + if (infc) + { + switch (offset & 0xff) + { + case 0xdc: + m_bank_locked[0] = false; + break; + case 0xdd: + m_bank_locked[0] = true; + break; + case 0xde: + m_bank_locked[1] = false; + break; + case 0xdf: + m_bank_locked[1] = true; + break; + } + } + + if (!infc && !infd) + { + if (offset >= 0x0000 && offset < 0x4000 && !m_bank_locked[romqa]) + { + m_nvram[(offset & 0x3fff) + (romqa * 0x4000)] = data; + } + } +} diff --git a/src/devices/bus/electron/cart/abr.h b/src/devices/bus/electron/cart/abr.h new file mode 100644 index 00000000000..b985db0a44d --- /dev/null +++ b/src/devices/bus/electron/cart/abr.h @@ -0,0 +1,45 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Advanced Battery-Backed RAM + +***************************************************************************/ + +#ifndef MAME_BUS_ELECTRON_CART_ABR_H +#define MAME_BUS_ELECTRON_CART_ABR_H + +#pragma once + +#include "slot.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> electron_abr_device + +class electron_abr_device : public device_t, + public device_electron_cart_interface +{ +public: + // construction/destruction + electron_abr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // electron_cart_interface overrides + virtual uint8_t read(address_space &space, offs_t offset, int infc, int infd, int romqa) override; + virtual void write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) override; + +private: + bool m_bank_locked[2]; +}; + +// device type definition +DECLARE_DEVICE_TYPE(ELECTRON_ABR, electron_abr_device) + +#endif // MAME_BUS_ELECTRON_CART_ABR_H diff --git a/src/devices/bus/electron/cart/click.cpp b/src/devices/bus/electron/cart/click.cpp new file mode 100644 index 00000000000..73be4739b04 --- /dev/null +++ b/src/devices/bus/electron/cart/click.cpp @@ -0,0 +1,171 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Slogger Click cartridge emulation + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Slogger_Click.html + +***************************************************************************/ + +#include "emu.h" +#include "click.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_CLICK, electron_click_device, "electron_click", "Slogger Click cartridge") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_START(electron_click_device::device_add_mconfig) + /* rtc */ + MCFG_MC146818_ADD("rtc", 32.768_kHz_XTAL) + MCFG_MC146818_IRQ_HANDLER(WRITELINE(electron_click_device, irq_w)) +MACHINE_CONFIG_END + +//------------------------------------------------- +// INPUT_PORTS( click ) +//------------------------------------------------- + +INPUT_PORTS_START(click) + PORT_START("BUTTON") + PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON1) PORT_NAME("Click") PORT_CODE(KEYCODE_HOME) PORT_CHANGED_MEMBER(DEVICE_SELF, electron_click_device, click_button, nullptr) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor electron_click_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(click); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_click_device - constructor +//------------------------------------------------- + +electron_click_device::electron_click_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ELECTRON_CLICK, tag, owner, clock) + , device_electron_cart_interface(mconfig, *this) + , m_rtc(*this, "rtc") + , m_page_register(0) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_click_device::device_start() +{ +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void electron_click_device::device_reset() +{ + m_page_register = 0; +} + + +//------------------------------------------------- +// read - cartridge data read +//------------------------------------------------- + +uint8_t electron_click_device::read(address_space &space, offs_t offset, int infc, int infd, int romqa) +{ + uint8_t data = 0xff; + + if (infc) + { + switch (offset & 0xff) + { + case 0xf8: + case 0xf9: + data = m_rtc->read(space, offset & 0x01); + break; + case 0xfc: + data = m_page_register; + break; + } + } + + if (!infc && !infd) + { + offs_t rom_page_offset = (m_page_register & 0x03) * 0x2000; + offs_t ram_page_offset = ((m_page_register & 0x0c) >> 2) * 0x2000; + + if (offset >= 0x0000 && offset < 0x2000) + { + data = m_rom[rom_page_offset + (offset & 0x1fff)]; + } + else if (offset >= 0x2000 && offset < 0x4000) + { + data = m_nvram[ram_page_offset + (offset & 0x1fff)]; + } + } + + return data; +} + +//------------------------------------------------- +// write - cartridge data write +//------------------------------------------------- + +void electron_click_device::write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) +{ + if (infc) + { + switch (offset & 0xff) + { + case 0xf8: + case 0xf9: + m_rtc->write(space, offset & 0x01, data); + break; + case 0xfc: + m_page_register = data; + break; + } + } + + if (!infc && !infd) + { + offs_t ram_page_offset = ((m_page_register & 0x0c) >> 2) * 0x2000; + + if (offset >= 0x2000 && offset < 0x4000) + { + m_nvram[ram_page_offset + (offset & 0x1fff)] = data; + } + } +} + +INPUT_CHANGED_MEMBER(electron_click_device::click_button) +{ + if (newval && !oldval) + { + m_slot->irq_w(ASSERT_LINE); + } + else + { + m_slot->irq_w(CLEAR_LINE); + } +} + +WRITE_LINE_MEMBER(electron_click_device::irq_w) +{ + m_slot->irq_w(state); +} diff --git a/src/devices/bus/electron/cart/click.h b/src/devices/bus/electron/cart/click.h new file mode 100644 index 00000000000..5fbc18d4759 --- /dev/null +++ b/src/devices/bus/electron/cart/click.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Slogger Click cartridge emulation + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Slogger_Click.html + +***************************************************************************/ + +#ifndef MAME_BUS_ELECTRON_CART_CLICK_H +#define MAME_BUS_ELECTRON_CART_CLICK_H + +#pragma once + +#include "slot.h" +#include "machine/mc146818.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> electron_click_device + +class electron_click_device : public device_t, + public device_electron_cart_interface +{ +public: + // construction/destruction + electron_click_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + DECLARE_INPUT_CHANGED_MEMBER(click_button); + +protected: + // device-level overrides + virtual void device_add_mconfig(machine_config &config) override; + virtual ioport_constructor device_input_ports() const override; + + virtual void device_start() override; + virtual void device_reset() override; + + // electron_cart_interface overrides + virtual uint8_t read(address_space &space, offs_t offset, int infc, int infd, int romqa) override; + virtual void write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) override; + +private: + DECLARE_WRITE_LINE_MEMBER(irq_w); + + required_device m_rtc; + + uint8_t m_page_register; +}; + +// device type definition +DECLARE_DEVICE_TYPE(ELECTRON_CLICK, electron_click_device) + +#endif // MAME_BUS_ELECTRON_CART_CLICK_H diff --git a/src/devices/bus/electron/cart/peg400.cpp b/src/devices/bus/electron/cart/peg400.cpp new file mode 100644 index 00000000000..a6f3398ff33 --- /dev/null +++ b/src/devices/bus/electron/cart/peg400.cpp @@ -0,0 +1,178 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Slogger Pegasus 400 disk interface + +**********************************************************************/ + + +#include "emu.h" +#include "peg400.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_PEG400, electron_peg400_device, "electron_peg400", "Slogger Pegasus 400 disk interface") + + +//------------------------------------------------- +// MACHINE_DRIVER( peg400 ) +//------------------------------------------------- + +FLOPPY_FORMATS_MEMBER(electron_peg400_device::floppy_formats) + FLOPPY_ACORN_SSD_FORMAT, + FLOPPY_ACORN_DSD_FORMAT, + FLOPPY_ACORN_ADFS_OLD_FORMAT +FLOPPY_FORMATS_END0 + +SLOT_INTERFACE_START(peg400_floppies) + SLOT_INTERFACE("35dd", FLOPPY_35_DD) + SLOT_INTERFACE("525qd", FLOPPY_525_QD) +SLOT_INTERFACE_END + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +MACHINE_CONFIG_START(electron_peg400_device::device_add_mconfig) + /* fdc */ + MCFG_WD1770_ADD("fdc", 16_MHz_XTAL / 2) + MCFG_WD_FDC_DRQ_CALLBACK(WRITELINE(electron_peg400_device, fdc_drq_w)) + MCFG_FLOPPY_DRIVE_ADD("fdc:0", peg400_floppies, "525qd", electron_peg400_device::floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) + MCFG_FLOPPY_DRIVE_ADD("fdc:1", peg400_floppies, nullptr, electron_peg400_device::floppy_formats) + MCFG_FLOPPY_DRIVE_SOUND(true) +MACHINE_CONFIG_END + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_peg400_device - constructor +//------------------------------------------------- + +electron_peg400_device::electron_peg400_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ELECTRON_PEG400, tag, owner, clock) + , device_electron_cart_interface(mconfig, *this) + , m_fdc(*this, "fdc") + , m_floppy0(*this, "fdc:0") + , m_floppy1(*this, "fdc:1") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_peg400_device::device_start() +{ +} + +//------------------------------------------------- +// read - cartridge data read +//------------------------------------------------- + +uint8_t electron_peg400_device::read(address_space &space, offs_t offset, int infc, int infd, int romqa) +{ + uint8_t data = 0xff; + + if (infc) + { + switch (offset & 0xff) + { + case 0xc0: + data = m_drive_control; + break; + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + data = m_fdc->read(space, offset & 0x03); + break; + } + } + + if (!infc && !infd) + { + if (offset >= 0x0000 && offset < 0x4000) + { + data = m_rom[(offset & 0x3fff) + (romqa * 0x4000)]; + } + + if (romqa == 0 && offset >= 0x3800 && offset < 0x4000) + { + data = m_ram[offset & 0x07ff]; + } + } + + return data; +} + +//------------------------------------------------- +// write - cartridge data write +//------------------------------------------------- + +void electron_peg400_device::write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) +{ + if (infc) + { + switch (offset & 0xff) + { + case 0xc0: + wd1770_control_w(space, 0, data); + break; + case 0xc4: + case 0xc5: + case 0xc6: + case 0xc7: + m_fdc->write(space, offset & 0x03, data); + break; + } + } + + if (!infc && !infd) + { + if (offset >= 0x3800 && offset < 0x4000) + { + m_ram[offset & 0x07ff] = data; + } + } +} + + +//************************************************************************** +// IMPLEMENTATION +//************************************************************************** + +WRITE8_MEMBER(electron_peg400_device::wd1770_control_w) +{ + floppy_image_device *floppy = nullptr; + + m_drive_control = data; + + // bit 0, 1: drive select + if (BIT(data, 0)) floppy = m_floppy0->get_device(); + if (BIT(data, 1)) floppy = m_floppy1->get_device(); + m_fdc->set_floppy(floppy); + + // bit 2: side select + if (floppy) + floppy->ss_w(BIT(data, 2)); + + // bit 3: density + m_fdc->dden_w(BIT(data, 3)); + + // bit 4: send DRQ to NMI signal + m_fdc_ie = BIT(data, 4); + + // bit 5: head load +} + +WRITE_LINE_MEMBER(electron_peg400_device::fdc_drq_w) +{ + m_slot->nmi_w((state && m_fdc_ie) ? ASSERT_LINE : CLEAR_LINE); +} diff --git a/src/devices/bus/electron/cart/peg400.h b/src/devices/bus/electron/cart/peg400.h new file mode 100644 index 00000000000..e85aaa232b4 --- /dev/null +++ b/src/devices/bus/electron/cart/peg400.h @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Slogger Pegasus 400 disk interface + +**********************************************************************/ + +#ifndef MAME_BUS_ELECTRON_CART_PEG400_H +#define MAME_BUS_ELECTRON_CART_PEG400_H + +#include "slot.h" +#include "machine/wd_fdc.h" +#include "formats/acorn_dsk.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class electron_peg400_device : + public device_t, + public device_electron_cart_interface +{ +public: + // construction/destruction + electron_peg400_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; + + // electron_cart_interface overrides + virtual uint8_t read(address_space &space, offs_t offset, int infc, int infd, int romqa) override; + virtual void write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) override; + +private: + DECLARE_WRITE8_MEMBER(wd1770_control_w); + DECLARE_FLOPPY_FORMATS(floppy_formats); + DECLARE_WRITE_LINE_MEMBER(fdc_drq_w); + + required_device m_fdc; + required_device m_floppy0; + optional_device m_floppy1; + + int m_drive_control; + int m_fdc_ie; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(ELECTRON_PEG400, electron_peg400_device) + + +#endif // MAME_BUS_ELECTRON_CART_PEG400_H diff --git a/src/devices/bus/electron/cart/slot.cpp b/src/devices/bus/electron/cart/slot.cpp new file mode 100644 index 00000000000..49791c92ce6 --- /dev/null +++ b/src/devices/bus/electron/cart/slot.cpp @@ -0,0 +1,284 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*********************************************************************************************************** + + Electron Cartridge slot emulation + + ***********************************************************************************************************/ + + +#include "emu.h" +#include "slot.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_CARTSLOT, electron_cartslot_device, "electron_cartslot", "Electron Cartridge Slot") + + +//************************************************************************** +// DEVICE ELECTRON_CARTSLOT CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_electron_cart_interface - constructor +//------------------------------------------------- + +device_electron_cart_interface::device_electron_cart_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device), + m_rom(nullptr), + m_rom_size(0) +{ + m_slot = dynamic_cast(device.owner()); +} + + +//------------------------------------------------- +// ~device_electron_cart_interface - destructor +//------------------------------------------------- + +device_electron_cart_interface::~device_electron_cart_interface() +{ +} + +//------------------------------------------------- +// rom_alloc - alloc the space for the cart +//------------------------------------------------- + +void device_electron_cart_interface::rom_alloc(uint32_t size, const char *tag) +{ + if (m_rom == nullptr) + { + if (size <= 0x8000) + { + m_rom = device().machine().memory().region_alloc(std::string(tag).append(ELECTRON_CART_ROM_REGION_TAG).c_str(), 0x8000, 1, ENDIANNESS_LITTLE)->base(); + m_rom_size = 0x8000; + } + else + { + m_rom = device().machine().memory().region_alloc(std::string(tag).append(ELECTRON_CART_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base(); + m_rom_size = size; + } + } +} + +//------------------------------------------------- +// ram_alloc - alloc the space for the on-cart RAM +//------------------------------------------------- + +void device_electron_cart_interface::ram_alloc(uint32_t size) +{ + m_ram.resize(size); +} + +//------------------------------------------------- +// ram_alloc - alloc the space for the on-cart RAM +//------------------------------------------------- + +void device_electron_cart_interface::nvram_alloc(uint32_t size) +{ + m_nvram.resize(size); +} + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_cartslot_device - constructor +//------------------------------------------------- +electron_cartslot_device::electron_cartslot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, ELECTRON_CARTSLOT, tag, owner, clock), + device_image_interface(mconfig, *this), + device_slot_interface(mconfig, *this), + m_cart(nullptr), + m_irq_handler(*this), + m_nmi_handler(*this) +{ +} + +//------------------------------------------------- +// electron_cartslot_device - destructor +//------------------------------------------------- + +electron_cartslot_device::~electron_cartslot_device() +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_cartslot_device::device_start() +{ + m_cart = dynamic_cast(get_card_device()); + + // resolve callbacks + m_irq_handler.resolve_safe(); + m_nmi_handler.resolve_safe(); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void electron_cartslot_device::device_reset() +{ +} + + +//------------------------------------------------- +// call load +//------------------------------------------------- + +image_init_result electron_cartslot_device::call_load() +{ + if (m_cart) + { + if (!loaded_through_softlist()) + { + uint32_t size = length(); + + if (size % 0x2000) + { + seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + return image_init_result::FAIL; + } + + m_cart->rom_alloc(size, tag()); + fread(m_cart->get_rom_base(), size); + } + else + { + // standard 2x16K ROMs cartridges + uint32_t upsize = get_software_region_length("uprom"); + uint32_t losize = get_software_region_length("lorom"); + + // other RAM/ROM device cartridges + uint32_t romsize = get_software_region_length("rom"); + uint32_t ramsize = get_software_region_length("ram"); + uint32_t nvramsize = get_software_region_length("nvram"); + + if ((upsize % 0x2000 && upsize != 0) || (losize % 0x2000 && losize != 0) || (romsize % 0x2000 && romsize != 0)) + { + seterror(IMAGE_ERROR_UNSPECIFIED, "Unsupported cartridge size"); + return image_init_result::FAIL; + } + + // load standard 2x16K ROM cartridges + if (losize != 0 || upsize != 0) + { + m_cart->rom_alloc(0x8000, tag()); + if (losize) + memcpy(m_cart->get_rom_base() + 0x0000, get_software_region("lorom"), losize); + if (upsize) + memcpy(m_cart->get_rom_base() + 0x4000, get_software_region("uprom"), upsize); + } + + // load ROM region of device cartridge + if (romsize != 0) + { + m_cart->rom_alloc(romsize, tag()); + memcpy(m_cart->get_rom_base(), get_software_region("rom"), romsize); + } + + // load RAM region of device cartridge + if (ramsize != 0) + { + m_cart->ram_alloc(ramsize); + memcpy(m_cart->get_ram_base(), get_software_region("ram"), ramsize); + } + + // load NVRAM region of device cartridge + if (nvramsize != 0) + { + std::vector default_nvram(nvramsize); + memcpy(&default_nvram[0], get_software_region("nvram"), nvramsize); + + // load NVRAM (using default if no NVRAM exists) + std::vector temp_nvram(nvramsize); + battery_load(&temp_nvram[0], nvramsize, &default_nvram[0]); + + // copy NVRAM into cartridge + m_cart->nvram_alloc(nvramsize); + memcpy(m_cart->get_nvram_base(), &temp_nvram[0], nvramsize); + } + } + } + + return image_init_result::PASS; +} + + +//------------------------------------------------- +// call_unload +//------------------------------------------------- + +void electron_cartslot_device::call_unload() +{ + if (m_cart && m_cart->get_nvram_base() && m_cart->get_nvram_size()) + battery_save(m_cart->get_nvram_base(), m_cart->get_nvram_size()); +} + + +//------------------------------------------------- +// get default card software +//------------------------------------------------- + +std::string electron_cartslot_device::get_default_card_software(get_default_card_software_hook &hook) const +{ + return software_get_default_slot("std"); +} + + +//------------------------------------------------- +// read - cartridge read +//------------------------------------------------- + +uint8_t electron_cartslot_device::read(address_space &space, offs_t offset, int infc, int infd, int romqa) +{ + uint8_t data = 0xff; + + if (m_cart != nullptr) + { + data = m_cart->read(space, offset, infc, infd, romqa); + } + + return data; +} + +//------------------------------------------------- +// write - cartridge write +//------------------------------------------------- + +void electron_cartslot_device::write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) +{ + if (m_cart != nullptr) + { + m_cart->write(space, offset, data, infc, infd, romqa); + } +} + + +//------------------------------------------------- +// SLOT_INTERFACE( electron_cart ) +//------------------------------------------------- + +#include "abr.h" +//#include "ap34.h" +#include "click.h" +//#include "cumana.h" +#include "peg400.h" +#include "std.h" + + +SLOT_INTERFACE_START(electron_cart) + SLOT_INTERFACE_INTERNAL("std", ELECTRON_STDCART) + SLOT_INTERFACE_INTERNAL("abr", ELECTRON_ABR) + //SLOT_INTERFACE_INTERNAL("ap34", ELECTRON_AP34) + SLOT_INTERFACE_INTERNAL("click", ELECTRON_CLICK) + //SLOT_INTERFACE_INTERNAL("cumana", ELECTRON_CUMANA) + SLOT_INTERFACE_INTERNAL("peg400", ELECTRON_PEG400) +SLOT_INTERFACE_END \ No newline at end of file diff --git a/src/devices/bus/electron/cart/slot.h b/src/devices/bus/electron/cart/slot.h new file mode 100644 index 00000000000..06d573ccbd1 --- /dev/null +++ b/src/devices/bus/electron/cart/slot.h @@ -0,0 +1,221 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************** + + Electron Cartridge slot emulation + +********************************************************************** + + Pinout: + A B + +5V 1 1 +5 + nOE 2 2 A10 + nRST 3 3 D3 + RW 4 4 A11 + A8 5 5 A9 + A13 6 6 D7 + A12 7 7 D6 + PHI2 8 8 D5 + -5V 9 9 D4 + NC 10 10 nOE2 + READY 11 11 BA7 + nNMI 12 12 BA6 + nIRQ 13 13 BA5 + nINFC 14 14 BA4 + nINFD 15 15 BA3 + ROMQA 16 16 BA2 + 16MHz 17 17 BA1 + nROMSTB 18 18 BA0 + ADOUT 19 19 D0 + AGND 20 20 D2 + NC 21 21 D1 + 0V 22 22 0V + + Signal Definitions: + + SIDE 'A' + 1 +5V - Power supply. This is the system logic supply rail. + 2 n0E - Output Enable : Input with CMOS levels. This is an active low signal during the PH12 + period of the system clock. + 3 nRST - System Reset : Input with CMOS levels. This signal is active low during system reset. + 4 RW - Read/Write : Input with CMOS levels. This pin is the CPU read/write line. + 5 A8 - Address line 8 : Input with TTL levels + 6 A13 - Address line 13 : Input with TTL levels + 7 A12 - Address line 12 : Input with TTL levels + 8 PH12 - CPU clock : Input with CMOS levels + This input is the host computer PH12out. + 9 -5V - The negative supply voltage. + 10 NC - This is a "no connect" on the Electron. + 11 READY - CPU wait state control : Open collector output + 12 nNMI - Non maskable interrupt : Open collector output + This signal is connected to the system NMI line. It is active low. + 13 nIRQ - Interrupt request : Open collector output + This signal is connected to the system IRQ line. It is active low. + 14 nINFC - Internal Page &FC : Memory active decode input : TTL active low + 15 nINFD - Internal page &FD : Memory active decode input : TTL active low + 16 ROMQA - Memory paging select : Input with TTL levels + This is the least significant bit of the ROM select latch located at &FE05 in the Electron. + 17 Clock - Clock is a 16MHz input with TTL levels. + 18 nROMSTB - nROMSTB is an active low input using TTL levels which selects the location &FC73. + This is intended to be used as a paging register. + 19 ADOUT - System audio output + 20 AGND - Audio Ground + 21 ADIN - Cartridge audio output + 22 0V - Zero volts + + SIDE 'B' + 1 +5V - Power supply. This is the system logic supply rail. + 2 A10 - Address line 10 : Input with TTL levels + 3 D3 - Data bus line 3 : Input/Output with TTL levels + 4 A11 - Address line 11 : Input with TTL levels + 5 A9 - Address line 9 : Input with TTL levels + 6 D7 - Most significant data bus line : Input/Output with TTL levels + 7 D6 - Data bus line 6 : Input/Output with TTL levels + 8 D5 - Data bus line 5 : Input/Output with TTL levels + 9 D4 - Data bus line 4 : Input/Output with TTL levels + 10 nOE2 - Output Enable : Input with TTL levels + This line provides an additional active low output enable for ROMs in the Electron. + This corresponds to ROM position 13 and consequently responds quickly to service + calls. It is low during the active low portion of PH12. + 11 BA7 - Buffered address line 7 : Input with TTL levels + 12 BA6 - Buffered address line 6 : Input with TTL levels + 13 BA5 - Buffered address line 5 : Input with TTL levels + 14 BA4 - Buffered address line 4 : Input with TTL levels + 15 BA3 - Buffered address line 3 : Input with TTL levels + 16 BA2 - Buffered address line 2 : Input with TTL levels + 17 BA1 - Buffered address line 1 : Input with TTL levels + 18 BA0 - Buffered address line 0 : Input with TTL levels + 19 D0 - Data bus line 0 : Input/Output with TTL levels + 20 D2 - Data bus line 2 : Input/Output with TTL levels + 21 D1 - Data bus line 1 : Input/Output with TTL levels + 22 0V - Zero volts. + +**********************************************************************/ +#ifndef MAME_BUS_ELECTRON_CARTSLOT_H +#define MAME_BUS_ELECTRON_CARTSLOT_H + +#pragma once + +#include "softlist_dev.h" + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define ELECTRON_CART_ROM_REGION_TAG ":cart:rom" + +#define MCFG_ELECTRON_CARTSLOT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, ELECTRON_CARTSLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + +#define MCFG_ELECTRON_CARTSLOT_IRQ_HANDLER(_devcb) \ + devcb = &electron_cartslot_device::set_irq_handler(*device, DEVCB_##_devcb); + +#define MCFG_ELECTRON_CARTSLOT_NMI_HANDLER(_devcb) \ + devcb = &electron_cartslot_device::set_nmi_handler(*device, DEVCB_##_devcb); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> electron_cartslot_device + +class device_electron_cart_interface; + +class electron_cartslot_device : public device_t, + public device_image_interface, + public device_slot_interface +{ +public: + // construction/destruction + electron_cartslot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~electron_cartslot_device(); + + // callbacks + template static devcb_base &set_irq_handler(device_t &device, Object &&cb) + { return downcast(device).m_irq_handler.set_callback(std::forward(cb)); } + + template static devcb_base &set_nmi_handler(device_t &device, Object &&cb) + { return downcast(device).m_nmi_handler.set_callback(std::forward(cb)); } + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // image-level overrides + virtual image_init_result call_load() override; + virtual void call_unload() override; + virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); } + + virtual iodevice_t image_type() const override { return IO_CARTSLOT; } + virtual bool is_readable() const override { return true; } + virtual bool is_writeable() const override { return true; } + virtual bool is_creatable() const override { return false; } + virtual bool must_be_loaded() const override { return false; } + virtual bool is_reset_on_load() const override { return true; } + virtual const char *image_interface() const override { return "electron_cart"; } + virtual const char *file_extensions() const override { return "rom,bin"; } + + // slot interface overrides + virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; + + // reading and writing + virtual uint8_t read(address_space &space, offs_t offset, int infc, int infd, int romqa); + virtual void write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa); + + DECLARE_WRITE_LINE_MEMBER(irq_w) { m_irq_handler(state); } + DECLARE_WRITE_LINE_MEMBER(nmi_w) { m_nmi_handler(state); } + +protected: + device_electron_cart_interface *m_cart; + +private: + devcb_write_line m_irq_handler; + devcb_write_line m_nmi_handler; +}; + + +// ======================> device_electron_cart_interface + +class device_electron_cart_interface : public device_slot_card_interface +{ +public: + // construction/destruction + virtual ~device_electron_cart_interface(); + + // reading and writing + virtual uint8_t read(address_space &space, offs_t offset, int infc, int infd, int romqa) { return 0xff; } + virtual void write(address_space &space, offs_t offset, uint8_t data, int infc, int infd, int romqa) { } + + void rom_alloc(uint32_t size, const char *tag); + void ram_alloc(uint32_t size); + void nvram_alloc(uint32_t size); + uint8_t* get_rom_base() { return m_rom; } + uint8_t* get_ram_base() { return &m_ram[0]; } + uint8_t* get_nvram_base() { return &m_nvram[0]; } + uint32_t get_rom_size() { return m_rom_size; } + uint32_t get_ram_size() { return m_ram.size(); } + uint32_t get_nvram_size() { return m_nvram.size(); } + +protected: + device_electron_cart_interface(const machine_config &mconfig, device_t &device); + + electron_cartslot_device *m_slot; + + // internal state + uint8_t *m_rom; + uint32_t m_rom_size; + std::vector m_ram; + std::vector m_nvram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(ELECTRON_CARTSLOT, electron_cartslot_device) + +SLOT_INTERFACE_EXTERN(electron_cart); + + +#endif // MAME_BUS_ELECTRON_CARTSLOT_H diff --git a/src/devices/bus/electron/cart/std.cpp b/src/devices/bus/electron/cart/std.cpp new file mode 100644 index 00000000000..b66e3b2ce0d --- /dev/null +++ b/src/devices/bus/electron/cart/std.cpp @@ -0,0 +1,56 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Acorn Electron standard cartridge emulation + +***************************************************************************/ + +#include "emu.h" +#include "std.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(ELECTRON_STDCART, electron_stdcart_device, "electron_stdcart", "Electron standard cartridge") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// electron_stdcart_device - constructor +//------------------------------------------------- + +electron_stdcart_device::electron_stdcart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, ELECTRON_STDCART, tag, owner, clock) + , device_electron_cart_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void electron_stdcart_device::device_start() +{ +} + +//------------------------------------------------- +// read - cartridge data read +//------------------------------------------------- + +uint8_t electron_stdcart_device::read(address_space &space, offs_t offset, int infc, int infd, int romqa) +{ + uint8_t data = 0xff; + + if (!infc && !infd) + { + data = m_rom[(offset & 0x3fff) + (romqa * 0x4000)]; + } + + return data; +} diff --git a/src/devices/bus/electron/cart/std.h b/src/devices/bus/electron/cart/std.h new file mode 100644 index 00000000000..e81e5684ee2 --- /dev/null +++ b/src/devices/bus/electron/cart/std.h @@ -0,0 +1,40 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Acorn Electron standard cartridge emulation + +***************************************************************************/ + +#ifndef MAME_BUS_ELECTRON_CART_STD_H +#define MAME_BUS_ELECTRON_CART_STD_H + +#pragma once + +#include "slot.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> electron_stdcart_device + +class electron_stdcart_device : public device_t, + public device_electron_cart_interface +{ +public: + // construction/destruction + electron_stdcart_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // electron_cart_interface overrides + virtual uint8_t read(address_space &space, offs_t offset, int infc, int infd, int romqa) override; +}; + +// device type definition +DECLARE_DEVICE_TYPE(ELECTRON_STDCART, electron_stdcart_device) + +#endif // MAME_BUS_ELECTRON_CART_STD_H diff --git a/src/devices/bus/electron/exp.cpp b/src/devices/bus/electron/exp.cpp index 2db692a1257..476eba184ca 100644 --- a/src/devices/bus/electron/exp.cpp +++ b/src/devices/bus/electron/exp.cpp @@ -87,10 +87,6 @@ void electron_expansion_slot_device::device_start() void electron_expansion_slot_device::device_reset() { - if (m_card != nullptr) - { - m_card->device().reset(); - } } //------------------------------------------------- diff --git a/src/devices/bus/electron/plus1.cpp b/src/devices/bus/electron/plus1.cpp index c84f7d5aa66..e7fdfd5f2c8 100644 --- a/src/devices/bus/electron/plus1.cpp +++ b/src/devices/bus/electron/plus1.cpp @@ -105,10 +105,12 @@ MACHINE_CONFIG_START(electron_plus1_device::device_add_mconfig) MCFG_ADC0844_CH4_CB(IOPORT("JOY4")) /* cartridges */ - MCFG_GENERIC_CARTSLOT_ADD("cart_sk1", generic_plain_slot, "electron_cart") - MCFG_GENERIC_LOAD(electron_plus1_device, electron_cart_sk1) - MCFG_GENERIC_CARTSLOT_ADD("cart_sk2", generic_plain_slot, "electron_cart") - MCFG_GENERIC_LOAD(electron_plus1_device, electron_cart_sk2) + MCFG_ELECTRON_CARTSLOT_ADD("cart_sk1", electron_cart, nullptr) + MCFG_ELECTRON_CARTSLOT_IRQ_HANDLER(WRITELINE(electron_plus1_device, irq_w)) + MCFG_ELECTRON_CARTSLOT_NMI_HANDLER(WRITELINE(electron_plus1_device, nmi_w)) + MCFG_ELECTRON_CARTSLOT_ADD("cart_sk2", electron_cart, nullptr) + MCFG_ELECTRON_CARTSLOT_IRQ_HANDLER(WRITELINE(electron_plus1_device, irq_w)) + MCFG_ELECTRON_CARTSLOT_NMI_HANDLER(WRITELINE(electron_plus1_device, nmi_w)) MACHINE_CONFIG_END //------------------------------------------------- @@ -152,6 +154,7 @@ electron_plus1_device::electron_plus1_device(const machine_config &mconfig, cons void electron_plus1_device::device_start() { + m_slot = dynamic_cast(owner()); } @@ -169,28 +172,39 @@ uint8_t electron_plus1_device::expbus_r(address_space &space, offs_t offset, uin case 1: if (m_cart_sk2->exists()) { - data = m_cart_sk2->read_rom(space, (offset & 0x3fff) + (m_romsel & 0x01) * 0x4000); + data = m_cart_sk2->read(space, offset & 0x3fff, 0, 0, m_romsel & 0x01); } break; case 2: case 3: if (m_cart_sk1->exists()) { - data = m_cart_sk1->read_rom(space, (offset & 0x3fff) + (m_romsel & 0x01) * 0x4000); + data = m_cart_sk1->read(space, offset & 0x3fff, 0, 0, m_romsel & 0x01); } break; case 12: - data = memregion("exp_rom")->base()[offset & 0x1fff]; + data = m_exp_rom->base()[offset & 0x1fff]; break; } } - else if (offset == 0xfc70) + else if ((offset & 0xfc00) == 0xfc00) { - data = m_adc->read(space, offset); + data &= m_cart_sk1->read(space, offset & 0xff, 1, 0, m_romsel & 0x01); + data &= m_cart_sk2->read(space, offset & 0xff, 1, 0, m_romsel & 0x01); + + if (offset == 0xfc70) + { + data &= m_adc->read(space, offset); + } + else if (offset == 0xfc72) + { + data &= status_r(space, offset); + } } - else if (offset == 0xfc72) + else if ((offset & 0xfd00) == 0xfd00) { - data = status_r(space, offset); + data &= m_cart_sk1->read(space, offset & 0xff, 0, 1, m_romsel & 0x01); + data &= m_cart_sk2->read(space, offset & 0xff, 0, 1, m_romsel & 0x01); } return data; @@ -203,17 +217,48 @@ uint8_t electron_plus1_device::expbus_r(address_space &space, offs_t offset, uin void electron_plus1_device::expbus_w(address_space &space, offs_t offset, uint8_t data) { - if (offset == 0xfc70) + if (offset >= 0x8000 && offset < 0xc000) { - m_adc->write(space, offset, data); + switch (m_romsel) + { + case 0: + case 1: + if (m_cart_sk2->exists()) + { + m_cart_sk2->write(space, offset & 0x3fff, data, 0, 0, m_romsel & 0x01); + } + break; + case 2: + case 3: + if (m_cart_sk1->exists()) + { + m_cart_sk1->write(space, offset & 0x3fff, data, 0, 0, m_romsel & 0x01); + } + break; + } } - else if (offset == 0xfc71) + else if ((offset & 0xfc00) == 0xfc00) { - m_cent_data_out->write(data); + m_cart_sk1->write(space, offset & 0xff, data, 1, 0, m_romsel & 0x01); + m_cart_sk2->write(space, offset & 0xff, data, 1, 0, m_romsel & 0x01); + + if (offset == 0xfc70) + { + m_adc->write(space, offset, data); + } + else if (offset == 0xfc71) + { + m_cent_data_out->write(data); + } + else if (offset == 0xfe05) + { + m_romsel = data & 0x0f; + } } - else if (offset == 0xfe05) + else if ((offset & 0xfd00) == 0xfd00) { - m_romsel = data & 0x0f; + m_cart_sk1->write(space, offset & 0xff, data, 0, 1, m_romsel & 0x01); + m_cart_sk2->write(space, offset & 0xff, data, 0, 1, m_romsel & 0x01); } } @@ -246,47 +291,12 @@ WRITE_LINE_MEMBER(electron_plus1_device::ready_w) m_adc_ready = !state; } -image_init_result electron_plus1_device::load_cart(device_image_interface &image, generic_slot_device *slot) +WRITE_LINE_MEMBER(electron_plus1_device::irq_w) { - if (image.software_entry() == nullptr) - { - uint32_t filesize = image.length(); - - if (filesize != 16384) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only size 16384 is supported"); - return image_init_result::FAIL; - } - - slot->rom_alloc(0x4000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - image.fread(slot->get_rom_base(), filesize); - return image_init_result::PASS; - } - else - { - int upsize = image.get_software_region_length("uprom"); - int losize = image.get_software_region_length("lorom"); - - if (upsize != 16384 && upsize != 0) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for uprom"); - return image_init_result::FAIL; - } - - if (losize != 16384 && losize != 0) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for lorom"); - return image_init_result::FAIL; - } - - slot->rom_alloc(0x8000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - - if (upsize) - memcpy(slot->get_rom_base(), image.get_software_region("uprom"), upsize); - - if (losize) - memcpy(slot->get_rom_base() + 0x4000, image.get_software_region("lorom"), losize); + m_slot->irq_w(state); +} - return image_init_result::PASS; - } +WRITE_LINE_MEMBER(electron_plus1_device::nmi_w) +{ + m_slot->nmi_w(state); } diff --git a/src/devices/bus/electron/plus1.h b/src/devices/bus/electron/plus1.h index f527703e9c8..415797905fd 100644 --- a/src/devices/bus/electron/plus1.h +++ b/src/devices/bus/electron/plus1.h @@ -14,8 +14,7 @@ #include "softlist.h" #include "machine/adc0844.h" #include "bus/centronics/ctronics.h" -#include "bus/generic/slot.h" -#include "bus/generic/carts.h" +#include "bus/electron/cart/slot.h" //************************************************************************** // TYPE DEFINITIONS @@ -45,14 +44,12 @@ private: DECLARE_READ8_MEMBER(status_r); DECLARE_WRITE_LINE_MEMBER(busy_w); DECLARE_WRITE_LINE_MEMBER(ready_w); - - image_init_result load_cart(device_image_interface &image, generic_slot_device *slot); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(electron_cart_sk1) { return load_cart(image, m_cart_sk1); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(electron_cart_sk2) { return load_cart(image, m_cart_sk2); } + DECLARE_WRITE_LINE_MEMBER(irq_w); + DECLARE_WRITE_LINE_MEMBER(nmi_w); required_memory_region m_exp_rom; - required_device m_cart_sk1; - required_device m_cart_sk2; + required_device m_cart_sk1; + required_device m_cart_sk2; required_device m_centronics; required_device m_cent_data_out; required_device m_adc; diff --git a/src/devices/bus/electron/plus3.cpp b/src/devices/bus/electron/plus3.cpp index 0a2be79a69e..62c30b1ad1f 100644 --- a/src/devices/bus/electron/plus3.cpp +++ b/src/devices/bus/electron/plus3.cpp @@ -66,7 +66,7 @@ ROM_END MACHINE_CONFIG_START(electron_plus3_device::device_add_mconfig) /* fdc */ - MCFG_WD1770_ADD("fdc", 16.0_MHz_XTAL / 2) + MCFG_WD1770_ADD("fdc", 16_MHz_XTAL / 2) MCFG_FLOPPY_DRIVE_ADD_FIXED("fdc:0", electron_floppies, "35dd", floppy_formats) MCFG_FLOPPY_DRIVE_SOUND(true) MCFG_FLOPPY_DRIVE_ADD("fdc:1", electron_floppies, nullptr, floppy_formats) diff --git a/src/devices/bus/electron/rombox.cpp b/src/devices/bus/electron/rombox.cpp index e5a1e2bff27..2ae1967c743 100644 --- a/src/devices/bus/electron/rombox.cpp +++ b/src/devices/bus/electron/rombox.cpp @@ -22,7 +22,7 @@ DEFINE_DEVICE_TYPE(ELECTRON_ROMBOX, electron_rombox_device, "electron_rombox", " //------------------------------------------------- -// MACHINE_DRIVER( rombox ) +// INPUT_PORTS( rombox ) //------------------------------------------------- static INPUT_PORTS_START( rombox ) @@ -39,7 +39,7 @@ static INPUT_PORTS_START( rombox ) INPUT_PORTS_END //------------------------------------------------- -// device_add_mconfig - add device configuration +// input_ports - device-specific input ports //------------------------------------------------- ioport_constructor electron_rombox_device::device_input_ports() const @@ -47,6 +47,10 @@ ioport_constructor electron_rombox_device::device_input_ports() const return INPUT_PORTS_NAME( rombox ); } +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + MACHINE_CONFIG_START(electron_rombox_device::device_add_mconfig) /* rom sockets */ MCFG_GENERIC_SOCKET_ADD("rom1", generic_plain_slot, "electron_rom") diff --git a/src/devices/bus/electron/romboxp.cpp b/src/devices/bus/electron/romboxp.cpp index 1baf1cdc99f..8fc1fdbc91a 100644 --- a/src/devices/bus/electron/romboxp.cpp +++ b/src/devices/bus/electron/romboxp.cpp @@ -4,6 +4,8 @@ Slogger Rombox Plus + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Slogger_RomBoxPlus.html + The Electron Rombox+ by Slogger has been designed to be compatible with the Acorn Plus 1 but with the added facility to allow the popular ROM based software to be used on the Electron microcomputer. @@ -26,7 +28,7 @@ DEFINE_DEVICE_TYPE(ELECTRON_ROMBOXP, electron_romboxp_device, "electron_romboxp", "Slogger Rombox+") //------------------------------------------------- -// MACHINE_DRIVER( romboxp ) +// ROM( romboxp ) //------------------------------------------------- ROM_START( romboxp ) @@ -55,6 +57,9 @@ ROM_START( romboxp ) ROMX_LOAD("elkexp210.rom", 0x0000, 0x2000, CRC(12442575) SHA1(eb8609991a9a8fb017b8100bfca4248d65faeea8), ROM_BIOS(7)) ROM_END +//------------------------------------------------- +// INPUT_PORTS( romboxp ) +//------------------------------------------------- static INPUT_PORTS_START( romboxp ) PORT_START("OPTION") @@ -67,7 +72,7 @@ static INPUT_PORTS_START( romboxp ) INPUT_PORTS_END //------------------------------------------------- -// device_add_mconfig - add device configuration +// input_ports - device-specific input ports //------------------------------------------------- ioport_constructor electron_romboxp_device::device_input_ports() const @@ -75,6 +80,10 @@ ioport_constructor electron_romboxp_device::device_input_ports() const return INPUT_PORTS_NAME( romboxp ); } +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + MACHINE_CONFIG_START(electron_romboxp_device::device_add_mconfig) /* printer */ MCFG_CENTRONICS_ADD("centronics", centronics_devices, "printer") @@ -96,10 +105,12 @@ MACHINE_CONFIG_START(electron_romboxp_device::device_add_mconfig) MCFG_GENERIC_LOAD(electron_romboxp_device, rom4_load) /* cartridges */ - MCFG_GENERIC_CARTSLOT_ADD("cart1", generic_plain_slot, "electron_cart") // ROM SLOT 0/1 - MCFG_GENERIC_LOAD(electron_romboxp_device, cart1_load) - MCFG_GENERIC_CARTSLOT_ADD("cart2", generic_plain_slot, "electron_cart") // ROM SLOT 2/3 - MCFG_GENERIC_LOAD(electron_romboxp_device, cart2_load) + MCFG_ELECTRON_CARTSLOT_ADD("cart1", electron_cart, nullptr) // ROM SLOT 0/1 + MCFG_ELECTRON_CARTSLOT_IRQ_HANDLER(WRITELINE(electron_romboxp_device, irq_w)) + MCFG_ELECTRON_CARTSLOT_NMI_HANDLER(WRITELINE(electron_romboxp_device, nmi_w)) + MCFG_ELECTRON_CARTSLOT_ADD("cart2", electron_cart, nullptr) // ROM SLOT 2/3 + MCFG_ELECTRON_CARTSLOT_IRQ_HANDLER(WRITELINE(electron_romboxp_device, irq_w)) + MCFG_ELECTRON_CARTSLOT_NMI_HANDLER(WRITELINE(electron_romboxp_device, nmi_w)) MACHINE_CONFIG_END const tiny_rom_entry *electron_romboxp_device::device_rom_region() const @@ -136,6 +147,7 @@ electron_romboxp_device::electron_romboxp_device(const machine_config &mconfig, void electron_romboxp_device::device_start() { + m_slot = dynamic_cast(owner()); } //------------------------------------------------- @@ -161,14 +173,14 @@ uint8_t electron_romboxp_device::expbus_r(address_space &space, offs_t offset, u case 1: if (m_cart[1]->exists()) { - data = m_cart[1]->read_rom(space, (offset & 0x3fff) + (m_romsel & 0x01) * 0x4000); + data = m_cart[1]->read(space, offset & 0x3fff, 0, 0, m_romsel & 0x01); } break; case 2: case 3: if (m_cart[0]->exists()) { - data = m_cart[0]->read_rom(space, (offset & 0x3fff) + (m_romsel & 0x01) * 0x4000); + data = m_cart[0]->read(space, offset & 0x3fff, 0, 0, m_romsel & 0x01); } break; case 4: @@ -181,7 +193,7 @@ uint8_t electron_romboxp_device::expbus_r(address_space &space, offs_t offset, u } break; case 12: - data = memregion("exp_rom")->base()[offset & 0x1fff]; + data = m_exp_rom->base()[offset & 0x1fff]; break; case 13: case 14: @@ -193,9 +205,20 @@ uint8_t electron_romboxp_device::expbus_r(address_space &space, offs_t offset, u break; } } - else if (offset == 0xfc72) + else if ((offset & 0xfc00) == 0xfc00) { - data = status_r(space, offset); + data &= m_cart[0]->read(space, offset & 0xff, 1, 0, m_romsel & 0x01); + data &= m_cart[1]->read(space, offset & 0xff, 1, 0, m_romsel & 0x01); + + if (offset == 0xfc72) + { + data &= status_r(space, offset); + } + } + else if ((offset & 0xfd00) == 0xfd00) + { + data &= m_cart[0]->read(space, offset & 0xff, 0, 1, m_romsel & 0x01); + data &= m_cart[1]->read(space, offset & 0xff, 0, 1, m_romsel & 0x01); } return data; @@ -207,13 +230,44 @@ uint8_t electron_romboxp_device::expbus_r(address_space &space, offs_t offset, u void electron_romboxp_device::expbus_w(address_space &space, offs_t offset, uint8_t data) { - if (offset == 0xfc71) + if (offset >= 0x8000 && offset < 0xc000) + { + switch (m_romsel) + { + case 0: + case 1: + if (m_cart[1]->exists()) + { + m_cart[1]->write(space, offset & 0x3fff, data, 0, 0, m_romsel & 0x01); + } + break; + case 2: + case 3: + if (m_cart[0]->exists()) + { + m_cart[0]->write(space, offset & 0x3fff, data, 0, 0, m_romsel & 0x01); + } + break; + } + } + else if ((offset & 0xfc00) == 0xfc00) { - m_cent_data_out->write(data); + m_cart[0]->write(space, offset & 0xff, data, 1, 0, m_romsel & 0x01); + m_cart[1]->write(space, offset & 0xff, data, 1, 0, m_romsel & 0x01); + + if (offset == 0xfc71) + { + m_cent_data_out->write(data); + } + else if (offset == 0xfe05) + { + m_romsel = data & 0x0f; + } } - else if (offset == 0xfe05) + else if ((offset & 0xfd00) == 0xfd00) { - m_romsel = data & 0x0f; + m_cart[0]->write(space, offset & 0xff, data, 0, 1, m_romsel & 0x01); + m_cart[1]->write(space, offset & 0xff, data, 0, 1, m_romsel & 0x01); } } @@ -255,48 +309,12 @@ image_init_result electron_romboxp_device::load_rom(device_image_interface &imag return image_init_result::PASS; } - -image_init_result electron_romboxp_device::load_cart(device_image_interface &image, generic_slot_device *slot) +WRITE_LINE_MEMBER(electron_romboxp_device::irq_w) { - if (image.software_entry() == nullptr) - { - uint32_t filesize = image.length(); - - if (filesize != 16384) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size: Only 16K is supported"); - return image_init_result::FAIL; - } - - slot->rom_alloc(0x4000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - image.fread(slot->get_rom_base(), filesize); - return image_init_result::PASS; - } - else - { - int upsize = image.get_software_region_length("uprom"); - int losize = image.get_software_region_length("lorom"); - - if (upsize != 16384 && upsize != 0) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for uprom"); - return image_init_result::FAIL; - } - - if (losize != 16384 && losize != 0) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "Invalid size for lorom"); - return image_init_result::FAIL; - } - - slot->rom_alloc(0x8000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - - if (upsize) - memcpy(slot->get_rom_base(), image.get_software_region("uprom"), upsize); - - if (losize) - memcpy(slot->get_rom_base() + 0x4000, image.get_software_region("lorom"), losize); + m_slot->irq_w(state); +} - return image_init_result::PASS; - } +WRITE_LINE_MEMBER(electron_romboxp_device::nmi_w) +{ + m_slot->nmi_w(state); } diff --git a/src/devices/bus/electron/romboxp.h b/src/devices/bus/electron/romboxp.h index 1b5646bbbb3..e350954eb18 100644 --- a/src/devices/bus/electron/romboxp.h +++ b/src/devices/bus/electron/romboxp.h @@ -4,6 +4,8 @@ Slogger Rombox Plus + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Slogger_RomBoxPlus.html + **********************************************************************/ @@ -12,6 +14,7 @@ #include "exp.h" #include "bus/centronics/ctronics.h" +#include "bus/electron/cart/slot.h" #include "bus/generic/slot.h" #include "bus/generic/carts.h" @@ -43,6 +46,8 @@ protected: private: DECLARE_READ8_MEMBER(status_r); DECLARE_WRITE_LINE_MEMBER(busy_w); + DECLARE_WRITE_LINE_MEMBER(irq_w); + DECLARE_WRITE_LINE_MEMBER(nmi_w); image_init_result load_rom(device_image_interface &image, generic_slot_device *slot); DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom1_load) { return load_rom(image, m_rom[0]); } @@ -50,13 +55,9 @@ private: DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom3_load) { return load_rom(image, m_rom[2]); } DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom4_load) { return load_rom(image, m_rom[3]); } - image_init_result load_cart(device_image_interface &image, generic_slot_device *slot); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart1_load) { return load_cart(image, m_cart[0]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart2_load) { return load_cart(image, m_cart[1]); } - required_memory_region m_exp_rom; required_device_array m_rom; - required_device_array m_cart; + required_device_array m_cart; required_device m_centronics; required_device m_cent_data_out; required_ioport m_option; diff --git a/src/mame/includes/electron.h b/src/mame/includes/electron.h index 589e79d1554..5a332cbd24d 100644 --- a/src/mame/includes/electron.h +++ b/src/mame/includes/electron.h @@ -43,6 +43,7 @@ public: m_maincpu(*this, "maincpu"), m_cassette(*this, "cassette"), m_beeper(*this, "beeper"), + m_region_basic(*this, "basic"), m_keybd(*this, "LINE.%u", 0), m_exp(*this, "exp"), m_ram(*this, RAM_TAG) @@ -106,6 +107,7 @@ public: required_device m_maincpu; required_device m_cassette; required_device m_beeper; + required_memory_region m_region_basic; required_ioport_array<14> m_keybd; required_device m_exp; required_device m_ram; diff --git a/src/mame/machine/electron.cpp b/src/mame/machine/electron.cpp index 923cb9ea565..a6fad3c6e74 100644 --- a/src/mame/machine/electron.cpp +++ b/src/mame/machine/electron.cpp @@ -192,7 +192,7 @@ READ8_MEMBER(electron_state::electron_paged_r) case 10: case 11: /* BASIC */ - data = memregion("basic")->base()[offset & 0x3fff]; + data = m_region_basic->base()[offset & 0x3fff]; break; default: @@ -210,9 +210,9 @@ WRITE8_MEMBER(electron_state::electron_paged_w) READ8_MEMBER(electron_state::electron_fred_r) { - /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfc */ + /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xff */ //logerror("FRED: read fc%02x\n", offset); - return m_exp->expbus_r(space, 0xfc00 + offset, 0xfc); + return m_exp->expbus_r(space, 0xfc00 + offset, 0xff); } WRITE8_MEMBER(electron_state::electron_fred_w) @@ -223,9 +223,9 @@ WRITE8_MEMBER(electron_state::electron_fred_w) READ8_MEMBER(electron_state::electron_jim_r) { - /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfd */ + /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xff */ //logerror("JIM: read fd%02x\n", offset); - return m_exp->expbus_r(space, 0xfd00 + offset, 0xfd); + return m_exp->expbus_r(space, 0xfd00 + offset, 0xff); } WRITE8_MEMBER(electron_state::electron_jim_w) @@ -237,7 +237,7 @@ WRITE8_MEMBER(electron_state::electron_jim_w) READ8_MEMBER(electron_state::electron_sheila_r) { /* The Issue 4 ULA returns data from OS ROM, whereas Issue 6 ULA will return 0xfe */ - uint8_t data = 0xfe; + uint8_t data = 0xff; switch ( offset & 0x0f ) { -- cgit v1.2.3