diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 4892fd8b9b1..90e2a936c18 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -4108,6 +4108,8 @@ end --------------------------------------------------- if (BUSES["EPSON_QX"]~=null) then files { + MAME_DIR .. "src/devices/bus/epson_qx/cqgmem.cpp", + MAME_DIR .. "src/devices/bus/epson_qx/cqgmem.h", MAME_DIR .. "src/devices/bus/epson_qx/cr1510.cpp", MAME_DIR .. "src/devices/bus/epson_qx/cr1510.h", MAME_DIR .. "src/devices/bus/epson_qx/ide.cpp", diff --git a/src/devices/bus/epson_qx/cqgmem.cpp b/src/devices/bus/epson_qx/cqgmem.cpp new file mode 100644 index 00000000000..822e1ed516d --- /dev/null +++ b/src/devices/bus/epson_qx/cqgmem.cpp @@ -0,0 +1,134 @@ +// license:BSD-3-Clause +// copyright-holders:Brian Johnson +/******************************************************************* + * + * commodity quote graphics 1 megabyte memory expansion + * + *******************************************************************/ + +#include "emu.h" +#include "cqgmem.h" + +//************************************************************************** +// CQGMEM DEVICE +//************************************************************************** + +DEFINE_DEVICE_TYPE(EPSON_QX_OPTION_CQGMEM, bus::epson_qx::cqgmem_device, "option_cqgmem", "Epson QX-10 1MB Memory Expansion") + +namespace bus::epson_qx { + +static INPUT_PORTS_START( cqgmem ) + PORT_START("IOBASE") + PORT_CONFNAME(0xf0, 0xf0, "IO Base Address Selection") + PORT_CONFSETTING(0x80, "&80") + PORT_CONFSETTING(0x90, "&90") + PORT_CONFSETTING(0xa0, "&A0") + PORT_CONFSETTING(0xb0, "&B0") + PORT_CONFSETTING(0xc0, "&C0") + PORT_CONFSETTING(0xd0, "&D0") + PORT_CONFSETTING(0xe0, "&E0") + PORT_CONFSETTING(0xf0, "&F0") +INPUT_PORTS_END + +//------------------------------------------------- +// cqgmem_device - constructor +//------------------------------------------------- +cqgmem_device::cqgmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, EPSON_QX_OPTION_CQGMEM, tag, owner, clock), + device_option_expansion_interface(mconfig, *this), + device_memory_interface(mconfig, *this), + m_ram(*this, "xmem", 0x100000, ENDIANNESS_LITTLE), + m_banks(*this, "bank%u", 0U), + m_iobase(*this, "IOBASE"), + m_space_config("xmem", ENDIANNESS_LITTLE, 8, 20, 0, address_map_constructor(FUNC(cqgmem_device::xmem_map), this)), + m_installed(false) +{ +} + +//------------------------------------------------- +// device_input_ports - device-specific ports +//------------------------------------------------- +ioport_constructor cqgmem_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( cqgmem ); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- +void cqgmem_device::device_start() +{ + m_installed = false; + + save_item(NAME(m_installed)); + save_item(NAME(m_banks_enabled)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- +void cqgmem_device::device_reset() +{ + if (!m_installed) { + address_space &space = m_bus->iospace(); + offs_t iobase = m_iobase->read() & 0xf0; + space.install_device(iobase, iobase+0x07, *this, &cqgmem_device::io_map); + + for (int i = 0; i < m_banks.size(); ++i) { + m_banks[i]->configure_entries(0, 128, m_ram, 0x2000); + } + } + + m_banks_enabled = 0; + + for (int i = 0; i < m_banks.size(); ++i) { + m_banks[i]->set_entry(0); + } +} + +// memory_space_config - return a description of +// any address spaces owned by this device +//------------------------------------------------- + +device_memory_interface::space_config_vector cqgmem_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(0, &m_space_config) + }; +} + +void cqgmem_device::xmem_map(address_map &map) +{ + map(0x00000, 0xfffff).ram().share("xmem"); +} + +void cqgmem_device::write(offs_t offset, uint8_t data) +{ + memory_view::memory_view_entry &view = m_bus->memview(); + + uint8_t bank = offset & 0x07; + uint8_t page = data & 0x7f; + uint8_t enable = (m_banks_enabled & ~((data & 0x80) >> bank)) | ((data & 0x80) >> bank); + uint16_t bank_addr = bank * 0x2000; + + m_banks[bank]->set_entry(page); + + if (data & 0x80) { + if (enable != m_banks_enabled) { + view.unmap_readwrite(bank_addr, bank_addr + 0x1fff); + view.install_readwrite_bank(bank_addr, bank_addr + 0x1fff, m_banks[bank]); + } + } else { + if (enable != m_banks_enabled) { + view.unmap_readwrite(bank_addr, bank_addr + 0x1fff); + } + } + m_banks_enabled = enable; +} + +void cqgmem_device::io_map(address_map &map) +{ + map(0x00, 0x06).w(FUNC(cqgmem_device::write)); +} + +} // namespace bus::epson_qx diff --git a/src/devices/bus/epson_qx/cqgmem.h b/src/devices/bus/epson_qx/cqgmem.h new file mode 100644 index 00000000000..ba019059c3e --- /dev/null +++ b/src/devices/bus/epson_qx/cqgmem.h @@ -0,0 +1,61 @@ +// license:BSD-3-Clause +// copyright-holders:Brian Johnson +/******************************************************************* + * + * commodity quote graphics 1 megabyte memory expansion + * + *******************************************************************/ + +#ifndef MAME_BUS_EPSON_QX_CQGMEM_H +#define MAME_BUS_EPSON_QX_CQGMEM_H + +#pragma once + +#include "option.h" + +namespace bus::epson_qx { + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +/* commodity quote graphics 1M memory expansion */ + +class cqgmem_device : public device_t, public device_option_expansion_interface, public device_memory_interface +{ +public: + // construction/destruction + cqgmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + virtual space_config_vector memory_space_config() const override; + + void write(offs_t offset, uint8_t data); + + void io_map(address_map &map); + void xmem_map(address_map &map); + +private: + uint8_t m_banks_enabled; + + memory_share_creator m_ram; + memory_bank_array_creator<7> m_banks; + required_ioport m_iobase; + const address_space_config m_space_config; + + bool m_installed; +}; + +} // namespace bus::epson_qx + +// device type definition +DECLARE_DEVICE_TYPE_NS(EPSON_QX_OPTION_CQGMEM, bus::epson_qx, cqgmem_device) + + +#endif // MAME_BUS_EPSON_QX_CQGMEM_H diff --git a/src/devices/bus/epson_qx/option.cpp b/src/devices/bus/epson_qx/option.cpp index 5b6ad3a0f3e..620570e2b22 100644 --- a/src/devices/bus/epson_qx/option.cpp +++ b/src/devices/bus/epson_qx/option.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "option.h" +#include "cqgmem.h" #include "cr1510.h" #include "ide.h" #include "multifont.h" @@ -210,6 +211,7 @@ void device_option_expansion_interface::interface_pre_start() void option_bus_devices(device_slot_interface &device) { + device.option_add("cqgmem", EPSON_QX_OPTION_CQGMEM); device.option_add("cr1510", EPSON_QX_OPTION_CR1510); device.option_add("ide", EPSON_QX_OPTION_IDE); device.option_add("multifont", EPSON_QX_OPTION_MULTIFONT);