summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/electron/sidewndr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/electron/sidewndr.cpp')
-rw-r--r--src/devices/bus/electron/sidewndr.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/src/devices/bus/electron/sidewndr.cpp b/src/devices/bus/electron/sidewndr.cpp
new file mode 100644
index 00000000000..0298bbce8e5
--- /dev/null
+++ b/src/devices/bus/electron/sidewndr.cpp
@@ -0,0 +1,185 @@
+// license:BSD-3-Clause
+// copyright-holders:Nigel Barnes
+/**********************************************************************
+
+ Wizard Sidewinder Rom Expansion Board
+
+ TODO: Fire button doesn't seem to be recognised.
+
+**********************************************************************/
+
+#include "emu.h"
+#include "sidewndr.h"
+
+#include "bus/generic/slot.h"
+#include "bus/generic/carts.h"
+#include "bus/vcs_ctrl/ctrl.h"
+
+
+namespace {
+
+class electron_sidewndr_device
+ : public device_t
+ , public device_electron_expansion_interface
+{
+public:
+ electron_sidewndr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, ELECTRON_SIDEWNDR, tag, owner, clock)
+ , device_electron_expansion_interface(mconfig, *this)
+ , m_exp(*this, "exp")
+ , m_exp_rom(*this, "exp_rom")
+ , m_rom(*this, "rom%u", 1)
+ , m_joy(*this, "joy")
+ , m_romsel(0)
+ {
+ }
+
+protected:
+ // device_t overrides
+ virtual void device_start() override ATTR_COLD { }
+
+ // optional information overrides
+ virtual void device_add_mconfig(machine_config &config) override ATTR_COLD;
+ virtual const tiny_rom_entry *device_rom_region() const override ATTR_COLD;
+
+ virtual uint8_t expbus_r(offs_t offset) override;
+ virtual void expbus_w(offs_t offset, uint8_t data) override;
+
+private:
+ std::pair<std::error_condition, std::string> load_rom(device_image_interface &image, generic_slot_device *slot);
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom1_load) { return load_rom(image, m_rom[0]); }
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom2_load) { return load_rom(image, m_rom[1]); }
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom3_load) { return load_rom(image, m_rom[2]); }
+
+ required_device<electron_expansion_slot_device> m_exp;
+ required_memory_region m_exp_rom;
+ required_device_array<generic_slot_device, 3> m_rom;
+ required_device<vcs_control_port_device> m_joy;
+
+ uint8_t m_romsel;
+};
+
+
+//-------------------------------------------------
+// rom_region - device-specific ROM region
+//-------------------------------------------------
+
+ROM_START( sidewndr )
+ ROM_REGION(0x2000, "exp_rom", 0)
+ ROM_LOAD("joyrom.rom", 0x0000, 0x2000, CRC(a7320cda) SHA1(771664dbf23bb14febeb414a0272762cd6091ead))
+ROM_END
+
+const tiny_rom_entry *electron_sidewndr_device::device_rom_region() const
+{
+ return ROM_NAME( sidewndr );
+}
+
+
+//-------------------------------------------------
+// device_add_mconfig - add device configuration
+//-------------------------------------------------
+
+void electron_sidewndr_device::device_add_mconfig(machine_config &config)
+{
+ GENERIC_SOCKET(config, m_rom[0], generic_plain_slot, "electron_rom", "bin,rom"); // ROM SLOT 6
+ m_rom[0]->set_device_load(FUNC(electron_sidewndr_device::rom1_load));
+ GENERIC_SOCKET(config, m_rom[1], generic_plain_slot, "electron_rom", "bin,rom"); // ROM SLOT 7
+ m_rom[1]->set_device_load(FUNC(electron_sidewndr_device::rom2_load));
+ GENERIC_SOCKET(config, m_rom[2], generic_plain_slot, "electron_rom", "bin,rom"); // ROM SLOT 8
+ m_rom[2]->set_device_load(FUNC(electron_sidewndr_device::rom3_load));
+
+ VCS_CONTROL_PORT(config, m_joy, vcs_control_port_devices, "joy");
+
+ ELECTRON_EXPANSION_SLOT(config, m_exp, DERIVED_CLOCK(1, 1), electron_expansion_devices, nullptr);
+ m_exp->irq_handler().set(DEVICE_SELF_OWNER, FUNC(electron_expansion_slot_device::irq_w));
+ m_exp->nmi_handler().set(DEVICE_SELF_OWNER, FUNC(electron_expansion_slot_device::nmi_w));
+}
+
+
+//-------------------------------------------------
+// expbus_r - expansion data read
+//-------------------------------------------------
+
+uint8_t electron_sidewndr_device::expbus_r(offs_t offset)
+{
+ uint8_t data = 0xff;
+
+ switch (offset >> 12)
+ {
+ case 0x8: case 0x9: case 0xa: case 0xb:
+ switch (m_romsel)
+ {
+ case 5:
+ data = m_exp_rom->base()[offset & 0x0fff];
+ break;
+ case 6:
+ case 7:
+ case 8:
+ data = m_rom[m_romsel - 6]->read_rom(offset & 0x3fff);
+ break;
+ }
+ break;
+
+ case 0xf:
+ switch (offset >> 8)
+ {
+ case 0xfc:
+ if (offset == 0xfc05)
+ {
+ data = bitswap<8>(m_joy->read_joy(), 7, 6, 4, 5, 3, 2, 1, 0);
+ }
+ break;
+
+ case 0xfd:
+ data = m_exp_rom->base()[offset & 0x1dff];
+ break;
+ }
+ break;
+ }
+
+ data &= m_exp->expbus_r(offset);
+
+ return data;
+}
+
+//-------------------------------------------------
+// expbus_w - expansion data write
+//-------------------------------------------------
+
+void electron_sidewndr_device::expbus_w(offs_t offset, uint8_t data)
+{
+ m_exp->expbus_w(offset, data);
+
+ if ((offset == 0xfe05) && !(data & 0xf0))
+ {
+ m_romsel = data & 0x0f;
+ }
+}
+
+//**************************************************************************
+// IMPLEMENTATION
+//**************************************************************************
+
+std::pair<std::error_condition, std::string> electron_sidewndr_device::load_rom(device_image_interface &image, generic_slot_device *slot)
+{
+ uint32_t const size = slot->common_get_size("rom");
+
+ // socket accepts 8K and 16K ROM only
+ if (size != 0x2000 && size != 0x4000)
+ return std::make_pair(image_error::INVALIDLENGTH, "Invalid size: Only 8K/16K is supported");
+
+ slot->rom_alloc(0x4000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE);
+ slot->common_load_rom(slot->get_rom_base(), size, "rom");
+
+ // mirror 8K ROMs
+ uint8_t *const crt = slot->get_rom_base();
+ if (size <= 0x2000)
+ memcpy(crt + 0x2000, crt, 0x2000);
+
+ return std::make_pair(std::error_condition(), std::string());
+}
+
+} // anonymous namespace
+
+
+DEFINE_DEVICE_TYPE_PRIVATE(ELECTRON_SIDEWNDR, device_electron_expansion_interface, electron_sidewndr_device, "electron_sidewndr", "Wizard Sidewinder Rom Expansion Board")